summaryrefslogtreecommitdiffhomepage
path: root/android
diff options
context:
space:
mode:
Diffstat (limited to 'android')
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceListViewModel.kt59
1 files changed, 39 insertions, 20 deletions
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceListViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceListViewModel.kt
index 0057457c5e..4a60508a38 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceListViewModel.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DeviceListViewModel.kt
@@ -33,6 +33,7 @@ class DeviceListViewModel(
private val dispatcher: CoroutineDispatcher = Dispatchers.Default
) : ViewModel() {
private val _stagedDeviceId = MutableStateFlow<DeviceId?>(null)
+ private val _loadingDevices = MutableStateFlow<List<DeviceId>>(emptyList())
private val _toastMessages = MutableSharedFlow<String>(extraBufferCapacity = 1)
val toastMessages = _toastMessages.asSharedFlow()
@@ -40,27 +41,29 @@ class DeviceListViewModel(
var accountToken: String? = null
private var cachedDeviceList: List<Device>? = null
- val uiState = deviceRepository.deviceList
- .combine(_stagedDeviceId) { deviceList, stagedDeviceId ->
- val devices = if (deviceList is DeviceList.Available) {
- deviceList.devices.also { cachedDeviceList = it }
- } else {
- cachedDeviceList
- }
- val deviceUiItems = devices?.map { device ->
- DeviceListItemUiState(device, false)
- } ?: emptyList()
- val isLoading = devices == null
- val stagedDevice = devices?.firstOrNull { device ->
- device.id == stagedDeviceId
- }
- DeviceListUiState(
- deviceUiItems = deviceUiItems,
- isLoading = isLoading,
- stagedDevice = stagedDevice
- )
+ val uiState = combine(
+ deviceRepository.deviceList,
+ _stagedDeviceId,
+ _loadingDevices
+ ) { deviceList, stagedDeviceId, loadingDevices ->
+ val devices = if (deviceList is DeviceList.Available) {
+ deviceList.devices.also { cachedDeviceList = it }
+ } else {
+ cachedDeviceList
}
- .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), DeviceListUiState.INITIAL)
+ val deviceUiItems = devices?.map { device ->
+ DeviceListItemUiState(device, loadingDevices.any { device.id == it })
+ } ?: emptyList()
+ val isLoading = devices == null
+ val stagedDevice = devices?.firstOrNull { device ->
+ device.id == stagedDeviceId
+ }
+ DeviceListUiState(
+ deviceUiItems = deviceUiItems,
+ isLoading = isLoading,
+ stagedDevice = stagedDevice
+ )
+ }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), DeviceListUiState.INITIAL)
fun stageDeviceForRemoval(deviceId: DeviceId) {
_stagedDeviceId.value = deviceId
@@ -81,6 +84,7 @@ class DeviceListViewModel(
deviceRepository.deviceRemovalEvent
.onSubscription {
clearStagedDevice()
+ setLoadingDevice(stagedDeviceId)
deviceRepository.removeDevice(token, stagedDeviceId)
}
.filter { (deviceId, result) ->
@@ -89,6 +93,8 @@ class DeviceListViewModel(
.first()
}
+ clearLoadingDevice(stagedDeviceId)
+
if (result == null) {
_toastMessages.tryEmit(
resources.getString(R.string.failed_to_remove_device)
@@ -99,6 +105,7 @@ class DeviceListViewModel(
}
} else {
_toastMessages.tryEmit(resources.getString(R.string.error_occurred))
+ clearLoadingDevices()
clearStagedDevice()
refreshDeviceList()
}
@@ -110,6 +117,18 @@ class DeviceListViewModel(
deviceRepository.refreshDeviceList(token)
}
+ private fun setLoadingDevice(deviceId: DeviceId) {
+ _loadingDevices.value = _loadingDevices.value.toMutableList().apply { add(deviceId) }
+ }
+
+ private fun clearLoadingDevice(deviceId: DeviceId) {
+ _loadingDevices.value = _loadingDevices.value.toMutableList().apply { remove(deviceId) }
+ }
+
+ private fun clearLoadingDevices() {
+ _loadingDevices.value = emptyList()
+ }
+
companion object {
private const val DEVICE_REMOVAL_TIMEOUT_MILLIS = 5000L
}