From d2e8a29af8060b8b13f0516c3d7b6284959580cb Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Sun, 9 Oct 2022 17:44:18 +0100 Subject: [PATCH] porting settings module to chat engine --- .../main/kotlin/app/dapk/st/graph/AppModule.kt | 3 +-- .../kotlin/app/dapk/st/engine/ChatEngine.kt | 7 +++++++ .../main/kotlin/app/dapk/st/engine/Models.kt | 17 +++++++++++++++++ features/navigator/build.gradle | 2 +- features/settings/build.gradle | 3 +-- .../app/dapk/st/settings/SettingsModule.kt | 9 +++------ .../app/dapk/st/settings/SettingsScreen.kt | 2 +- .../app/dapk/st/settings/SettingsState.kt | 3 +-- .../app/dapk/st/settings/SettingsViewModel.kt | 12 +++++------- .../app/dapk/st/engine/MappingExtensions.kt | 15 +++++++++++++++ .../kotlin/app/dapk/st/engine/MatrixEngine.kt | 14 +++++++++++++- 11 files changed, 65 insertions(+), 22 deletions(-) diff --git a/app/src/main/kotlin/app/dapk/st/graph/AppModule.kt b/app/src/main/kotlin/app/dapk/st/graph/AppModule.kt index 28d6b80..a1ea937 100644 --- a/app/src/main/kotlin/app/dapk/st/graph/AppModule.kt +++ b/app/src/main/kotlin/app/dapk/st/graph/AppModule.kt @@ -192,10 +192,9 @@ internal class FeatureModules internal constructor( val homeModule by unsafeLazy { HomeModule(matrixModules.engine, storeModule.value, buildMeta) } val settingsModule by unsafeLazy { SettingsModule( + matrixModules.engine, storeModule.value, pushModule, - matrixModules.crypto, - matrixModules.sync, context.contentResolver, buildMeta, deviceMeta, diff --git a/chat-engine/src/main/kotlin/app/dapk/st/engine/ChatEngine.kt b/chat-engine/src/main/kotlin/app/dapk/st/engine/ChatEngine.kt index 339ba79..f5e7fe8 100644 --- a/chat-engine/src/main/kotlin/app/dapk/st/engine/ChatEngine.kt +++ b/chat-engine/src/main/kotlin/app/dapk/st/engine/ChatEngine.kt @@ -1,14 +1,21 @@ package app.dapk.st.engine +import app.dapk.st.matrix.common.RoomId import kotlinx.coroutines.flow.Flow +import java.io.InputStream interface ChatEngine { fun directory(): Flow + fun invites(): Flow suspend fun login(request: LoginRequest): LoginResult suspend fun me(forceRefresh: Boolean): Me + suspend fun refresh(roomIds: List) + + suspend fun InputStream.importRoomKeys(password: String): Flow + } diff --git a/chat-engine/src/main/kotlin/app/dapk/st/engine/Models.kt b/chat-engine/src/main/kotlin/app/dapk/st/engine/Models.kt index 14d1189..df5631a 100644 --- a/chat-engine/src/main/kotlin/app/dapk/st/engine/Models.kt +++ b/chat-engine/src/main/kotlin/app/dapk/st/engine/Models.kt @@ -62,3 +62,20 @@ data class Me( val avatarUrl: AvatarUrl?, val homeServerUrl: HomeServerUrl, ) + +sealed interface ImportResult { + data class Success(val roomIds: Set, val totalImportedKeysCount: Long) : ImportResult + data class Error(val cause: Type) : ImportResult { + + sealed interface Type { + data class Unknown(val cause: Throwable) : Type + object NoKeysFound : Type + object UnexpectedDecryptionOutput : Type + object UnableToOpenFile : Type + object InvalidFile : Type + } + + } + + data class Update(val importedKeysCount: Long) : ImportResult +} diff --git a/features/navigator/build.gradle b/features/navigator/build.gradle index 6c97c96..f3bacd7 100644 --- a/features/navigator/build.gradle +++ b/features/navigator/build.gradle @@ -4,5 +4,5 @@ apply plugin: 'kotlin-parcelize' dependencies { compileOnly project(":domains:android:stub") implementation project(":core") - implementation project(":matrix:common") + implementation project(":chat-engine") } \ No newline at end of file diff --git a/features/settings/build.gradle b/features/settings/build.gradle index 00ef2c0..fc553d4 100644 --- a/features/settings/build.gradle +++ b/features/settings/build.gradle @@ -1,8 +1,7 @@ applyAndroidComposeLibraryModule(project) dependencies { - implementation project(":matrix:services:sync") - implementation project(":matrix:services:crypto") + implementation project(":chat-engine") implementation project(":features:navigator") implementation project(':domains:store') implementation project(':domains:android:push') diff --git a/features/settings/src/main/kotlin/app/dapk/st/settings/SettingsModule.kt b/features/settings/src/main/kotlin/app/dapk/st/settings/SettingsModule.kt index a0c695a..b498f95 100644 --- a/features/settings/src/main/kotlin/app/dapk/st/settings/SettingsModule.kt +++ b/features/settings/src/main/kotlin/app/dapk/st/settings/SettingsModule.kt @@ -5,16 +5,14 @@ import app.dapk.st.core.* import app.dapk.st.domain.StoreModule import app.dapk.st.domain.application.eventlog.LoggingStore import app.dapk.st.domain.application.message.MessageOptionsStore -import app.dapk.st.matrix.crypto.CryptoService -import app.dapk.st.matrix.sync.SyncService +import app.dapk.st.engine.ChatEngine import app.dapk.st.push.PushModule import app.dapk.st.settings.eventlogger.EventLoggerViewModel class SettingsModule( + private val chatEngine: ChatEngine, private val storeModule: StoreModule, private val pushModule: PushModule, - private val cryptoService: CryptoService, - private val syncService: SyncService, private val contentResolver: ContentResolver, private val buildMeta: BuildMeta, private val deviceMeta: DeviceMeta, @@ -26,10 +24,9 @@ class SettingsModule( internal fun settingsViewModel(): SettingsViewModel { return SettingsViewModel( + chatEngine, storeModule.cacheCleaner(), contentResolver, - cryptoService, - syncService, UriFilenameResolver(contentResolver, coroutineDispatchers), SettingsItemFactory(buildMeta, deviceMeta, pushModule.pushTokenRegistrars(), themeStore, loggingStore, messageOptionsStore), pushModule.pushTokenRegistrars(), diff --git a/features/settings/src/main/kotlin/app/dapk/st/settings/SettingsScreen.kt b/features/settings/src/main/kotlin/app/dapk/st/settings/SettingsScreen.kt index edf9bc3..09522f2 100644 --- a/features/settings/src/main/kotlin/app/dapk/st/settings/SettingsScreen.kt +++ b/features/settings/src/main/kotlin/app/dapk/st/settings/SettingsScreen.kt @@ -42,7 +42,7 @@ import app.dapk.st.core.components.Header import app.dapk.st.core.extensions.takeAs import app.dapk.st.core.getActivity import app.dapk.st.design.components.* -import app.dapk.st.matrix.crypto.ImportResult +import app.dapk.st.engine.ImportResult import app.dapk.st.navigator.Navigator import app.dapk.st.settings.SettingsEvent.* import app.dapk.st.settings.eventlogger.EventLogActivity diff --git a/features/settings/src/main/kotlin/app/dapk/st/settings/SettingsState.kt b/features/settings/src/main/kotlin/app/dapk/st/settings/SettingsState.kt index 0c73de2..ff796c7 100644 --- a/features/settings/src/main/kotlin/app/dapk/st/settings/SettingsState.kt +++ b/features/settings/src/main/kotlin/app/dapk/st/settings/SettingsState.kt @@ -2,10 +2,9 @@ package app.dapk.st.settings import android.net.Uri import app.dapk.st.core.Lce -import app.dapk.st.core.LceWithProgress import app.dapk.st.design.components.Route import app.dapk.st.design.components.SpiderPage -import app.dapk.st.matrix.crypto.ImportResult +import app.dapk.st.engine.ImportResult import app.dapk.st.push.Registrar internal data class SettingsScreenState( diff --git a/features/settings/src/main/kotlin/app/dapk/st/settings/SettingsViewModel.kt b/features/settings/src/main/kotlin/app/dapk/st/settings/SettingsViewModel.kt index 5510e5d..a05783d 100644 --- a/features/settings/src/main/kotlin/app/dapk/st/settings/SettingsViewModel.kt +++ b/features/settings/src/main/kotlin/app/dapk/st/settings/SettingsViewModel.kt @@ -9,9 +9,8 @@ import app.dapk.st.design.components.SpiderPage import app.dapk.st.domain.StoreCleaner import app.dapk.st.domain.application.eventlog.LoggingStore import app.dapk.st.domain.application.message.MessageOptionsStore -import app.dapk.st.matrix.crypto.CryptoService -import app.dapk.st.matrix.crypto.ImportResult -import app.dapk.st.matrix.sync.SyncService +import app.dapk.st.engine.ChatEngine +import app.dapk.st.engine.ImportResult import app.dapk.st.push.PushTokenRegistrars import app.dapk.st.push.Registrar import app.dapk.st.settings.SettingItem.Id.* @@ -26,10 +25,9 @@ import kotlinx.coroutines.launch private const val PRIVACY_POLICY_URL = "https://ouchadam.github.io/small-talk/privacy/" internal class SettingsViewModel( + private val chatEngine: ChatEngine, private val cacheCleaner: StoreCleaner, private val contentResolver: ContentResolver, - private val cryptoService: CryptoService, - private val syncService: SyncService, private val uriFilenameResolver: UriFilenameResolver, private val settingsItemFactory: SettingsItemFactory, private val pushTokenRegistrars: PushTokenRegistrars, @@ -142,7 +140,7 @@ internal class SettingsViewModel( fun importFromFileKeys(file: Uri, passphrase: String) { updatePageState { copy(importProgress = ImportResult.Update(0)) } viewModelScope.launch { - with(cryptoService) { + with(chatEngine) { runCatching { contentResolver.openInputStream(file)!! } .fold( onSuccess = { fileStream -> @@ -159,7 +157,7 @@ internal class SettingsViewModel( } is ImportResult.Success -> { - syncService.forceManualRefresh(it.roomIds.toList()) + chatEngine.refresh(it.roomIds.toList()) } } } diff --git a/matrix-chat-engine/src/main/kotlin/app/dapk/st/engine/MappingExtensions.kt b/matrix-chat-engine/src/main/kotlin/app/dapk/st/engine/MappingExtensions.kt index 6e26cc4..8e61404 100644 --- a/matrix-chat-engine/src/main/kotlin/app/dapk/st/engine/MappingExtensions.kt +++ b/matrix-chat-engine/src/main/kotlin/app/dapk/st/engine/MappingExtensions.kt @@ -4,6 +4,7 @@ import app.dapk.st.matrix.auth.AuthService import app.dapk.st.matrix.sync.InviteMeta import app.dapk.st.matrix.auth.AuthService.LoginRequest as MatrixLoginRequest import app.dapk.st.matrix.auth.AuthService.LoginResult as MatrixLoginResult +import app.dapk.st.matrix.crypto.ImportResult as MatrixImportResult import app.dapk.st.matrix.room.ProfileService.Me as MatrixMe import app.dapk.st.matrix.sync.LastMessage as MatrixLastMessage import app.dapk.st.matrix.sync.RoomInvite as MatrixRoomInvite @@ -62,3 +63,17 @@ fun InviteMeta.engine() = when (this) { is InviteMeta.Room -> RoomInvite.InviteMeta.Room(this.roomName) } +fun MatrixImportResult.engine() = when (this) { + is MatrixImportResult.Error -> ImportResult.Error( + when (val error = this.cause) { + MatrixImportResult.Error.Type.InvalidFile -> ImportResult.Error.Type.InvalidFile + MatrixImportResult.Error.Type.NoKeysFound -> ImportResult.Error.Type.NoKeysFound + MatrixImportResult.Error.Type.UnableToOpenFile -> ImportResult.Error.Type.UnableToOpenFile + MatrixImportResult.Error.Type.UnexpectedDecryptionOutput -> ImportResult.Error.Type.UnexpectedDecryptionOutput + is MatrixImportResult.Error.Type.Unknown -> ImportResult.Error.Type.Unknown(error.cause) + } + ) + + is MatrixImportResult.Success -> ImportResult.Success(this.roomIds, this.totalImportedKeysCount) + is MatrixImportResult.Update -> ImportResult.Update(this.importedKeysCount) +} \ No newline at end of file diff --git a/matrix-chat-engine/src/main/kotlin/app/dapk/st/engine/MatrixEngine.kt b/matrix-chat-engine/src/main/kotlin/app/dapk/st/engine/MatrixEngine.kt index 9caefa5..5fd7dda 100644 --- a/matrix-chat-engine/src/main/kotlin/app/dapk/st/engine/MatrixEngine.kt +++ b/matrix-chat-engine/src/main/kotlin/app/dapk/st/engine/MatrixEngine.kt @@ -30,6 +30,7 @@ import app.dapk.st.olm.OlmStore import app.dapk.st.olm.OlmWrapper import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map +import java.io.InputStream import java.time.Clock class MatrixEngine internal constructor( @@ -50,6 +51,17 @@ class MatrixEngine internal constructor( return matrix.value.profileService().me(forceRefresh).engine() } + override suspend fun refresh(roomIds: List) { + matrix.value.syncService().forceManualRefresh(roomIds) + + } + + override suspend fun InputStream.importRoomKeys(password: String): Flow { + return with(matrix.value.cryptoService()) { + importRoomKeys(password).map { it.engine() } + } + } + class Factory { fun create( @@ -72,7 +84,7 @@ class MatrixEngine internal constructor( knownDeviceStore: KnownDeviceStore, olmStore: OlmStore, ): ChatEngine { - val lazyMatrix = unsafeLazy { + val lazyMatrix = lazy { MatrixFactory.createMatrix( base64, buildMeta,