Skip to content

Commit fcb162e

Browse files
authored
Merge pull request #2402 from switchifyapp/fix/pc-unpair-ui-refresh-2401
Fix PC connection screen not refreshing after unpair
2 parents 93d9e1c + bd69e2c commit fcb162e

2 files changed

Lines changed: 48 additions & 1 deletion

File tree

app/src/main/java/com/enaboapps/switchify/pc/PcConnectionViewModel.kt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ class PcConnectionViewModel(
7676

7777
private val rowStatuses = MutableStateFlow<Map<String, PcRowStatus>>(emptyMap())
7878

79+
// Bumped on every token store mutation so the combine pipeline re-reads
80+
// token-derived state (saved pairings, row actions); the store itself is not observable.
81+
private val tokenRevision = MutableStateFlow(0)
82+
7983
private data class DiscoveryInputs(
8084
val pcs: List<DiscoveredPc>,
8185
val status: PcDiscoveryStatus,
@@ -85,7 +89,7 @@ class PcConnectionViewModel(
8589

8690
init {
8791
viewModelScope.launch {
88-
combine(discoveryService.pcs, discoveryService.status, rowStatuses, PcConnectionStateHolder.connectionState) { pcs, status, statuses, connection ->
92+
combine(discoveryService.pcs, discoveryService.status, rowStatuses, PcConnectionStateHolder.connectionState, tokenRevision) { pcs, status, statuses, connection, _ ->
8993
DiscoveryInputs(pcs, status, statuses, connection)
9094
}.collect { inputs ->
9195
val connectedDesktopId = (inputs.connection as? PcConnectionState.Connected)?.session?.desktopId
@@ -145,6 +149,7 @@ class PcConnectionViewModel(
145149
when (val ping = connector.authenticatedPing(pc, pairing.token)) {
146150
is PcPingResult.Connected -> {
147151
tokenStore.saveToken(pc.desktopId, pairing.token, ping.websocketUrl, pc.displayName)
152+
tokenRevision.update { it + 1 }
148153
PcConnectionStateHolder.setConnected(
149154
PcAuthenticatedSession(pc.desktopId, identityRepository.getDeviceId(), ping.websocketUrl),
150155
pc.displayName
@@ -153,6 +158,7 @@ class PcConnectionViewModel(
153158
}
154159
is PcPingResult.AuthFailed -> {
155160
tokenStore.clearToken(pc.desktopId)
161+
tokenRevision.update { it + 1 }
156162
PcConnectionStateHolder.setDisconnected()
157163
setIdle(pc.desktopId, PcRowStatus.Failed, ping.message)
158164
}
@@ -175,6 +181,7 @@ class PcConnectionViewModel(
175181
when (val result = connector.authenticatedPing(pc, token)) {
176182
is PcPingResult.Connected -> {
177183
tokenStore.saveToken(pc.desktopId, token, result.websocketUrl, pc.displayName)
184+
tokenRevision.update { it + 1 }
178185
PcConnectionStateHolder.setConnected(
179186
PcAuthenticatedSession(pc.desktopId, identityRepository.getDeviceId(), result.websocketUrl),
180187
pc.displayName
@@ -183,6 +190,7 @@ class PcConnectionViewModel(
183190
}
184191
is PcPingResult.AuthFailed -> {
185192
tokenStore.clearToken(pc.desktopId)
193+
tokenRevision.update { it + 1 }
186194
PcConnectionStateHolder.setDisconnected()
187195
setIdle(pc.desktopId, PcRowStatus.Failed, result.message)
188196
}
@@ -208,6 +216,7 @@ class PcConnectionViewModel(
208216
fun confirmUnpair() {
209217
val unpair = _uiState.value.pendingUnpair ?: return
210218
tokenStore.clearToken(unpair.desktopId)
219+
tokenRevision.update { it + 1 }
211220
val connected = PcConnectionStateHolder.connectionState.value as? PcConnectionState.Connected
212221
if (connected?.session?.desktopId == unpair.desktopId) {
213222
PcConnectionStateHolder.setDisconnected()

app/src/test/java/com/enaboapps/switchify/pc/PcConnectionViewModelTest.kt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,44 @@ class PcConnectionViewModelTest {
241241
assertEquals(false, viewModel.uiState.value.permissionRequired)
242242
}
243243

244+
@Test
245+
fun confirmUnpairRemovesSavedPairingRow() = runTest(dispatcher) {
246+
val discovery = FakeDiscovery(emptyList())
247+
val tokens = FakeTokenStore(
248+
initialTokens = mutableMapOf("desktop-1" to "token"),
249+
initialLastUrls = mutableMapOf("desktop-1" to "ws://192.168.1.20:7347"),
250+
initialServiceNames = mutableMapOf("desktop-1" to "Switchify PC")
251+
)
252+
val viewModel = viewModel(discovery, tokens, FakeConnector())
253+
advanceUntilIdle()
254+
255+
assertEquals(1, viewModel.uiState.value.savedPairings.size)
256+
257+
viewModel.requestUnpair("desktop-1", "Switchify PC")
258+
viewModel.confirmUnpair()
259+
advanceUntilIdle()
260+
261+
assertEquals(emptyList<PcSavedPairingRowState>(), viewModel.uiState.value.savedPairings)
262+
}
263+
264+
@Test
265+
fun confirmUnpairRefreshesDiscoveredRow() = runTest(dispatcher) {
266+
val discovery = FakeDiscovery(listOf(pc))
267+
val tokens = FakeTokenStore(initialTokens = mutableMapOf("desktop-1" to "token"))
268+
val viewModel = viewModel(discovery, tokens, FakeConnector())
269+
advanceUntilIdle()
270+
271+
assertEquals(true, viewModel.uiState.value.discoveredPcs.first().canUnpair)
272+
assertEquals("Connect", viewModel.uiState.value.discoveredPcs.first().actionText)
273+
274+
viewModel.requestUnpair("desktop-1", "Switchify PC")
275+
viewModel.confirmUnpair()
276+
advanceUntilIdle()
277+
278+
assertEquals(false, viewModel.uiState.value.discoveredPcs.first().canUnpair)
279+
assertEquals("Request access", viewModel.uiState.value.discoveredPcs.first().actionText)
280+
}
281+
244282
@Test
245283
fun dismissUnpairKeepsToken() = runTest(dispatcher) {
246284
val discovery = FakeDiscovery(listOf(pc))

0 commit comments

Comments
 (0)