@@ -24,7 +24,9 @@ data class PcApprovalCodeState(
2424
2525data 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+
6083data 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