@@ -26,6 +26,9 @@ data class PcConnectionUiState(
2626 val permissionRequired : Boolean = false ,
2727 val discoveryStatus : PcDiscoveryStatus = PcDiscoveryStatus .Empty ,
2828 val discoveryStatusText : String = " Searching for Switchify PC..." ,
29+ val defaultPreference : PcDefaultPcPreference = PcDefaultPcPreference .LastConnection ,
30+ val lastConnectedDesktopId : String? = null ,
31+ val defaultPcChoices : List <PcDefaultPcChoice > = emptyList(),
2932 val pcRows : List <PcConnectionRowState > = emptyList(),
3033 val discoveredPcs : List <PcRowState > = emptyList(),
3134 val savedPairings : List <PcSavedPairingRowState > = emptyList(),
@@ -37,6 +40,12 @@ data class PcConnectionUiState(
3740 val pendingUnpair : PcUnpairConfirmationState ? = null
3841)
3942
43+ data class PcDefaultPcChoice (
44+ val preference : PcDefaultPcPreference ,
45+ val title : String ,
46+ val description : String
47+ )
48+
4049data class PcRowState (
4150 val pc : DiscoveredPc ,
4251 val title : String ,
@@ -129,11 +138,18 @@ class PcConnectionViewModel(
129138 val hasTokenByDesktopId = withContext(backgroundDispatcher) {
130139 inputs.pcs.associate { pc -> pc.desktopId to ! tokenStore.getToken(pc.desktopId).isNullOrBlank() }
131140 }
141+ val allPairings = withContext(backgroundDispatcher) {
142+ tokenStore.listPairings()
143+ }
132144 val savedPairings = withContext(backgroundDispatcher) {
133- savedPairings(discoveredDesktopIds)
145+ savedPairings(allPairings, discoveredDesktopIds)
146+ }
147+ val defaultPreference = withContext(backgroundDispatcher) {
148+ tokenStore.getDefaultPcPreference()
134149 }
135- val defaultDesktopId = withContext(backgroundDispatcher) {
136- tokenStore.getDefaultDesktopId()
150+ val defaultDesktopId = (defaultPreference as ? PcDefaultPcPreference .SpecificPc )?.desktopId
151+ val lastConnectedDesktopId = withContext(backgroundDispatcher) {
152+ tokenStore.getLastConnectedDesktopId()
137153 }
138154 val pcRows = buildPcRows(
139155 pcs = inputs.pcs,
@@ -148,6 +164,9 @@ class PcConnectionViewModel(
148164 current.copy(
149165 discoveryStatus = inputs.status,
150166 discoveryStatusText = discoveryStatusText(inputs.status, inputs.pcs.isEmpty()),
167+ defaultPreference = defaultPreference,
168+ lastConnectedDesktopId = lastConnectedDesktopId,
169+ defaultPcChoices = buildDefaultPcChoices(allPairings, inputs.pcs, lastConnectedDesktopId),
151170 pcRows = pcRows,
152171 discoveredPcs = inputs.pcs.map { pc ->
153172 rowState(
@@ -252,17 +271,38 @@ class PcConnectionViewModel(
252271 }
253272
254273 fun setDefaultPc (desktopId : String , displayName : String ) {
255- if (tokenStore.getToken(desktopId).isNullOrBlank()) return
256- tokenStore.setDefaultDesktopId(desktopId)
257- tokenRevision.update { it + 1 }
258- _uiState .update {
259- it.copy(message = " Default PC set to $displayName ." )
260- }
274+ setDefaultPcPreference(PcDefaultPcPreference .SpecificPc (desktopId), displayName)
261275 }
262276
263277 fun clearDefaultPc () {
264- tokenStore.clearDefaultDesktopId()
278+ setDefaultPcPreference(PcDefaultPcPreference .LastConnection )
279+ }
280+
281+ fun setDefaultPcPreference (preference : PcDefaultPcPreference ) {
282+ val displayName = (preference as ? PcDefaultPcPreference .SpecificPc )?.desktopId?.let { desktopId ->
283+ _uiState .value.pcRows.firstOrNull { it.desktopId == desktopId }?.title
284+ ? : tokenStore.getServiceName(desktopId)
285+ ? : desktopId
286+ }
287+ setDefaultPcPreference(preference, displayName)
288+ }
289+
290+ private fun setDefaultPcPreference (
291+ preference : PcDefaultPcPreference ,
292+ displayName : String? = null
293+ ) {
294+ if (preference is PcDefaultPcPreference .SpecificPc && tokenStore.getToken(preference.desktopId).isNullOrBlank()) {
295+ return
296+ }
297+ tokenStore.setDefaultPcPreference(preference)
265298 tokenRevision.update { it + 1 }
299+ _uiState .update {
300+ val message = when (preference) {
301+ PcDefaultPcPreference .LastConnection -> " Default set to last connection."
302+ is PcDefaultPcPreference .SpecificPc -> " Default PC set to ${displayName ? : preference.desktopId} ."
303+ }
304+ it.copy(message = message)
305+ }
266306 }
267307
268308 fun stopPcBluetooth () {
@@ -309,7 +349,7 @@ class PcConnectionViewModel(
309349 }
310350 return PcRowState (
311351 pc = pc,
312- title = pc.displayName ,
352+ title = pc.controlDeviceName ,
313353 summary = summary,
314354 actionText = actionText,
315355 enabled = ! connected && ! isBusy,
@@ -320,8 +360,11 @@ class PcConnectionViewModel(
320360 )
321361 }
322362
323- private fun savedPairings (discoveredDesktopIds : Set <String >): List <PcSavedPairingRowState > {
324- return tokenStore.listPairings()
363+ private fun savedPairings (
364+ pairings : List <PcStoredPairing >,
365+ discoveredDesktopIds : Set <String >
366+ ): List <PcSavedPairingRowState > {
367+ return pairings
325368 .filterNot { it.desktopId in discoveredDesktopIds }
326369 .map { pairing ->
327370 PcSavedPairingRowState (
@@ -334,6 +377,33 @@ class PcConnectionViewModel(
334377 }
335378 }
336379
380+ private fun buildDefaultPcChoices (
381+ pairings : List <PcStoredPairing >,
382+ discoveredPcs : List <DiscoveredPc >,
383+ lastConnectedDesktopId : String?
384+ ): List <PcDefaultPcChoice > {
385+ val discoveredNames = discoveredPcs.associate { it.desktopId to it.controlDeviceName }
386+ val lastConnectionDisplayName = pairings.firstOrNull {
387+ it.desktopId == lastConnectedDesktopId
388+ }?.let { pairing -> discoveredNames[pairing.desktopId] ? : pairing.serviceName ? : pairing.desktopId }
389+ val lastConnectionDescription = lastConnectionDisplayName?.let {
390+ " Currently: $it "
391+ } ? : " Switchify will use the most recently connected PC."
392+ return listOf (
393+ PcDefaultPcChoice (
394+ preference = PcDefaultPcPreference .LastConnection ,
395+ title = " Use last connection" ,
396+ description = lastConnectionDescription
397+ )
398+ ) + pairings.map { pairing ->
399+ PcDefaultPcChoice (
400+ preference = PcDefaultPcPreference .SpecificPc (pairing.desktopId),
401+ title = discoveredNames[pairing.desktopId] ? : pairing.serviceName ? : pairing.desktopId,
402+ description = " Always connect to this PC when it is available."
403+ )
404+ }
405+ }
406+
337407 private fun buildPcRows (
338408 pcs : List <DiscoveredPc >,
339409 statuses : Map <String , PcRowStatus >,
@@ -383,7 +453,7 @@ class PcConnectionViewModel(
383453 }
384454 return PcConnectionRowState (
385455 desktopId = pc.desktopId,
386- title = pc.displayName ,
456+ title = pc.controlDeviceName ,
387457 summary = summary,
388458 source = PcConnectionRowSource .Discovered ,
389459 status = rowStatus,
@@ -440,7 +510,7 @@ class PcConnectionViewModel(
440510 desktopId = pc.desktopId,
441511 status = PcRowStatus .WaitingApproval ,
442512 message = null ,
443- approvalCode = PcApprovalCodeState (pc.displayName , verificationCode)
513+ approvalCode = PcApprovalCodeState (pc.controlDeviceName , verificationCode)
444514 )
445515 when (val pairing = connector.requestApproval(pc, requestNonce)) {
446516 is PcPairingResult .Paired -> {
@@ -449,11 +519,12 @@ class PcConnectionViewModel(
449519 isAuthFailure = { it is PcPingResult .AuthFailed }
450520 )) {
451521 is PcPingResult .Connected -> {
452- tokenStore.saveToken(pc.desktopId, pairing.token, ping.endpointId, pc.displayName)
522+ tokenStore.saveToken(pc.desktopId, pairing.token, ping.endpointId, pc.controlDeviceName)
523+ tokenStore.recordSuccessfulConnection(pc.desktopId)
453524 tokenRevision.update { it + 1 }
454525 PcConnectionStateHolder .setConnected(
455526 PcAuthenticatedSession (pc.desktopId, identityRepository.getDeviceId(), ping.endpointId),
456- pc.displayName
527+ pc.controlDeviceName
457528 )
458529 setIdle(pc.desktopId, PcRowStatus .Connected , null )
459530 }
@@ -480,11 +551,12 @@ class PcConnectionViewModel(
480551 isAuthFailure = { it is PcPingResult .AuthFailed }
481552 )) {
482553 is PcPingResult .Connected -> {
483- tokenStore.saveToken(pc.desktopId, token, result.endpointId, pc.displayName)
554+ tokenStore.saveToken(pc.desktopId, token, result.endpointId, pc.controlDeviceName)
555+ tokenStore.recordSuccessfulConnection(pc.desktopId)
484556 tokenRevision.update { it + 1 }
485557 PcConnectionStateHolder .setConnected(
486558 PcAuthenticatedSession (pc.desktopId, identityRepository.getDeviceId(), result.endpointId),
487- pc.displayName
559+ pc.controlDeviceName
488560 )
489561 setIdle(pc.desktopId, PcRowStatus .Connected , null )
490562 }
0 commit comments