feat: hide watch-related UI entirely when no watch has ever been paired - #25
Open
PonceGL wants to merge 1 commit into
Open
feat: hide watch-related UI entirely when no watch has ever been paired#25PonceGL wants to merge 1 commit into
PonceGL wants to merge 1 commit into
Conversation
Three watch-related entry points on the phone — the "Send to Watch" playlist menu item, SongInfoBottomSheet's per-song send button, and the new "Watch" Settings category — used to always show, even for someone who's never paired a Wear OS device. The existing reachability check (CapabilityClient FILTER_REACHABLE) already correctly shows these as disabled/"not connected" for a paired-but-currently-unreachable watch; what was missing was a distinct signal for "has the user ever paired a watch with PixelPlay installed at all", to hide the UI entirely in that case instead of showing a permanently-broken option. Added WearPhoneTransferSender.refreshWatchPairingState(), same shape as the existing isPixelPlayWatchAvailable() but using CapabilityClient's FILTER_ALL (every node that's ever advertised the capability, reachable or not) instead of FILTER_REACHABLE. Stored in PhoneWatchTransferStateStore.isAnyWatchPaired, the same shared singleton that already holds reachableWatchNodeIds — same pattern, distinct concept, defaults to false (safer to hide for someone who's never paired anything than to flash the UI on before the first check resolves). Refreshed at three points: app startup (PixelPlayApplication, same dagger.Lazy + best-effort try/catch shape as resumePersistedBatchIfNeeded), inside the existing refreshWatchAvailability() in both PlaylistViewModel and SongInfoBottomSheetViewModel (fires wherever reachability already gets refreshed, no new call sites needed there), and a new LaunchedEffect(Unit) on PlaylistDetailScreen's composition and on the Settings hub — needed so the flag is resolved before the user opens a menu/list that needs to gate on it, not only after they tap something that was already conditionally hidden. Left untouched: the send-to-watch confirmation dialog's existing "not connected" messaging for a paired-but-unreachable watch — already correct, not this change's concern. Test coverage: 3 new PhoneWatchTransferStateStore cases (default false, flips independently of reachableWatchNodeIds). Fixed PlaylistViewModelTest's mock, which needed a stub for the new call. refreshWatchPairingState() itself isn't unit tested — same static-GMS-call constraint as isPixelPlayWatchAvailable() next to it, already undtested for the same reason. Verified :app still builds clean in release (R8 + shrinkResources).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Qué resuelve
Los tres puntos de entrada de "enviar/gestionar reloj" en el teléfono (menú "Enviar a reloj" de una playlist, botón de enviar canción en
SongInfoBottomSheet, y la nueva categoría "Reloj" en Ajustes) se mostraban siempre, sin importar si el usuario alguna vez emparejó un Wear OS. El caso "emparejado pero desconectado ahora mismo" ya estaba bien resuelto (visible, deshabilitado, mensaje "no conectado") — lo que faltaba era la otra mitad: nunca emparejado → ocultar del todo.Mecanismo
CapabilityClient.FILTER_ALL(nodos que alguna vez anunciaron la capacidad, alcanzables o no) en vez deFILTER_REACHABLE(solo ahora mismo). NuevaWearPhoneTransferSender.refreshWatchPairingState(), mismo molde queisPixelPlayWatchAvailable()ya existente, actualizando un nuevoPhoneWatchTransferStateStore.isAnyWatchPaired(defaultfalse— más seguro ocultar de más que de menos para quien nunca emparejó nada).Se refresca en tres puntos: arranque de la app (mismo patrón que
resumePersistedBatchIfNeeded), dentro derefreshWatchAvailability()en ambos ViewModels (gratis, sin nuevos call sites), y unLaunchedEffect(Unit)nuevo enPlaylistDetailScreen/Ajustes para que el flag ya esté resuelto antes de decidir si mostrar el menú, no solo después de tocarlo.Tests
3 casos nuevos en
PhoneWatchTransferStateStoreTest(defaultfalse, independiente dereachableWatchNodeIds). Arreglé el mock dePlaylistViewModelTestque necesitaba un stub para la llamada nueva.refreshWatchPairingState()en sí no tiene test unitario — misma limitación queisPixelPlayWatchAvailable()al lado (llamada estática a GMS, sin agente de mockeo inline).Verifiqué
:app:assembleRelease(R8 + shrinkResources) limpio.Pendiente de hardware: confirmar en un teléfono sin reloj emparejado que las tres opciones no aparecen, que aparecen al emparejar uno, y que se quedan visibles (con el comportamiento "no conectado" ya existente) al apagar el reloj sin desemparejarlo.