porting settings module to chat engine

This commit is contained in:
Adam Brown 2022-10-09 17:44:18 +01:00
parent 492d7df9ac
commit d2e8a29af8
11 changed files with 65 additions and 22 deletions

View File

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

View File

@ -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<DirectoryState>
fun invites(): Flow<InviteState>
suspend fun login(request: LoginRequest): LoginResult
suspend fun me(forceRefresh: Boolean): Me
suspend fun refresh(roomIds: List<RoomId>)
suspend fun InputStream.importRoomKeys(password: String): Flow<ImportResult>
}

View File

@ -62,3 +62,20 @@ data class Me(
val avatarUrl: AvatarUrl?,
val homeServerUrl: HomeServerUrl,
)
sealed interface ImportResult {
data class Success(val roomIds: Set<RoomId>, 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
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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<Page.ImportRoomKey> { 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())
}
}
}

View File

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

View File

@ -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<RoomId>) {
matrix.value.syncService().forceManualRefresh(roomIds)
}
override suspend fun InputStream.importRoomKeys(password: String): Flow<ImportResult> {
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,