Clean after benoits review
This commit is contained in:
parent
4b6484d317
commit
48fa9e1a5e
|
@ -22,7 +22,6 @@ import androidx.lifecycle.OnLifecycleEvent
|
|||
import arrow.core.Option
|
||||
import im.vector.app.core.di.ActiveSessionHolder
|
||||
import im.vector.app.core.utils.BehaviorDataSource
|
||||
import im.vector.app.features.invite.InvitesAcceptor
|
||||
import im.vector.app.features.session.coroutineScope
|
||||
import im.vector.app.features.ui.UiStateRepository
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
|
@ -52,8 +51,7 @@ fun RoomGroupingMethod.group() = (this as? RoomGroupingMethod.ByLegacyGroup)?.gr
|
|||
class AppStateHandler @Inject constructor(
|
||||
private val sessionDataSource: ActiveSessionDataSource,
|
||||
private val uiStateRepository: UiStateRepository,
|
||||
private val activeSessionHolder: ActiveSessionHolder,
|
||||
private val invitesAcceptor: InvitesAcceptor
|
||||
private val activeSessionHolder: ActiveSessionHolder
|
||||
) : LifecycleObserver {
|
||||
|
||||
private val compositeDisposable = CompositeDisposable()
|
||||
|
@ -63,10 +61,6 @@ class AppStateHandler @Inject constructor(
|
|||
|
||||
fun getCurrentRoomGroupingMethod(): RoomGroupingMethod? = selectedSpaceDataSource.currentValue?.orNull()
|
||||
|
||||
init {
|
||||
observeActiveSession()
|
||||
}
|
||||
|
||||
fun setCurrentSpace(spaceId: String?, session: Session? = null) {
|
||||
val uSession = session ?: activeSessionHolder.getSafeActiveSession() ?: return
|
||||
if (selectedSpaceDataSource.currentValue?.orNull() is RoomGroupingMethod.BySpace
|
||||
|
@ -103,7 +97,6 @@ class AppStateHandler @Inject constructor(
|
|||
.subscribe {
|
||||
// sessionDataSource could already return a session while activeSession holder still returns null
|
||||
it.orNull()?.let { session ->
|
||||
invitesAcceptor.onSessionActive(session)
|
||||
if (uiStateRepository.isGroupingMethodSpace(session.sessionId)) {
|
||||
setCurrentSpace(uiStateRepository.getSelectedSpace(session.sessionId), session)
|
||||
} else {
|
||||
|
@ -123,8 +116,14 @@ class AppStateHandler @Inject constructor(
|
|||
return (selectedSpaceDataSource.currentValue?.orNull() as? RoomGroupingMethod.ByLegacyGroup)?.groupSummary?.groupId
|
||||
}
|
||||
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
|
||||
fun entersForeground() {
|
||||
observeActiveSession()
|
||||
}
|
||||
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
|
||||
fun entersBackground() {
|
||||
compositeDisposable.clear()
|
||||
val session = activeSessionHolder.getSafeActiveSession() ?: return
|
||||
when (val currentMethod = selectedSpaceDataSource.currentValue?.orNull() ?: RoomGroupingMethod.BySpace(null)) {
|
||||
is RoomGroupingMethod.BySpace -> {
|
||||
|
|
|
@ -47,6 +47,7 @@ import im.vector.app.core.rx.RxConfig
|
|||
import im.vector.app.features.call.webrtc.WebRtcCallManager
|
||||
import im.vector.app.features.configuration.VectorConfiguration
|
||||
import im.vector.app.features.disclaimer.doNotShowDisclaimerDialog
|
||||
import im.vector.app.features.invite.InvitesAcceptor
|
||||
import im.vector.app.features.lifecycle.VectorActivityLifecycleCallbacks
|
||||
import im.vector.app.features.notifications.NotificationDrawerManager
|
||||
import im.vector.app.features.notifications.NotificationUtils
|
||||
|
@ -95,6 +96,7 @@ class VectorApplication :
|
|||
@Inject lateinit var popupAlertManager: PopupAlertManager
|
||||
@Inject lateinit var pinLocker: PinLocker
|
||||
@Inject lateinit var callManager: WebRtcCallManager
|
||||
@Inject lateinit var invitesAcceptor: InvitesAcceptor
|
||||
|
||||
lateinit var vectorComponent: VectorComponent
|
||||
|
||||
|
@ -116,6 +118,7 @@ class VectorApplication :
|
|||
appContext = this
|
||||
vectorComponent = DaggerVectorComponent.factory().create(this)
|
||||
vectorComponent.inject(this)
|
||||
invitesAcceptor.initialize()
|
||||
vectorUncaughtExceptionHandler.activate(this)
|
||||
rxConfig.setupRxPlugin()
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ import im.vector.app.features.call.lookup.CallProtocolsChecker
|
|||
import im.vector.app.features.call.webrtc.WebRtcCallManager
|
||||
import im.vector.app.features.createdirect.DirectRoomHelper
|
||||
import im.vector.app.features.invite.AutoAcceptInvites
|
||||
import im.vector.app.features.invite.showInvites
|
||||
import im.vector.app.features.ui.UiStateRepository
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
@ -208,7 +209,7 @@ private val autoAcceptInvites: AutoAcceptInvites)
|
|||
val activeSpaceRoomId = groupingMethod.spaceSummary?.roomId
|
||||
var dmInvites = 0
|
||||
var roomsInvite = 0
|
||||
if (!autoAcceptInvites.hideInvites) {
|
||||
if (autoAcceptInvites.showInvites()) {
|
||||
dmInvites = session.getRoomSummaries(
|
||||
roomSummaryQueryParams {
|
||||
memberships = listOf(Membership.INVITE)
|
||||
|
|
|
@ -23,6 +23,7 @@ import im.vector.app.RoomGroupingMethod
|
|||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.features.home.RoomListDisplayMode
|
||||
import im.vector.app.features.invite.AutoAcceptInvites
|
||||
import im.vector.app.features.invite.showInvites
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
@ -75,7 +76,7 @@ class GroupRoomListSectionBuilder(
|
|||
)
|
||||
}
|
||||
RoomListDisplayMode.NOTIFICATIONS -> {
|
||||
if (!autoAcceptInvites.hideInvites) {
|
||||
if (autoAcceptInvites.showInvites()) {
|
||||
addSection(
|
||||
sections,
|
||||
activeGroupAwareQueries,
|
||||
|
@ -118,7 +119,7 @@ class GroupRoomListSectionBuilder(
|
|||
private fun buildRoomsSections(sections: MutableList<RoomsSection>,
|
||||
activeSpaceAwareQueries: MutableList<UpdatableLivePageResult>,
|
||||
actualGroupId: String?) {
|
||||
if (!autoAcceptInvites.hideInvites) {
|
||||
if (autoAcceptInvites.showInvites()) {
|
||||
addSection(
|
||||
sections,
|
||||
activeSpaceAwareQueries,
|
||||
|
@ -185,7 +186,7 @@ class GroupRoomListSectionBuilder(
|
|||
activeSpaceAwareQueries: MutableList<UpdatableLivePageResult>,
|
||||
actualGroupId: String?
|
||||
) {
|
||||
if (!autoAcceptInvites.hideInvites) {
|
||||
if (autoAcceptInvites.showInvites()) {
|
||||
addSection(sections,
|
||||
activeSpaceAwareQueries,
|
||||
R.string.invitations_header,
|
||||
|
|
|
@ -27,6 +27,7 @@ import im.vector.app.R
|
|||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.features.home.RoomListDisplayMode
|
||||
import im.vector.app.features.invite.AutoAcceptInvites
|
||||
import im.vector.app.features.invite.showInvites
|
||||
import im.vector.app.space
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.disposables.Disposable
|
||||
|
@ -90,7 +91,7 @@ class SpaceRoomListSectionBuilder(
|
|||
)
|
||||
}
|
||||
RoomListDisplayMode.NOTIFICATIONS -> {
|
||||
if (!autoAcceptInvites.hideInvites) {
|
||||
if (autoAcceptInvites.showInvites()) {
|
||||
addSection(
|
||||
sections = sections,
|
||||
activeSpaceUpdaters = activeSpaceAwareQueries,
|
||||
|
@ -140,7 +141,7 @@ class SpaceRoomListSectionBuilder(
|
|||
}
|
||||
|
||||
private fun buildRoomsSections(sections: MutableList<RoomsSection>, activeSpaceAwareQueries: MutableList<RoomListViewModel.ActiveSpaceQueryUpdater>) {
|
||||
if (!autoAcceptInvites.hideInvites) {
|
||||
if (autoAcceptInvites.showInvites()) {
|
||||
addSection(
|
||||
sections = sections,
|
||||
activeSpaceUpdaters = activeSpaceAwareQueries,
|
||||
|
@ -259,7 +260,7 @@ class SpaceRoomListSectionBuilder(
|
|||
}
|
||||
|
||||
private fun buildDmSections(sections: MutableList<RoomsSection>, activeSpaceAwareQueries: MutableList<RoomListViewModel.ActiveSpaceQueryUpdater>) {
|
||||
if (!autoAcceptInvites.hideInvites) {
|
||||
if (autoAcceptInvites.showInvites()) {
|
||||
addSection(sections = sections,
|
||||
activeSpaceUpdaters = activeSpaceAwareQueries,
|
||||
nameRes = R.string.invitations_header,
|
||||
|
|
|
@ -18,12 +18,28 @@ package im.vector.app.features.invite
|
|||
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* This interface defines 2 flags so you can handle auto accept invites.
|
||||
* At the moment we only have [CompileTimeAutoAcceptInvites] implementation.
|
||||
*/
|
||||
interface AutoAcceptInvites {
|
||||
/**
|
||||
* Enable auto-accept invites. It means, as soon as you got an invite from the sync, it will try to join it.
|
||||
*/
|
||||
val isEnabled: Boolean
|
||||
|
||||
/**
|
||||
* Hide invites from the UI (from notifications, notification count and room list). By default invites are hidden when [isEnabled] is true
|
||||
*/
|
||||
val hideInvites: Boolean
|
||||
get() = isEnabled
|
||||
}
|
||||
|
||||
fun AutoAcceptInvites.showInvites() = !hideInvites
|
||||
|
||||
/**
|
||||
* Simple compile time implementation of AutoAcceptInvites flags.
|
||||
*/
|
||||
class CompileTimeAutoAcceptInvites @Inject constructor() : AutoAcceptInvites {
|
||||
override val isEnabled = false
|
||||
override val hideInvites = isEnabled
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package im.vector.app.features.invite
|
||||
|
||||
import im.vector.app.ActiveSessionDataSource
|
||||
import im.vector.app.features.session.coroutineScope
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.disposables.Disposable
|
||||
|
@ -23,7 +24,10 @@ import kotlinx.coroutines.async
|
|||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.sync.Semaphore
|
||||
import kotlinx.coroutines.sync.withPermit
|
||||
import org.matrix.android.sdk.api.extensions.orFalse
|
||||
import org.matrix.android.sdk.api.failure.Failure
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.room.Room
|
||||
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
|
||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
|
||||
|
@ -39,16 +43,35 @@ import javax.inject.Singleton
|
|||
* This mechanism will be on only if AutoAcceptInvites.isEnabled is true.
|
||||
*/
|
||||
@Singleton
|
||||
class InvitesAcceptor @Inject constructor(private val autoAcceptInvites: AutoAcceptInvites) : Session.Listener {
|
||||
class InvitesAcceptor @Inject constructor(
|
||||
private val sessionDataSource: ActiveSessionDataSource,
|
||||
private val autoAcceptInvites: AutoAcceptInvites
|
||||
) : Session.Listener {
|
||||
|
||||
private val disposables = HashMap<String, Disposable>()
|
||||
private lateinit var activeSessionDisposable: Disposable
|
||||
private val shouldRejectRoomIds = mutableSetOf<String>()
|
||||
private val invitedRoomDisposables = HashMap<String, Disposable>()
|
||||
private val semaphore = Semaphore(1)
|
||||
|
||||
fun onSessionActive(session: Session) {
|
||||
fun initialize() {
|
||||
observeActiveSession()
|
||||
}
|
||||
|
||||
private fun observeActiveSession() {
|
||||
activeSessionDisposable = sessionDataSource.observe()
|
||||
.distinctUntilChanged()
|
||||
.subscribe {
|
||||
it.orNull()?.let { session ->
|
||||
onSessionActive(session)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun onSessionActive(session: Session) {
|
||||
if (!autoAcceptInvites.isEnabled) {
|
||||
return
|
||||
}
|
||||
if (disposables.containsKey(session.sessionId)) {
|
||||
if (invitedRoomDisposables.containsKey(session.sessionId)) {
|
||||
return
|
||||
}
|
||||
session.addListener(this)
|
||||
|
@ -74,11 +97,15 @@ class InvitesAcceptor @Inject constructor(private val autoAcceptInvites: AutoAcc
|
|||
}
|
||||
}
|
||||
.also {
|
||||
disposables[session.sessionId] = it
|
||||
invitedRoomDisposables[session.sessionId] = it
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun Session.joinRoomSafely(roomId: String) {
|
||||
if (shouldRejectRoomIds.contains(roomId)) {
|
||||
getRoom(roomId)?.rejectInviteSafely()
|
||||
return
|
||||
}
|
||||
val roomMembershipChanged = getChangeMemberships(roomId)
|
||||
if (roomMembershipChanged != ChangeMembershipState.Joined && !roomMembershipChanged.isInProgress()) {
|
||||
try {
|
||||
|
@ -86,12 +113,31 @@ class InvitesAcceptor @Inject constructor(private val autoAcceptInvites: AutoAcc
|
|||
joinRoom(roomId)
|
||||
} catch (failure: Throwable) {
|
||||
Timber.v("Failed auto join room: $roomId")
|
||||
// if we got 404 on invites, the inviting user have left or the hs is off.
|
||||
if (failure is Failure.ServerError && failure.httpCode == 404) {
|
||||
val room = getRoom(roomId) ?: return
|
||||
val inviterId = room.roomSummary()?.inviterId
|
||||
// if the inviting user is on the same HS, there can only be one cause: they left, so we try to reject the invite.
|
||||
if (inviterId?.endsWith(sessionParams.credentials.homeServer.orEmpty()).orFalse()) {
|
||||
shouldRejectRoomIds.add(roomId)
|
||||
room.rejectInviteSafely()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun Room.rejectInviteSafely() {
|
||||
try {
|
||||
leave(null)
|
||||
shouldRejectRoomIds.remove(roomId)
|
||||
} catch (failure: Throwable) {
|
||||
Timber.v("Fail rejecting invite for room: $roomId")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSessionStopped(session: Session) {
|
||||
session.removeListener(this)
|
||||
disposables.remove(session.sessionId)?.dispose()
|
||||
invitedRoomDisposables.remove(session.sessionId)?.dispose()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue