mirror of
https://github.com/anyproto/anytype-kotlin.git
synced 2025-06-08 05:47:05 +09:00
DROID-2738 Sync status | Status caching logic (#1483)
This commit is contained in:
parent
25ec9bd98a
commit
642bfdceae
34 changed files with 304 additions and 270 deletions
|
@ -57,6 +57,7 @@ import com.anytypeio.anytype.domain.cover.RemoveDocCover
|
|||
import com.anytypeio.anytype.domain.cover.SetDocCoverImage
|
||||
import com.anytypeio.anytype.domain.download.DownloadFile
|
||||
import com.anytypeio.anytype.domain.event.interactor.InterceptEvents
|
||||
import com.anytypeio.anytype.domain.event.interactor.SpaceSyncAndP2PStatusProvider
|
||||
import com.anytypeio.anytype.domain.icon.SetDocumentImageIcon
|
||||
import com.anytypeio.anytype.domain.launch.GetDefaultObjectType
|
||||
import com.anytypeio.anytype.domain.library.StorelessSubscriptionContainer
|
||||
|
@ -109,7 +110,6 @@ import com.anytypeio.anytype.presentation.editor.render.DefaultBlockViewRenderer
|
|||
import com.anytypeio.anytype.presentation.editor.selection.SelectionStateHolder
|
||||
import com.anytypeio.anytype.presentation.editor.toggle.ToggleStateHolder
|
||||
import com.anytypeio.anytype.presentation.search.ObjectSearchConstants
|
||||
import com.anytypeio.anytype.presentation.sync.SpaceSyncAndP2PStatusProvider
|
||||
import com.anytypeio.anytype.presentation.templates.ObjectTypeTemplatesContainer
|
||||
import com.anytypeio.anytype.presentation.util.CopyFileToCacheDirectory
|
||||
import com.anytypeio.anytype.presentation.util.Dispatcher
|
||||
|
|
|
@ -29,6 +29,7 @@ import com.anytypeio.anytype.domain.dataview.SetDataViewQuery
|
|||
import com.anytypeio.anytype.domain.dataview.interactor.CreateDataViewObject
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.UpdateDataViewViewer
|
||||
import com.anytypeio.anytype.domain.event.interactor.InterceptEvents
|
||||
import com.anytypeio.anytype.domain.event.interactor.SpaceSyncAndP2PStatusProvider
|
||||
import com.anytypeio.anytype.domain.launch.GetDefaultObjectType
|
||||
import com.anytypeio.anytype.domain.library.StorelessSubscriptionContainer
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
|
@ -68,7 +69,6 @@ import com.anytypeio.anytype.presentation.sets.ObjectSetViewModelFactory
|
|||
import com.anytypeio.anytype.presentation.sets.state.DefaultObjectStateReducer
|
||||
import com.anytypeio.anytype.presentation.sets.subscription.DefaultDataViewSubscription
|
||||
import com.anytypeio.anytype.presentation.sets.viewer.ViewerDelegate
|
||||
import com.anytypeio.anytype.presentation.sync.SpaceSyncAndP2PStatusProvider
|
||||
import com.anytypeio.anytype.presentation.templates.ObjectTypeTemplatesContainer
|
||||
import com.anytypeio.anytype.presentation.util.Dispatcher
|
||||
import com.anytypeio.anytype.presentation.widgets.collection.DateProviderImpl
|
||||
|
|
|
@ -52,11 +52,11 @@ import com.anytypeio.anytype.domain.download.DownloadFile
|
|||
import com.anytypeio.anytype.domain.download.Downloader
|
||||
import com.anytypeio.anytype.domain.event.interactor.EventChannel
|
||||
import com.anytypeio.anytype.domain.event.interactor.InterceptEvents
|
||||
import com.anytypeio.anytype.domain.event.interactor.SpaceSyncAndP2PStatusProvider
|
||||
import com.anytypeio.anytype.domain.icon.SetDocumentImageIcon
|
||||
import com.anytypeio.anytype.domain.launch.GetDefaultObjectType
|
||||
import com.anytypeio.anytype.domain.library.StorelessSubscriptionContainer
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.domain.multiplayer.ActiveSpaceMemberSubscriptionContainer
|
||||
import com.anytypeio.anytype.domain.multiplayer.UserPermissionProvider
|
||||
import com.anytypeio.anytype.domain.networkmode.GetNetworkMode
|
||||
import com.anytypeio.anytype.domain.`object`.ConvertObjectToCollection
|
||||
|
@ -100,9 +100,7 @@ import com.anytypeio.anytype.domain.unsplash.DownloadUnsplashImage
|
|||
import com.anytypeio.anytype.domain.unsplash.UnsplashRepository
|
||||
import com.anytypeio.anytype.domain.workspace.FileLimitsEventChannel
|
||||
import com.anytypeio.anytype.domain.workspace.InterceptFileLimitEvents
|
||||
import com.anytypeio.anytype.domain.workspace.P2PStatusChannel
|
||||
import com.anytypeio.anytype.domain.workspace.SpaceManager
|
||||
import com.anytypeio.anytype.domain.workspace.SpaceSyncStatusChannel
|
||||
import com.anytypeio.anytype.presentation.analytics.AnalyticSpaceHelperDelegate
|
||||
import com.anytypeio.anytype.presentation.common.Action
|
||||
import com.anytypeio.anytype.presentation.common.Delegator
|
||||
|
@ -127,7 +125,6 @@ import com.anytypeio.anytype.presentation.relations.providers.ObjectRelationProv
|
|||
import com.anytypeio.anytype.presentation.relations.providers.ObjectRelationProvider.Companion.INTRINSIC_PROVIDER_TYPE
|
||||
import com.anytypeio.anytype.presentation.relations.providers.ObjectValueProvider
|
||||
import com.anytypeio.anytype.presentation.relations.providers.RelationListProvider
|
||||
import com.anytypeio.anytype.presentation.sync.SpaceSyncAndP2PStatusProvider
|
||||
import com.anytypeio.anytype.presentation.templates.ObjectTypeTemplatesContainer
|
||||
import com.anytypeio.anytype.presentation.util.CopyFileToCacheDirectory
|
||||
import com.anytypeio.anytype.presentation.util.DefaultCopyFileToCacheDirectory
|
||||
|
@ -1204,18 +1201,6 @@ object EditorUseCaseModule {
|
|||
spaceManager = spaceManager
|
||||
)
|
||||
|
||||
@Provides
|
||||
@PerScreen
|
||||
fun provideSpaceSyncStatusProvider(
|
||||
activeSpace: ActiveSpaceMemberSubscriptionContainer,
|
||||
syncChannel: SpaceSyncStatusChannel,
|
||||
p2PStatusChannel: P2PStatusChannel
|
||||
): SpaceSyncAndP2PStatusProvider = SpaceSyncAndP2PStatusProvider.Impl(
|
||||
activeSpace = activeSpace,
|
||||
spaceSyncStatusChannel = syncChannel,
|
||||
p2PStatusChannel = p2PStatusChannel
|
||||
)
|
||||
|
||||
@Module
|
||||
interface Bindings {
|
||||
|
||||
|
|
|
@ -32,12 +32,12 @@ import com.anytypeio.anytype.domain.dataview.interactor.SetDataViewViewerPositio
|
|||
import com.anytypeio.anytype.domain.dataview.interactor.UpdateDataViewViewer
|
||||
import com.anytypeio.anytype.domain.event.interactor.EventChannel
|
||||
import com.anytypeio.anytype.domain.event.interactor.InterceptEvents
|
||||
import com.anytypeio.anytype.domain.event.interactor.SpaceSyncAndP2PStatusProvider
|
||||
import com.anytypeio.anytype.domain.icon.SetDocumentImageIcon
|
||||
import com.anytypeio.anytype.domain.launch.GetDefaultObjectType
|
||||
import com.anytypeio.anytype.domain.library.StorelessSubscriptionContainer
|
||||
import com.anytypeio.anytype.domain.misc.DateProvider
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.domain.multiplayer.ActiveSpaceMemberSubscriptionContainer
|
||||
import com.anytypeio.anytype.domain.multiplayer.UserPermissionProvider
|
||||
import com.anytypeio.anytype.domain.`object`.ConvertObjectToCollection
|
||||
import com.anytypeio.anytype.domain.`object`.DuplicateObject
|
||||
|
@ -65,9 +65,7 @@ import com.anytypeio.anytype.domain.templates.CreateTemplate
|
|||
import com.anytypeio.anytype.domain.templates.GetTemplates
|
||||
import com.anytypeio.anytype.domain.unsplash.DownloadUnsplashImage
|
||||
import com.anytypeio.anytype.domain.unsplash.UnsplashRepository
|
||||
import com.anytypeio.anytype.domain.workspace.P2PStatusChannel
|
||||
import com.anytypeio.anytype.domain.workspace.SpaceManager
|
||||
import com.anytypeio.anytype.domain.workspace.SpaceSyncStatusChannel
|
||||
import com.anytypeio.anytype.presentation.analytics.AnalyticSpaceHelperDelegate
|
||||
import com.anytypeio.anytype.presentation.common.Action
|
||||
import com.anytypeio.anytype.presentation.common.Delegator
|
||||
|
@ -95,7 +93,6 @@ import com.anytypeio.anytype.presentation.sets.subscription.DataViewSubscription
|
|||
import com.anytypeio.anytype.presentation.sets.subscription.DefaultDataViewSubscription
|
||||
import com.anytypeio.anytype.presentation.sets.viewer.DefaultViewerDelegate
|
||||
import com.anytypeio.anytype.presentation.sets.viewer.ViewerDelegate
|
||||
import com.anytypeio.anytype.presentation.sync.SpaceSyncAndP2PStatusProvider
|
||||
import com.anytypeio.anytype.presentation.templates.ObjectTypeTemplatesContainer
|
||||
import com.anytypeio.anytype.presentation.util.CopyFileToCacheDirectory
|
||||
import com.anytypeio.anytype.presentation.util.DefaultCopyFileToCacheDirectory
|
||||
|
@ -714,18 +711,6 @@ object ObjectSetModule {
|
|||
analytics = analytics,
|
||||
dispatcher = dispatcher
|
||||
)
|
||||
|
||||
@Provides
|
||||
@PerScreen
|
||||
fun provideSpaceSyncStatusProvider(
|
||||
activeSpace: ActiveSpaceMemberSubscriptionContainer,
|
||||
syncChannel: SpaceSyncStatusChannel,
|
||||
p2PStatusChannel: P2PStatusChannel
|
||||
): SpaceSyncAndP2PStatusProvider = SpaceSyncAndP2PStatusProvider.Impl(
|
||||
activeSpace = activeSpace,
|
||||
spaceSyncStatusChannel = syncChannel,
|
||||
p2PStatusChannel = p2PStatusChannel
|
||||
)
|
||||
}
|
||||
|
||||
data class DefaultComponentParam(
|
||||
|
|
|
@ -9,21 +9,29 @@ import com.anytypeio.anytype.data.auth.event.FileLimitsDataChannel
|
|||
import com.anytypeio.anytype.data.auth.event.FileLimitsRemoteChannel
|
||||
import com.anytypeio.anytype.data.auth.event.SubscriptionDataChannel
|
||||
import com.anytypeio.anytype.data.auth.event.SubscriptionEventRemoteChannel
|
||||
import com.anytypeio.anytype.data.auth.status.SyncAndP2PStatusEventsStore
|
||||
import com.anytypeio.anytype.di.main.ConfigModule.DEFAULT_APP_COROUTINE_SCOPE
|
||||
import com.anytypeio.anytype.domain.account.AccountStatusChannel
|
||||
import com.anytypeio.anytype.domain.event.interactor.EventChannel
|
||||
import com.anytypeio.anytype.domain.search.SubscriptionEventChannel
|
||||
import com.anytypeio.anytype.domain.workspace.FileLimitsEventChannel
|
||||
import com.anytypeio.anytype.middleware.EventProxy
|
||||
import com.anytypeio.anytype.middleware.interactor.AccountStatusMiddlewareChannel
|
||||
import com.anytypeio.anytype.middleware.interactor.EventHandlerChannel
|
||||
import com.anytypeio.anytype.middleware.interactor.EventHandlerChannelImpl
|
||||
import com.anytypeio.anytype.middleware.interactor.EventHandler
|
||||
import com.anytypeio.anytype.middleware.interactor.FileLimitsMiddlewareChannel
|
||||
import com.anytypeio.anytype.middleware.interactor.MiddlewareEventChannel
|
||||
import com.anytypeio.anytype.middleware.interactor.MiddlewareProtobufLogger
|
||||
import com.anytypeio.anytype.middleware.interactor.MiddlewareSubscriptionEventChannel
|
||||
import com.anytypeio.anytype.middleware.interactor.SyncAndP2PStatusEventsStoreImpl
|
||||
import com.anytypeio.anytype.presentation.common.PayloadDelegator
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import javax.inject.Named
|
||||
import javax.inject.Singleton
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
||||
@Module(includes = [EventModule.Bindings::class])
|
||||
object EventModule {
|
||||
|
@ -110,13 +118,40 @@ object EventModule {
|
|||
channel: FileLimitsRemoteChannel
|
||||
): FileLimitsEventChannel = FileLimitsDataChannel(channel = channel)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideEventHandler(
|
||||
logger: MiddlewareProtobufLogger,
|
||||
@Named(DEFAULT_APP_COROUTINE_SCOPE) scope: CoroutineScope,
|
||||
channel: EventHandlerChannel,
|
||||
syncP2PStore: SyncAndP2PStatusEventsStore
|
||||
): EventProxy = EventHandler(
|
||||
scope = scope,
|
||||
logger = logger,
|
||||
channel = channel,
|
||||
syncP2PStore = syncP2PStore
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideSyncAndP2PStatusEventsSubscription(
|
||||
@Named(DEFAULT_APP_COROUTINE_SCOPE) scope: CoroutineScope,
|
||||
channel: EventHandlerChannel
|
||||
): SyncAndP2PStatusEventsStore = SyncAndP2PStatusEventsStoreImpl(
|
||||
scope = scope,
|
||||
channel = channel
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideDefaultEventChannel(): EventHandlerChannel = EventHandlerChannelImpl()
|
||||
|
||||
@Module
|
||||
interface Bindings {
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindEventProxy(handler: EventHandler): EventProxy
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun payloadDelegator(default: PayloadDelegator.Default): PayloadDelegator
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
|
|||
import com.anytypeio.anytype.domain.block.repo.BlockRepository
|
||||
import com.anytypeio.anytype.domain.config.ConfigStorage
|
||||
import com.anytypeio.anytype.domain.debugging.Logger
|
||||
import com.anytypeio.anytype.domain.event.interactor.SpaceSyncAndP2PStatusProvider
|
||||
import com.anytypeio.anytype.domain.library.StorelessSubscriptionContainer
|
||||
import com.anytypeio.anytype.domain.multiplayer.ActiveSpaceMemberSubscriptionContainer
|
||||
import com.anytypeio.anytype.domain.multiplayer.DefaultUserPermissionProvider
|
||||
|
@ -24,6 +25,8 @@ import com.anytypeio.anytype.domain.search.SubscriptionEventChannel
|
|||
import com.anytypeio.anytype.domain.spaces.SpaceDeletedStatusWatcher
|
||||
import com.anytypeio.anytype.domain.subscriptions.GlobalSubscriptionManager
|
||||
import com.anytypeio.anytype.domain.workspace.SpaceManager
|
||||
import com.anytypeio.anytype.domain.workspace.SyncAndP2PStatusChannel
|
||||
import com.anytypeio.anytype.presentation.sync.SpaceSyncAndP2PStatusProviderImpl
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import javax.inject.Named
|
||||
|
@ -163,6 +166,17 @@ object SubscriptionsModule {
|
|||
awaitAccountStart = awaitAccountStartManager
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideSpaceSyncStatusProvider(
|
||||
syncChannel: SyncAndP2PStatusChannel,
|
||||
spaceManager: SpaceManager
|
||||
): SpaceSyncAndP2PStatusProvider = SpaceSyncAndP2PStatusProviderImpl(
|
||||
spaceManager = spaceManager,
|
||||
spaceSyncStatusChannel = syncChannel
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
|
|
|
@ -1,30 +1,27 @@
|
|||
package com.anytypeio.anytype.di.main
|
||||
|
||||
import com.anytypeio.anytype.data.auth.status.P2PStatusDataChannel
|
||||
import com.anytypeio.anytype.data.auth.status.P2PStatusRemoteChannel
|
||||
import com.anytypeio.anytype.data.auth.status.SpaceStatusDataChannel
|
||||
import com.anytypeio.anytype.data.auth.status.SpaceStatusRemoteChannel
|
||||
import com.anytypeio.anytype.data.auth.status.SyncAndP2PStatusDataChannel
|
||||
import com.anytypeio.anytype.data.auth.status.SyncAndP2PStatusEventsStore
|
||||
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
|
||||
import com.anytypeio.anytype.domain.block.repo.BlockRepository
|
||||
import com.anytypeio.anytype.domain.config.ConfigStorage
|
||||
import com.anytypeio.anytype.domain.debugging.Logger
|
||||
import com.anytypeio.anytype.domain.workspace.P2PStatusChannel
|
||||
import com.anytypeio.anytype.domain.workspace.SpaceManager
|
||||
import com.anytypeio.anytype.domain.workspace.SpaceSyncStatusChannel
|
||||
import com.anytypeio.anytype.domain.workspace.SyncAndP2PStatusChannel
|
||||
import com.anytypeio.anytype.domain.workspace.WorkspaceManager
|
||||
import com.anytypeio.anytype.middleware.EventProxy
|
||||
import com.anytypeio.anytype.middleware.interactor.P2PStatusRemoteChannelImpl
|
||||
import com.anytypeio.anytype.middleware.interactor.SpaceSyncStatusRemoteChannelImpl
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
object WorkspaceModule {
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
fun manager(): WorkspaceManager = WorkspaceManager.DefaultWorkspaceManager()
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
fun spaces(
|
||||
|
@ -40,29 +37,9 @@ object WorkspaceModule {
|
|||
)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideSyncStatusRemoteChannel(
|
||||
proxy: EventProxy
|
||||
): SpaceStatusRemoteChannel = SpaceSyncStatusRemoteChannelImpl(events = proxy)
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun spaceSyncStatusChannel(
|
||||
channel: SpaceStatusRemoteChannel
|
||||
): SpaceSyncStatusChannel = SpaceStatusDataChannel(channel)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
fun p2pStatusRemoteChannel(
|
||||
proxy: EventProxy
|
||||
): P2PStatusRemoteChannel = P2PStatusRemoteChannelImpl(events = proxy)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
fun p2pStatusChannel(
|
||||
channel: P2PStatusRemoteChannel
|
||||
): P2PStatusChannel = P2PStatusDataChannel(channel)
|
||||
store: SyncAndP2PStatusEventsStore
|
||||
): SyncAndP2PStatusChannel = SyncAndP2PStatusDataChannel(store)
|
||||
}
|
|
@ -53,6 +53,7 @@ import com.anytypeio.anytype.core_models.Key
|
|||
import com.anytypeio.anytype.core_models.ObjectWrapper
|
||||
import com.anytypeio.anytype.core_models.ThemeColor
|
||||
import com.anytypeio.anytype.core_models.Url
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceSyncAndP2PStatusState
|
||||
import com.anytypeio.anytype.core_models.primitives.SpaceId
|
||||
import com.anytypeio.anytype.core_ui.extensions.addTextFromSelectedStart
|
||||
import com.anytypeio.anytype.core_ui.extensions.color
|
||||
|
@ -125,7 +126,6 @@ import com.anytypeio.anytype.presentation.editor.model.EditorFooter
|
|||
import com.anytypeio.anytype.presentation.editor.template.SelectTemplateViewState
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectIcon
|
||||
import com.anytypeio.anytype.presentation.relations.value.tagstatus.RelationContext
|
||||
import com.anytypeio.anytype.presentation.sync.SpaceSyncAndP2PStatusState
|
||||
import com.anytypeio.anytype.ui.alert.AlertUpdateAppFragment
|
||||
import com.anytypeio.anytype.ui.base.NavigationFragment
|
||||
import com.anytypeio.anytype.ui.base.navigation
|
||||
|
@ -871,7 +871,7 @@ open class EditorFragment : NavigationFragment<FragmentEditorBinding>(R.layout.f
|
|||
|
||||
private fun bindSyncStatus(status: SpaceSyncAndP2PStatusState) {
|
||||
binding.topToolbar.status.bind(status)
|
||||
if (status is SpaceSyncAndP2PStatusState.Initial) {
|
||||
if (status is SpaceSyncAndP2PStatusState.Init) {
|
||||
binding.topToolbar.hideStatusContainer()
|
||||
} else {
|
||||
binding.topToolbar.showStatusContainer()
|
||||
|
|
|
@ -44,6 +44,7 @@ import com.anytypeio.anytype.R
|
|||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.Key
|
||||
import com.anytypeio.anytype.core_models.ObjectWrapper
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceSyncAndP2PStatusState
|
||||
import com.anytypeio.anytype.core_models.primitives.SpaceId
|
||||
import com.anytypeio.anytype.core_ui.extensions.setEmojiOrNull
|
||||
import com.anytypeio.anytype.core_ui.features.dataview.ViewerGridAdapter
|
||||
|
@ -100,7 +101,6 @@ import com.anytypeio.anytype.presentation.sets.ViewerLayoutWidgetUi
|
|||
import com.anytypeio.anytype.presentation.sets.ViewersWidgetUi
|
||||
import com.anytypeio.anytype.presentation.sets.isVisible
|
||||
import com.anytypeio.anytype.presentation.sets.model.Viewer
|
||||
import com.anytypeio.anytype.presentation.sync.SpaceSyncAndP2PStatusState
|
||||
import com.anytypeio.anytype.ui.base.NavigationFragment
|
||||
import com.anytypeio.anytype.ui.editor.cover.SelectCoverObjectSetFragment
|
||||
import com.anytypeio.anytype.ui.editor.modals.IconPickerFragmentBase
|
||||
|
|
|
@ -113,4 +113,13 @@ enum class P2PStatus {
|
|||
NOT_CONNECTED,
|
||||
NOT_POSSIBLE,
|
||||
CONNECTED
|
||||
}
|
||||
|
||||
sealed class SpaceSyncAndP2PStatusState {
|
||||
data object Init : SpaceSyncAndP2PStatusState()
|
||||
data class Error(val message: String) : SpaceSyncAndP2PStatusState()
|
||||
data class Success(
|
||||
val spaceSyncUpdate: SpaceSyncUpdate,
|
||||
val p2PStatusUpdate: P2PStatusUpdate
|
||||
) : SpaceSyncAndP2PStatusState()
|
||||
}
|
|
@ -148,8 +148,8 @@ private fun ColumnScope.ErrorState() {
|
|||
private fun SuccessState(spaceSyncUpdate: SpaceSyncUpdate, p2pStatus: P2PStatusUpdate) {
|
||||
if (spaceSyncUpdate is SpaceSyncUpdate.Update) {
|
||||
SpaceSyncStatusItem(spaceSyncUpdate)
|
||||
Divider()
|
||||
}
|
||||
Divider()
|
||||
if (p2pStatus is P2PStatusUpdate.Update) {
|
||||
P2PStatusItem(p2pStatus)
|
||||
}
|
||||
|
|
|
@ -3,13 +3,14 @@ package com.anytypeio.anytype.core_ui.widgets
|
|||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import androidx.appcompat.widget.AppCompatImageView
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceSyncAndP2PStatusState
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceSyncError
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceSyncStatus
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceSyncUpdate
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
import com.anytypeio.anytype.core_utils.ext.gone
|
||||
import com.anytypeio.anytype.core_utils.ext.visible
|
||||
import com.anytypeio.anytype.presentation.sync.SpaceSyncAndP2PStatusState
|
||||
|
||||
|
||||
class StatusBadgeWidget @JvmOverloads constructor(
|
||||
context: Context,
|
||||
|
@ -22,7 +23,7 @@ class StatusBadgeWidget @JvmOverloads constructor(
|
|||
visible()
|
||||
setImageResource(R.drawable.ic_sync_error_10)
|
||||
}
|
||||
SpaceSyncAndP2PStatusState.Initial -> {
|
||||
SpaceSyncAndP2PStatusState.Init -> {
|
||||
gone()
|
||||
}
|
||||
is SpaceSyncAndP2PStatusState.Success -> {
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
package com.anytypeio.anytype.data.auth.status
|
||||
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.multiplayer.P2PStatusUpdate
|
||||
import com.anytypeio.anytype.domain.workspace.P2PStatusChannel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface P2PStatusRemoteChannel {
|
||||
fun observe(activeSpaceId: Id): Flow<P2PStatusUpdate>
|
||||
}
|
||||
|
||||
class P2PStatusDataChannel(
|
||||
private val channel: P2PStatusRemoteChannel
|
||||
) : P2PStatusChannel {
|
||||
|
||||
override fun observe(activeSpaceId: Id): Flow<P2PStatusUpdate> {
|
||||
return channel.observe(activeSpaceId)
|
||||
}
|
||||
}
|
|
@ -1,19 +1,14 @@
|
|||
package com.anytypeio.anytype.data.auth.status
|
||||
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.multiplayer.P2PStatusUpdate
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceSyncUpdate
|
||||
import com.anytypeio.anytype.domain.workspace.SpaceSyncStatusChannel
|
||||
import com.anytypeio.anytype.domain.workspace.SyncAndP2PStatusChannel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface SpaceStatusRemoteChannel {
|
||||
fun observe(activeSpaceId: String): Flow<SpaceSyncUpdate>
|
||||
}
|
||||
class SyncAndP2PStatusDataChannel(
|
||||
private val store: SyncAndP2PStatusEventsStore
|
||||
) : SyncAndP2PStatusChannel {
|
||||
|
||||
class SpaceStatusDataChannel(
|
||||
private val channel: SpaceStatusRemoteChannel
|
||||
) : SpaceSyncStatusChannel {
|
||||
|
||||
override fun observe(activeSpaceId: Id): Flow<SpaceSyncUpdate> {
|
||||
return channel.observe(activeSpaceId)
|
||||
}
|
||||
override fun p2pStatus(): Flow<Map<String, P2PStatusUpdate>> = store.p2pStatus
|
||||
override fun syncStatus(): Flow<Map<String, SpaceSyncUpdate>> = store.syncStatus
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.anytypeio.anytype.data.auth.status
|
||||
|
||||
import com.anytypeio.anytype.core_models.multiplayer.P2PStatusUpdate
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceSyncUpdate
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface SyncAndP2PStatusEventsStore {
|
||||
val p2pStatus: Flow<Map<String, P2PStatusUpdate>>
|
||||
val syncStatus: Flow<Map<String, SpaceSyncUpdate>>
|
||||
|
||||
fun start()
|
||||
fun stop()
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package com.anytypeio.anytype.domain.event.interactor
|
||||
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceSyncAndP2PStatusState
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface SpaceSyncAndP2PStatusProvider {
|
||||
fun observe(): Flow<SpaceSyncAndP2PStatusState>
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
package com.anytypeio.anytype.domain.workspace
|
||||
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.multiplayer.P2PStatusUpdate
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface P2PStatusChannel {
|
||||
fun observe(activeSpaceId: Id): Flow<P2PStatusUpdate>
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
package com.anytypeio.anytype.domain.workspace
|
||||
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceSyncUpdate
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface SpaceSyncStatusChannel {
|
||||
fun observe(activeSpaceId: Id): Flow<SpaceSyncUpdate>
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package com.anytypeio.anytype.domain.workspace
|
||||
|
||||
import com.anytypeio.anytype.core_models.multiplayer.P2PStatusUpdate
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceSyncUpdate
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface SyncAndP2PStatusChannel {
|
||||
fun p2pStatus(): Flow<Map<String, P2PStatusUpdate>>
|
||||
fun syncStatus(): Flow<Map<String, SpaceSyncUpdate>>
|
||||
}
|
|
@ -1,24 +1,29 @@
|
|||
package com.anytypeio.anytype.middleware.interactor
|
||||
|
||||
import anytype.Event
|
||||
import com.anytypeio.anytype.middleware.BuildConfig
|
||||
import com.anytypeio.anytype.data.auth.status.SyncAndP2PStatusEventsStore
|
||||
import com.anytypeio.anytype.middleware.EventProxy
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import service.Service.setEventHandlerMobile
|
||||
import timber.log.Timber
|
||||
import java.io.IOException
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import service.Service.setEventHandlerMobile
|
||||
import timber.log.Timber
|
||||
|
||||
class EventHandler @Inject constructor(
|
||||
private val logger: MiddlewareProtobufLogger
|
||||
private val logger: MiddlewareProtobufLogger,
|
||||
private val scope: CoroutineScope,
|
||||
private val channel: EventHandlerChannel,
|
||||
private val syncP2PStore: SyncAndP2PStatusEventsStore
|
||||
) : EventProxy {
|
||||
|
||||
private val scope: CoroutineScope = GlobalScope
|
||||
private val channel = MutableSharedFlow<Event>(0, 1)
|
||||
|
||||
init {
|
||||
scope.launch {
|
||||
syncP2PStore.start()
|
||||
}
|
||||
scope.launch {
|
||||
setEventHandlerMobile { bytes ->
|
||||
if (bytes != null) {
|
||||
|
@ -43,5 +48,5 @@ class EventHandler @Inject constructor(
|
|||
logger.logEvent(event)
|
||||
}
|
||||
|
||||
override fun flow(): Flow<Event> = channel
|
||||
override fun flow(): Flow<Event> = channel.flow()
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.anytypeio.anytype.middleware.interactor
|
||||
|
||||
import anytype.Event
|
||||
import kotlinx.coroutines.channels.BufferOverflow
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
|
||||
interface EventHandlerChannel {
|
||||
fun flow(): Flow<Event>
|
||||
suspend fun emit(event: Event)
|
||||
}
|
||||
|
||||
class EventHandlerChannelImpl() : EventHandlerChannel {
|
||||
|
||||
private val _channel = MutableSharedFlow<Event>(
|
||||
replay = 0,
|
||||
extraBufferCapacity = 1
|
||||
)
|
||||
|
||||
override fun flow(): Flow<Event> = _channel
|
||||
|
||||
override suspend fun emit(event: Event) {
|
||||
_channel.emit(event)
|
||||
}
|
||||
|
||||
fun trySend(event: Event) {
|
||||
_channel.tryEmit(event)
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
package com.anytypeio.anytype.middleware.interactor
|
||||
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.multiplayer.P2PStatusUpdate
|
||||
import com.anytypeio.anytype.data.auth.status.P2PStatusRemoteChannel
|
||||
import com.anytypeio.anytype.middleware.EventProxy
|
||||
import com.anytypeio.anytype.middleware.mappers.toCoreModel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.mapNotNull
|
||||
|
||||
class P2PStatusRemoteChannelImpl(private val events: EventProxy) : P2PStatusRemoteChannel {
|
||||
|
||||
override fun observe(activeSpaceId: Id): Flow<P2PStatusUpdate> {
|
||||
return events.flow()
|
||||
.mapNotNull { emission ->
|
||||
emission.messages.lastOrNull()?.p2pStatusUpdate
|
||||
}
|
||||
.filter { event -> event.spaceId == activeSpaceId }
|
||||
.map { event ->
|
||||
P2PStatusUpdate.Update(
|
||||
spaceId = event.spaceId,
|
||||
status = event.status.toCoreModel(),
|
||||
devicesCounter = event.devicesCounter
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package com.anytypeio.anytype.middleware.interactor
|
||||
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceSyncUpdate
|
||||
import com.anytypeio.anytype.data.auth.status.SpaceStatusRemoteChannel
|
||||
import com.anytypeio.anytype.middleware.EventProxy
|
||||
import com.anytypeio.anytype.middleware.mappers.toCoreModel
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.mapNotNull
|
||||
|
||||
class SpaceSyncStatusRemoteChannelImpl(private val events: EventProxy) : SpaceStatusRemoteChannel {
|
||||
|
||||
override fun observe(activeSpaceId: Id): Flow<SpaceSyncUpdate> {
|
||||
return events.flow()
|
||||
.mapNotNull { emission ->
|
||||
emission.messages.lastOrNull()?.spaceSyncStatusUpdate
|
||||
}
|
||||
.filter { event -> event.id == activeSpaceId }
|
||||
.map { event ->
|
||||
SpaceSyncUpdate.Update(
|
||||
id = event.id,
|
||||
status = event.status.toCoreModel(),
|
||||
network = event.network.toCoreModel(),
|
||||
error = event.error.toCoreModel(),
|
||||
syncingObjectsCounter = event.syncingObjectsCounter
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
package com.anytypeio.anytype.middleware.interactor
|
||||
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.multiplayer.P2PStatusUpdate
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceSyncUpdate
|
||||
import com.anytypeio.anytype.core_utils.ext.cancel
|
||||
import com.anytypeio.anytype.data.auth.status.SyncAndP2PStatusEventsStore
|
||||
import com.anytypeio.anytype.middleware.mappers.MP2PStatusUpdate
|
||||
import com.anytypeio.anytype.middleware.mappers.MSyncStatusUpdate
|
||||
import com.anytypeio.anytype.middleware.mappers.toCoreModel
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
|
||||
class SyncAndP2PStatusEventsStoreImpl(
|
||||
private val scope: CoroutineScope,
|
||||
private val channel: EventHandlerChannel,
|
||||
private val dispatcher: CoroutineDispatcher = Dispatchers.IO
|
||||
) : SyncAndP2PStatusEventsStore {
|
||||
|
||||
private val _p2pStatus = MutableStateFlow<MutableMap<Id, P2PStatusUpdate>>(mutableMapOf())
|
||||
private val _syncStatus = MutableStateFlow<MutableMap<Id, SpaceSyncUpdate>>(mutableMapOf())
|
||||
|
||||
override val p2pStatus: Flow<Map<Id, P2PStatusUpdate>> get() = _p2pStatus
|
||||
override val syncStatus: Flow<Map<Id, SpaceSyncUpdate>> get() = _syncStatus
|
||||
|
||||
private val jobs = mutableListOf<Job>()
|
||||
|
||||
override fun start() {
|
||||
Timber.i("SyncAndP2PStatusEventsStoreImpl start")
|
||||
jobs.cancel()
|
||||
jobs += scope.launch(dispatcher) {
|
||||
channel.flow()
|
||||
.catch { e ->
|
||||
Timber.e(e, "Error collecting P2P & Sync status updates")
|
||||
}
|
||||
.collect { emission ->
|
||||
emission.messages.forEach { message ->
|
||||
message.p2pStatusUpdate?.let { processP2PStatusUpdate(it) }
|
||||
message.spaceSyncStatusUpdate?.let { processSpaceSyncUpdate(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun stop() {
|
||||
Timber.i("SyncAndP2PStatusEventsStoreImpl stop")
|
||||
jobs.cancel()
|
||||
}
|
||||
|
||||
private fun processP2PStatusUpdate(update: MP2PStatusUpdate) {
|
||||
val p2pUpdate = P2PStatusUpdate.Update(
|
||||
spaceId = update.spaceId,
|
||||
status = update.status.toCoreModel(),
|
||||
devicesCounter = update.devicesCounter
|
||||
)
|
||||
_p2pStatus.update { currentMap ->
|
||||
currentMap[update.spaceId] = p2pUpdate
|
||||
currentMap
|
||||
}
|
||||
}
|
||||
|
||||
private fun processSpaceSyncUpdate(update: MSyncStatusUpdate) {
|
||||
val syncUpdate = SpaceSyncUpdate.Update(
|
||||
id = update.id,
|
||||
status = update.status.toCoreModel(),
|
||||
network = update.network.toCoreModel(),
|
||||
error = update.error.toCoreModel(),
|
||||
syncingObjectsCounter = update.syncingObjectsCounter
|
||||
)
|
||||
|
||||
_syncStatus.update { currentMap ->
|
||||
currentMap[update.id] = syncUpdate
|
||||
currentMap
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,8 @@
|
|||
package com.anytypeio.anytype.middleware.mappers
|
||||
|
||||
import anytype.Event.P2PStatus
|
||||
import anytype.Event.Space
|
||||
|
||||
typealias MAccount = anytype.model.Account
|
||||
typealias MAccountStatus = anytype.model.Account.Status
|
||||
typealias MAccountStatusType = anytype.model.Account.StatusType
|
||||
|
@ -95,4 +98,6 @@ typealias MSpaceSyncStatus = anytype.Event.Space.Status
|
|||
typealias MSpaceSyncNetwork = anytype.Event.Space.Network
|
||||
typealias MSpaceSyncError = anytype.Event.Space.SyncError
|
||||
|
||||
typealias MP2PStatus = anytype.Event.P2PStatus.Status
|
||||
typealias MP2PStatus = anytype.Event.P2PStatus.Status
|
||||
typealias MP2PStatusUpdate = P2PStatus.Update
|
||||
typealias MSyncStatusUpdate = Space.SyncStatus.Update
|
|
@ -1,11 +1,11 @@
|
|||
package com.anytypeio.anytype.middleware.mappers
|
||||
|
||||
import anytype.Event
|
||||
import com.anytypeio.anytype.core_models.SearchResult
|
||||
import com.anytypeio.anytype.core_models.Event.Command.DataView.UpdateView.DVFilterUpdate
|
||||
import com.anytypeio.anytype.core_models.Event.Command.DataView.UpdateView.DVSortUpdate
|
||||
import com.anytypeio.anytype.core_models.Event.Command.DataView.UpdateView.DVViewerRelationUpdate
|
||||
import com.anytypeio.anytype.core_models.Event.Command.DataView.UpdateView.DVViewerFields
|
||||
import com.anytypeio.anytype.core_models.Event.Command.DataView.UpdateView.DVViewerRelationUpdate
|
||||
import com.anytypeio.anytype.core_models.SearchResult
|
||||
|
||||
fun Event.Object.Subscription.Counters.parse(): SearchResult.Counter = SearchResult.Counter(
|
||||
total = total.toInt(),
|
||||
|
|
|
@ -49,6 +49,7 @@ import com.anytypeio.anytype.core_models.ext.sortByType
|
|||
import com.anytypeio.anytype.core_models.ext.supportNesting
|
||||
import com.anytypeio.anytype.core_models.ext.title
|
||||
import com.anytypeio.anytype.core_models.ext.updateTextContent
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceSyncAndP2PStatusState
|
||||
import com.anytypeio.anytype.core_models.primitives.SpaceId
|
||||
import com.anytypeio.anytype.core_models.primitives.TypeId
|
||||
import com.anytypeio.anytype.core_models.primitives.TypeKey
|
||||
|
@ -77,6 +78,7 @@ import com.anytypeio.anytype.domain.cover.SetDocCoverImage
|
|||
import com.anytypeio.anytype.domain.editor.Editor
|
||||
import com.anytypeio.anytype.domain.error.Error
|
||||
import com.anytypeio.anytype.domain.event.interactor.InterceptEvents
|
||||
import com.anytypeio.anytype.domain.event.interactor.SpaceSyncAndP2PStatusProvider
|
||||
import com.anytypeio.anytype.domain.icon.SetDocumentImageIcon
|
||||
import com.anytypeio.anytype.domain.icon.SetImageIcon
|
||||
import com.anytypeio.anytype.domain.launch.GetDefaultObjectType
|
||||
|
@ -251,8 +253,6 @@ import com.anytypeio.anytype.presentation.relations.getObjectRelations
|
|||
import com.anytypeio.anytype.presentation.relations.views
|
||||
import com.anytypeio.anytype.presentation.search.ObjectSearchConstants
|
||||
import com.anytypeio.anytype.presentation.search.ObjectSearchViewModel
|
||||
import com.anytypeio.anytype.presentation.sync.SpaceSyncAndP2PStatusProvider
|
||||
import com.anytypeio.anytype.presentation.sync.SpaceSyncAndP2PStatusState
|
||||
import com.anytypeio.anytype.presentation.sync.SyncStatusWidgetState
|
||||
import com.anytypeio.anytype.presentation.sync.toSyncStatusWidgetState
|
||||
import com.anytypeio.anytype.presentation.sync.updateStatus
|
||||
|
@ -7347,7 +7347,7 @@ class EditorViewModel(
|
|||
}
|
||||
|
||||
//region SYNC STATUS
|
||||
val spaceSyncStatus = MutableStateFlow<SpaceSyncAndP2PStatusState>(SpaceSyncAndP2PStatusState.Initial)
|
||||
val spaceSyncStatus = MutableStateFlow<SpaceSyncAndP2PStatusState>(SpaceSyncAndP2PStatusState.Init)
|
||||
val syncStatusWidget = MutableStateFlow<SyncStatusWidgetState>(SyncStatusWidgetState.Hidden)
|
||||
|
||||
fun onSyncStatusBadgeClicked() {
|
||||
|
@ -7359,6 +7359,9 @@ class EditorViewModel(
|
|||
jobs += viewModelScope.launch {
|
||||
spaceSyncAndP2PStatusProvider
|
||||
.observe()
|
||||
.catch {
|
||||
Timber.e(it, "Error while observing sync status")
|
||||
}
|
||||
.collect { syncAndP2pState ->
|
||||
spaceSyncStatus.value = syncAndP2pState
|
||||
syncStatusWidget.value = syncStatusWidget.value.updateStatus(syncAndP2pState)
|
||||
|
|
|
@ -16,6 +16,7 @@ import com.anytypeio.anytype.domain.block.interactor.sets.CreateObjectSet
|
|||
import com.anytypeio.anytype.domain.block.interactor.sets.GetObjectTypes
|
||||
import com.anytypeio.anytype.domain.cover.SetDocCoverImage
|
||||
import com.anytypeio.anytype.domain.event.interactor.InterceptEvents
|
||||
import com.anytypeio.anytype.domain.event.interactor.SpaceSyncAndP2PStatusProvider
|
||||
import com.anytypeio.anytype.domain.icon.SetDocumentImageIcon
|
||||
import com.anytypeio.anytype.domain.launch.GetDefaultObjectType
|
||||
import com.anytypeio.anytype.domain.library.StorelessSubscriptionContainer
|
||||
|
@ -46,7 +47,6 @@ import com.anytypeio.anytype.presentation.common.StateReducer
|
|||
import com.anytypeio.anytype.presentation.editor.editor.Orchestrator
|
||||
import com.anytypeio.anytype.presentation.editor.editor.table.EditorTableDelegate
|
||||
import com.anytypeio.anytype.presentation.editor.render.DefaultBlockViewRenderer
|
||||
import com.anytypeio.anytype.presentation.sync.SpaceSyncAndP2PStatusProvider
|
||||
import com.anytypeio.anytype.presentation.templates.ObjectTypeTemplatesContainer
|
||||
import com.anytypeio.anytype.presentation.util.CopyFileToCacheDirectory
|
||||
import com.anytypeio.anytype.presentation.util.Dispatcher
|
||||
|
|
|
@ -22,6 +22,7 @@ import com.anytypeio.anytype.core_models.RelationFormat
|
|||
import com.anytypeio.anytype.core_models.Relations
|
||||
import com.anytypeio.anytype.core_models.isDataView
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceMemberPermissions
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceSyncAndP2PStatusState
|
||||
import com.anytypeio.anytype.core_models.primitives.SpaceId
|
||||
import com.anytypeio.anytype.core_models.primitives.TypeId
|
||||
import com.anytypeio.anytype.core_models.primitives.TypeKey
|
||||
|
@ -39,6 +40,7 @@ import com.anytypeio.anytype.domain.cover.SetDocCoverImage
|
|||
import com.anytypeio.anytype.domain.dataview.interactor.CreateDataViewObject
|
||||
import com.anytypeio.anytype.domain.error.Error
|
||||
import com.anytypeio.anytype.domain.event.interactor.InterceptEvents
|
||||
import com.anytypeio.anytype.domain.event.interactor.SpaceSyncAndP2PStatusProvider
|
||||
import com.anytypeio.anytype.domain.library.StoreSearchByIdsParams
|
||||
import com.anytypeio.anytype.domain.library.StorelessSubscriptionContainer
|
||||
import com.anytypeio.anytype.domain.misc.DateProvider
|
||||
|
@ -96,8 +98,6 @@ import com.anytypeio.anytype.presentation.sets.subscription.DefaultDataViewSubsc
|
|||
import com.anytypeio.anytype.presentation.sets.viewer.ViewerDelegate
|
||||
import com.anytypeio.anytype.presentation.sets.viewer.ViewerEvent
|
||||
import com.anytypeio.anytype.presentation.sets.viewer.ViewerView
|
||||
import com.anytypeio.anytype.presentation.sync.SpaceSyncAndP2PStatusProvider
|
||||
import com.anytypeio.anytype.presentation.sync.SpaceSyncAndP2PStatusState
|
||||
import com.anytypeio.anytype.presentation.sync.SyncStatusWidgetState
|
||||
import com.anytypeio.anytype.presentation.sync.toSyncStatusWidgetState
|
||||
import com.anytypeio.anytype.presentation.sync.updateStatus
|
||||
|
@ -2821,7 +2821,7 @@ class ObjectSetViewModel(
|
|||
//endregion
|
||||
|
||||
//region SYNC STATUS
|
||||
val spaceSyncStatus = MutableStateFlow<SpaceSyncAndP2PStatusState>(SpaceSyncAndP2PStatusState.Initial)
|
||||
val spaceSyncStatus = MutableStateFlow<SpaceSyncAndP2PStatusState>(SpaceSyncAndP2PStatusState.Init)
|
||||
val syncStatusWidget = MutableStateFlow<SyncStatusWidgetState>(SyncStatusWidgetState.Hidden)
|
||||
|
||||
fun onSyncStatusBadgeClicked() {
|
||||
|
@ -2833,6 +2833,9 @@ class ObjectSetViewModel(
|
|||
jobs += viewModelScope.launch {
|
||||
spaceSyncAndP2PStatusProvider
|
||||
.observe()
|
||||
.catch {
|
||||
Timber.e(it, "Error while observing sync status")
|
||||
}
|
||||
.collect { syncAndP2pState ->
|
||||
spaceSyncStatus.value = syncAndP2pState
|
||||
syncStatusWidget.value = syncStatusWidget.value.updateStatus(syncAndP2pState)
|
||||
|
|
|
@ -12,6 +12,7 @@ import com.anytypeio.anytype.domain.collections.AddObjectToCollection
|
|||
import com.anytypeio.anytype.domain.cover.SetDocCoverImage
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.CreateDataViewObject
|
||||
import com.anytypeio.anytype.domain.event.interactor.InterceptEvents
|
||||
import com.anytypeio.anytype.domain.event.interactor.SpaceSyncAndP2PStatusProvider
|
||||
import com.anytypeio.anytype.domain.library.StorelessSubscriptionContainer
|
||||
import com.anytypeio.anytype.domain.misc.DateProvider
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
|
@ -38,7 +39,6 @@ import com.anytypeio.anytype.presentation.editor.cover.CoverImageHashProvider
|
|||
import com.anytypeio.anytype.presentation.sets.state.ObjectStateReducer
|
||||
import com.anytypeio.anytype.presentation.sets.subscription.DataViewSubscription
|
||||
import com.anytypeio.anytype.presentation.sets.viewer.ViewerDelegate
|
||||
import com.anytypeio.anytype.presentation.sync.SpaceSyncAndP2PStatusProvider
|
||||
import com.anytypeio.anytype.presentation.templates.ObjectTypeTemplatesContainer
|
||||
import com.anytypeio.anytype.presentation.util.Dispatcher
|
||||
|
||||
|
|
|
@ -1,74 +1,44 @@
|
|||
package com.anytypeio.anytype.presentation.sync
|
||||
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.multiplayer.P2PStatusUpdate
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceSyncAndP2PStatusState
|
||||
import com.anytypeio.anytype.core_models.multiplayer.SpaceSyncUpdate
|
||||
import com.anytypeio.anytype.domain.multiplayer.ActiveSpaceMemberSubscriptionContainer
|
||||
import com.anytypeio.anytype.domain.workspace.P2PStatusChannel
|
||||
import com.anytypeio.anytype.domain.workspace.SpaceSyncStatusChannel
|
||||
import com.anytypeio.anytype.domain.event.interactor.SpaceSyncAndP2PStatusProvider
|
||||
import com.anytypeio.anytype.domain.workspace.SpaceManager
|
||||
import com.anytypeio.anytype.domain.workspace.SyncAndP2PStatusChannel
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.emptyFlow
|
||||
import kotlinx.coroutines.flow.flatMapLatest
|
||||
import kotlinx.coroutines.flow.onStart
|
||||
import timber.log.Timber
|
||||
|
||||
interface SpaceSyncAndP2PStatusProvider {
|
||||
class SpaceSyncAndP2PStatusProviderImpl @Inject constructor(
|
||||
private val spaceSyncStatusChannel: SyncAndP2PStatusChannel,
|
||||
private val spaceManager: SpaceManager
|
||||
) : SpaceSyncAndP2PStatusProvider {
|
||||
|
||||
suspend fun observe(): Flow<SpaceSyncAndP2PStatusState>
|
||||
override fun observe(): Flow<SpaceSyncAndP2PStatusState> =
|
||||
combine(
|
||||
spaceManager.observe(),
|
||||
spaceSyncStatusChannel.p2pStatus(),
|
||||
spaceSyncStatusChannel.syncStatus()
|
||||
) { activeSpace, p2pStatus, syncStatus ->
|
||||
val p2PStatusUpdate = p2pStatus[activeSpace.space]
|
||||
val spaceSyncUpdate = syncStatus[activeSpace.space]
|
||||
|
||||
class Impl @Inject constructor(
|
||||
private val activeSpace: ActiveSpaceMemberSubscriptionContainer,
|
||||
private val spaceSyncStatusChannel: SpaceSyncStatusChannel,
|
||||
private val p2PStatusChannel: P2PStatusChannel
|
||||
) : SpaceSyncAndP2PStatusProvider {
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
override suspend fun observe(): Flow<SpaceSyncAndP2PStatusState> {
|
||||
return activeSpace
|
||||
.observe()
|
||||
.flatMapLatest { activeSpace ->
|
||||
when (activeSpace) {
|
||||
is ActiveSpaceMemberSubscriptionContainer.Store.Data -> {
|
||||
observeSpaceSyncStatus(spaceId = activeSpace.config.space)
|
||||
}
|
||||
|
||||
ActiveSpaceMemberSubscriptionContainer.Store.Empty -> {
|
||||
emptyFlow()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun observeSpaceSyncStatus(spaceId: Id): Flow<SpaceSyncAndP2PStatusState> {
|
||||
val syncFlow =
|
||||
spaceSyncStatusChannel.observe(spaceId).onStart { emit(SpaceSyncUpdate.Initial) }
|
||||
val p2pFlow =
|
||||
p2PStatusChannel.observe(spaceId).onStart { emit(P2PStatusUpdate.Initial) }
|
||||
|
||||
return combine(syncFlow, p2pFlow) { syncStatus, p2PStatus ->
|
||||
if (syncStatus is SpaceSyncUpdate.Initial && p2PStatus is P2PStatusUpdate.Initial) {
|
||||
SpaceSyncAndP2PStatusState.Initial
|
||||
} else {
|
||||
SpaceSyncAndP2PStatusState.Success(
|
||||
spaceSyncUpdate = syncStatus,
|
||||
p2PStatusUpdate = p2PStatus
|
||||
)
|
||||
}
|
||||
if (p2PStatusUpdate == null && spaceSyncUpdate == null) {
|
||||
SpaceSyncAndP2PStatusState.Init
|
||||
} else {
|
||||
SpaceSyncAndP2PStatusState.Success(
|
||||
spaceSyncUpdate = spaceSyncUpdate ?: SpaceSyncUpdate.Initial,
|
||||
p2PStatusUpdate = p2PStatusUpdate ?: P2PStatusUpdate.Initial
|
||||
)
|
||||
}
|
||||
}.catch { e ->
|
||||
Timber.e(e, "Error observing sync and P2P status")
|
||||
emit(SpaceSyncAndP2PStatusState.Error("Error observing sync and P2P status, ${e.message}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class SpaceSyncAndP2PStatusState {
|
||||
data object Initial : SpaceSyncAndP2PStatusState()
|
||||
data class Error(val message: String) : SpaceSyncAndP2PStatusState()
|
||||
data class Success(
|
||||
val spaceSyncUpdate: SpaceSyncUpdate,
|
||||
val p2PStatusUpdate: P2PStatusUpdate
|
||||
) : SpaceSyncAndP2PStatusState()
|
||||
}
|
||||
|
||||
fun SyncStatusWidgetState.updateStatus(newState: SpaceSyncAndP2PStatusState): SyncStatusWidgetState {
|
||||
return when (this) {
|
||||
|
@ -89,7 +59,7 @@ fun SpaceSyncAndP2PStatusState.toSyncStatusWidgetState(): SyncStatusWidgetState
|
|||
SyncStatusWidgetState.Error(message = message)
|
||||
}
|
||||
|
||||
SpaceSyncAndP2PStatusState.Initial -> {
|
||||
SpaceSyncAndP2PStatusState.Init -> {
|
||||
SyncStatusWidgetState.Hidden
|
||||
}
|
||||
|
||||
|
@ -106,7 +76,7 @@ sealed class SyncStatusWidgetState {
|
|||
data object Hidden : SyncStatusWidgetState()
|
||||
data class Error(val message: String) : SyncStatusWidgetState()
|
||||
data class Success(
|
||||
val spaceSyncUpdate: SpaceSyncUpdate,
|
||||
val p2PStatusUpdate: P2PStatusUpdate
|
||||
val spaceSyncUpdate: SpaceSyncUpdate = SpaceSyncUpdate.Initial,
|
||||
val p2PStatusUpdate: P2PStatusUpdate = P2PStatusUpdate.Initial
|
||||
) : SyncStatusWidgetState()
|
||||
}
|
|
@ -60,6 +60,7 @@ import com.anytypeio.anytype.domain.config.Gateway
|
|||
import com.anytypeio.anytype.domain.cover.SetDocCoverImage
|
||||
import com.anytypeio.anytype.domain.download.DownloadFile
|
||||
import com.anytypeio.anytype.domain.event.interactor.InterceptEvents
|
||||
import com.anytypeio.anytype.domain.event.interactor.SpaceSyncAndP2PStatusProvider
|
||||
import com.anytypeio.anytype.domain.icon.SetDocumentImageIcon
|
||||
import com.anytypeio.anytype.domain.launch.GetDefaultObjectType
|
||||
import com.anytypeio.anytype.domain.library.StorelessSubscriptionContainer
|
||||
|
@ -119,7 +120,6 @@ import com.anytypeio.anytype.presentation.editor.render.parseThemeBackgroundColo
|
|||
import com.anytypeio.anytype.presentation.editor.selection.SelectionStateHolder
|
||||
import com.anytypeio.anytype.presentation.editor.toggle.ToggleStateHolder
|
||||
import com.anytypeio.anytype.presentation.navigation.AppNavigation
|
||||
import com.anytypeio.anytype.presentation.sync.SpaceSyncAndP2PStatusProvider
|
||||
import com.anytypeio.anytype.presentation.templates.ObjectTypeTemplatesContainer
|
||||
import com.anytypeio.anytype.presentation.util.CopyFileToCacheDirectory
|
||||
import com.anytypeio.anytype.presentation.util.CoroutinesTestRule
|
||||
|
|
|
@ -52,6 +52,7 @@ import com.anytypeio.anytype.domain.config.Gateway
|
|||
import com.anytypeio.anytype.domain.cover.SetDocCoverImage
|
||||
import com.anytypeio.anytype.domain.download.DownloadFile
|
||||
import com.anytypeio.anytype.domain.event.interactor.InterceptEvents
|
||||
import com.anytypeio.anytype.domain.event.interactor.SpaceSyncAndP2PStatusProvider
|
||||
import com.anytypeio.anytype.domain.icon.SetDocumentImageIcon
|
||||
import com.anytypeio.anytype.domain.launch.GetDefaultObjectType
|
||||
import com.anytypeio.anytype.domain.library.StorelessSubscriptionContainer
|
||||
|
@ -111,7 +112,6 @@ import com.anytypeio.anytype.presentation.editor.render.DefaultBlockViewRenderer
|
|||
import com.anytypeio.anytype.presentation.editor.selection.SelectionStateHolder
|
||||
import com.anytypeio.anytype.presentation.editor.toggle.ToggleStateHolder
|
||||
import com.anytypeio.anytype.presentation.home.UserPermissionProviderStub
|
||||
import com.anytypeio.anytype.presentation.sync.SpaceSyncAndP2PStatusProvider
|
||||
import com.anytypeio.anytype.presentation.templates.ObjectTypeTemplatesContainer
|
||||
import com.anytypeio.anytype.presentation.util.CopyFileToCacheDirectory
|
||||
import com.anytypeio.anytype.presentation.util.Dispatcher
|
||||
|
|
|
@ -36,6 +36,7 @@ import com.anytypeio.anytype.domain.cover.SetDocCoverImage
|
|||
import com.anytypeio.anytype.domain.dataview.interactor.CreateDataViewObject
|
||||
import com.anytypeio.anytype.domain.dataview.interactor.UpdateDataViewViewer
|
||||
import com.anytypeio.anytype.domain.event.interactor.InterceptEvents
|
||||
import com.anytypeio.anytype.domain.event.interactor.SpaceSyncAndP2PStatusProvider
|
||||
import com.anytypeio.anytype.domain.launch.GetDefaultObjectType
|
||||
import com.anytypeio.anytype.domain.library.StoreSearchByIdsParams
|
||||
import com.anytypeio.anytype.domain.library.StorelessSubscriptionContainer
|
||||
|
@ -81,7 +82,6 @@ import com.anytypeio.anytype.presentation.sets.subscription.DataViewSubscription
|
|||
import com.anytypeio.anytype.presentation.sets.subscription.DefaultDataViewSubscription
|
||||
import com.anytypeio.anytype.presentation.sets.updateFormatForSubscription
|
||||
import com.anytypeio.anytype.presentation.sets.viewer.ViewerDelegate
|
||||
import com.anytypeio.anytype.presentation.sync.SpaceSyncAndP2PStatusProvider
|
||||
import com.anytypeio.anytype.presentation.templates.ObjectTypeTemplatesContainer
|
||||
import com.anytypeio.anytype.presentation.util.DefaultCoroutineTestRule
|
||||
import com.anytypeio.anytype.presentation.util.Dispatcher
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue