mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 13:57:10 +09:00
DROID-1953 Objects. | Enhancement | Creating widgets from object's three-dot menu (#607)
This commit is contained in:
parent
299cd654a3
commit
e9ea4fd74d
8 changed files with 122 additions and 18 deletions
|
@ -5,7 +5,6 @@ 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.tools.FeatureToggles
|
||||
import com.anytypeio.anytype.domain.`object`.DuplicateObject
|
||||
import com.anytypeio.anytype.domain.auth.repo.AuthRepository
|
||||
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
|
||||
import com.anytypeio.anytype.domain.block.interactor.CreateBlock
|
||||
|
@ -15,12 +14,15 @@ 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`.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.page.CloseBlock
|
||||
import com.anytypeio.anytype.domain.page.OpenPage
|
||||
import com.anytypeio.anytype.domain.templates.CreateTemplateFromObject
|
||||
import com.anytypeio.anytype.domain.widgets.CreateWidget
|
||||
import com.anytypeio.anytype.domain.workspace.SpaceManager
|
||||
import com.anytypeio.anytype.presentation.common.Action
|
||||
import com.anytypeio.anytype.presentation.common.Delegator
|
||||
import com.anytypeio.anytype.presentation.editor.Editor
|
||||
|
@ -120,7 +122,9 @@ object ObjectMenuModule {
|
|||
addObjectToCollection: AddObjectToCollection,
|
||||
createTemplateFromObject: CreateTemplateFromObject,
|
||||
setObjectDetails: SetObjectDetails,
|
||||
debugGoroutinesShareDownloader: DebugGoroutinesShareDownloader
|
||||
debugGoroutinesShareDownloader: DebugGoroutinesShareDownloader,
|
||||
createWidget: CreateWidget,
|
||||
spaceManager: SpaceManager
|
||||
): ObjectMenuViewModel.Factory = ObjectMenuViewModel.Factory(
|
||||
setObjectIsArchived = setObjectIsArchived,
|
||||
duplicateObject = duplicateObject,
|
||||
|
@ -138,7 +142,9 @@ object ObjectMenuModule {
|
|||
addObjectToCollection = addObjectToCollection,
|
||||
createTemplateFromObject = createTemplateFromObject,
|
||||
setObjectDetails = setObjectDetails,
|
||||
debugGoroutinesShareDownloader = debugGoroutinesShareDownloader
|
||||
debugGoroutinesShareDownloader = debugGoroutinesShareDownloader,
|
||||
createWidget = createWidget,
|
||||
spaceManager = spaceManager
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
|
@ -206,7 +212,9 @@ object ObjectSetMenuModule {
|
|||
featureToggles: FeatureToggles,
|
||||
dispatcher: Dispatcher<Payload>,
|
||||
addObjectToCollection: AddObjectToCollection,
|
||||
debugGoroutinesShareDownloader: DebugGoroutinesShareDownloader
|
||||
debugGoroutinesShareDownloader: DebugGoroutinesShareDownloader,
|
||||
createWidget: CreateWidget,
|
||||
spaceManager: SpaceManager
|
||||
): ObjectSetMenuViewModel.Factory = ObjectSetMenuViewModel.Factory(
|
||||
setObjectIsArchived = setObjectIsArchived,
|
||||
addToFavorite = addToFavorite,
|
||||
|
@ -220,7 +228,9 @@ object ObjectSetMenuModule {
|
|||
dispatcher = dispatcher,
|
||||
menuOptionsProvider = createMenuOptionsProvider(state, featureToggles),
|
||||
addObjectToCollection = addObjectToCollection,
|
||||
debugGoroutinesShareDownloader = debugGoroutinesShareDownloader
|
||||
debugGoroutinesShareDownloader = debugGoroutinesShareDownloader,
|
||||
createWidget = createWidget,
|
||||
spaceManager = spaceManager
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
|
|
|
@ -84,6 +84,10 @@ class ObjectActionAdapter(
|
|||
ivActionIcon.setImageResource(R.drawable.ic_set_as_default_24)
|
||||
tvActionTitle.setText(R.string.set_as_default)
|
||||
}
|
||||
ObjectAction.CREATE_WIDGET -> {
|
||||
ivActionIcon.setImageResource(R.drawable.ic_object_action_to_widgets_24)
|
||||
tvActionTitle.setText(R.string.object_action_to_widgets)
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<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="M4,3.5H20C20.828,3.5 21.5,4.172 21.5,5V8C21.5,8.828 20.828,9.5 20,9.5H4C3.172,9.5 2.5,8.828 2.5,8V5C2.5,4.172 3.172,3.5 4,3.5ZM1,5C1,3.343 2.343,2 4,2H20C21.657,2 23,3.343 23,5V8C23,9.657 21.657,11 20,11H4C2.343,11 1,9.657 1,8V5ZM4,15.5H20C20.828,15.5 21.5,16.172 21.5,17V20C21.5,20.828 20.828,21.5 20,21.5H4C3.172,21.5 2.5,20.828 2.5,20V17C2.5,16.172 3.172,15.5 4,15.5ZM1,17C1,15.343 2.343,14 4,14H20C21.657,14 23,15.343 23,17V20C23,21.657 21.657,23 20,23H4C2.343,23 1,21.657 1,20V17Z"
|
||||
android:fillColor="@color/glyph_active"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
|
@ -445,7 +445,6 @@
|
|||
<string name="layout_todo_description">Action-focused layout with a checkbox</string>
|
||||
<string name="move_to_bin">To Bin</string>
|
||||
<string name="undoredo">Undo/Redo</string>
|
||||
<string name="object_action_duplicate">Duplicate</string>
|
||||
<string name="object_removal_process">Object removal process</string>
|
||||
<string name="please_wait_your_object_deletion">Please wait a bit. Your objects will be deleted shortly.</string>
|
||||
<string name="large">Large</string>
|
||||
|
@ -1087,6 +1086,13 @@
|
|||
|
||||
<!--endregion-->
|
||||
|
||||
<!--region OBJECT ACTIONS -->
|
||||
|
||||
<string name="object_action_duplicate">Duplicate</string>
|
||||
<string name="object_action_to_widgets">To widgets</string>
|
||||
|
||||
<!--endregion-->
|
||||
|
||||
<!--region CONTENT DESCRIPTIONS FOR ACCESSIBILITY -->
|
||||
|
||||
<string name="content_description_add_block" translatable="false">Add block button</string>
|
||||
|
|
|
@ -15,5 +15,6 @@ enum class ObjectAction {
|
|||
UNLOCK,
|
||||
LINK_TO,
|
||||
DELETE_FILES,
|
||||
SET_AS_DEFAULT
|
||||
SET_AS_DEFAULT,
|
||||
CREATE_WIDGET
|
||||
}
|
|
@ -24,6 +24,8 @@ 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
|
||||
import com.anytypeio.anytype.domain.widgets.CreateWidget
|
||||
import com.anytypeio.anytype.domain.workspace.SpaceManager
|
||||
import com.anytypeio.anytype.presentation.common.Action
|
||||
import com.anytypeio.anytype.presentation.common.Delegator
|
||||
import com.anytypeio.anytype.presentation.editor.Editor
|
||||
|
@ -35,6 +37,7 @@ import com.anytypeio.anytype.presentation.util.Dispatcher
|
|||
import com.anytypeio.anytype.presentation.util.downloader.DebugGoroutinesShareDownloader
|
||||
import com.anytypeio.anytype.presentation.util.downloader.DebugTreeShareDownloader
|
||||
import com.anytypeio.anytype.presentation.util.downloader.MiddlewareShareDownloader
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
|
||||
|
@ -48,6 +51,7 @@ class ObjectMenuViewModel(
|
|||
dispatcher: Dispatcher<Payload>,
|
||||
menuOptionsProvider: ObjectMenuOptionsProvider,
|
||||
duplicateObject: DuplicateObject,
|
||||
createWidget: CreateWidget,
|
||||
private val debugTreeShareDownloader: DebugTreeShareDownloader,
|
||||
private val storage: Editor.Storage,
|
||||
private val analytics: Analytics,
|
||||
|
@ -55,7 +59,8 @@ class ObjectMenuViewModel(
|
|||
private val addObjectToCollection: AddObjectToCollection,
|
||||
private val createTemplateFromObject: CreateTemplateFromObject,
|
||||
private val setObjectDetails: SetObjectDetails,
|
||||
private val debugGoroutinesShareDownloader: DebugGoroutinesShareDownloader
|
||||
private val debugGoroutinesShareDownloader: DebugGoroutinesShareDownloader,
|
||||
private val spaceManager: SpaceManager
|
||||
) : ObjectMenuViewModelBase(
|
||||
setObjectIsArchived = setObjectIsArchived,
|
||||
addToFavorite = addToFavorite,
|
||||
|
@ -68,7 +73,9 @@ class ObjectMenuViewModel(
|
|||
analytics = analytics,
|
||||
menuOptionsProvider = menuOptionsProvider,
|
||||
addObjectToCollection = addObjectToCollection,
|
||||
debugGoroutinesShareDownloader = debugGoroutinesShareDownloader
|
||||
debugGoroutinesShareDownloader = debugGoroutinesShareDownloader,
|
||||
createWidget = createWidget,
|
||||
spaceManager = spaceManager
|
||||
) {
|
||||
|
||||
private val objectRestrictions = storage.objectRestrictions.current()
|
||||
|
@ -96,6 +103,8 @@ class ObjectMenuViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
add(ObjectAction.CREATE_WIDGET)
|
||||
|
||||
if (isTemplate) {
|
||||
add(ObjectAction.SET_AS_DEFAULT)
|
||||
}
|
||||
|
@ -265,6 +274,11 @@ class ObjectMenuViewModel(
|
|||
ObjectAction.SET_AS_DEFAULT -> {
|
||||
proceedWithSettingAsDefaultTemplate(ctx = ctx)
|
||||
}
|
||||
ObjectAction.CREATE_WIDGET -> {
|
||||
val details = storage.details.current().details[ctx]
|
||||
val wrapper = ObjectWrapper.Basic(details?.map ?: emptyMap())
|
||||
proceedWithCreatingWidget(obj = wrapper)
|
||||
}
|
||||
ObjectAction.MOVE_TO,
|
||||
ObjectAction.MOVE_TO_BIN,
|
||||
ObjectAction.DELETE_FILES -> {
|
||||
|
@ -395,7 +409,7 @@ class ObjectMenuViewModel(
|
|||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
class Factory(
|
||||
class Factory @Inject constructor(
|
||||
private val setObjectIsArchived: SetObjectIsArchived,
|
||||
private val duplicateObject: DuplicateObject,
|
||||
private val debugTreeShareDownloader: DebugTreeShareDownloader,
|
||||
|
@ -412,7 +426,9 @@ class ObjectMenuViewModel(
|
|||
private val addObjectToCollection: AddObjectToCollection,
|
||||
private val createTemplateFromObject: CreateTemplateFromObject,
|
||||
private val setObjectDetails: SetObjectDetails,
|
||||
private val debugGoroutinesShareDownloader: DebugGoroutinesShareDownloader
|
||||
private val debugGoroutinesShareDownloader: DebugGoroutinesShareDownloader,
|
||||
private val createWidget: CreateWidget,
|
||||
private val spaceManager: SpaceManager
|
||||
) : ViewModelProvider.Factory {
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return ObjectMenuViewModel(
|
||||
|
@ -432,7 +448,9 @@ class ObjectMenuViewModel(
|
|||
addObjectToCollection = addObjectToCollection,
|
||||
createTemplateFromObject = createTemplateFromObject,
|
||||
setObjectDetails = setObjectDetails,
|
||||
debugGoroutinesShareDownloader = debugGoroutinesShareDownloader
|
||||
debugGoroutinesShareDownloader = debugGoroutinesShareDownloader,
|
||||
createWidget = createWidget,
|
||||
spaceManager = spaceManager
|
||||
) as T
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,15 +7,20 @@ import com.anytypeio.anytype.core_models.Block
|
|||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.Key
|
||||
import com.anytypeio.anytype.core_models.ObjectType
|
||||
import com.anytypeio.anytype.core_models.ObjectWrapper
|
||||
import com.anytypeio.anytype.core_models.Payload
|
||||
import com.anytypeio.anytype.domain.`object`.DuplicateObject
|
||||
import com.anytypeio.anytype.core_models.WidgetLayout
|
||||
import com.anytypeio.anytype.core_models.isDataView
|
||||
import com.anytypeio.anytype.domain.base.fold
|
||||
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`.DuplicateObject
|
||||
import com.anytypeio.anytype.domain.objects.SetObjectIsArchived
|
||||
import com.anytypeio.anytype.domain.page.AddBackLinkToObject
|
||||
import com.anytypeio.anytype.domain.widgets.CreateWidget
|
||||
import com.anytypeio.anytype.domain.workspace.SpaceManager
|
||||
import com.anytypeio.anytype.presentation.common.Action
|
||||
import com.anytypeio.anytype.presentation.common.BaseViewModel
|
||||
import com.anytypeio.anytype.presentation.common.Delegator
|
||||
|
@ -50,7 +55,9 @@ abstract class ObjectMenuViewModelBase(
|
|||
private val menuOptionsProvider: ObjectMenuOptionsProvider,
|
||||
private val duplicateObject: DuplicateObject,
|
||||
private val addObjectToCollection: AddObjectToCollection,
|
||||
private val debugGoroutinesShareDownloader: DebugGoroutinesShareDownloader
|
||||
private val debugGoroutinesShareDownloader: DebugGoroutinesShareDownloader,
|
||||
private val createWidget: CreateWidget,
|
||||
private val spaceManager: SpaceManager
|
||||
) : BaseViewModel() {
|
||||
|
||||
protected val jobs = mutableListOf<Job>()
|
||||
|
@ -345,6 +352,36 @@ abstract class ObjectMenuViewModelBase(
|
|||
}
|
||||
}
|
||||
|
||||
fun proceedWithCreatingWidget(obj: ObjectWrapper.Basic) {
|
||||
viewModelScope.launch {
|
||||
val config = spaceManager.getConfig()
|
||||
if (config != null) {
|
||||
createWidget(
|
||||
CreateWidget.Params(
|
||||
ctx = config.widgets,
|
||||
source = obj.id,
|
||||
type = if (obj.layout.isDataView()) {
|
||||
WidgetLayout.COMPACT_LIST
|
||||
} else {
|
||||
WidgetLayout.TREE
|
||||
}
|
||||
)
|
||||
).collect { result ->
|
||||
result.fold(
|
||||
onSuccess = {
|
||||
sendToast("Widget created")
|
||||
isDismissed.value = true
|
||||
},
|
||||
onFailure = {
|
||||
Timber.e(it, "Error while creating widget")
|
||||
sendToast(SOMETHING_WENT_WRONG_MSG)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class Command {
|
||||
object OpenObjectIcons : Command()
|
||||
object OpenSetIcons : Command()
|
||||
|
|
|
@ -5,6 +5,7 @@ import androidx.lifecycle.ViewModelProvider
|
|||
import androidx.lifecycle.viewModelScope
|
||||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
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.collections.AddObjectToCollection
|
||||
|
@ -14,6 +15,8 @@ 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.widgets.CreateWidget
|
||||
import com.anytypeio.anytype.domain.workspace.SpaceManager
|
||||
import com.anytypeio.anytype.presentation.common.Action
|
||||
import com.anytypeio.anytype.presentation.common.Delegator
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectAction
|
||||
|
@ -21,6 +24,7 @@ import com.anytypeio.anytype.presentation.sets.dataViewState
|
|||
import com.anytypeio.anytype.presentation.sets.state.ObjectState
|
||||
import com.anytypeio.anytype.presentation.util.Dispatcher
|
||||
import com.anytypeio.anytype.presentation.util.downloader.DebugGoroutinesShareDownloader
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
@ -34,6 +38,8 @@ class ObjectSetMenuViewModel(
|
|||
urlBuilder: UrlBuilder,
|
||||
dispatcher: Dispatcher<Payload>,
|
||||
menuOptionsProvider: ObjectMenuOptionsProvider,
|
||||
createWidget: CreateWidget,
|
||||
spaceManager: SpaceManager,
|
||||
private val objectState: StateFlow<ObjectState>,
|
||||
private val analytics: Analytics,
|
||||
private val addObjectToCollection: AddObjectToCollection,
|
||||
|
@ -50,11 +56,13 @@ class ObjectSetMenuViewModel(
|
|||
analytics = analytics,
|
||||
menuOptionsProvider = menuOptionsProvider,
|
||||
addObjectToCollection = addObjectToCollection,
|
||||
debugGoroutinesShareDownloader = debugGoroutinesShareDownloader
|
||||
debugGoroutinesShareDownloader = debugGoroutinesShareDownloader,
|
||||
createWidget = createWidget,
|
||||
spaceManager = spaceManager
|
||||
) {
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
class Factory(
|
||||
class Factory @Inject constructor(
|
||||
private val setObjectIsArchived: SetObjectIsArchived,
|
||||
private val addToFavorite: AddToFavorite,
|
||||
private val removeFromFavorite: RemoveFromFavorite,
|
||||
|
@ -67,7 +75,9 @@ class ObjectSetMenuViewModel(
|
|||
private val objectState: StateFlow<ObjectState>,
|
||||
private val menuOptionsProvider: ObjectMenuOptionsProvider,
|
||||
private val addObjectToCollection: AddObjectToCollection,
|
||||
private val debugGoroutinesShareDownloader: DebugGoroutinesShareDownloader
|
||||
private val debugGoroutinesShareDownloader: DebugGoroutinesShareDownloader,
|
||||
private val createWidget: CreateWidget,
|
||||
private val spaceManager: SpaceManager
|
||||
) : ViewModelProvider.Factory {
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return ObjectSetMenuViewModel(
|
||||
|
@ -83,7 +93,9 @@ class ObjectSetMenuViewModel(
|
|||
dispatcher = dispatcher,
|
||||
menuOptionsProvider = menuOptionsProvider,
|
||||
addObjectToCollection = addObjectToCollection,
|
||||
debugGoroutinesShareDownloader = debugGoroutinesShareDownloader
|
||||
debugGoroutinesShareDownloader = debugGoroutinesShareDownloader,
|
||||
createWidget = createWidget,
|
||||
spaceManager = spaceManager
|
||||
) as T
|
||||
}
|
||||
}
|
||||
|
@ -148,6 +160,7 @@ class ObjectSetMenuViewModel(
|
|||
} else {
|
||||
add(ObjectAction.ADD_TO_FAVOURITE)
|
||||
}
|
||||
add(ObjectAction.CREATE_WIDGET)
|
||||
val dataViewState = objectState.value.dataViewState()
|
||||
if (dataViewState != null && !dataViewState.objectRestrictions.contains(ObjectRestriction.DUPLICATE)) {
|
||||
add(ObjectAction.DUPLICATE)
|
||||
|
@ -175,6 +188,11 @@ class ObjectSetMenuViewModel(
|
|||
ObjectAction.DUPLICATE -> {
|
||||
proceedWithDuplication(ctx = ctx, details = objectState.value.dataViewState()?.details)
|
||||
}
|
||||
ObjectAction.CREATE_WIDGET -> {
|
||||
val details = objectState.value.dataViewState()?.details?.get(ctx)
|
||||
val wrapper = ObjectWrapper.Basic(details?.map ?: emptyMap())
|
||||
proceedWithCreatingWidget(obj = wrapper)
|
||||
}
|
||||
ObjectAction.MOVE_TO,
|
||||
ObjectAction.SEARCH_ON_PAGE,
|
||||
ObjectAction.UNDO_REDO,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue