starting engine migration
- add a chat-engine abstraction - create a matrix-chat-engine implementation - starts by porting the initial creation and directory listing
This commit is contained in:
parent
94731d006e
commit
128c2db432
|
@ -106,6 +106,9 @@ dependencies {
|
|||
|
||||
implementation project(":core")
|
||||
|
||||
implementation project(":chat-engine")
|
||||
implementation project(":matrix-chat-engine")
|
||||
|
||||
implementation Dependencies.google.androidxComposeUi
|
||||
implementation Dependencies.mavenCentral.ktorAndroid
|
||||
implementation Dependencies.mavenCentral.sqldelightAndroid
|
||||
|
|
|
@ -17,6 +17,7 @@ import app.dapk.st.core.extensions.ErrorTracker
|
|||
import app.dapk.st.core.extensions.unsafeLazy
|
||||
import app.dapk.st.directory.DirectoryModule
|
||||
import app.dapk.st.domain.StoreModule
|
||||
import app.dapk.st.engine.MatrixEngine
|
||||
import app.dapk.st.firebase.messaging.MessagingModule
|
||||
import app.dapk.st.home.HomeModule
|
||||
import app.dapk.st.home.MainActivity
|
||||
|
@ -164,12 +165,8 @@ internal class FeatureModules internal constructor(
|
|||
|
||||
val directoryModule by unsafeLazy {
|
||||
DirectoryModule(
|
||||
syncService = matrixModules.sync,
|
||||
messageService = matrixModules.message,
|
||||
context = context,
|
||||
credentialsStore = storeModule.value.credentialsStore(),
|
||||
roomStore = storeModule.value.roomStore(),
|
||||
roomService = matrixModules.room,
|
||||
chatEngine = matrixModules.engine,
|
||||
)
|
||||
}
|
||||
val loginModule by unsafeLazy {
|
||||
|
@ -252,6 +249,30 @@ internal class MatrixModules(
|
|||
private val buildMeta: BuildMeta,
|
||||
) {
|
||||
|
||||
val engine by unsafeLazy {
|
||||
val store = storeModule.value
|
||||
MatrixEngine.Factory().create(
|
||||
base64,
|
||||
buildMeta,
|
||||
logger,
|
||||
SmallTalkDeviceNameGenerator(),
|
||||
coroutineDispatchers,
|
||||
trackingModule.errorTracker,
|
||||
imageContentReader,
|
||||
BackgroundWorkAdapter(workModule.workScheduler()),
|
||||
store.memberStore(),
|
||||
store.roomStore(),
|
||||
store.profileStore(),
|
||||
store.syncStore(),
|
||||
store.overviewStore(),
|
||||
store.filterStore(),
|
||||
store.localEchoStore,
|
||||
store.credentialsStore(),
|
||||
store.knownDevicesStore(),
|
||||
OlmPersistenceWrapper(store.olmStore(), base64),
|
||||
)
|
||||
}
|
||||
|
||||
val matrix by unsafeLazy {
|
||||
val store = storeModule.value
|
||||
val credentialsStore = store.credentialsStore()
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
plugins {
|
||||
id 'kotlin'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api Dependencies.mavenCentral.kotlinCoroutinesCore
|
||||
api project(":matrix:common")
|
||||
|
||||
implementation project(":matrix:services:sync")
|
||||
implementation project(":matrix:services:message")
|
||||
implementation project(":matrix:services:room")
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package app.dapk.st.engine
|
||||
|
||||
import app.dapk.st.matrix.common.AvatarUrl
|
||||
import app.dapk.st.matrix.common.EventId
|
||||
import app.dapk.st.matrix.common.RoomId
|
||||
import app.dapk.st.matrix.common.RoomMember
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface ChatEngine {
|
||||
|
||||
fun directory(): Flow<DirectoryState>
|
||||
|
||||
}
|
||||
|
||||
typealias DirectoryState = List<DirectoryItem>
|
||||
typealias OverviewState = List<RoomOverview>
|
||||
|
||||
data class DirectoryItem(
|
||||
val overview: RoomOverview,
|
||||
val unreadCount: UnreadCount,
|
||||
val typing: Typing?
|
||||
)
|
||||
|
||||
data class RoomOverview(
|
||||
val roomId: RoomId,
|
||||
val roomCreationUtc: Long,
|
||||
val roomName: String?,
|
||||
val roomAvatarUrl: AvatarUrl?,
|
||||
val lastMessage: LastMessage?,
|
||||
val isGroup: Boolean,
|
||||
val readMarker: EventId?,
|
||||
val isEncrypted: Boolean,
|
||||
) {
|
||||
|
||||
data class LastMessage(
|
||||
val content: String,
|
||||
val utcTimestamp: Long,
|
||||
val author: RoomMember,
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class UnreadCount(val value: Int)
|
||||
|
||||
data class Typing(val roomId: RoomId, val members: List<RoomMember>)
|
|
@ -1,9 +1,7 @@
|
|||
applyAndroidComposeLibraryModule(project)
|
||||
|
||||
dependencies {
|
||||
implementation project(":matrix:services:sync")
|
||||
implementation project(":matrix:services:message")
|
||||
implementation project(":matrix:services:room")
|
||||
implementation project(":chat-engine")
|
||||
implementation project(":domains:android:compose-core")
|
||||
implementation project(":domains:android:viewmodel")
|
||||
implementation project(":features:messenger")
|
||||
|
|
|
@ -38,9 +38,10 @@ import app.dapk.st.design.components.Toolbar
|
|||
import app.dapk.st.directory.DirectoryEvent.OpenDownloadUrl
|
||||
import app.dapk.st.directory.DirectoryScreenState.Content
|
||||
import app.dapk.st.directory.DirectoryScreenState.EmptyLoading
|
||||
import app.dapk.st.engine.DirectoryItem
|
||||
import app.dapk.st.engine.RoomOverview
|
||||
import app.dapk.st.engine.Typing
|
||||
import app.dapk.st.matrix.common.RoomId
|
||||
import app.dapk.st.matrix.sync.RoomOverview
|
||||
import app.dapk.st.matrix.sync.SyncService
|
||||
import app.dapk.st.messenger.MessengerActivity
|
||||
import kotlinx.coroutines.launch
|
||||
import java.time.Clock
|
||||
|
@ -147,7 +148,7 @@ private fun Content(listState: LazyListState, state: Content) {
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun DirectoryItem(room: RoomFoo, onClick: (RoomId) -> Unit, clock: Clock) {
|
||||
private fun DirectoryItem(room: DirectoryItem, onClick: (RoomId) -> Unit, clock: Clock) {
|
||||
val overview = room.overview
|
||||
val roomName = overview.roomName ?: "Empty room"
|
||||
val hasUnread = room.unreadCount.value > 0
|
||||
|
@ -233,7 +234,7 @@ private fun DirectoryItem(room: RoomFoo, onClick: (RoomId) -> Unit, clock: Clock
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun body(overview: RoomOverview, secondaryText: Color, typing: SyncService.SyncEvent.Typing?) {
|
||||
private fun body(overview: RoomOverview, secondaryText: Color, typing: Typing?) {
|
||||
val bodySize = 14.sp
|
||||
|
||||
when {
|
||||
|
|
|
@ -2,31 +2,17 @@ package app.dapk.st.directory
|
|||
|
||||
import android.content.Context
|
||||
import app.dapk.st.core.ProvidableModule
|
||||
import app.dapk.st.matrix.common.CredentialsStore
|
||||
import app.dapk.st.matrix.message.MessageService
|
||||
import app.dapk.st.matrix.room.RoomService
|
||||
import app.dapk.st.matrix.sync.RoomStore
|
||||
import app.dapk.st.matrix.sync.SyncService
|
||||
import app.dapk.st.engine.ChatEngine
|
||||
|
||||
class DirectoryModule(
|
||||
private val syncService: SyncService,
|
||||
private val messageService: MessageService,
|
||||
private val roomService: RoomService,
|
||||
private val context: Context,
|
||||
private val credentialsStore: CredentialsStore,
|
||||
private val roomStore: RoomStore,
|
||||
private val chatEngine: ChatEngine,
|
||||
) : ProvidableModule {
|
||||
|
||||
fun directoryViewModel(): DirectoryViewModel {
|
||||
return DirectoryViewModel(
|
||||
ShortcutHandler(context),
|
||||
DirectoryUseCase(
|
||||
syncService,
|
||||
messageService,
|
||||
roomService,
|
||||
credentialsStore,
|
||||
roomStore,
|
||||
)
|
||||
chatEngine,
|
||||
)
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
package app.dapk.st.directory
|
||||
|
||||
import app.dapk.st.engine.DirectoryState
|
||||
|
||||
sealed interface DirectoryScreenState {
|
||||
|
||||
object EmptyLoading : DirectoryScreenState
|
||||
|
|
|
@ -2,6 +2,7 @@ package app.dapk.st.directory
|
|||
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import app.dapk.st.directory.DirectoryScreenState.*
|
||||
import app.dapk.st.engine.ChatEngine
|
||||
import app.dapk.st.viewmodel.DapkViewModel
|
||||
import app.dapk.st.viewmodel.MutableStateFactory
|
||||
import app.dapk.st.viewmodel.defaultStateFactory
|
||||
|
@ -12,7 +13,7 @@ import kotlinx.coroutines.launch
|
|||
|
||||
class DirectoryViewModel(
|
||||
private val shortcutHandler: ShortcutHandler,
|
||||
private val directoryUseCase: DirectoryUseCase,
|
||||
private val chatEngine: ChatEngine,
|
||||
factory: MutableStateFactory<DirectoryScreenState> = defaultStateFactory(),
|
||||
) : DapkViewModel<DirectoryScreenState, DirectoryEvent>(
|
||||
initialState = EmptyLoading,
|
||||
|
@ -23,7 +24,7 @@ class DirectoryViewModel(
|
|||
|
||||
fun start() {
|
||||
syncJob = viewModelScope.launch {
|
||||
directoryUseCase.state().onEach {
|
||||
chatEngine.directory().onEach {
|
||||
shortcutHandler.onDirectoryUpdate(it.map { it.overview })
|
||||
state = when (it.isEmpty()) {
|
||||
true -> Empty
|
||||
|
|
|
@ -5,8 +5,8 @@ import android.content.pm.ShortcutInfo
|
|||
import androidx.core.app.Person
|
||||
import androidx.core.content.pm.ShortcutInfoCompat
|
||||
import androidx.core.content.pm.ShortcutManagerCompat
|
||||
import app.dapk.st.engine.RoomOverview
|
||||
import app.dapk.st.matrix.common.RoomId
|
||||
import app.dapk.st.matrix.sync.RoomOverview
|
||||
import app.dapk.st.messenger.MessengerActivity
|
||||
|
||||
class ShortcutHandler(private val context: Context) {
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
plugins {
|
||||
id 'kotlin'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api Dependencies.mavenCentral.kotlinCoroutinesCore
|
||||
|
||||
implementation project(":core")
|
||||
implementation project(":chat-engine")
|
||||
|
||||
implementation project(":domains:olm")
|
||||
|
||||
implementation project(":matrix:matrix")
|
||||
implementation project(":matrix:matrix-http-ktor")
|
||||
implementation project(":matrix:services:auth")
|
||||
implementation project(":matrix:services:sync")
|
||||
implementation project(":matrix:services:room")
|
||||
implementation project(":matrix:services:push")
|
||||
implementation project(":matrix:services:message")
|
||||
implementation project(":matrix:services:device")
|
||||
implementation project(":matrix:services:crypto")
|
||||
implementation project(":matrix:services:profile")
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package app.dapk.st.directory
|
||||
package app.dapk.st.engine
|
||||
|
||||
import app.dapk.st.matrix.common.CredentialsStore
|
||||
import app.dapk.st.matrix.common.RoomId
|
||||
|
@ -6,22 +6,12 @@ import app.dapk.st.matrix.common.RoomMember
|
|||
import app.dapk.st.matrix.common.UserId
|
||||
import app.dapk.st.matrix.message.MessageService
|
||||
import app.dapk.st.matrix.room.RoomService
|
||||
import app.dapk.st.matrix.sync.*
|
||||
import app.dapk.st.matrix.sync.RoomStore
|
||||
import app.dapk.st.matrix.sync.SyncService
|
||||
import app.dapk.st.matrix.sync.SyncService.SyncEvent.Typing
|
||||
import kotlinx.coroutines.flow.*
|
||||
|
||||
@JvmInline
|
||||
value class UnreadCount(val value: Int)
|
||||
|
||||
typealias DirectoryState = List<RoomFoo>
|
||||
|
||||
data class RoomFoo(
|
||||
val overview: RoomOverview,
|
||||
val unreadCount: UnreadCount,
|
||||
val typing: Typing?
|
||||
)
|
||||
|
||||
class DirectoryUseCase(
|
||||
internal class DirectoryUseCase(
|
||||
private val syncService: SyncService,
|
||||
private val messageService: MessageService,
|
||||
private val roomService: RoomService,
|
||||
|
@ -38,10 +28,10 @@ class DirectoryUseCase(
|
|||
syncService.events()
|
||||
) { overviewState, localEchos, unread, events ->
|
||||
overviewState.mergeWithLocalEchos(localEchos, userId).map { roomOverview ->
|
||||
RoomFoo(
|
||||
DirectoryItem(
|
||||
overview = roomOverview,
|
||||
unreadCount = UnreadCount(unread[roomOverview.roomId] ?: 0),
|
||||
typing = events.filterIsInstance<Typing>().firstOrNull { it.roomId == roomOverview.roomId }
|
||||
typing = events.filterIsInstance<Typing>().firstOrNull { it.roomId == roomOverview.roomId }?.engine()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +40,7 @@ class DirectoryUseCase(
|
|||
|
||||
private fun overviewDatasource() = combine(
|
||||
syncService.startSyncing().map { false }.onStart { emit(true) },
|
||||
syncService.overview()
|
||||
syncService.overview().map { it.map { it.engine() } }
|
||||
) { isFirstLoad, overview ->
|
||||
when {
|
||||
isFirstLoad && overview.isEmpty() -> null
|
||||
|
@ -81,7 +71,7 @@ class DirectoryUseCase(
|
|||
val latestEcho = echos.maxByOrNull { it.timestampUtc }
|
||||
return if (latestEcho != null && latestEcho.timestampUtc > (this.lastMessage?.utcTimestamp ?: 0)) {
|
||||
this.copy(
|
||||
lastMessage = LastMessage(
|
||||
lastMessage = RoomOverview.LastMessage(
|
||||
content = when (val message = latestEcho.message) {
|
||||
is MessageService.Message.TextMessage -> message.content.body
|
||||
is MessageService.Message.ImageMessage -> "\uD83D\uDCF7"
|
||||
|
@ -96,3 +86,6 @@ class DirectoryUseCase(
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package app.dapk.st.engine
|
||||
|
||||
import app.dapk.st.matrix.sync.LastMessage as MatrixLastMessage
|
||||
import app.dapk.st.matrix.sync.RoomOverview as MatrixRoomOverview
|
||||
import app.dapk.st.matrix.sync.SyncService.SyncEvent.Typing as MatrixTyping
|
||||
|
||||
fun MatrixRoomOverview.engine() = RoomOverview(
|
||||
this.roomId,
|
||||
this.roomCreationUtc,
|
||||
this.roomName,
|
||||
this.roomAvatarUrl,
|
||||
this.lastMessage?.engine(),
|
||||
this.isGroup,
|
||||
this.readMarker,
|
||||
this.isEncrypted
|
||||
)
|
||||
|
||||
fun MatrixLastMessage.engine() = RoomOverview.LastMessage(
|
||||
this.content,
|
||||
this.utcTimestamp,
|
||||
this.author,
|
||||
)
|
||||
|
||||
fun MatrixTyping.engine() = Typing(
|
||||
this.roomId,
|
||||
this.members,
|
||||
)
|
|
@ -0,0 +1,317 @@
|
|||
package app.dapk.st.engine
|
||||
|
||||
import app.dapk.st.core.Base64
|
||||
import app.dapk.st.core.BuildMeta
|
||||
import app.dapk.st.core.CoroutineDispatchers
|
||||
import app.dapk.st.core.SingletonFlows
|
||||
import app.dapk.st.core.extensions.ErrorTracker
|
||||
import app.dapk.st.matrix.MatrixClient
|
||||
import app.dapk.st.matrix.auth.DeviceDisplayNameGenerator
|
||||
import app.dapk.st.matrix.auth.installAuthService
|
||||
import app.dapk.st.matrix.common.*
|
||||
import app.dapk.st.matrix.crypto.RoomMembersProvider
|
||||
import app.dapk.st.matrix.crypto.Verification
|
||||
import app.dapk.st.matrix.crypto.cryptoService
|
||||
import app.dapk.st.matrix.crypto.installCryptoService
|
||||
import app.dapk.st.matrix.device.KnownDeviceStore
|
||||
import app.dapk.st.matrix.device.deviceService
|
||||
import app.dapk.st.matrix.device.installEncryptionService
|
||||
import app.dapk.st.matrix.http.ktor.KtorMatrixHttpClientFactory
|
||||
import app.dapk.st.matrix.message.*
|
||||
import app.dapk.st.matrix.message.internal.ImageContentReader
|
||||
import app.dapk.st.matrix.push.installPushService
|
||||
import app.dapk.st.matrix.room.*
|
||||
import app.dapk.st.matrix.sync.*
|
||||
import app.dapk.st.matrix.sync.internal.request.ApiToDeviceEvent
|
||||
import app.dapk.st.matrix.sync.internal.room.MessageDecrypter
|
||||
import app.dapk.st.olm.DeviceKeyFactory
|
||||
import app.dapk.st.olm.OlmStore
|
||||
import app.dapk.st.olm.OlmWrapper
|
||||
import java.time.Clock
|
||||
|
||||
class MatrixEngine internal constructor(
|
||||
private val directoryUseCase: Lazy<DirectoryUseCase>,
|
||||
) : ChatEngine {
|
||||
|
||||
override fun directory() = directoryUseCase.value.state()
|
||||
|
||||
class Factory {
|
||||
|
||||
fun create(
|
||||
base64: Base64,
|
||||
buildMeta: BuildMeta,
|
||||
logger: MatrixLogger,
|
||||
nameGenerator: DeviceDisplayNameGenerator,
|
||||
coroutineDispatchers: CoroutineDispatchers,
|
||||
errorTracker: ErrorTracker,
|
||||
imageContentReader: ImageContentReader,
|
||||
backgroundScheduler: BackgroundScheduler,
|
||||
memberStore: MemberStore,
|
||||
roomStore: RoomStore,
|
||||
profileStore: ProfileStore,
|
||||
syncStore: SyncStore,
|
||||
overviewStore: OverviewStore,
|
||||
filterStore: FilterStore,
|
||||
localEchoStore: LocalEchoStore,
|
||||
credentialsStore: CredentialsStore,
|
||||
knownDeviceStore: KnownDeviceStore,
|
||||
olmStore: OlmStore,
|
||||
): ChatEngine {
|
||||
val matrix = MatrixFactory.createMatrix(
|
||||
base64,
|
||||
buildMeta,
|
||||
logger,
|
||||
nameGenerator,
|
||||
coroutineDispatchers,
|
||||
errorTracker,
|
||||
imageContentReader,
|
||||
backgroundScheduler,
|
||||
memberStore,
|
||||
roomStore,
|
||||
profileStore,
|
||||
syncStore,
|
||||
overviewStore,
|
||||
filterStore,
|
||||
localEchoStore,
|
||||
credentialsStore,
|
||||
knownDeviceStore,
|
||||
olmStore
|
||||
)
|
||||
|
||||
val directoryUseCase = unsafeLazy {
|
||||
DirectoryUseCase(
|
||||
matrix.syncService(),
|
||||
matrix.messageService(),
|
||||
matrix.roomService(),
|
||||
credentialsStore,
|
||||
roomStore
|
||||
)
|
||||
}
|
||||
|
||||
return MatrixEngine(directoryUseCase)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
object MatrixFactory {
|
||||
|
||||
fun createMatrix(
|
||||
base64: Base64,
|
||||
buildMeta: BuildMeta,
|
||||
logger: MatrixLogger,
|
||||
nameGenerator: DeviceDisplayNameGenerator,
|
||||
coroutineDispatchers: CoroutineDispatchers,
|
||||
errorTracker: ErrorTracker,
|
||||
imageContentReader: ImageContentReader,
|
||||
backgroundScheduler: BackgroundScheduler,
|
||||
memberStore: MemberStore,
|
||||
roomStore: RoomStore,
|
||||
profileStore: ProfileStore,
|
||||
syncStore: SyncStore,
|
||||
overviewStore: OverviewStore,
|
||||
filterStore: FilterStore,
|
||||
localEchoStore: LocalEchoStore,
|
||||
credentialsStore: CredentialsStore,
|
||||
knownDeviceStore: KnownDeviceStore,
|
||||
olmStore: OlmStore,
|
||||
) = MatrixClient(
|
||||
KtorMatrixHttpClientFactory(
|
||||
credentialsStore,
|
||||
includeLogging = buildMeta.isDebug,
|
||||
),
|
||||
logger
|
||||
).also {
|
||||
it.install {
|
||||
installAuthService(credentialsStore, nameGenerator)
|
||||
installEncryptionService(knownDeviceStore)
|
||||
|
||||
val singletonFlows = SingletonFlows(coroutineDispatchers)
|
||||
val olm = OlmWrapper(
|
||||
olmStore = olmStore,
|
||||
singletonFlows = singletonFlows,
|
||||
jsonCanonicalizer = JsonCanonicalizer(),
|
||||
deviceKeyFactory = DeviceKeyFactory(JsonCanonicalizer()),
|
||||
errorTracker = errorTracker,
|
||||
logger = logger,
|
||||
clock = Clock.systemUTC(),
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
)
|
||||
installCryptoService(
|
||||
credentialsStore,
|
||||
olm,
|
||||
roomMembersProvider = { services ->
|
||||
RoomMembersProvider {
|
||||
services.roomService().joinedMembers(it).map { it.userId }
|
||||
}
|
||||
},
|
||||
base64 = base64,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
)
|
||||
installMessageService(
|
||||
localEchoStore,
|
||||
backgroundScheduler,
|
||||
imageContentReader,
|
||||
messageEncrypter = {
|
||||
val cryptoService = it.cryptoService()
|
||||
MessageEncrypter { message ->
|
||||
val result = cryptoService.encrypt(
|
||||
roomId = message.roomId,
|
||||
credentials = credentialsStore.credentials()!!,
|
||||
messageJson = message.contents,
|
||||
)
|
||||
|
||||
MessageEncrypter.EncryptedMessagePayload(
|
||||
result.algorithmName,
|
||||
result.senderKey,
|
||||
result.cipherText,
|
||||
result.sessionId,
|
||||
result.deviceId,
|
||||
)
|
||||
}
|
||||
},
|
||||
mediaEncrypter = {
|
||||
val cryptoService = it.cryptoService()
|
||||
MediaEncrypter { input ->
|
||||
val result = cryptoService.encrypt(input)
|
||||
MediaEncrypter.Result(
|
||||
uri = result.uri,
|
||||
contentLength = result.contentLength,
|
||||
algorithm = result.algorithm,
|
||||
ext = result.ext,
|
||||
keyOperations = result.keyOperations,
|
||||
kty = result.kty,
|
||||
k = result.k,
|
||||
iv = result.iv,
|
||||
hashes = result.hashes,
|
||||
v = result.v,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
installRoomService(
|
||||
memberStore,
|
||||
roomMessenger = {
|
||||
val messageService = it.messageService()
|
||||
object : RoomMessenger {
|
||||
override suspend fun enableEncryption(roomId: RoomId) {
|
||||
messageService.sendEventMessage(
|
||||
roomId, MessageService.EventMessage.Encryption(
|
||||
algorithm = AlgorithmName("m.megolm.v1.aes-sha2")
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
roomInviteRemover = {
|
||||
overviewStore.removeInvites(listOf(it))
|
||||
}
|
||||
)
|
||||
|
||||
installProfileService(profileStore, singletonFlows, credentialsStore)
|
||||
|
||||
installSyncService(
|
||||
credentialsStore,
|
||||
overviewStore,
|
||||
roomStore,
|
||||
syncStore,
|
||||
filterStore,
|
||||
deviceNotifier = { services ->
|
||||
val encryption = services.deviceService()
|
||||
val crypto = services.cryptoService()
|
||||
DeviceNotifier { userIds, syncToken ->
|
||||
encryption.updateStaleDevices(userIds)
|
||||
crypto.updateOlmSession(userIds, syncToken)
|
||||
}
|
||||
},
|
||||
messageDecrypter = { serviceProvider ->
|
||||
val cryptoService = serviceProvider.cryptoService()
|
||||
MessageDecrypter {
|
||||
cryptoService.decrypt(it)
|
||||
}
|
||||
},
|
||||
keySharer = { serviceProvider ->
|
||||
val cryptoService = serviceProvider.cryptoService()
|
||||
KeySharer { sharedRoomKeys ->
|
||||
cryptoService.importRoomKeys(sharedRoomKeys)
|
||||
}
|
||||
},
|
||||
verificationHandler = { services ->
|
||||
val cryptoService = services.cryptoService()
|
||||
VerificationHandler { apiEvent ->
|
||||
logger.matrixLog(MatrixLogTag.VERIFICATION, "got a verification request $it")
|
||||
cryptoService.onVerificationEvent(
|
||||
when (apiEvent) {
|
||||
is ApiToDeviceEvent.VerificationRequest -> Verification.Event.Requested(
|
||||
apiEvent.sender,
|
||||
apiEvent.content.fromDevice,
|
||||
apiEvent.content.transactionId,
|
||||
apiEvent.content.methods,
|
||||
apiEvent.content.timestampPosix,
|
||||
)
|
||||
|
||||
is ApiToDeviceEvent.VerificationReady -> Verification.Event.Ready(
|
||||
apiEvent.sender,
|
||||
apiEvent.content.fromDevice,
|
||||
apiEvent.content.transactionId,
|
||||
apiEvent.content.methods,
|
||||
)
|
||||
|
||||
is ApiToDeviceEvent.VerificationStart -> Verification.Event.Started(
|
||||
apiEvent.sender,
|
||||
apiEvent.content.fromDevice,
|
||||
apiEvent.content.method,
|
||||
apiEvent.content.protocols,
|
||||
apiEvent.content.hashes,
|
||||
apiEvent.content.codes,
|
||||
apiEvent.content.short,
|
||||
apiEvent.content.transactionId,
|
||||
)
|
||||
|
||||
is ApiToDeviceEvent.VerificationCancel -> TODO()
|
||||
is ApiToDeviceEvent.VerificationAccept -> TODO()
|
||||
is ApiToDeviceEvent.VerificationKey -> Verification.Event.Key(
|
||||
apiEvent.sender,
|
||||
apiEvent.content.transactionId,
|
||||
apiEvent.content.key
|
||||
)
|
||||
|
||||
is ApiToDeviceEvent.VerificationMac -> Verification.Event.Mac(
|
||||
apiEvent.sender,
|
||||
apiEvent.content.transactionId,
|
||||
apiEvent.content.keys,
|
||||
apiEvent.content.mac,
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
oneTimeKeyProducer = { services ->
|
||||
val cryptoService = services.cryptoService()
|
||||
MaybeCreateMoreKeys {
|
||||
cryptoService.maybeCreateMoreKeys(it)
|
||||
}
|
||||
},
|
||||
roomMembersService = { services ->
|
||||
val roomService = services.roomService()
|
||||
object : RoomMembersService {
|
||||
override suspend fun find(roomId: RoomId, userIds: List<UserId>) = roomService.findMembers(roomId, userIds)
|
||||
override suspend fun findSummary(roomId: RoomId) = roomService.findMembersSummary(roomId)
|
||||
override suspend fun insert(roomId: RoomId, members: List<RoomMember>) = roomService.insertMembers(roomId, members)
|
||||
}
|
||||
},
|
||||
errorTracker = errorTracker,
|
||||
coroutineDispatchers = coroutineDispatchers,
|
||||
)
|
||||
|
||||
installPushService(credentialsStore)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun <T> unsafeLazy(initializer: () -> T): Lazy<T> = lazy(mode = LazyThreadSafetyMode.NONE, initializer = initializer)
|
|
@ -55,3 +55,6 @@ include ':matrix:services:profile'
|
|||
include ':core'
|
||||
|
||||
include ':test-harness'
|
||||
|
||||
include ':chat-engine'
|
||||
include ':matrix-chat-engine'
|
Loading…
Reference in New Issue