DROID-1068 Widgets | Enhancement | Add a navigation panel (#3055)

This commit is contained in:
Mikhail 2023-03-29 17:51:58 +03:00 committed by GitHub
parent 8d3c041e94
commit f35ba08050
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 126 additions and 12 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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