diff --git a/analytics/src/main/java/com/anytypeio/anytype/analytics/base/EventsDictionary.kt b/analytics/src/main/java/com/anytypeio/anytype/analytics/base/EventsDictionary.kt index 4add7dc3a4..06187bbd6f 100644 --- a/analytics/src/main/java/com/anytypeio/anytype/analytics/base/EventsDictionary.kt +++ b/analytics/src/main/java/com/anytypeio/anytype/analytics/base/EventsDictionary.kt @@ -31,6 +31,7 @@ object EventsDictionary { const val loginScreenShow = "ScreenLogin" const val searchScreenShow = "ScreenSearch" const val createObjectNavBar = "CreateObjectNavBar" + const val createObjectCollectionsNavBar = "CreateObjectCollectionsNavBar" const val signupScreenShow = "ScreenAuthRegistration" const val invitationScreenShow = "ScreenAuthInvitation" const val aboutAnalyticsScreenShow = "ScreenDisclaimer" diff --git a/app/src/main/java/com/anytypeio/anytype/navigation/Navigator.kt b/app/src/main/java/com/anytypeio/anytype/navigation/Navigator.kt index db5e08f6c8..7e2dfac38e 100644 --- a/app/src/main/java/com/anytypeio/anytype/navigation/Navigator.kt +++ b/app/src/main/java/com/anytypeio/anytype/navigation/Navigator.kt @@ -97,7 +97,6 @@ class Navigator : AppNavigation { R.id.objectNavigation, bundleOf(EditorFragment.ID_KEY to id), navOptions { - popUpTo = R.id.homeScreen launchSingleTop = true } ) @@ -115,7 +114,6 @@ class Navigator : AppNavigation { R.id.dataViewNavigation, bundleOf(ObjectSetFragment.CONTEXT_ID_KEY to id), navOptions { - popUpTo = R.id.homeScreen launchSingleTop = true } ) @@ -206,7 +204,6 @@ class Navigator : AppNavigation { R.id.homeScreen, bundleOf(EditorFragment.ID_KEY to pageId), navOptions { - popUpTo = R.id.homeScreen launchSingleTop = true } ) diff --git a/app/src/main/java/com/anytypeio/anytype/ui/widgets/collection/CollectionDI.kt b/app/src/main/java/com/anytypeio/anytype/ui/widgets/collection/CollectionDI.kt index 4e298687e8..bc05c44068 100644 --- a/app/src/main/java/com/anytypeio/anytype/ui/widgets/collection/CollectionDI.kt +++ b/app/src/main/java/com/anytypeio/anytype/ui/widgets/collection/CollectionDI.kt @@ -12,17 +12,21 @@ import com.anytypeio.anytype.domain.block.interactor.Move import com.anytypeio.anytype.domain.block.interactor.sets.GetObjectTypes import com.anytypeio.anytype.domain.block.repo.BlockRepository import com.anytypeio.anytype.domain.config.ConfigStorage +import com.anytypeio.anytype.domain.config.UserSettingsRepository import com.anytypeio.anytype.domain.dashboard.interactor.SetObjectListIsFavorite import com.anytypeio.anytype.domain.event.interactor.EventChannel import com.anytypeio.anytype.domain.event.interactor.InterceptEvents +import com.anytypeio.anytype.domain.launch.GetDefaultPageType import com.anytypeio.anytype.domain.library.StorelessSubscriptionContainer import com.anytypeio.anytype.domain.misc.UrlBuilder import com.anytypeio.anytype.domain.`object`.OpenObject import com.anytypeio.anytype.domain.objects.DeleteObjects import com.anytypeio.anytype.domain.objects.ObjectStore import com.anytypeio.anytype.domain.objects.SetObjectListIsArchived +import com.anytypeio.anytype.domain.page.CreateObject import com.anytypeio.anytype.domain.search.ObjectSearchSubscriptionContainer import com.anytypeio.anytype.domain.search.SubscriptionEventChannel +import com.anytypeio.anytype.domain.templates.GetTemplates import com.anytypeio.anytype.domain.workspace.WorkspaceManager import com.anytypeio.anytype.presentation.util.Dispatcher import com.anytypeio.anytype.presentation.widgets.WidgetDispatchEvent @@ -140,6 +144,47 @@ object CollectionModule { dispatchers: AppCoroutineDispatchers ): DeleteObjects = DeleteObjects(repo, dispatchers) + @JvmStatic + @Provides + @PerScreen + fun getCreateObject( + repo: BlockRepository, + getTemplates: GetTemplates, + getDefaultPageType: GetDefaultPageType, + dispatchers: AppCoroutineDispatchers + ): CreateObject = CreateObject( + repo = repo, + getTemplates = getTemplates, + getDefaultPageType = getDefaultPageType, + dispatchers = dispatchers + ) + + @JvmStatic + @Provides + @PerScreen + fun provideGetDefaultPageType( + userSettingsRepository: UserSettingsRepository, + blockRepository: BlockRepository, + workspaceManager: WorkspaceManager, + dispatchers: AppCoroutineDispatchers + ): GetDefaultPageType = GetDefaultPageType( + userSettingsRepository = userSettingsRepository, + blockRepository = blockRepository, + workspaceManager = workspaceManager, + dispatchers = dispatchers + ) + + @JvmStatic + @Provides + @PerScreen + fun provideGetTemplates( + repo: BlockRepository, + dispatchers: AppCoroutineDispatchers + ): GetTemplates = GetTemplates( + repo = repo, + dispatchers = dispatchers + ) + @Module interface Declarations { @PerScreen @@ -163,6 +208,7 @@ interface CollectionDependencies : ComponentDependencies { fun workspaceManager(): WorkspaceManager fun analytics(): Analytics fun eventChannel(): EventChannel + fun userSettingsRepository(): UserSettingsRepository fun dispatchers(): AppCoroutineDispatchers } \ No newline at end of file diff --git a/app/src/main/java/com/anytypeio/anytype/ui/widgets/collection/CollectionFragment.kt b/app/src/main/java/com/anytypeio/anytype/ui/widgets/collection/CollectionFragment.kt index aeff2a0c5f..c84b305413 100644 --- a/app/src/main/java/com/anytypeio/anytype/ui/widgets/collection/CollectionFragment.kt +++ b/app/src/main/java/com/anytypeio/anytype/ui/widgets/collection/CollectionFragment.kt @@ -68,6 +68,9 @@ class CollectionFragment : BaseComposeFragment() { is Command.LaunchObjectSet -> launchObjectSet(command.target) is Command.Exit -> exit() is Command.ConfirmRemoveFromBin -> confirmRemoveFromBin(command) + is Command.OpenCollection -> navigation.launchCollections(command.subscription) + is Command.ToDesktop -> navigation.exitToDesktop() + is Command.ToSearch -> navigation.openPageSearch() } } diff --git a/app/src/main/java/com/anytypeio/anytype/ui/widgets/collection/CollectionScreen.kt b/app/src/main/java/com/anytypeio/anytype/ui/widgets/collection/CollectionScreen.kt index c3225f1878..71abb7d621 100644 --- a/app/src/main/java/com/anytypeio/anytype/ui/widgets/collection/CollectionScreen.kt +++ b/app/src/main/java/com/anytypeio/anytype/ui/widgets/collection/CollectionScreen.kt @@ -74,6 +74,7 @@ import androidx.compose.ui.viewinterop.AndroidView import androidx.core.widget.doAfterTextChanged import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.anytypeio.anytype.R +import com.anytypeio.anytype.core_ui.foundation.components.BottomNavigationMenu import com.anytypeio.anytype.core_ui.foundation.noRippleClickable import com.anytypeio.anytype.core_ui.widgets.CollectionActionWidget import com.anytypeio.anytype.core_ui.widgets.ObjectIconWidget @@ -108,12 +109,25 @@ fun ScreenContent(vm: CollectionViewModel, uiState: CollectionUiState) { Modifier.background(color = colorResource(R.color.background_primary)) ) { - Column { - TopBar(vm, uiState) - SearchBar(vm, uiState) - ListView(vm, uiState) + Box { + Column( + Modifier.padding(0.dp, 0.dp, 0.dp, 32.dp) + ) { + TopBar(vm, uiState) + SearchBar(vm, uiState) + ListView(vm, uiState) + } + Box(Modifier.align(BottomCenter)) { + BottomNavigationMenu( + backClick = { vm.onPrevClicked() }, + homeClick = { vm.onHomeClicked() }, + searchClick = { vm.onSearchClicked() }, + addDocClick = { vm.onAddClicked() }, + ) + } } + if (uiState.operationInProgress) { LinearProgressIndicator( modifier = Modifier @@ -580,7 +594,7 @@ private fun BlockWidget( modifier = Modifier .fillMaxWidth() .wrapContentHeight() - .absolutePadding(16.dp, 0.dp, 16.dp, 22.dp), + .absolutePadding(16.dp, 0.dp, 16.dp, 48.dp), factory = { context -> CollectionActionWidget(context).apply { layoutParams = LinearLayout.LayoutParams( diff --git a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/foundation/components/BottomNavigationMenu.kt b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/foundation/components/BottomNavigationMenu.kt index ca8a2c8d5a..5957f9f6bd 100644 --- a/core-ui/src/main/java/com/anytypeio/anytype/core_ui/foundation/components/BottomNavigationMenu.kt +++ b/core-ui/src/main/java/com/anytypeio/anytype/core_ui/foundation/components/BottomNavigationMenu.kt @@ -35,8 +35,8 @@ fun BottomNavigationMenu( /** * Workaround for clicks through the bottom navigation menu. */ - .noRippleClickable { }, - horizontalArrangement = Arrangement.SpaceEvenly, + .noRippleClickable { }, + horizontalArrangement = Arrangement.SpaceAround, verticalAlignment = Alignment.CenterVertically ) { MenuItem(BottomNavigationItem.BACK.res, onClick = backClick) @@ -64,7 +64,7 @@ private fun MenuItem( private enum class BottomNavigationItem(@DrawableRes val res: Int) { BACK(R.drawable.ic_main_toolbar_back), HOME(R.drawable.ic_main_toolbar_home), - SEARCH(R.drawable.ic_main_toolbar_search), + SEARCH(R.drawable.ic_page_toolbar_search), ADD_DOC(R.drawable.ic_page_toolbar_add_doc) } diff --git a/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/collection/CollectionViewModel.kt b/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/collection/CollectionViewModel.kt index 75f90cc18a..0913db963e 100644 --- a/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/collection/CollectionViewModel.kt +++ b/presentation/src/main/java/com/anytypeio/anytype/presentation/widgets/collection/CollectionViewModel.kt @@ -33,7 +33,9 @@ import com.anytypeio.anytype.domain.misc.UrlBuilder import com.anytypeio.anytype.domain.`object`.OpenObject import com.anytypeio.anytype.domain.objects.DeleteObjects import com.anytypeio.anytype.domain.objects.SetObjectListIsArchived +import com.anytypeio.anytype.domain.page.CreateObject import com.anytypeio.anytype.domain.workspace.WorkspaceManager +import com.anytypeio.anytype.presentation.extension.sendAnalyticsObjectCreateEvent import com.anytypeio.anytype.presentation.navigation.DefaultObjectView import com.anytypeio.anytype.presentation.objects.ObjectAction import com.anytypeio.anytype.presentation.objects.getProperName @@ -78,6 +80,7 @@ class CollectionViewModel( private val deleteObjects: DeleteObjects, private val resourceProvider: CollectionResourceProvider, private val openObject: OpenObject, + private val createObject: CreateObject, private val configstorage: ConfigStorage, interceptEvents: InterceptEvents, private val objectPayloadDispatcher: Dispatcher, @@ -472,7 +475,7 @@ class CollectionViewModel( if (interactionMode.value == InteractionMode.Edit && subscription != Subscription.Bin) { onDone() } else if (!(subscription == Subscription.Bin && isExpanded)) { - launch { commands.emit(Command.Exit) } + onPrevClicked() } } @@ -617,6 +620,50 @@ class CollectionViewModel( return curr } + fun onHomeClicked() { + launch { + commands.emit(Command.ToDesktop) + } + } + + fun onPrevClicked() { + launch { + commands.emit(Command.Exit) + } + } + + fun onSearchClicked() { + launch { + commands.emit(Command.ToSearch) + } + } + + fun onAddClicked() { + viewModelScope.sendEvent( + analytics = analytics, + eventName = EventsDictionary.createObjectCollectionsNavBar, + props = Props(mapOf(EventsPropertiesKey.context to null)) + ) + + launch { + createObject.execute(CreateObject.Param(type = null)) + .fold( + onSuccess = { result -> + if (result.appliedTemplate != null) { + sendAnalyticsObjectCreateEvent( + analytics = analytics, + objType = result.type, + route = EventsDictionary.Routes.objPowerTool, + context = null + ) + } + commands.emit(Command.LaunchDocument(result.objectId)) + }, + onFailure = { e -> Timber.e(e, "Error while creating a new page") } + ) + } + } + class Factory @Inject constructor( private val container: StorelessSubscriptionContainer, private val workspaceManager: WorkspaceManager, @@ -629,6 +676,7 @@ class CollectionViewModel( private val deleteObjects: DeleteObjects, private val resourceProvider: CollectionResourceProvider, private val openObject: OpenObject, + private val createObject: CreateObject, private val configStorage: ConfigStorage, private val interceptEvents: InterceptEvents, private val objectPayloadDispatcher: Dispatcher, @@ -651,6 +699,7 @@ class CollectionViewModel( deleteObjects = deleteObjects, resourceProvider = resourceProvider, openObject = openObject, + createObject = createObject, configstorage = configStorage, interceptEvents = interceptEvents, objectPayloadDispatcher = objectPayloadDispatcher, @@ -664,7 +713,11 @@ class CollectionViewModel( sealed class Command { data class ConfirmRemoveFromBin(val count: Int) : Command() data class LaunchDocument(val id: Id) : Command() + data class OpenCollection(val subscription: Subscription) : Command() data class LaunchObjectSet(val target: Id) : Command() + + object ToDesktop : Command() + object ToSearch : Command() object Exit : Command() } }