1
0
Fork 0
mirror of https://github.com/anyproto/anytype-kotlin.git synced 2025-06-08 05:47:05 +09:00

DROID-1776 App | Tech | Integrate event process model + event handling (#1018)

This commit is contained in:
Konstantin Ivanov 2024-03-20 13:49:43 +01:00 committed by GitHub
parent 2ef91fa045
commit f2f301d7b4
Signed by: github
GPG key ID: B5690EEEBB952194
10 changed files with 193 additions and 5 deletions

View file

@ -4,6 +4,8 @@ import com.anytypeio.anytype.core_utils.tools.FeatureToggles
import com.anytypeio.anytype.data.auth.account.AccountStatusDataChannel
import com.anytypeio.anytype.data.auth.account.AccountStatusRemoteChannel
import com.anytypeio.anytype.data.auth.event.EventDataChannel
import com.anytypeio.anytype.data.auth.event.EventProcessDateChannel
import com.anytypeio.anytype.data.auth.event.EventProcessRemoteChannel
import com.anytypeio.anytype.data.auth.event.EventRemoteChannel
import com.anytypeio.anytype.data.auth.event.FileLimitsDataChannel
import com.anytypeio.anytype.data.auth.event.SubscriptionDataChannel
@ -15,6 +17,7 @@ import com.anytypeio.anytype.domain.event.interactor.EventChannel
import com.anytypeio.anytype.domain.search.SubscriptionEventChannel
import com.anytypeio.anytype.domain.status.ThreadStatusChannel
import com.anytypeio.anytype.data.auth.event.FileLimitsRemoteChannel
import com.anytypeio.anytype.domain.workspace.EventProcessChannel
import com.anytypeio.anytype.domain.workspace.FileLimitsEventChannel
import com.anytypeio.anytype.middleware.EventProxy
import com.anytypeio.anytype.middleware.interactor.*
@ -129,6 +132,20 @@ object EventModule {
channel: FileLimitsRemoteChannel
): FileLimitsEventChannel = FileLimitsDataChannel(channel = channel)
@JvmStatic
@Provides
@Singleton
fun provideEventProcessRemoteChannel(
proxy: EventProxy
): EventProcessRemoteChannel = EventProcessMiddlewareChannel(events = proxy)
@JvmStatic
@Provides
@Singleton
fun provideProcessDataChannel(
channel: EventProcessRemoteChannel
): EventProcessChannel = EventProcessDateChannel(channel = channel)
@Module
interface Bindings {

View file

@ -32,7 +32,7 @@ object DefaultDeepLinkResolver : DeepLinkResolver {
source = source.orEmpty()
)
} catch (e: Exception) {
Timber.e(e, "Error while resolving deeplink: $deeplink")
//Timber.e(e, "Error while resolving deeplink: $deeplink")
DeepLinkResolver.Action.Unknown
}
}
@ -42,7 +42,7 @@ object DefaultDeepLinkResolver : DeepLinkResolver {
}
else -> DeepLinkResolver.Action.Unknown
}.also { Timber.d("Resolved deeplink: $deeplink to action: $it") }
}//.also { Timber.d("Resolved deeplink: $deeplink to action: $it") }
}
object DefaultSpaceInviteResolver : SpaceInviteResolver {

View file

@ -1,9 +1,15 @@
package com.anytypeio.anytype.other
import android.os.Build
import com.anytypeio.anytype.domain.misc.DeepLinkResolver
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
@Config(sdk = [Build.VERSION_CODES.P])
@RunWith(RobolectricTestRunner::class)
class DefaultDeepLinkResolverTest {
private val deepLinkResolver = DefaultDeepLinkResolver
@ -11,13 +17,13 @@ class DefaultDeepLinkResolverTest {
@Test
fun `resolve returns Import Experience for import experience deeplinks`() {
// Given
val deeplink = "anytype://main/import/?type=experience"
val deeplink = "anytype://main/import/?type=experience123&source=source321"
// When
val result = deepLinkResolver.resolve(deeplink)
// Then
assertEquals(DeepLinkResolver.Action.Import.Experience, result)
assertEquals(DeepLinkResolver.Action.Import.Experience(type = "experience123", source = "source321"), result)
}
@Test

View file

@ -0,0 +1,45 @@
package com.anytypeio.anytype.core_models
data class Process(
val id: String,
val type: Type,
val state: State,
val progress: Progress?
) {
enum class Type {
DROP_FILES,
IMPORT,
EXPORT,
SAVE_FILE,
RECOVER_ACCOUNT,
MIGRATION
}
enum class State {
NONE,
RUNNING,
DONE,
CANCELED,
ERROR
}
data class Progress(
val total: Long,
val done: Long,
val message: String
)
sealed class Event {
data class New(
val process: Process?
) : Event()
data class Update(
val process: Process?
) : Event()
data class Done(
val process: Process?
) : Event()
}
}

View file

@ -0,0 +1,18 @@
package com.anytypeio.anytype.data.auth.event
import com.anytypeio.anytype.core_models.Process
import com.anytypeio.anytype.domain.workspace.EventProcessChannel
import kotlinx.coroutines.flow.Flow
interface EventProcessRemoteChannel {
fun observe(): Flow<List<Process.Event>>
}
class EventProcessDateChannel(
private val channel: EventProcessRemoteChannel
) : EventProcessChannel {
override fun observe(): Flow<List<Process.Event>> {
return channel.observe()
}
}

View file

@ -0,0 +1,8 @@
package com.anytypeio.anytype.domain.workspace
import com.anytypeio.anytype.core_models.Process
import kotlinx.coroutines.flow.Flow
interface EventProcessChannel {
fun observe(): Flow<List<Process.Event>>
}

View file

@ -0,0 +1,45 @@
package com.anytypeio.anytype.middleware.interactor
import com.anytypeio.anytype.core_models.Process
import com.anytypeio.anytype.data.auth.event.EventProcessRemoteChannel
import com.anytypeio.anytype.middleware.EventProxy
import com.anytypeio.anytype.middleware.mappers.toCoreModel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.mapNotNull
class EventProcessMiddlewareChannel(
private val events: EventProxy
) : EventProcessRemoteChannel {
override fun observe(): Flow<List<Process.Event>> {
return events.flow()
.mapNotNull { emission ->
emission.messages.mapNotNull { message ->
when {
message.processNew != null -> {
val event = message.processNew
checkNotNull(event)
Process.Event.New(
process = event.process?.toCoreModel()
)
}
message.processUpdate != null -> {
val event = message.processUpdate
checkNotNull(event)
Process.Event.Update(
process = event.process?.toCoreModel()
)
}
message.processDone != null -> {
val event = message.processDone
checkNotNull(event)
Process.Event.Done(
process = event.process?.toCoreModel()
)
}
else -> null
}
}
}
}
}

View file

@ -70,3 +70,8 @@ typealias MNetworkMode = anytype.Rpc.Account.NetworkMode
typealias MParticipantPermission = anytype.model.ParticipantPermissions
typealias MManifestInfo = anytype.model.ManifestInfo
typealias MProcess = anytype.Model.Process
typealias MProcessType = anytype.Model.Process.Type
typealias MProcessState = anytype.Model.Process.State
typealias MProcessProgress = anytype.Model.Process.Progress

View file

@ -22,6 +22,7 @@ import com.anytypeio.anytype.core_models.DVViewerCardSize
import com.anytypeio.anytype.core_models.DVViewerRelation
import com.anytypeio.anytype.core_models.DVViewerType
import com.anytypeio.anytype.core_models.Event
import com.anytypeio.anytype.core_models.Process
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.ManifestInfo
import com.anytypeio.anytype.core_models.NodeUsage
@ -807,4 +808,42 @@ fun MManifestInfo.toCoreModel(): ManifestInfo {
categories = categories,
language = language
)
}
fun MProcess.toCoreModel(): Process {
return Process(
id = id,
type = type.toCoreModel(),
state = state.toCoreModel(),
progress = progress?.toCoreModel()
)
}
fun MProcessType.toCoreModel(): Process.Type {
return when (this) {
MProcessType.DropFiles -> Process.Type.DROP_FILES
MProcessType.Import -> Process.Type.IMPORT
MProcessType.Export -> Process.Type.EXPORT
MProcessType.SaveFile -> Process.Type.SAVE_FILE
MProcessType.RecoverAccount -> Process.Type.RECOVER_ACCOUNT
MProcessType.Migration -> Process.Type.MIGRATION
}
}
fun MProcessState.toCoreModel(): Process.State {
return when (this) {
MProcessState.None -> Process.State.NONE
MProcessState.Running -> Process.State.RUNNING
MProcessState.Done -> Process.State.DONE
MProcessState.Canceled -> Process.State.CANCELED
MProcessState.Error -> Process.State.ERROR
}
}
fun MProcessProgress.toCoreModel(): Process.Progress {
return Process.Progress(
total = total,
done = done,
message = message
)
}

View file

@ -11,6 +11,7 @@ import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
import com.anytypeio.anytype.domain.config.ConfigStorage
import com.anytypeio.anytype.domain.config.UserSettingsRepository
import com.anytypeio.anytype.domain.misc.AppActionManager
import com.anytypeio.anytype.domain.multiplayer.UserPermissionProvider
import com.anytypeio.anytype.domain.search.ObjectTypesSubscriptionManager
import com.anytypeio.anytype.domain.search.RelationsSubscriptionManager
import com.anytypeio.anytype.domain.spaces.SpaceDeletedStatusWatcher
@ -82,6 +83,9 @@ class DeleteAccountViewModelTest {
lateinit var vm: DeletedAccountViewModel
@Mock
lateinit var userPermissionProvider: UserPermissionProvider
@Before
fun setup() {
MockitoAnnotations.openMocks(this)
@ -105,7 +109,8 @@ class DeleteAccountViewModelTest {
relationsSubscriptionManager = relationsSubscriptionManager,
spaceDeletedStatusWatcher = spaceDeletedStatusWatcher,
objectTypesSubscriptionManager = objectTypesSubscriptionManager,
appActionManager = appActionManager
appActionManager = appActionManager,
userPermissionProvider = userPermissionProvider
)
}