diff --git a/core/src/main/java/org/futo/circles/core/workspace/SharedCircleDataSource.kt b/core/src/main/java/org/futo/circles/core/workspace/SharedCircleDataSource.kt index e7253a585757a203c1b2222b2524d549c2c060ff..0ed778a34f931bbc0bb80795c7e9d46711f6fe9b 100644 --- a/core/src/main/java/org/futo/circles/core/workspace/SharedCircleDataSource.kt +++ b/core/src/main/java/org/futo/circles/core/workspace/SharedCircleDataSource.kt @@ -1,12 +1,26 @@ package org.futo.circles.core.workspace +import android.os.Build +import androidx.lifecycle.asFlow +import androidx.lifecycle.map +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.withContext import org.futo.circles.core.extensions.getRoomOwners import org.futo.circles.core.model.PROFILE_SPACE_ACCOUNT_DATA_KEY import org.futo.circles.core.provider.MatrixSessionProvider import org.futo.circles.core.room.RoomRelationsBuilder +import org.futo.circles.core.utils.getJoinedRoomById import org.futo.circles.core.utils.getTimelineRoomFor +import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.getRoomSummary import org.matrix.android.sdk.api.session.room.model.Membership +import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.RoomType import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams import javax.inject.Inject @@ -19,6 +33,34 @@ class SharedCircleDataSource @Inject constructor( fun getSharedCirclesSpaceId() = spacesTreeAccountDataSource.getRoomIdByKey(PROFILE_SPACE_ACCOUNT_DATA_KEY) + suspend fun unfollowUsersSharedCircle(userId: String) { + val userSharedCircleId = + getSharedCircleFor(userId)?.roomId ?: throw IllegalArgumentException("User's profile not found") + val mySharedCircleId = getSharedCirclesSpaceId() + ?: throw IllegalArgumentException("Workspace configuration failure") + + roomRelationsBuilder.removeRelations(userSharedCircleId, mySharedCircleId) + MatrixSessionProvider.getSessionOrThrow().roomService().leaveRoom(userSharedCircleId) + } + + fun observeAndAutoAcceptSharedSpaceInvites(coroutineScope: CoroutineScope): Job { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) return Job() + val session = MatrixSessionProvider.currentSession ?: return Job() + return session.roomService().getRoomSummariesLive( + roomSummaryQueryParams { + excludeType = null + memberships = listOf(Membership.INVITE) + }).map { it.filter { it.roomType == RoomType.SPACE }.map { it.roomId } } + .asFlow().onEach { roomsIds -> + withContext(Dispatchers.IO) { + roomsIds.forEach { acceptSharedCircleInvite(session, it) } + } + } + .flowOn(Dispatchers.Default) + .catch { } + .launchIn(coroutineScope) + } + suspend fun addToSharedCircles(timelineId: String) { getSharedCirclesSpaceId()?.let { roomRelationsBuilder.setRelations(timelineId, it) } } @@ -27,11 +69,14 @@ class SharedCircleDataSource @Inject constructor( getSharedCirclesSpaceId()?.let { roomRelationsBuilder.removeRelations(timelineId, it) } } - fun getSharedCircleFor(userId: String) = MatrixSessionProvider.currentSession?.roomService() - ?.getRoomSummaries(roomSummaryQueryParams { excludeType = null })?.firstOrNull { summary -> - summary.roomType == RoomType.SPACE && summary.membership == Membership.JOIN && - getRoomOwners(summary.roomId).map { it.userId }.contains(userId) - } + fun getSharedCircleFor(userId: String): RoomSummary? { + val sharedCirclesSpaceId = getSharedCirclesSpaceId() ?: return null + val userSharedCircleId = + getJoinedRoomById(sharedCirclesSpaceId)?.roomSummary()?.spaceChildren?.firstOrNull { child -> + getRoomOwners(child.childRoomId).map { it.userId }.contains(userId) + }?.childRoomId ?: return null + return getJoinedRoomById(userSharedCircleId)?.roomSummary() + } fun getSharedCirclesTimelinesIds() = getSharedCirclesSpaceId()?.let { MatrixSessionProvider.currentSession?.getRoomSummary(it)?.spaceChildren?.map { it.childRoomId } @@ -41,4 +86,10 @@ class SharedCircleDataSource @Inject constructor( val timelineId = getTimelineRoomFor(circleId)?.roomId return sharedCirclesTimelineIds.contains(timelineId) } + + private suspend fun acceptSharedCircleInvite(session: Session, roomId: String) { + session.roomService().joinRoom(roomId) + val sharedCirclesSpaceId = getSharedCirclesSpaceId() ?: return + roomRelationsBuilder.setRelations(roomId, sharedCirclesSpaceId) + } } \ No newline at end of file