1
0
Fork 0
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:
Konstantin Ivanov 2024-08-19 14:14:54 +02:00 committed by GitHub
parent 25ec9bd98a
commit 642bfdceae
Signed by: github
GPG key ID: B5690EEEBB952194
34 changed files with 304 additions and 270 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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