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 arrow.core.Option
|
||||||
import im.vector.app.core.di.ActiveSessionHolder
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
import im.vector.app.core.utils.BehaviorDataSource
|
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.session.coroutineScope
|
||||||
import im.vector.app.features.ui.UiStateRepository
|
import im.vector.app.features.ui.UiStateRepository
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
|
@ -52,8 +51,7 @@ fun RoomGroupingMethod.group() = (this as? RoomGroupingMethod.ByLegacyGroup)?.gr
|
||||||
class AppStateHandler @Inject constructor(
|
class AppStateHandler @Inject constructor(
|
||||||
private val sessionDataSource: ActiveSessionDataSource,
|
private val sessionDataSource: ActiveSessionDataSource,
|
||||||
private val uiStateRepository: UiStateRepository,
|
private val uiStateRepository: UiStateRepository,
|
||||||
private val activeSessionHolder: ActiveSessionHolder,
|
private val activeSessionHolder: ActiveSessionHolder
|
||||||
private val invitesAcceptor: InvitesAcceptor
|
|
||||||
) : LifecycleObserver {
|
) : LifecycleObserver {
|
||||||
|
|
||||||
private val compositeDisposable = CompositeDisposable()
|
private val compositeDisposable = CompositeDisposable()
|
||||||
|
@ -63,10 +61,6 @@ class AppStateHandler @Inject constructor(
|
||||||
|
|
||||||
fun getCurrentRoomGroupingMethod(): RoomGroupingMethod? = selectedSpaceDataSource.currentValue?.orNull()
|
fun getCurrentRoomGroupingMethod(): RoomGroupingMethod? = selectedSpaceDataSource.currentValue?.orNull()
|
||||||
|
|
||||||
init {
|
|
||||||
observeActiveSession()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setCurrentSpace(spaceId: String?, session: Session? = null) {
|
fun setCurrentSpace(spaceId: String?, session: Session? = null) {
|
||||||
val uSession = session ?: activeSessionHolder.getSafeActiveSession() ?: return
|
val uSession = session ?: activeSessionHolder.getSafeActiveSession() ?: return
|
||||||
if (selectedSpaceDataSource.currentValue?.orNull() is RoomGroupingMethod.BySpace
|
if (selectedSpaceDataSource.currentValue?.orNull() is RoomGroupingMethod.BySpace
|
||||||
|
@ -103,7 +97,6 @@ class AppStateHandler @Inject constructor(
|
||||||
.subscribe {
|
.subscribe {
|
||||||
// sessionDataSource could already return a session while activeSession holder still returns null
|
// sessionDataSource could already return a session while activeSession holder still returns null
|
||||||
it.orNull()?.let { session ->
|
it.orNull()?.let { session ->
|
||||||
invitesAcceptor.onSessionActive(session)
|
|
||||||
if (uiStateRepository.isGroupingMethodSpace(session.sessionId)) {
|
if (uiStateRepository.isGroupingMethodSpace(session.sessionId)) {
|
||||||
setCurrentSpace(uiStateRepository.getSelectedSpace(session.sessionId), session)
|
setCurrentSpace(uiStateRepository.getSelectedSpace(session.sessionId), session)
|
||||||
} else {
|
} else {
|
||||||
|
@ -123,8 +116,14 @@ class AppStateHandler @Inject constructor(
|
||||||
return (selectedSpaceDataSource.currentValue?.orNull() as? RoomGroupingMethod.ByLegacyGroup)?.groupSummary?.groupId
|
return (selectedSpaceDataSource.currentValue?.orNull() as? RoomGroupingMethod.ByLegacyGroup)?.groupSummary?.groupId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
|
||||||
|
fun entersForeground() {
|
||||||
|
observeActiveSession()
|
||||||
|
}
|
||||||
|
|
||||||
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
|
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
|
||||||
fun entersBackground() {
|
fun entersBackground() {
|
||||||
|
compositeDisposable.clear()
|
||||||
val session = activeSessionHolder.getSafeActiveSession() ?: return
|
val session = activeSessionHolder.getSafeActiveSession() ?: return
|
||||||
when (val currentMethod = selectedSpaceDataSource.currentValue?.orNull() ?: RoomGroupingMethod.BySpace(null)) {
|
when (val currentMethod = selectedSpaceDataSource.currentValue?.orNull() ?: RoomGroupingMethod.BySpace(null)) {
|
||||||
is RoomGroupingMethod.BySpace -> {
|
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.call.webrtc.WebRtcCallManager
|
||||||
import im.vector.app.features.configuration.VectorConfiguration
|
import im.vector.app.features.configuration.VectorConfiguration
|
||||||
import im.vector.app.features.disclaimer.doNotShowDisclaimerDialog
|
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.lifecycle.VectorActivityLifecycleCallbacks
|
||||||
import im.vector.app.features.notifications.NotificationDrawerManager
|
import im.vector.app.features.notifications.NotificationDrawerManager
|
||||||
import im.vector.app.features.notifications.NotificationUtils
|
import im.vector.app.features.notifications.NotificationUtils
|
||||||
|
@ -95,6 +96,7 @@ class VectorApplication :
|
||||||
@Inject lateinit var popupAlertManager: PopupAlertManager
|
@Inject lateinit var popupAlertManager: PopupAlertManager
|
||||||
@Inject lateinit var pinLocker: PinLocker
|
@Inject lateinit var pinLocker: PinLocker
|
||||||
@Inject lateinit var callManager: WebRtcCallManager
|
@Inject lateinit var callManager: WebRtcCallManager
|
||||||
|
@Inject lateinit var invitesAcceptor: InvitesAcceptor
|
||||||
|
|
||||||
lateinit var vectorComponent: VectorComponent
|
lateinit var vectorComponent: VectorComponent
|
||||||
|
|
||||||
|
@ -116,6 +118,7 @@ class VectorApplication :
|
||||||
appContext = this
|
appContext = this
|
||||||
vectorComponent = DaggerVectorComponent.factory().create(this)
|
vectorComponent = DaggerVectorComponent.factory().create(this)
|
||||||
vectorComponent.inject(this)
|
vectorComponent.inject(this)
|
||||||
|
invitesAcceptor.initialize()
|
||||||
vectorUncaughtExceptionHandler.activate(this)
|
vectorUncaughtExceptionHandler.activate(this)
|
||||||
rxConfig.setupRxPlugin()
|
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.call.webrtc.WebRtcCallManager
|
||||||
import im.vector.app.features.createdirect.DirectRoomHelper
|
import im.vector.app.features.createdirect.DirectRoomHelper
|
||||||
import im.vector.app.features.invite.AutoAcceptInvites
|
import im.vector.app.features.invite.AutoAcceptInvites
|
||||||
|
import im.vector.app.features.invite.showInvites
|
||||||
import im.vector.app.features.ui.UiStateRepository
|
import im.vector.app.features.ui.UiStateRepository
|
||||||
import io.reactivex.schedulers.Schedulers
|
import io.reactivex.schedulers.Schedulers
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
@ -208,7 +209,7 @@ private val autoAcceptInvites: AutoAcceptInvites)
|
||||||
val activeSpaceRoomId = groupingMethod.spaceSummary?.roomId
|
val activeSpaceRoomId = groupingMethod.spaceSummary?.roomId
|
||||||
var dmInvites = 0
|
var dmInvites = 0
|
||||||
var roomsInvite = 0
|
var roomsInvite = 0
|
||||||
if (!autoAcceptInvites.hideInvites) {
|
if (autoAcceptInvites.showInvites()) {
|
||||||
dmInvites = session.getRoomSummaries(
|
dmInvites = session.getRoomSummaries(
|
||||||
roomSummaryQueryParams {
|
roomSummaryQueryParams {
|
||||||
memberships = listOf(Membership.INVITE)
|
memberships = listOf(Membership.INVITE)
|
||||||
|
|
|
@ -23,6 +23,7 @@ import im.vector.app.RoomGroupingMethod
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
import im.vector.app.features.home.RoomListDisplayMode
|
import im.vector.app.features.home.RoomListDisplayMode
|
||||||
import im.vector.app.features.invite.AutoAcceptInvites
|
import im.vector.app.features.invite.AutoAcceptInvites
|
||||||
|
import im.vector.app.features.invite.showInvites
|
||||||
import io.reactivex.disposables.Disposable
|
import io.reactivex.disposables.Disposable
|
||||||
import io.reactivex.schedulers.Schedulers
|
import io.reactivex.schedulers.Schedulers
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
@ -75,7 +76,7 @@ class GroupRoomListSectionBuilder(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
RoomListDisplayMode.NOTIFICATIONS -> {
|
RoomListDisplayMode.NOTIFICATIONS -> {
|
||||||
if (!autoAcceptInvites.hideInvites) {
|
if (autoAcceptInvites.showInvites()) {
|
||||||
addSection(
|
addSection(
|
||||||
sections,
|
sections,
|
||||||
activeGroupAwareQueries,
|
activeGroupAwareQueries,
|
||||||
|
@ -118,7 +119,7 @@ class GroupRoomListSectionBuilder(
|
||||||
private fun buildRoomsSections(sections: MutableList<RoomsSection>,
|
private fun buildRoomsSections(sections: MutableList<RoomsSection>,
|
||||||
activeSpaceAwareQueries: MutableList<UpdatableLivePageResult>,
|
activeSpaceAwareQueries: MutableList<UpdatableLivePageResult>,
|
||||||
actualGroupId: String?) {
|
actualGroupId: String?) {
|
||||||
if (!autoAcceptInvites.hideInvites) {
|
if (autoAcceptInvites.showInvites()) {
|
||||||
addSection(
|
addSection(
|
||||||
sections,
|
sections,
|
||||||
activeSpaceAwareQueries,
|
activeSpaceAwareQueries,
|
||||||
|
@ -185,7 +186,7 @@ class GroupRoomListSectionBuilder(
|
||||||
activeSpaceAwareQueries: MutableList<UpdatableLivePageResult>,
|
activeSpaceAwareQueries: MutableList<UpdatableLivePageResult>,
|
||||||
actualGroupId: String?
|
actualGroupId: String?
|
||||||
) {
|
) {
|
||||||
if (!autoAcceptInvites.hideInvites) {
|
if (autoAcceptInvites.showInvites()) {
|
||||||
addSection(sections,
|
addSection(sections,
|
||||||
activeSpaceAwareQueries,
|
activeSpaceAwareQueries,
|
||||||
R.string.invitations_header,
|
R.string.invitations_header,
|
||||||
|
|
|
@ -27,6 +27,7 @@ import im.vector.app.R
|
||||||
import im.vector.app.core.resources.StringProvider
|
import im.vector.app.core.resources.StringProvider
|
||||||
import im.vector.app.features.home.RoomListDisplayMode
|
import im.vector.app.features.home.RoomListDisplayMode
|
||||||
import im.vector.app.features.invite.AutoAcceptInvites
|
import im.vector.app.features.invite.AutoAcceptInvites
|
||||||
|
import im.vector.app.features.invite.showInvites
|
||||||
import im.vector.app.space
|
import im.vector.app.space
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
import io.reactivex.disposables.Disposable
|
import io.reactivex.disposables.Disposable
|
||||||
|
@ -90,7 +91,7 @@ class SpaceRoomListSectionBuilder(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
RoomListDisplayMode.NOTIFICATIONS -> {
|
RoomListDisplayMode.NOTIFICATIONS -> {
|
||||||
if (!autoAcceptInvites.hideInvites) {
|
if (autoAcceptInvites.showInvites()) {
|
||||||
addSection(
|
addSection(
|
||||||
sections = sections,
|
sections = sections,
|
||||||
activeSpaceUpdaters = activeSpaceAwareQueries,
|
activeSpaceUpdaters = activeSpaceAwareQueries,
|
||||||
|
@ -140,7 +141,7 @@ class SpaceRoomListSectionBuilder(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildRoomsSections(sections: MutableList<RoomsSection>, activeSpaceAwareQueries: MutableList<RoomListViewModel.ActiveSpaceQueryUpdater>) {
|
private fun buildRoomsSections(sections: MutableList<RoomsSection>, activeSpaceAwareQueries: MutableList<RoomListViewModel.ActiveSpaceQueryUpdater>) {
|
||||||
if (!autoAcceptInvites.hideInvites) {
|
if (autoAcceptInvites.showInvites()) {
|
||||||
addSection(
|
addSection(
|
||||||
sections = sections,
|
sections = sections,
|
||||||
activeSpaceUpdaters = activeSpaceAwareQueries,
|
activeSpaceUpdaters = activeSpaceAwareQueries,
|
||||||
|
@ -259,7 +260,7 @@ class SpaceRoomListSectionBuilder(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildDmSections(sections: MutableList<RoomsSection>, activeSpaceAwareQueries: MutableList<RoomListViewModel.ActiveSpaceQueryUpdater>) {
|
private fun buildDmSections(sections: MutableList<RoomsSection>, activeSpaceAwareQueries: MutableList<RoomListViewModel.ActiveSpaceQueryUpdater>) {
|
||||||
if (!autoAcceptInvites.hideInvites) {
|
if (autoAcceptInvites.showInvites()) {
|
||||||
addSection(sections = sections,
|
addSection(sections = sections,
|
||||||
activeSpaceUpdaters = activeSpaceAwareQueries,
|
activeSpaceUpdaters = activeSpaceAwareQueries,
|
||||||
nameRes = R.string.invitations_header,
|
nameRes = R.string.invitations_header,
|
||||||
|
|
|
@ -18,12 +18,28 @@ package im.vector.app.features.invite
|
||||||
|
|
||||||
import javax.inject.Inject
|
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 {
|
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
|
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
|
val hideInvites: Boolean
|
||||||
|
get() = isEnabled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun AutoAcceptInvites.showInvites() = !hideInvites
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple compile time implementation of AutoAcceptInvites flags.
|
||||||
|
*/
|
||||||
class CompileTimeAutoAcceptInvites @Inject constructor() : AutoAcceptInvites {
|
class CompileTimeAutoAcceptInvites @Inject constructor() : AutoAcceptInvites {
|
||||||
override val isEnabled = false
|
override val isEnabled = false
|
||||||
override val hideInvites = isEnabled
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package im.vector.app.features.invite
|
package im.vector.app.features.invite
|
||||||
|
|
||||||
|
import im.vector.app.ActiveSessionDataSource
|
||||||
import im.vector.app.features.session.coroutineScope
|
import im.vector.app.features.session.coroutineScope
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
import io.reactivex.disposables.Disposable
|
import io.reactivex.disposables.Disposable
|
||||||
|
@ -23,7 +24,10 @@ import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.sync.Semaphore
|
import kotlinx.coroutines.sync.Semaphore
|
||||||
import kotlinx.coroutines.sync.withPermit
|
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.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.members.ChangeMembershipState
|
||||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||||
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
|
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.
|
* This mechanism will be on only if AutoAcceptInvites.isEnabled is true.
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@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)
|
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) {
|
if (!autoAcceptInvites.isEnabled) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (disposables.containsKey(session.sessionId)) {
|
if (invitedRoomDisposables.containsKey(session.sessionId)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
session.addListener(this)
|
session.addListener(this)
|
||||||
|
@ -74,11 +97,15 @@ class InvitesAcceptor @Inject constructor(private val autoAcceptInvites: AutoAcc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.also {
|
.also {
|
||||||
disposables[session.sessionId] = it
|
invitedRoomDisposables[session.sessionId] = it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun Session.joinRoomSafely(roomId: String) {
|
private suspend fun Session.joinRoomSafely(roomId: String) {
|
||||||
|
if (shouldRejectRoomIds.contains(roomId)) {
|
||||||
|
getRoom(roomId)?.rejectInviteSafely()
|
||||||
|
return
|
||||||
|
}
|
||||||
val roomMembershipChanged = getChangeMemberships(roomId)
|
val roomMembershipChanged = getChangeMemberships(roomId)
|
||||||
if (roomMembershipChanged != ChangeMembershipState.Joined && !roomMembershipChanged.isInProgress()) {
|
if (roomMembershipChanged != ChangeMembershipState.Joined && !roomMembershipChanged.isInProgress()) {
|
||||||
try {
|
try {
|
||||||
|
@ -86,12 +113,31 @@ class InvitesAcceptor @Inject constructor(private val autoAcceptInvites: AutoAcc
|
||||||
joinRoom(roomId)
|
joinRoom(roomId)
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
Timber.v("Failed auto join room: $roomId")
|
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) {
|
override fun onSessionStopped(session: Session) {
|
||||||
session.removeListener(this)
|
session.removeListener(this)
|
||||||
disposables.remove(session.sessionId)?.dispose()
|
invitedRoomDisposables.remove(session.sessionId)?.dispose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue