mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-16 02:05:06 +08:00
Remember ignored unknown sessions
This commit is contained in:
parent
7ef1970a0b
commit
42b47c25aa
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2019 New Vector Ltd
|
* Copyright 2019 New Vector Ltd
|
||||||
*
|
*
|
||||||
@ -61,7 +60,7 @@ class HomeDetailFragment @Inject constructor(
|
|||||||
private val unreadCounterBadgeViews = arrayListOf<UnreadCounterBadgeView>()
|
private val unreadCounterBadgeViews = arrayListOf<UnreadCounterBadgeView>()
|
||||||
|
|
||||||
private val viewModel: HomeDetailViewModel by fragmentViewModel()
|
private val viewModel: HomeDetailViewModel by fragmentViewModel()
|
||||||
private val unknownDeviceDetectorSharedViewModel : UnknownDeviceDetectorSharedViewModel by activityViewModel()
|
private val unknownDeviceDetectorSharedViewModel: UnknownDeviceDetectorSharedViewModel by activityViewModel()
|
||||||
|
|
||||||
private lateinit var sharedActionViewModel: HomeSharedActionViewModel
|
private lateinit var sharedActionViewModel: HomeSharedActionViewModel
|
||||||
|
|
||||||
@ -112,7 +111,11 @@ class HomeDetailFragment @Inject constructor(
|
|||||||
?.navigator
|
?.navigator
|
||||||
?.requestSessionVerification(requireContext(), newest.deviceId ?: "")
|
?.requestSessionVerification(requireContext(), newest.deviceId ?: "")
|
||||||
}
|
}
|
||||||
dismissedAction = Runnable {}
|
dismissedAction = Runnable {
|
||||||
|
unknownDeviceDetectorSharedViewModel.handle(
|
||||||
|
UnknownDeviceDetectorSharedViewModel.Action.IgnoreDevice(newest.deviceId ?: "")
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ package im.vector.riotx.features.home
|
|||||||
import com.airbnb.mvrx.Async
|
import com.airbnb.mvrx.Async
|
||||||
import com.airbnb.mvrx.MvRxState
|
import com.airbnb.mvrx.MvRxState
|
||||||
import com.airbnb.mvrx.MvRxViewModelFactory
|
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||||
|
import com.airbnb.mvrx.Success
|
||||||
import com.airbnb.mvrx.Uninitialized
|
import com.airbnb.mvrx.Uninitialized
|
||||||
import com.airbnb.mvrx.ViewModelContext
|
import com.airbnb.mvrx.ViewModelContext
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
@ -30,9 +31,11 @@ import im.vector.matrix.android.internal.crypto.model.rest.DevicesListResponse
|
|||||||
import im.vector.matrix.rx.rx
|
import im.vector.matrix.rx.rx
|
||||||
import im.vector.matrix.rx.singleBuilder
|
import im.vector.matrix.rx.singleBuilder
|
||||||
import im.vector.riotx.core.di.HasScreenInjector
|
import im.vector.riotx.core.di.HasScreenInjector
|
||||||
import im.vector.riotx.core.platform.EmptyAction
|
|
||||||
import im.vector.riotx.core.platform.EmptyViewEvents
|
import im.vector.riotx.core.platform.EmptyViewEvents
|
||||||
import im.vector.riotx.core.platform.VectorViewModel
|
import im.vector.riotx.core.platform.VectorViewModel
|
||||||
|
import im.vector.riotx.core.platform.VectorViewModelAction
|
||||||
|
import im.vector.riotx.features.settings.VectorPreferences
|
||||||
|
import timber.log.Timber
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
data class UnknownDevicesState(
|
data class UnknownDevicesState(
|
||||||
@ -40,16 +43,31 @@ data class UnknownDevicesState(
|
|||||||
val canCrossSign: Boolean = false
|
val canCrossSign: Boolean = false
|
||||||
) : MvRxState
|
) : MvRxState
|
||||||
|
|
||||||
class UnknownDeviceDetectorSharedViewModel(session: Session, initialState: UnknownDevicesState)
|
class UnknownDeviceDetectorSharedViewModel(
|
||||||
: VectorViewModel<UnknownDevicesState, EmptyAction, EmptyViewEvents>(initialState) {
|
session: Session,
|
||||||
|
private val vectorPreferences: VectorPreferences,
|
||||||
|
initialState: UnknownDevicesState)
|
||||||
|
: VectorViewModel<UnknownDevicesState, UnknownDeviceDetectorSharedViewModel.Action, EmptyViewEvents>(initialState) {
|
||||||
|
|
||||||
|
sealed class Action : VectorViewModelAction {
|
||||||
|
data class IgnoreDevice(val deviceId: String) : Action()
|
||||||
|
}
|
||||||
|
|
||||||
|
val ignoredDeviceList = ArrayList<String>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|
||||||
|
ignoredDeviceList.addAll(
|
||||||
|
vectorPreferences.getUnknownDeviceDismissedList().also {
|
||||||
|
Timber.v("## Detector - Remembered ignored list $it")
|
||||||
|
}
|
||||||
|
)
|
||||||
session.rx().liveUserCryptoDevices(session.myUserId)
|
session.rx().liveUserCryptoDevices(session.myUserId)
|
||||||
.debounce(600, TimeUnit.MILLISECONDS)
|
.debounce(600, TimeUnit.MILLISECONDS)
|
||||||
.distinct()
|
.distinct()
|
||||||
.switchMap { deviceList ->
|
.switchMap { deviceList ->
|
||||||
// Timber.v("## Detector - ============================")
|
Timber.v("## Detector - ============================")
|
||||||
// Timber.v("## Detector - Crypto device update ${deviceList.map { "${it.deviceId} : ${it.isVerified}" }}")
|
Timber.v("## Detector - Crypto device update ${deviceList.map { "${it.deviceId} : ${it.isVerified}" }}")
|
||||||
singleBuilder<DevicesListResponse> {
|
singleBuilder<DevicesListResponse> {
|
||||||
session.cryptoService().getDevicesList(it)
|
session.cryptoService().getDevicesList(it)
|
||||||
NoOpCancellable
|
NoOpCancellable
|
||||||
@ -59,10 +77,13 @@ class UnknownDeviceDetectorSharedViewModel(session: Session, initialState: Unkno
|
|||||||
deviceList.firstOrNull { info.deviceId == it.deviceId }?.let {
|
deviceList.firstOrNull { info.deviceId == it.deviceId }?.let {
|
||||||
!it.isVerified
|
!it.isVerified
|
||||||
} ?: false
|
} ?: false
|
||||||
}?.sortedByDescending { it.lastSeenTs }
|
}
|
||||||
|
?.sortedByDescending { it.lastSeenTs }
|
||||||
?.map {
|
?.map {
|
||||||
session.getUser(it.user_id ?: "")?.toMatrixItem() to it
|
session.getUser(it.user_id ?: "")?.toMatrixItem() to it
|
||||||
} ?: emptyList()
|
}
|
||||||
|
?.filter { !ignoredDeviceList.contains(it.second.deviceId) }
|
||||||
|
?: emptyList()
|
||||||
}
|
}
|
||||||
.toObservable()
|
.toObservable()
|
||||||
}
|
}
|
||||||
@ -76,12 +97,28 @@ class UnknownDeviceDetectorSharedViewModel(session: Session, initialState: Unkno
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handle(action: EmptyAction) {}
|
override fun handle(action: Action) {
|
||||||
|
when (action) {
|
||||||
|
is Action.IgnoreDevice -> {
|
||||||
|
// local echo
|
||||||
|
withState { state ->
|
||||||
|
state.unknownSessions.invoke()?.let {
|
||||||
|
val updated = it.filter { it.second.deviceId != action.deviceId }
|
||||||
|
setState {
|
||||||
|
copy(unknownSessions = Success(updated))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ignoredDeviceList.add(action.deviceId)
|
||||||
|
vectorPreferences.storeUnknownDeviceDismissedList(ignoredDeviceList)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object : MvRxViewModelFactory<UnknownDeviceDetectorSharedViewModel, UnknownDevicesState> {
|
companion object : MvRxViewModelFactory<UnknownDeviceDetectorSharedViewModel, UnknownDevicesState> {
|
||||||
override fun create(viewModelContext: ViewModelContext, state: UnknownDevicesState): UnknownDeviceDetectorSharedViewModel? {
|
override fun create(viewModelContext: ViewModelContext, state: UnknownDevicesState): UnknownDeviceDetectorSharedViewModel? {
|
||||||
val session = (viewModelContext.activity as HasScreenInjector).injector().activeSessionHolder().getActiveSession()
|
val session = (viewModelContext.activity as HasScreenInjector).injector().activeSessionHolder().getActiveSession()
|
||||||
return UnknownDeviceDetectorSharedViewModel(session, state)
|
return UnknownDeviceDetectorSharedViewModel(session, VectorPreferences(viewModelContext.activity()), state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import android.provider.MediaStore
|
|||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import com.squareup.seismic.ShakeDetector
|
import com.squareup.seismic.ShakeDetector
|
||||||
|
import im.vector.matrix.android.api.extensions.tryThis
|
||||||
import im.vector.riotx.BuildConfig
|
import im.vector.riotx.BuildConfig
|
||||||
import im.vector.riotx.R
|
import im.vector.riotx.R
|
||||||
import im.vector.riotx.features.homeserver.ServerUrlsRepository
|
import im.vector.riotx.features.homeserver.ServerUrlsRepository
|
||||||
@ -166,6 +167,8 @@ class VectorPreferences @Inject constructor(private val context: Context) {
|
|||||||
private const val MEDIA_SAVING_1_MONTH = 2
|
private const val MEDIA_SAVING_1_MONTH = 2
|
||||||
private const val MEDIA_SAVING_FOREVER = 3
|
private const val MEDIA_SAVING_FOREVER = 3
|
||||||
|
|
||||||
|
private const val SETTINGS_UNKNOWN_DEVICE_DISMISSED_LIST = "SETTINGS_UNKNWON_DEVICE_DISMISSED_LIST"
|
||||||
|
|
||||||
// some preferences keys must be kept after a logout
|
// some preferences keys must be kept after a logout
|
||||||
private val mKeysToKeepAfterLogout = listOf(
|
private val mKeysToKeepAfterLogout = listOf(
|
||||||
SETTINGS_DEFAULT_MEDIA_COMPRESSION_KEY,
|
SETTINGS_DEFAULT_MEDIA_COMPRESSION_KEY,
|
||||||
@ -364,6 +367,18 @@ class VectorPreferences @Inject constructor(private val context: Context) {
|
|||||||
return defaultPrefs.getBoolean(SETTINGS_PLAY_SHUTTER_SOUND_KEY, true)
|
return defaultPrefs.getBoolean(SETTINGS_PLAY_SHUTTER_SOUND_KEY, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun storeUnknownDeviceDismissedList(deviceIds: List<String>) {
|
||||||
|
defaultPrefs.edit(true) {
|
||||||
|
putStringSet(SETTINGS_UNKNOWN_DEVICE_DISMISSED_LIST, deviceIds.toSet())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getUnknownDeviceDismissedList(): List<String> {
|
||||||
|
return tryThis {
|
||||||
|
defaultPrefs.getStringSet(SETTINGS_UNKNOWN_DEVICE_DISMISSED_LIST, null)?.toList()
|
||||||
|
} ?: emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the notification ringtone
|
* Update the notification ringtone
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user