mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
DROID-1460 Editor | Enhancement | Use-current-object-as-template action (#315)
This commit is contained in:
parent
1ca5bb5632
commit
750e9f79ab
22 changed files with 232 additions and 24 deletions
|
@ -18,6 +18,7 @@ import com.anytypeio.anytype.domain.objects.SetObjectIsArchived
|
|||
import com.anytypeio.anytype.domain.page.AddBackLinkToObject
|
||||
import com.anytypeio.anytype.domain.page.CloseBlock
|
||||
import com.anytypeio.anytype.domain.page.OpenPage
|
||||
import com.anytypeio.anytype.domain.templates.CreateTemplateFromObject
|
||||
import com.anytypeio.anytype.presentation.common.Action
|
||||
import com.anytypeio.anytype.presentation.common.Delegator
|
||||
import com.anytypeio.anytype.presentation.editor.Editor
|
||||
|
@ -112,7 +113,8 @@ object ObjectMenuModule {
|
|||
updateFields: UpdateFields,
|
||||
featureToggles: FeatureToggles,
|
||||
delegator: Delegator<Action>,
|
||||
addObjectToCollection: AddObjectToCollection
|
||||
addObjectToCollection: AddObjectToCollection,
|
||||
createTemplateFromObject: CreateTemplateFromObject
|
||||
): ObjectMenuViewModel.Factory = ObjectMenuViewModel.Factory(
|
||||
setObjectIsArchived = setObjectIsArchived,
|
||||
duplicateObject = duplicateObject,
|
||||
|
@ -127,7 +129,8 @@ object ObjectMenuModule {
|
|||
updateFields = updateFields,
|
||||
delegator = delegator,
|
||||
menuOptionsProvider = createMenuOptionsProvider(storage, featureToggles),
|
||||
addObjectToCollection = addObjectToCollection
|
||||
addObjectToCollection = addObjectToCollection,
|
||||
createTemplateFromObject = createTemplateFromObject
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
|
|
|
@ -32,6 +32,9 @@ import androidx.core.view.WindowInsetsCompat
|
|||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleEventObserver
|
||||
import androidx.lifecycle.distinctUntilChanged
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.DefaultItemAnimator
|
||||
|
@ -145,6 +148,7 @@ import com.anytypeio.anytype.ui.relations.RelationAddToObjectBlockFragment
|
|||
import com.anytypeio.anytype.ui.relations.RelationDateValueFragment
|
||||
import com.anytypeio.anytype.ui.relations.RelationTextValueFragment
|
||||
import com.anytypeio.anytype.ui.relations.RelationValueFragment
|
||||
import com.anytypeio.anytype.ui.templates.EditorTemplateFragment
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import javax.inject.Inject
|
||||
|
@ -506,6 +510,8 @@ open class EditorFragment : NavigationFragment<FragmentEditorBinding>(R.layout.f
|
|||
OutsideClickDetector(vm::onOutsideClicked)
|
||||
)
|
||||
|
||||
observeSelectingTemplate()
|
||||
|
||||
binding.recycler.apply {
|
||||
layoutManager = LinearLayoutManager(requireContext())
|
||||
setHasFixedSize(true)
|
||||
|
@ -2088,6 +2094,30 @@ open class EditorFragment : NavigationFragment<FragmentEditorBinding>(R.layout.f
|
|||
}
|
||||
}
|
||||
|
||||
open fun observeSelectingTemplate() {
|
||||
val navController = findNavController()
|
||||
val navBackStackEntry = navController.getBackStackEntry(R.id.pageScreen)
|
||||
val observer = LifecycleEventObserver { _, event ->
|
||||
if (event == Lifecycle.Event.ON_RESUME
|
||||
&& navBackStackEntry.savedStateHandle.contains(EditorTemplateFragment.ARG_TEMPLATE_ID)
|
||||
) {
|
||||
val result =
|
||||
navBackStackEntry.savedStateHandle.get<String>(EditorTemplateFragment.ARG_TEMPLATE_ID);
|
||||
if (!result.isNullOrBlank()) {
|
||||
navBackStackEntry.savedStateHandle.remove<String>(EditorTemplateFragment.ARG_TEMPLATE_ID)
|
||||
vm.onCreateObjectWithTemplateClicked(template = result)
|
||||
}
|
||||
}
|
||||
}
|
||||
navBackStackEntry.lifecycle.addObserver(observer)
|
||||
|
||||
viewLifecycleOwner.lifecycle.addObserver(LifecycleEventObserver { _, event ->
|
||||
if (event == Lifecycle.Event.ON_DESTROY) {
|
||||
navBackStackEntry.lifecycle.removeObserver(observer)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//------------ End of Anytype Custom Context Menu ------------
|
||||
|
||||
override fun inflateBinding(
|
||||
|
|
|
@ -25,6 +25,7 @@ import com.anytypeio.anytype.databinding.FragmentObjectMenuBinding
|
|||
import com.anytypeio.anytype.presentation.objects.ObjectIcon
|
||||
import com.anytypeio.anytype.presentation.objects.menu.ObjectMenuOptionsProvider
|
||||
import com.anytypeio.anytype.presentation.objects.menu.ObjectMenuViewModelBase
|
||||
import com.anytypeio.anytype.ui.editor.EditorModalFragment
|
||||
import com.anytypeio.anytype.ui.editor.cover.SelectCoverObjectFragment
|
||||
import com.anytypeio.anytype.ui.editor.cover.SelectCoverObjectSetFragment
|
||||
import com.anytypeio.anytype.ui.editor.layout.ObjectLayoutFragment
|
||||
|
@ -130,9 +131,18 @@ abstract class ObjectMenuBaseFragment :
|
|||
ObjectMenuViewModelBase.Command.OpenLinkToChooser -> openLinkChooser()
|
||||
is ObjectMenuViewModelBase.Command.OpenSnackbar -> openSnackbar(command)
|
||||
is ObjectMenuViewModelBase.Command.ShareDebugTree -> shareFile(command.uri)
|
||||
is ObjectMenuViewModelBase.Command.OpenTemplate -> openTemplate(command)
|
||||
}
|
||||
}
|
||||
|
||||
private fun openTemplate(command: ObjectMenuViewModelBase.Command.OpenTemplate) {
|
||||
toast(getString(R.string.snackbar_template_add) + command.typeName)
|
||||
findNavController().navigate(
|
||||
R.id.nav_editor_modal,
|
||||
bundleOf(EditorModalFragment.ARG_ID to command.template)
|
||||
)
|
||||
}
|
||||
|
||||
private fun openObjectCover() {
|
||||
findNavController().navigate(
|
||||
R.id.objectCoverScreen,
|
||||
|
|
|
@ -31,6 +31,8 @@ import androidx.core.view.updateLayoutParams
|
|||
import androidx.core.view.updatePadding
|
||||
import androidx.fragment.app.setFragmentResultListener
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleEventObserver
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
|
@ -99,7 +101,6 @@ import com.anytypeio.anytype.ui.sets.modals.ObjectSetSettingsFragment
|
|||
import com.anytypeio.anytype.ui.sets.modals.SetObjectCreateRecordFragmentBase
|
||||
import com.anytypeio.anytype.ui.sets.modals.sort.ViewerSortFragment
|
||||
import com.anytypeio.anytype.ui.templates.EditorTemplateFragment.Companion.ARG_TEMPLATE_ID
|
||||
import com.anytypeio.anytype.ui.templates.EditorTemplateFragment.Companion.SELECTED_TEMPLATE_INITIAL_VALUE
|
||||
import com.bumptech.glide.Glide
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
|
@ -1166,13 +1167,25 @@ open class ObjectSetFragment :
|
|||
)
|
||||
|
||||
private fun observeSelectingTemplate() {
|
||||
findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<String>(
|
||||
ARG_TEMPLATE_ID,
|
||||
SELECTED_TEMPLATE_INITIAL_VALUE
|
||||
)?.observe(viewLifecycleOwner) { template: Id ->
|
||||
Timber.d("Get result from EditorTemplateFragment: $template")
|
||||
if (template.isNotEmpty()) vm.proceedWithCreatingNewDataViewObject(template)
|
||||
val navController = findNavController()
|
||||
val navBackStackEntry = navController.getBackStackEntry(R.id.objectSetScreen)
|
||||
val observer = LifecycleEventObserver { _, event ->
|
||||
if (event == Lifecycle.Event.ON_RESUME
|
||||
&& navBackStackEntry.savedStateHandle.contains(ARG_TEMPLATE_ID)) {
|
||||
val result = navBackStackEntry.savedStateHandle.get<String>(ARG_TEMPLATE_ID);
|
||||
if (!result.isNullOrBlank()) {
|
||||
navBackStackEntry.savedStateHandle.remove<String>(ARG_TEMPLATE_ID)
|
||||
vm.proceedWithCreatingNewDataViewObject(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
navBackStackEntry.lifecycle.addObserver(observer)
|
||||
|
||||
viewLifecycleOwner.lifecycle.addObserver(LifecycleEventObserver { _, event ->
|
||||
if (event == Lifecycle.Event.ON_DESTROY) {
|
||||
navBackStackEntry.lifecycle.removeObserver(observer)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -73,6 +73,10 @@ class EditorTemplateFragment : EditorFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
override fun observeSelectingTemplate() {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(id: String): EditorTemplateFragment =
|
||||
EditorTemplateFragment().apply {
|
||||
|
@ -80,6 +84,5 @@ class EditorTemplateFragment : EditorFragment() {
|
|||
}
|
||||
|
||||
const val ARG_TEMPLATE_ID = "template_id"
|
||||
const val SELECTED_TEMPLATE_INITIAL_VALUE = ""
|
||||
}
|
||||
}
|
|
@ -308,6 +308,7 @@
|
|||
android:id="@+id/btnSelectTemplate"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/dp_10"
|
||||
android:layout_marginStart="@dimen/dp_20"
|
||||
android:layout_marginEnd="@dimen/dp_20"
|
||||
android:text="Select Template"
|
||||
|
|
|
@ -76,8 +76,9 @@ class ObjectActionAdapter(
|
|||
ivActionIcon.setImageResource(R.drawable.ic_object_action_link_to)
|
||||
tvActionTitle.setText(R.string.link_to)
|
||||
}
|
||||
ObjectAction.MOVE_TO -> {
|
||||
|
||||
ObjectAction.USE_AS_TEMPLATE -> {
|
||||
ivActionIcon.setImageResource(R.drawable.ic_object_action_template)
|
||||
tvActionTitle.setText(R.string.make_template)
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
|
|
|
@ -265,6 +265,7 @@
|
|||
<string name="move_to">Move to</string>
|
||||
<string name="preview">Preview</string>
|
||||
<string name="link_to">Link to</string>
|
||||
<string name="make_template">Make template</string>
|
||||
<string name="linked_to">Linked to</string>
|
||||
<string name="remove_link">Remove link</string>
|
||||
<string name="mention_suggester_new_page">Create new object</string>
|
||||
|
|
|
@ -849,4 +849,8 @@ class BlockDataRepository(
|
|||
override suspend fun duplicateObjectsList(ids: List<Id>): List<Id> {
|
||||
return remote.duplicateObjectsList(ids)
|
||||
}
|
||||
|
||||
override suspend fun createTemplateFromObject(ctx: Id): Id {
|
||||
return remote.createTemplateFromObject(ctx)
|
||||
}
|
||||
}
|
|
@ -364,4 +364,5 @@ interface BlockRemote {
|
|||
suspend fun setInternalFlags(command: Command.SetInternalFlags): Payload
|
||||
|
||||
suspend fun duplicateObjectsList(ids: List<Id>): List<Id>
|
||||
suspend fun createTemplateFromObject(ctx: Id): Id
|
||||
}
|
|
@ -414,4 +414,5 @@ interface BlockRepository {
|
|||
suspend fun fileSpaceUsage(): FileLimits
|
||||
suspend fun setInternalFlags(command: Command.SetInternalFlags): Payload
|
||||
suspend fun duplicateObjectsList(ids: List<Id>): List<Id>
|
||||
suspend fun createTemplateFromObject(ctx: Id): Id
|
||||
}
|
|
@ -36,7 +36,7 @@ class CreateObject(
|
|||
}
|
||||
|
||||
val command = Command.CreateObject(
|
||||
template = null,
|
||||
template = params.template,
|
||||
prefilled = prefilled,
|
||||
internalFlags = internalFlags
|
||||
)
|
||||
|
@ -52,7 +52,8 @@ class CreateObject(
|
|||
}
|
||||
|
||||
data class Param(
|
||||
val type: String?
|
||||
val type: String?,
|
||||
val template: Id? = null
|
||||
)
|
||||
|
||||
data class Result(
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package com.anytypeio.anytype.domain.templates
|
||||
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
|
||||
import com.anytypeio.anytype.domain.base.ResultInteractor
|
||||
import com.anytypeio.anytype.domain.block.repo.BlockRepository
|
||||
import javax.inject.Inject
|
||||
|
||||
class CreateTemplateFromObject @Inject constructor(
|
||||
private val repo: BlockRepository,
|
||||
dispatchers: AppCoroutineDispatchers
|
||||
) : ResultInteractor<CreateTemplateFromObject.Params, Id>(
|
||||
dispatchers.io
|
||||
) {
|
||||
|
||||
override suspend fun doWork(params: Params): Id {
|
||||
return repo.createTemplateFromObject(params.obj)
|
||||
}
|
||||
|
||||
data class Params(val obj: Id)
|
||||
}
|
|
@ -800,4 +800,8 @@ class BlockMiddleware(
|
|||
override suspend fun duplicateObjectsList(ids: List<Id>): List<Id> {
|
||||
return middleware.duplicateObjectsList(ids)
|
||||
}
|
||||
|
||||
override suspend fun createTemplateFromObject(ctx: Id): Id {
|
||||
return middleware.createTemplateFromObject(ctx)
|
||||
}
|
||||
}
|
|
@ -2244,6 +2244,19 @@ class Middleware @Inject constructor(
|
|||
return response.ids
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun createTemplateFromObject(
|
||||
ctx: Id
|
||||
): Id {
|
||||
val request = Rpc.Template.CreateFromObject.Request(
|
||||
contextId = ctx
|
||||
)
|
||||
if (BuildConfig.DEBUG) logRequest(request)
|
||||
val response = service.createTemplateFromObject(request)
|
||||
if (BuildConfig.DEBUG) logResponse(response)
|
||||
return response.id
|
||||
}
|
||||
|
||||
private fun logRequest(any: Any) {
|
||||
logger.logRequest(any).also {
|
||||
if (BuildConfig.DEBUG && threadInfo.isOnMainThread()) {
|
||||
|
|
|
@ -149,6 +149,9 @@ interface MiddlewareService {
|
|||
@Throws(Exception::class)
|
||||
fun objectsListDuplicate(request: Rpc.Object.ListDuplicate.Request): Rpc.Object.ListDuplicate.Response
|
||||
|
||||
@Throws(Exception::class)
|
||||
fun createTemplateFromObject(request: Rpc.Template.CreateFromObject.Request): Rpc.Template.CreateFromObject.Response
|
||||
|
||||
//endregion
|
||||
|
||||
//region OBJECT'S RELATIONS command
|
||||
|
|
|
@ -1599,6 +1599,19 @@ class MiddlewareServiceImplementation @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun createTemplateFromObject(request: Rpc.Template.CreateFromObject.Request): Rpc.Template.CreateFromObject.Response {
|
||||
val encoded = Service.templateCreateFromObject(
|
||||
Rpc.Template.CreateFromObject.Request.ADAPTER.encode(request)
|
||||
)
|
||||
val response = Rpc.Template.CreateFromObject.Response.ADAPTER.decode(encoded)
|
||||
val error = response.error
|
||||
if (error != null && error.code != Rpc.Template.CreateFromObject.Response.Error.Code.NULL) {
|
||||
throw Exception(error.description)
|
||||
} else {
|
||||
return response
|
||||
}
|
||||
}
|
||||
|
||||
override fun spaceUsage(request: Rpc.File.SpaceUsage.Request): Rpc.File.SpaceUsage.Response {
|
||||
val encoded = Service.fileSpaceUsage(
|
||||
Rpc.File.SpaceUsage.Request.ADAPTER.encode(request)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
<resources>
|
||||
<string name="app_name">Middleware</string>
|
||||
<string name="snackbar_template_add">The template was added to the type</string>
|
||||
</resources>
|
||||
|
|
|
@ -3143,23 +3143,32 @@ class EditorViewModel(
|
|||
fun onAddNewDocumentClicked() {
|
||||
|
||||
Timber.d("onAddNewDocumentClicked, ")
|
||||
proceedWithCreatingNewObject(type = null, template = null)
|
||||
}
|
||||
|
||||
fun onCreateObjectWithTemplateClicked(template: Id) {
|
||||
Timber.d("onCreateObjectWithTemplateClicked, template:[$template]")
|
||||
val objType = getObjectTypeFromDetails() ?: return
|
||||
proceedWithCreatingNewObject(type = objType, template = template)
|
||||
}
|
||||
|
||||
private fun proceedWithCreatingNewObject(type: Id?, template: Id?) {
|
||||
val startTime = System.currentTimeMillis()
|
||||
jobs += viewModelScope.launch {
|
||||
createObject.async(CreateObject.Param(type = null))
|
||||
viewModelScope.launch {
|
||||
val params = CreateObject.Param(type = type, template = template)
|
||||
createObject.async(params = params)
|
||||
.fold(
|
||||
onSuccess = { result ->
|
||||
sendAnalyticsObjectCreateEvent(
|
||||
analytics = analytics,
|
||||
type = result.type,
|
||||
storeOfObjectTypes = storeOfObjectTypes,
|
||||
route = EventsDictionary.Routes.navigation,
|
||||
view = EventsDictionary.View.viewNavbar,
|
||||
route = EventsDictionary.Routes.objPowerTool,
|
||||
startTime = startTime
|
||||
)
|
||||
proceedWithOpeningObject(result.objectId)
|
||||
},
|
||||
onFailure = { e -> Timber.e(e, "Error while creating a new page") }
|
||||
onFailure = { e -> Timber.e(e, "Error while creating a new object") }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import com.anytypeio.anytype.analytics.base.EventsDictionary.changeSortValue
|
|||
import com.anytypeio.anytype.analytics.base.EventsDictionary.changeViewType
|
||||
import com.anytypeio.anytype.analytics.base.EventsDictionary.clickNewOption
|
||||
import com.anytypeio.anytype.analytics.base.EventsDictionary.collectionScreenShow
|
||||
import com.anytypeio.anytype.analytics.base.EventsDictionary.createTemplate
|
||||
import com.anytypeio.anytype.analytics.base.EventsDictionary.duplicateView
|
||||
import com.anytypeio.anytype.analytics.base.EventsDictionary.objectCreate
|
||||
import com.anytypeio.anytype.analytics.base.EventsDictionary.objectDuplicate
|
||||
|
@ -1730,4 +1731,23 @@ fun CoroutineScope.sendAnalyticsSelectTemplateEvent(
|
|||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fun CoroutineScope.sendAnalyticsCreateTemplateEvent(
|
||||
analytics: Analytics,
|
||||
objectType: String?,
|
||||
startTime: Long
|
||||
) {
|
||||
sendEvent(
|
||||
analytics = analytics,
|
||||
eventName = createTemplate,
|
||||
props = Props(
|
||||
buildMap {
|
||||
put(EventsPropertiesKey.route, "MenuObject")
|
||||
put(EventsPropertiesKey.objectType, objectType)
|
||||
}
|
||||
),
|
||||
startTime = startTime,
|
||||
middleTime = System.currentTimeMillis()
|
||||
)
|
||||
}
|
|
@ -8,6 +8,7 @@ import com.anytypeio.anytype.analytics.base.EventsDictionary
|
|||
import com.anytypeio.anytype.analytics.base.sendEvent
|
||||
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.restrictions.ObjectRestriction
|
||||
import com.anytypeio.anytype.domain.base.fold
|
||||
|
@ -19,10 +20,15 @@ import com.anytypeio.anytype.domain.misc.UrlBuilder
|
|||
import com.anytypeio.anytype.domain.`object`.DuplicateObject
|
||||
import com.anytypeio.anytype.domain.objects.SetObjectIsArchived
|
||||
import com.anytypeio.anytype.domain.page.AddBackLinkToObject
|
||||
import com.anytypeio.anytype.domain.templates.CreateTemplateFromObject
|
||||
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.objects.ObjectAction
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectIcon
|
||||
import com.anytypeio.anytype.presentation.objects.getProperName
|
||||
import com.anytypeio.anytype.presentation.objects.isTemplatesAllowed
|
||||
import com.anytypeio.anytype.presentation.util.Dispatcher
|
||||
import com.anytypeio.anytype.presentation.util.downloader.DebugTreeShareDownloader
|
||||
import com.anytypeio.anytype.presentation.util.downloader.MiddlewareShareDownloader
|
||||
|
@ -43,7 +49,8 @@ class ObjectMenuViewModel(
|
|||
private val storage: Editor.Storage,
|
||||
private val analytics: Analytics,
|
||||
private val updateFields: UpdateFields,
|
||||
private val addObjectToCollection: AddObjectToCollection
|
||||
private val addObjectToCollection: AddObjectToCollection,
|
||||
private val createTemplateFromObject: CreateTemplateFromObject
|
||||
) : ObjectMenuViewModelBase(
|
||||
setObjectIsArchived = setObjectIsArchived,
|
||||
addToFavorite = addToFavorite,
|
||||
|
@ -86,6 +93,15 @@ class ObjectMenuViewModel(
|
|||
if (!isProfile && !objectRestrictions.contains(ObjectRestriction.DUPLICATE)) {
|
||||
add(ObjectAction.DUPLICATE)
|
||||
}
|
||||
|
||||
val objTypeId = storage.details.current().details[ctx]?.type?.firstOrNull()
|
||||
storage.details.current().details[objTypeId]?.let { objType ->
|
||||
val objTypeWrapper = ObjectWrapper.Type(objType.map)
|
||||
val isTemplateAllowed = objTypeWrapper.isTemplatesAllowed()
|
||||
if (isTemplateAllowed && !isTemplate) {
|
||||
add(ObjectAction.USE_AS_TEMPLATE)
|
||||
}
|
||||
}
|
||||
if (!isTemplate) {
|
||||
add(ObjectAction.LINK_TO)
|
||||
}
|
||||
|
@ -229,15 +245,47 @@ class ObjectMenuViewModel(
|
|||
}
|
||||
isDismissed.value = true
|
||||
}
|
||||
ObjectAction.USE_AS_TEMPLATE -> {
|
||||
proceedWithCreatingTemplateFromObject(ctx)
|
||||
}
|
||||
ObjectAction.MOVE_TO,
|
||||
ObjectAction.MOVE_TO_BIN,
|
||||
ObjectAction.USE_AS_TEMPLATE,
|
||||
ObjectAction.DELETE_FILES -> {
|
||||
throw IllegalStateException("$action is unsupported")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun proceedWithCreatingTemplateFromObject(ctx: Id) {
|
||||
val startTime = System.currentTimeMillis()
|
||||
viewModelScope.launch {
|
||||
val params = CreateTemplateFromObject.Params(obj = ctx)
|
||||
createTemplateFromObject.async(params).fold(
|
||||
onSuccess = { template ->
|
||||
val objTypeId = storage.details.current().details[ctx]?.type?.firstOrNull()
|
||||
sendAnalyticsCreateTemplateEvent(analytics, objTypeId, startTime)
|
||||
commands.emit(buildOpenTemplateCommand(ctx, template))
|
||||
isDismissed.value = true
|
||||
},
|
||||
onFailure = {
|
||||
Timber.e(it, "Error while creating template from object")
|
||||
_toasts.emit(SOMETHING_WENT_WRONG_MSG)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildOpenTemplateCommand(ctx: Id, template: Id): Command.OpenTemplate {
|
||||
val type = storage.details.current().details[ctx]?.type?.firstOrNull()
|
||||
val objType =
|
||||
ObjectWrapper.Basic(storage.details.current().details[type]?.map ?: emptyMap())
|
||||
return Command.OpenTemplate(
|
||||
template = template,
|
||||
icon = ObjectIcon.from(objType, objType.layout, urlBuilder),
|
||||
typeName = objType.getProperName()
|
||||
)
|
||||
}
|
||||
|
||||
private fun proceedWithUpdatingLockStatus(
|
||||
ctx: Id,
|
||||
isLocked: Boolean
|
||||
|
@ -307,7 +355,8 @@ class ObjectMenuViewModel(
|
|||
private val updateFields: UpdateFields,
|
||||
private val delegator: Delegator<Action>,
|
||||
private val menuOptionsProvider: ObjectMenuOptionsProvider,
|
||||
private val addObjectToCollection: AddObjectToCollection
|
||||
private val addObjectToCollection: AddObjectToCollection,
|
||||
private val createTemplateFromObject: CreateTemplateFromObject
|
||||
) : ViewModelProvider.Factory {
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return ObjectMenuViewModel(
|
||||
|
@ -324,7 +373,8 @@ class ObjectMenuViewModel(
|
|||
updateFields = updateFields,
|
||||
delegator = delegator,
|
||||
menuOptionsProvider = menuOptionsProvider,
|
||||
addObjectToCollection = addObjectToCollection
|
||||
addObjectToCollection = addObjectToCollection,
|
||||
createTemplateFromObject = createTemplateFromObject
|
||||
) as T
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ abstract class ObjectMenuViewModelBase(
|
|||
private val removeFromFavorite: RemoveFromFavorite,
|
||||
private val addBackLinkToObject: AddBackLinkToObject,
|
||||
protected val delegator: Delegator<Action>,
|
||||
private val urlBuilder: UrlBuilder,
|
||||
protected val urlBuilder: UrlBuilder,
|
||||
protected val dispatcher: Dispatcher<Payload>,
|
||||
private val analytics: Analytics,
|
||||
private val menuOptionsProvider: ObjectMenuOptionsProvider,
|
||||
|
@ -340,6 +340,11 @@ abstract class ObjectMenuViewModelBase(
|
|||
val icon: ObjectIcon,
|
||||
val isCollection: Boolean = false
|
||||
) : Command()
|
||||
data class OpenTemplate(
|
||||
val template: Id,
|
||||
val typeName: String,
|
||||
val icon: ObjectIcon
|
||||
) : Command()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue