mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
DROID-1460 Editor | Enhancement | Set as default template (#322)
This commit is contained in:
parent
750e9f79ab
commit
c506825251
10 changed files with 113 additions and 17 deletions
|
@ -1,22 +1,12 @@
|
|||
package com.anytypeio.anytype.analytics.props
|
||||
|
||||
data class Props(val map: Map<String?, Any?>) {
|
||||
private val default = map.withDefault { null }
|
||||
|
||||
companion object {
|
||||
|
||||
const val CHAR_TYPE_BUNDLED = '_'
|
||||
const val OBJ_TYPE_CUSTOM = "custom"
|
||||
const val OBJ_LAYOUT_NONE = "none"
|
||||
|
||||
fun empty() = Props(emptyMap())
|
||||
|
||||
fun mapType(type: String): String {
|
||||
return if (type.startsWith(CHAR_TYPE_BUNDLED, ignoreCase = true)) {
|
||||
type
|
||||
} else {
|
||||
OBJ_TYPE_CUSTOM
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ package com.anytypeio.anytype.di.feature
|
|||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.core_models.Payload
|
||||
import com.anytypeio.anytype.core_utils.di.scope.PerDialog
|
||||
import com.anytypeio.anytype.core_utils.di.scope.PerScreen
|
||||
import com.anytypeio.anytype.core_utils.tools.FeatureToggles
|
||||
import com.anytypeio.anytype.domain.`object`.DuplicateObject
|
||||
import com.anytypeio.anytype.domain.auth.repo.AuthRepository
|
||||
|
@ -14,6 +15,7 @@ import com.anytypeio.anytype.domain.collections.AddObjectToCollection
|
|||
import com.anytypeio.anytype.domain.dashboard.interactor.AddToFavorite
|
||||
import com.anytypeio.anytype.domain.dashboard.interactor.RemoveFromFavorite
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.domain.`object`.SetObjectDetails
|
||||
import com.anytypeio.anytype.domain.objects.SetObjectIsArchived
|
||||
import com.anytypeio.anytype.domain.page.AddBackLinkToObject
|
||||
import com.anytypeio.anytype.domain.page.CloseBlock
|
||||
|
@ -114,7 +116,8 @@ object ObjectMenuModule {
|
|||
featureToggles: FeatureToggles,
|
||||
delegator: Delegator<Action>,
|
||||
addObjectToCollection: AddObjectToCollection,
|
||||
createTemplateFromObject: CreateTemplateFromObject
|
||||
createTemplateFromObject: CreateTemplateFromObject,
|
||||
setObjectDetails: SetObjectDetails
|
||||
): ObjectMenuViewModel.Factory = ObjectMenuViewModel.Factory(
|
||||
setObjectIsArchived = setObjectIsArchived,
|
||||
duplicateObject = duplicateObject,
|
||||
|
@ -130,7 +133,19 @@ object ObjectMenuModule {
|
|||
delegator = delegator,
|
||||
menuOptionsProvider = createMenuOptionsProvider(storage, featureToggles),
|
||||
addObjectToCollection = addObjectToCollection,
|
||||
createTemplateFromObject = createTemplateFromObject
|
||||
createTemplateFromObject = createTemplateFromObject,
|
||||
setObjectDetails = setObjectDetails
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@PerDialog
|
||||
fun provideSetObjectDetails(
|
||||
repo: BlockRepository,
|
||||
dispatchers: AppCoroutineDispatchers
|
||||
): SetObjectDetails = SetObjectDetails(
|
||||
repo,
|
||||
dispatchers
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
|
|
|
@ -125,6 +125,8 @@ sealed class ObjectWrapper {
|
|||
}
|
||||
else -> emptyList()
|
||||
}
|
||||
|
||||
val targetObjectType: Id? by default
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -80,6 +80,10 @@ class ObjectActionAdapter(
|
|||
ivActionIcon.setImageResource(R.drawable.ic_object_action_template)
|
||||
tvActionTitle.setText(R.string.make_template)
|
||||
}
|
||||
ObjectAction.SET_AS_DEFAULT -> {
|
||||
ivActionIcon.setImageResource(R.drawable.ic_set_as_default_24)
|
||||
tvActionTitle.setText(R.string.set_as_default)
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
|
16
core-ui/src/main/res/drawable/ic_set_as_default_24.xml
Normal file
16
core-ui/src/main/res/drawable/ic_set_as_default_24.xml
Normal file
|
@ -0,0 +1,16 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M3.707,9.807C3.317,10.197 3.317,10.83 3.707,11.221L13.779,21.293C14.17,21.683 14.803,21.683 15.193,21.293L16.27,20.216C16.483,20.003 16.588,19.706 16.557,19.406L16.17,15.673C16.136,15.344 16.266,15.02 16.518,14.807L22.172,10.012C22.618,9.633 22.646,8.955 22.232,8.542L16.458,2.768C16.045,2.354 15.367,2.382 14.988,2.828L10.192,8.482C9.978,8.734 9.654,8.864 9.326,8.83L5.594,8.443C5.294,8.412 4.997,8.517 4.784,8.73L3.707,9.807Z"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="1.5"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="@color/glyph_active"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M2.47,20.47C2.177,20.763 2.177,21.237 2.47,21.53C2.763,21.823 3.237,21.823 3.53,21.53L2.47,20.47ZM3.53,21.53L9.187,15.873L8.127,14.813L2.47,20.47L3.53,21.53Z"
|
||||
android:fillColor="@color/glyph_active"/>
|
||||
</vector>
|
|
@ -654,5 +654,6 @@
|
|||
<string name="templates_menu_duplicate">Duplicate</string>
|
||||
<string name="templates_menu_delete">Delete</string>
|
||||
<string name="unsupported">Unsupported</string>
|
||||
<string name="set_as_default">Set as default</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -5,6 +5,7 @@ import com.anytypeio.anytype.analytics.base.EventsDictionary
|
|||
import com.anytypeio.anytype.analytics.base.EventsDictionary.addFilter
|
||||
import com.anytypeio.anytype.analytics.base.EventsDictionary.addSort
|
||||
import com.anytypeio.anytype.analytics.base.EventsDictionary.addView
|
||||
import com.anytypeio.anytype.analytics.base.EventsDictionary.changeDefaultTemplate
|
||||
import com.anytypeio.anytype.analytics.base.EventsDictionary.changeFilterValue
|
||||
import com.anytypeio.anytype.analytics.base.EventsDictionary.changeSortValue
|
||||
import com.anytypeio.anytype.analytics.base.EventsDictionary.changeViewType
|
||||
|
@ -1750,4 +1751,25 @@ fun CoroutineScope.sendAnalyticsCreateTemplateEvent(
|
|||
startTime = startTime,
|
||||
middleTime = System.currentTimeMillis()
|
||||
)
|
||||
}
|
||||
|
||||
fun CoroutineScope.sendAnalyticsDefaultTemplateEvent(
|
||||
analytics: Analytics,
|
||||
objType: ObjectWrapper.Type,
|
||||
startTime: Long,
|
||||
route: String? = null
|
||||
) {
|
||||
val objectType = objType.sourceObject ?: OBJ_TYPE_CUSTOM
|
||||
sendEvent(
|
||||
analytics = analytics,
|
||||
eventName = changeDefaultTemplate,
|
||||
props = Props(
|
||||
buildMap {
|
||||
put(EventsPropertiesKey.type, objectType)
|
||||
put(EventsPropertiesKey.route, route)
|
||||
}
|
||||
),
|
||||
startTime = startTime,
|
||||
middleTime = System.currentTimeMillis()
|
||||
)
|
||||
}
|
|
@ -14,5 +14,6 @@ enum class ObjectAction {
|
|||
LOCK,
|
||||
UNLOCK,
|
||||
LINK_TO,
|
||||
DELETE_FILES
|
||||
DELETE_FILES,
|
||||
SET_AS_DEFAULT
|
||||
}
|
|
@ -10,6 +10,7 @@ import com.anytypeio.anytype.core_models.Block
|
|||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.ObjectWrapper
|
||||
import com.anytypeio.anytype.core_models.Payload
|
||||
import com.anytypeio.anytype.core_models.Relations
|
||||
import com.anytypeio.anytype.core_models.restrictions.ObjectRestriction
|
||||
import com.anytypeio.anytype.domain.base.fold
|
||||
import com.anytypeio.anytype.domain.block.interactor.UpdateFields
|
||||
|
@ -18,6 +19,7 @@ import com.anytypeio.anytype.domain.dashboard.interactor.AddToFavorite
|
|||
import com.anytypeio.anytype.domain.dashboard.interactor.RemoveFromFavorite
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.domain.`object`.DuplicateObject
|
||||
import com.anytypeio.anytype.domain.`object`.SetObjectDetails
|
||||
import com.anytypeio.anytype.domain.objects.SetObjectIsArchived
|
||||
import com.anytypeio.anytype.domain.page.AddBackLinkToObject
|
||||
import com.anytypeio.anytype.domain.templates.CreateTemplateFromObject
|
||||
|
@ -25,6 +27,8 @@ import com.anytypeio.anytype.presentation.common.Action
|
|||
import com.anytypeio.anytype.presentation.common.Delegator
|
||||
import com.anytypeio.anytype.presentation.editor.Editor
|
||||
import com.anytypeio.anytype.presentation.extension.sendAnalyticsCreateTemplateEvent
|
||||
import com.anytypeio.anytype.presentation.extension.sendAnalyticsDefaultTemplateEvent
|
||||
import com.anytypeio.anytype.presentation.extension.sendAnalyticsCreateTemplateEvent
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectAction
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectIcon
|
||||
import com.anytypeio.anytype.presentation.objects.getProperName
|
||||
|
@ -50,7 +54,8 @@ class ObjectMenuViewModel(
|
|||
private val analytics: Analytics,
|
||||
private val updateFields: UpdateFields,
|
||||
private val addObjectToCollection: AddObjectToCollection,
|
||||
private val createTemplateFromObject: CreateTemplateFromObject
|
||||
private val createTemplateFromObject: CreateTemplateFromObject,
|
||||
private val setObjectDetails: SetObjectDetails
|
||||
) : ObjectMenuViewModelBase(
|
||||
setObjectIsArchived = setObjectIsArchived,
|
||||
addToFavorite = addToFavorite,
|
||||
|
@ -89,11 +94,17 @@ class ObjectMenuViewModel(
|
|||
add(ObjectAction.DELETE)
|
||||
}
|
||||
}
|
||||
add(ObjectAction.UNDO_REDO)
|
||||
|
||||
if (isTemplate) {
|
||||
add(ObjectAction.SET_AS_DEFAULT)
|
||||
}
|
||||
|
||||
if (!isProfile && !objectRestrictions.contains(ObjectRestriction.DUPLICATE)) {
|
||||
add(ObjectAction.DUPLICATE)
|
||||
}
|
||||
|
||||
add(ObjectAction.UNDO_REDO)
|
||||
|
||||
val objTypeId = storage.details.current().details[ctx]?.type?.firstOrNull()
|
||||
storage.details.current().details[objTypeId]?.let { objType ->
|
||||
val objTypeWrapper = ObjectWrapper.Type(objType.map)
|
||||
|
@ -248,6 +259,9 @@ class ObjectMenuViewModel(
|
|||
ObjectAction.USE_AS_TEMPLATE -> {
|
||||
proceedWithCreatingTemplateFromObject(ctx)
|
||||
}
|
||||
ObjectAction.SET_AS_DEFAULT -> {
|
||||
proceedWithSettingAsDefaultTemplate(ctx = ctx)
|
||||
}
|
||||
ObjectAction.MOVE_TO,
|
||||
ObjectAction.MOVE_TO_BIN,
|
||||
ObjectAction.DELETE_FILES -> {
|
||||
|
@ -256,6 +270,34 @@ class ObjectMenuViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
private fun proceedWithSettingAsDefaultTemplate(ctx: Id) {
|
||||
val startTime = System.currentTimeMillis()
|
||||
val objTemplate = ObjectWrapper.Basic(
|
||||
storage.details.current().details[ctx]?.map ?: emptyMap()
|
||||
)
|
||||
val targetObjectTypeId = objTemplate.targetObjectType ?: return
|
||||
val objType = ObjectWrapper.Type(
|
||||
storage.details.current().details[targetObjectTypeId]?.map ?: emptyMap()
|
||||
)
|
||||
viewModelScope.launch {
|
||||
val params = SetObjectDetails.Params(
|
||||
ctx = targetObjectTypeId,
|
||||
details = mapOf(Relations.DEFAULT_TEMPLATE_ID to ctx)
|
||||
)
|
||||
setObjectDetails.async(params).fold(
|
||||
onSuccess = {
|
||||
sendAnalyticsDefaultTemplateEvent(analytics, objType, startTime)
|
||||
_toasts.emit("Template is set as default")
|
||||
isDismissed.value = true
|
||||
},
|
||||
onFailure = {
|
||||
Timber.e(it, "Error while setting template as default")
|
||||
_toasts.emit(SOMETHING_WENT_WRONG_MSG)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun proceedWithCreatingTemplateFromObject(ctx: Id) {
|
||||
val startTime = System.currentTimeMillis()
|
||||
viewModelScope.launch {
|
||||
|
@ -356,7 +398,8 @@ class ObjectMenuViewModel(
|
|||
private val delegator: Delegator<Action>,
|
||||
private val menuOptionsProvider: ObjectMenuOptionsProvider,
|
||||
private val addObjectToCollection: AddObjectToCollection,
|
||||
private val createTemplateFromObject: CreateTemplateFromObject
|
||||
private val createTemplateFromObject: CreateTemplateFromObject,
|
||||
private val setObjectDetails: SetObjectDetails
|
||||
) : ViewModelProvider.Factory {
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return ObjectMenuViewModel(
|
||||
|
@ -374,7 +417,8 @@ class ObjectMenuViewModel(
|
|||
delegator = delegator,
|
||||
menuOptionsProvider = menuOptionsProvider,
|
||||
addObjectToCollection = addObjectToCollection,
|
||||
createTemplateFromObject = createTemplateFromObject
|
||||
createTemplateFromObject = createTemplateFromObject,
|
||||
setObjectDetails = setObjectDetails
|
||||
) as T
|
||||
}
|
||||
}
|
||||
|
|
|
@ -178,6 +178,7 @@ class ObjectSetMenuViewModel(
|
|||
ObjectAction.UNLOCK,
|
||||
ObjectAction.MOVE_TO_BIN,
|
||||
ObjectAction.USE_AS_TEMPLATE,
|
||||
ObjectAction.SET_AS_DEFAULT,
|
||||
ObjectAction.DELETE_FILES -> throw IllegalStateException("$action is unsupported")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue