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 4cf8b85..99e2d26 100644 --- a/app/src/main/kotlin/app/dapk/st/graph/AppModule.kt +++ b/app/src/main/kotlin/app/dapk/st/graph/AppModule.kt @@ -191,7 +191,7 @@ internal class FeatureModules internal constructor( storeModule.value.messageStore(), ) } - val profileModule by unsafeLazy { ProfileModule(matrixModules.profile, matrixModules.sync, matrixModules.room, trackingModule.errorTracker) } + val profileModule by unsafeLazy { ProfileModule(matrixModules.engine, trackingModule.errorTracker) } val notificationsModule by unsafeLazy { NotificationsModule( imageLoaderModule.iconLoader(), @@ -459,7 +459,6 @@ internal class MatrixModules( val sync by unsafeLazy { matrix.syncService() } val room by unsafeLazy { matrix.roomService() } - val profile by unsafeLazy { matrix.profileService() } } internal class DomainModules( 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 cf83a79..ad64a3a 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 @@ -24,6 +24,10 @@ interface ChatEngine { suspend fun registerPushToken(token: String, gatewayUrl: String) + suspend fun joinRoom(roomId: RoomId) + + suspend fun rejectJoinRoom(roomId: RoomId) + fun mediaDecrypter(): MediaDecrypter fun pushHandler(): PushHandler diff --git a/features/profile/build.gradle b/features/profile/build.gradle index 6a2f7b0..89e50f1 100644 --- a/features/profile/build.gradle +++ b/features/profile/build.gradle @@ -1,9 +1,7 @@ applyAndroidComposeLibraryModule(project) dependencies { - implementation project(":matrix:services:sync") - implementation project(":matrix:services:room") - implementation project(":matrix:services:profile") + implementation project(":chat-engine") implementation project(":features:settings") implementation project(':domains:store') implementation project(":domains:android:compose-core") diff --git a/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileModule.kt b/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileModule.kt index 43d7d44..4766144 100644 --- a/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileModule.kt +++ b/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileModule.kt @@ -2,19 +2,15 @@ package app.dapk.st.profile import app.dapk.st.core.ProvidableModule import app.dapk.st.core.extensions.ErrorTracker -import app.dapk.st.matrix.room.ProfileService -import app.dapk.st.matrix.room.RoomService -import app.dapk.st.matrix.sync.SyncService +import app.dapk.st.engine.ChatEngine class ProfileModule( - private val profileService: ProfileService, - private val syncService: SyncService, - private val roomService: RoomService, + private val chatEngine: ChatEngine, private val errorTracker: ErrorTracker, ) : ProvidableModule { fun profileViewModel(): ProfileViewModel { - return ProfileViewModel(profileService, syncService, roomService, errorTracker) + return ProfileViewModel(chatEngine, errorTracker) } } \ No newline at end of file diff --git a/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileScreen.kt b/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileScreen.kt index 889ecf4..d08d2b4 100644 --- a/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileScreen.kt +++ b/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileScreen.kt @@ -21,8 +21,8 @@ import app.dapk.st.core.Lce import app.dapk.st.core.LifecycleEffect import app.dapk.st.core.components.CenteredLoading import app.dapk.st.design.components.* -import app.dapk.st.matrix.sync.InviteMeta -import app.dapk.st.matrix.sync.RoomInvite +import app.dapk.st.engine.RoomInvite +import app.dapk.st.engine.RoomInvite.InviteMeta import app.dapk.st.settings.SettingsActivity @Composable diff --git a/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileState.kt b/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileState.kt index 5e0b6e2..b7754df 100644 --- a/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileState.kt +++ b/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileState.kt @@ -3,9 +3,8 @@ package app.dapk.st.profile import app.dapk.st.core.Lce import app.dapk.st.design.components.Route import app.dapk.st.design.components.SpiderPage -import app.dapk.st.matrix.common.RoomId -import app.dapk.st.matrix.room.ProfileService -import app.dapk.st.matrix.sync.RoomInvite +import app.dapk.st.engine.Me +import app.dapk.st.engine.RoomInvite data class ProfileScreenState( val page: SpiderPage, @@ -14,12 +13,12 @@ data class ProfileScreenState( sealed interface Page { data class Profile(val content: Lce) : Page { data class Content( - val me: ProfileService.Me, + val me: Me, val invitationsCount: Int, ) } - data class Invitations(val content: Lce>): Page + data class Invitations(val content: Lce>) : Page object Routes { val profile = Route("Profile") diff --git a/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileViewModel.kt b/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileViewModel.kt index bec102a..bb3cfb6 100644 --- a/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileViewModel.kt +++ b/features/profile/src/main/kotlin/app/dapk/st/profile/ProfileViewModel.kt @@ -5,25 +5,20 @@ import androidx.lifecycle.viewModelScope import app.dapk.st.core.Lce import app.dapk.st.core.extensions.ErrorTracker import app.dapk.st.design.components.SpiderPage +import app.dapk.st.engine.ChatEngine import app.dapk.st.matrix.common.RoomId -import app.dapk.st.matrix.room.ProfileService -import app.dapk.st.matrix.room.RoomService -import app.dapk.st.matrix.sync.SyncService import app.dapk.st.viewmodel.DapkViewModel import kotlinx.coroutines.Job import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch class ProfileViewModel( - private val profileService: ProfileService, - private val syncService: SyncService, - private val roomService: RoomService, + private val chatEngine: ChatEngine, private val errorTracker: ErrorTracker, ) : DapkViewModel( ProfileScreenState(SpiderPage(Page.Routes.profile, "Profile", null, Page.Profile(Lce.Loading()), hasToolbar = false)) ) { - private var syncingJob: Job? = null private var currentPageJob: Job? = null fun start() { @@ -31,15 +26,13 @@ class ProfileViewModel( } private fun goToProfile() { - syncingJob = syncService.startSyncing().launchIn(viewModelScope) - combine( flow { - val result = runCatching { profileService.me(forceRefresh = true) } + val result = runCatching { chatEngine.me(forceRefresh = true) } .onFailure { errorTracker.track(it, "Loading profile") } emit(result) }, - syncService.invites(), + chatEngine.invites(), transform = { me, invites -> me to invites } ) .onEach { (me, invites) -> @@ -57,7 +50,7 @@ class ProfileViewModel( fun goToInvitations() { updateState { copy(page = SpiderPage(Page.Routes.invitation, "Invitations", Page.Routes.profile, Page.Invitations(Lce.Loading()))) } - syncService.invites() + chatEngine.invites() .onEach { updatePageState { copy(content = Lce.Content(it)) @@ -89,13 +82,13 @@ class ProfileViewModel( } fun acceptRoomInvite(roomId: RoomId) { - launchCatching { roomService.joinRoom(roomId) }.fold( + launchCatching { chatEngine.joinRoom(roomId) }.fold( onError = {} ) } fun rejectRoomInvite(roomId: RoomId) { - launchCatching { roomService.rejectJoinRoom(roomId) }.fold( + launchCatching { chatEngine.rejectJoinRoom(roomId) }.fold( onError = { Log.e("!!!", it.message, it) } @@ -115,7 +108,7 @@ class ProfileViewModel( } fun stop() { - syncingJob?.cancel() + currentPageJob?.cancel() } } diff --git a/matrix-chat-engine/src/main/kotlin/app/dapk/st/engine/InviteUseCase.kt b/matrix-chat-engine/src/main/kotlin/app/dapk/st/engine/InviteUseCase.kt new file mode 100644 index 0000000..740a8ce --- /dev/null +++ b/matrix-chat-engine/src/main/kotlin/app/dapk/st/engine/InviteUseCase.kt @@ -0,0 +1,25 @@ +package app.dapk.st.engine + +import app.dapk.st.matrix.sync.SyncService +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.filterNotNull +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onStart + +class InviteUseCase( + private val syncService: SyncService +) { + + fun invites() = invitesDatasource() + + private fun invitesDatasource() = combine( + syncService.startSyncing().map { false }.onStart { emit(true) }, + syncService.invites().map { it.map { it.engine() } } + ) { isFirstLoad, invites -> + when { + isFirstLoad && invites.isEmpty() -> null + else -> invites + } + }.filterNotNull() + +} \ 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 f921cfd..3bda72d 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 @@ -39,12 +39,11 @@ class MatrixEngine internal constructor( private val sendMessageUseCase: Lazy, private val matrixMediaDecrypter: Lazy, private val matrixPushHandler: Lazy, + private val inviteUseCase: Lazy, ) : ChatEngine { override fun directory() = directoryUseCase.value.state() - override fun invites(): Flow { - return matrix.value.syncService().invites().map { it.map { it.engine() } } - } + override fun invites() = inviteUseCase.value.invites() override suspend fun messages(roomId: RoomId, disableReadReceipts: Boolean): Flow { return timelineUseCase.value.foo(roomId, isReadReceiptsDisabled = disableReadReceipts) @@ -81,6 +80,14 @@ class MatrixEngine internal constructor( matrix.value.pushService().registerPush(token, gatewayUrl) } + override suspend fun joinRoom(roomId: RoomId) { + matrix.value.roomService().joinRoom(roomId) + } + + override suspend fun rejectJoinRoom(roomId: RoomId) { + matrix.value.roomService().rejectJoinRoom(roomId) + } + override fun mediaDecrypter(): MediaDecrypter { val mediaDecrypter = matrixMediaDecrypter.value return object : MediaDecrypter { @@ -163,7 +170,17 @@ class MatrixEngine internal constructor( val mediaDecrypter = unsafeLazy { MatrixMediaDecrypter(base64) } val pushHandler = unsafeLazy { MatrixPushHandler(backgroundScheduler, credentialsStore, lazyMatrix.value.syncService(), roomStore) } - return MatrixEngine(directoryUseCase, lazyMatrix, timelineUseCase, sendMessageUseCase, mediaDecrypter, pushHandler) + val invitesUseCase = unsafeLazy { InviteUseCase(lazyMatrix.value.syncService()) } + + return MatrixEngine( + directoryUseCase, + lazyMatrix, + timelineUseCase, + sendMessageUseCase, + mediaDecrypter, + pushHandler, + invitesUseCase, + ) } }