1
0
Fork 0
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:
Konstantin Ivanov 2023-08-30 10:12:15 +02:00 committed by GitHub
parent 750e9f79ab
commit c506825251
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 113 additions and 17 deletions

View file

@ -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
}
}
}
}

View file

@ -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

View file

@ -125,6 +125,8 @@ sealed class ObjectWrapper {
}
else -> emptyList()
}
val targetObjectType: Id? by default
}
/**

View file

@ -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 -> {}
}
}

View 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>

View file

@ -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>

View file

@ -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()
)
}

View file

@ -14,5 +14,6 @@ enum class ObjectAction {
LOCK,
UNLOCK,
LINK_TO,
DELETE_FILES
DELETE_FILES,
SET_AS_DEFAULT
}

View file

@ -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
}
}

View file

@ -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")
}
}