Skip to content

Commit 2a9253f

Browse files
Redesign Connect to PC screen (#2590)
- Reorder the Connect to PC screen around a status-first layout - Add clearer nearby and paired PC rows with status chips and separated primary actions - Preserve existing connect, request access, default PC, and unpair behavior - Add overview-state and discovery-status tests for the redesigned screen 🤖 Auto-generated Co-authored-by: Owen McGirr <o.a.mcgirr@gmail.com>
1 parent e49eeb4 commit 2a9253f

5 files changed

Lines changed: 760 additions & 151 deletions

File tree

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

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ data class PcApprovalCodeState(
2424

2525
data class PcConnectionUiState(
2626
val permissionRequired: Boolean = false,
27+
val discoveryStatus: PcDiscoveryStatus = PcDiscoveryStatus.Empty,
2728
val discoveryStatusText: String = "Searching for Switchify PC...",
29+
val pcRows: List<PcConnectionRowState> = emptyList(),
2830
val discoveredPcs: List<PcRowState> = emptyList(),
2931
val savedPairings: List<PcSavedPairingRowState> = emptyList(),
3032
val connectedDesktopId: String? = null,
@@ -57,6 +59,27 @@ data class PcSavedPairingRowState(
5759
val isDefault: Boolean = false
5860
)
5961

62+
data class PcConnectionRowState(
63+
val desktopId: String,
64+
val title: String,
65+
val summary: String,
66+
val source: PcConnectionRowSource,
67+
val status: PcRowStatus,
68+
val actionText: String?,
69+
val enabled: Boolean,
70+
val canRequestAccess: Boolean,
71+
val canConnect: Boolean,
72+
val canUnpair: Boolean,
73+
val canSetDefault: Boolean,
74+
val isDefault: Boolean,
75+
val discoveredPc: DiscoveredPc?
76+
)
77+
78+
enum class PcConnectionRowSource {
79+
Discovered,
80+
SavedOnly
81+
}
82+
6083
data class PcUnpairConfirmationState(
6184
val desktopId: String,
6285
val displayName: String
@@ -112,9 +135,20 @@ class PcConnectionViewModel(
112135
val defaultDesktopId = withContext(backgroundDispatcher) {
113136
tokenStore.getDefaultDesktopId()
114137
}
138+
val pcRows = buildPcRows(
139+
pcs = inputs.pcs,
140+
statuses = inputs.statuses,
141+
connectedDesktopId = connectedDesktopId,
142+
hasTokenByDesktopId = hasTokenByDesktopId,
143+
savedPairings = savedPairings,
144+
defaultDesktopId = defaultDesktopId,
145+
isBusy = _uiState.value.isBusy
146+
)
115147
_uiState.update { current ->
116148
current.copy(
149+
discoveryStatus = inputs.status,
117150
discoveryStatusText = discoveryStatusText(inputs.status, inputs.pcs.isEmpty()),
151+
pcRows = pcRows,
118152
discoveredPcs = inputs.pcs.map { pc ->
119153
rowState(
120154
pc = pc,
@@ -300,6 +334,91 @@ class PcConnectionViewModel(
300334
}
301335
}
302336

337+
private fun buildPcRows(
338+
pcs: List<DiscoveredPc>,
339+
statuses: Map<String, PcRowStatus>,
340+
connectedDesktopId: String?,
341+
hasTokenByDesktopId: Map<String, Boolean>,
342+
savedPairings: List<PcSavedPairingRowState>,
343+
defaultDesktopId: String?,
344+
isBusy: Boolean
345+
): List<PcConnectionRowState> {
346+
val discoveredRows = pcs.map { pc ->
347+
discoveredPcRow(
348+
pc = pc,
349+
status = statuses[pc.desktopId] ?: PcRowStatus.Idle,
350+
connectedDesktopId = connectedDesktopId,
351+
hasToken = hasTokenByDesktopId[pc.desktopId] == true,
352+
defaultDesktopId = defaultDesktopId,
353+
isBusy = isBusy
354+
)
355+
}
356+
val savedOnlyRows = savedPairings.map { pairing ->
357+
savedOnlyPcRow(pairing, defaultDesktopId)
358+
}
359+
return discoveredRows + savedOnlyRows
360+
}
361+
362+
private fun discoveredPcRow(
363+
pc: DiscoveredPc,
364+
status: PcRowStatus,
365+
connectedDesktopId: String?,
366+
hasToken: Boolean,
367+
defaultDesktopId: String?,
368+
isBusy: Boolean
369+
): PcConnectionRowState {
370+
val connected = connectedDesktopId == pc.desktopId || status == PcRowStatus.Connected
371+
val rowStatus = if (connected) PcRowStatus.Connected else status
372+
val actionText = when {
373+
connected -> null
374+
hasToken -> "Connect"
375+
else -> "Request access"
376+
}
377+
val summary = when {
378+
connected -> "Connected"
379+
status == PcRowStatus.WaitingApproval -> "Waiting for approval on your PC..."
380+
status == PcRowStatus.Connecting -> "Connecting..."
381+
status == PcRowStatus.Failed -> "Try again"
382+
else -> pc.primaryAddress
383+
}
384+
return PcConnectionRowState(
385+
desktopId = pc.desktopId,
386+
title = pc.displayName,
387+
summary = summary,
388+
source = PcConnectionRowSource.Discovered,
389+
status = rowStatus,
390+
actionText = actionText,
391+
enabled = !connected && !isBusy,
392+
canRequestAccess = !hasToken && !connected,
393+
canConnect = hasToken && !connected,
394+
canUnpair = hasToken || connected,
395+
canSetDefault = hasToken,
396+
isDefault = pc.desktopId == defaultDesktopId,
397+
discoveredPc = pc
398+
)
399+
}
400+
401+
private fun savedOnlyPcRow(
402+
pairing: PcSavedPairingRowState,
403+
defaultDesktopId: String?
404+
): PcConnectionRowState {
405+
return PcConnectionRowState(
406+
desktopId = pairing.desktopId,
407+
title = pairing.title,
408+
summary = if (pairing.canConnect) pairing.summary else "Not available",
409+
source = PcConnectionRowSource.SavedOnly,
410+
status = PcRowStatus.Idle,
411+
actionText = if (pairing.canConnect) "Connect" else null,
412+
enabled = pairing.canConnect,
413+
canRequestAccess = false,
414+
canConnect = pairing.canConnect,
415+
canUnpair = pairing.canUnpair,
416+
canSetDefault = pairing.canSetDefault,
417+
isDefault = pairing.desktopId == defaultDesktopId,
418+
discoveredPc = null
419+
)
420+
}
421+
303422
private fun savedPairingSummary(lastEndpoint: String?): String {
304423
if (lastEndpoint.isNullOrBlank()) return "Not nearby"
305424
return lastEndpoint

0 commit comments

Comments
 (0)