morille 0.1.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/README.md +15 -3
  2. package/dist/app.d.ts.map +1 -0
  3. package/dist/app.js +2 -0
  4. package/dist/app.js.map +1 -0
  5. package/dist/components/animated-subtitle.d.ts +19 -0
  6. package/dist/components/animated-subtitle.d.ts.map +1 -0
  7. package/dist/components/animated-subtitle.js +109 -0
  8. package/dist/components/animated-subtitle.js.map +1 -0
  9. package/dist/components/animated-title.d.ts +16 -0
  10. package/dist/components/animated-title.d.ts.map +1 -0
  11. package/dist/components/animated-title.js +47 -0
  12. package/dist/components/animated-title.js.map +1 -0
  13. package/dist/components/browse-detail-view.d.ts.map +1 -0
  14. package/dist/components/browse-detail-view.js +2 -1
  15. package/dist/components/browse-detail-view.js.map +1 -0
  16. package/dist/components/device-indicator.d.ts +18 -0
  17. package/dist/components/device-indicator.d.ts.map +1 -0
  18. package/dist/components/device-indicator.js +53 -0
  19. package/dist/components/device-indicator.js.map +1 -0
  20. package/dist/components/device-picker-view.d.ts +10 -0
  21. package/dist/components/device-picker-view.d.ts.map +1 -0
  22. package/dist/components/device-picker-view.js +65 -0
  23. package/dist/components/device-picker-view.js.map +1 -0
  24. package/dist/components/lyrics-panel.d.ts.map +1 -0
  25. package/dist/components/lyrics-view.d.ts.map +1 -0
  26. package/dist/components/lyrics-view.js +2 -1
  27. package/dist/components/lyrics-view.js.map +1 -0
  28. package/dist/components/panel-content.d.ts.map +1 -0
  29. package/dist/components/panel-content.js +4 -0
  30. package/dist/components/panel-content.js.map +1 -0
  31. package/dist/components/playback-status.d.ts.map +1 -0
  32. package/dist/components/player.d.ts.map +1 -1
  33. package/dist/components/player.js +46 -10
  34. package/dist/components/player.js.map +1 -1
  35. package/dist/components/progress-bar.d.ts.map +1 -0
  36. package/dist/components/progress-bar.js +2 -1
  37. package/dist/components/progress-bar.js.map +1 -0
  38. package/dist/components/queue-view.d.ts.map +1 -0
  39. package/dist/components/queue-view.js +2 -1
  40. package/dist/components/queue-view.js.map +1 -0
  41. package/dist/components/search-panel.d.ts.map +1 -0
  42. package/dist/components/search-panel.js +3 -2
  43. package/dist/components/search-panel.js.map +1 -0
  44. package/dist/components/shimmer.d.ts.map +1 -0
  45. package/dist/components/shimmer.js +2 -2
  46. package/dist/components/shimmer.js.map +1 -0
  47. package/dist/components/track-facts.d.ts +13 -0
  48. package/dist/components/track-facts.d.ts.map +1 -0
  49. package/dist/components/track-facts.js +52 -0
  50. package/dist/components/track-facts.js.map +1 -0
  51. package/dist/components/track-info-skeleton.d.ts.map +1 -0
  52. package/dist/components/track-info.d.ts.map +1 -0
  53. package/dist/components/track-info.js +2 -1
  54. package/dist/components/track-info.js.map +1 -0
  55. package/dist/config.d.ts +3 -4
  56. package/dist/config.d.ts.map +1 -1
  57. package/dist/config.js +3 -4
  58. package/dist/config.js.map +1 -1
  59. package/dist/contexts/devices-context.d.ts +28 -0
  60. package/dist/contexts/devices-context.d.ts.map +1 -0
  61. package/dist/contexts/devices-context.js +33 -0
  62. package/dist/contexts/devices-context.js.map +1 -0
  63. package/dist/contexts/lyrics-context.d.ts.map +1 -0
  64. package/dist/contexts/panel-mode-context.d.ts +2 -1
  65. package/dist/contexts/panel-mode-context.d.ts.map +1 -0
  66. package/dist/contexts/panel-mode-context.js +3 -0
  67. package/dist/contexts/panel-mode-context.js.map +1 -0
  68. package/dist/contexts/queue-context.d.ts.map +1 -0
  69. package/dist/contexts/search-context.d.ts.map +1 -0
  70. package/dist/hooks/use-album-art.d.ts.map +1 -0
  71. package/dist/hooks/use-album-art.js +3 -1
  72. package/dist/hooks/use-album-art.js.map +1 -0
  73. package/dist/hooks/use-browse.d.ts.map +1 -0
  74. package/dist/hooks/use-browse.js +7 -3
  75. package/dist/hooks/use-browse.js.map +1 -0
  76. package/dist/hooks/use-devices.d.ts +24 -0
  77. package/dist/hooks/use-devices.d.ts.map +1 -0
  78. package/dist/hooks/use-devices.js +106 -0
  79. package/dist/hooks/use-devices.js.map +1 -0
  80. package/dist/hooks/use-lyrics.d.ts.map +1 -0
  81. package/dist/hooks/use-playback.d.ts +7 -0
  82. package/dist/hooks/use-playback.d.ts.map +1 -0
  83. package/dist/hooks/use-playback.js +59 -18
  84. package/dist/hooks/use-playback.js.map +1 -0
  85. package/dist/hooks/use-player-input.d.ts.map +1 -0
  86. package/dist/hooks/use-player-input.js +31 -2
  87. package/dist/hooks/use-player-input.js.map +1 -0
  88. package/dist/hooks/use-queue.d.ts.map +1 -0
  89. package/dist/hooks/use-queue.js +8 -3
  90. package/dist/hooks/use-queue.js.map +1 -0
  91. package/dist/hooks/use-search.d.ts.map +1 -0
  92. package/dist/hooks/use-search.js +2 -1
  93. package/dist/hooks/use-search.js.map +1 -0
  94. package/dist/icons.d.ts +29 -0
  95. package/dist/icons.d.ts.map +1 -0
  96. package/dist/icons.js +43 -0
  97. package/dist/icons.js.map +1 -0
  98. package/dist/index.d.ts +1 -0
  99. package/dist/index.d.ts.map +1 -0
  100. package/dist/index.js +4 -0
  101. package/dist/index.js.map +1 -0
  102. package/dist/logger.d.ts +9 -0
  103. package/dist/logger.d.ts.map +1 -0
  104. package/dist/logger.js +15 -0
  105. package/dist/logger.js.map +1 -0
  106. package/dist/main.d.ts.map +1 -0
  107. package/dist/spotify/auth.d.ts.map +1 -0
  108. package/dist/spotify/auth.js +3 -1
  109. package/dist/spotify/auth.js.map +1 -0
  110. package/dist/spotify/client.d.ts.map +1 -0
  111. package/dist/spotify/client.js +3 -1
  112. package/dist/spotify/client.js.map +1 -0
  113. package/dist/spotify/devices.d.ts +36 -0
  114. package/dist/spotify/devices.d.ts.map +1 -0
  115. package/dist/spotify/devices.js +72 -0
  116. package/dist/spotify/devices.js.map +1 -0
  117. package/dist/spotify/fetch-with-retry.d.ts.map +1 -0
  118. package/dist/spotify/fetch-with-retry.js +5 -4
  119. package/dist/spotify/fetch-with-retry.js.map +1 -0
  120. package/dist/spotify/lyrics.d.ts.map +1 -0
  121. package/dist/spotify/lyrics.js +5 -2
  122. package/dist/spotify/lyrics.js.map +1 -0
  123. package/dist/spotify/playback.d.ts +9 -0
  124. package/dist/spotify/playback.d.ts.map +1 -0
  125. package/dist/spotify/playback.js +40 -8
  126. package/dist/spotify/playback.js.map +1 -0
  127. package/dist/spotify/search.d.ts.map +1 -0
  128. package/dist/spotify/search.js +4 -4
  129. package/dist/spotify/search.js.map +1 -0
  130. package/dist/spotify/track-facts.d.ts +9 -0
  131. package/dist/spotify/track-facts.d.ts.map +1 -0
  132. package/dist/spotify/track-facts.js +95 -0
  133. package/dist/spotify/track-facts.js.map +1 -0
  134. package/package.json +21 -1
@@ -1,5 +1,6 @@
1
1
  import { useEffect, useRef, useState } from 'react';
2
2
  import terminalImage from 'terminal-image';
3
+ import { logger } from '../logger.js';
3
4
  /**
4
5
  * Fetches an album art image and converts it to a terminal-renderable ANSI string.
5
6
  * Caches by URL to avoid re-fetching on every render cycle.
@@ -38,7 +39,8 @@ export function useAlbumArt(imageUrl, height) {
38
39
  setArt(rendered);
39
40
  }
40
41
  }
41
- catch {
42
+ catch (err) {
43
+ logger.error(`Failed to render album art for ${imageUrl}:`, err);
42
44
  if (!cancelled) {
43
45
  setArt(null);
44
46
  }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-album-art.js","sourceRoot":"","sources":["../../src/hooks/use-album-art.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACpD,OAAO,aAAa,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,QAAuB,EAAE,MAAc;IACjE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,MAAM,CAIb,IAAI,CAAC,CAAC;IAEhB,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,CAAC,IAAI,CAAC,CAAC;YACb,OAAO;QACT,CAAC;QAED,IAAI,QAAQ,CAAC,OAAO,EAAE,GAAG,KAAK,QAAQ,IAAI,QAAQ,CAAC,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC7E,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC7B,OAAO;QACT,CAAC;QAED,IAAI,SAAS,GAAG,KAAK,CAAC;QAEtB,KAAK,UAAU,IAAI;YACjB,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAS,CAAC,CAAC;gBACxC,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC;gBACjD,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE;oBACvE,MAAM;oBACN,mBAAmB,EAAE,IAAI;oBACzB,kBAAkB,EAAE,KAAK;iBAC1B,CAAC,CAAC;gBAEH,IAAI,CAAC,SAAS,EAAE,CAAC;oBACf,QAAQ,CAAC,OAAO,GAAG;wBACjB,GAAG,EAAE,QAAS;wBACd,MAAM;wBACN,GAAG,EAAE,QAAQ;qBACd,CAAC;oBACF,MAAM,CAAC,QAAQ,CAAC,CAAC;gBACnB,CAAC;YACH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,KAAK,CAAC,kCAAkC,QAAQ,GAAG,EAAE,GAAG,CAAC,CAAC;gBACjE,IAAI,CAAC,SAAS,EAAE,CAAC;oBACf,MAAM,CAAC,IAAI,CAAC,CAAC;gBACf,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,EAAE,CAAC;QACP,OAAO,GAAG,EAAE;YACV,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC;IACJ,CAAC,EAAE;QACD,QAAQ;QACR,MAAM;KACP,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-browse.d.ts","sourceRoot":"","sources":["../../src/hooks/use-browse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAG1D,OAAO,KAAK,EAA+B,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAG9F,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,OAAO,GAAG,UAAU,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,EAAE,MAAM,CAAC;QACZ,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;CACJ,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,UAAU;;;;;yBAQxB,MAAM;+BA2BH,MAAM;;;EAyD5B"}
@@ -1,4 +1,5 @@
1
1
  import { useCallback, useRef, useState } from 'react';
2
+ import { logger } from '../logger.js';
2
3
  import { fetchAlbumTracks, fetchPlaylistTracks, fetchUserPlaylists } from '../spotify/search.js';
3
4
  /**
4
5
  * Manages drill-down browse state for albums, playlists, and user playlist library.
@@ -26,7 +27,8 @@ export function useBrowse(client) {
26
27
  tracks: album.tracks,
27
28
  });
28
29
  }
29
- catch {
30
+ catch (err) {
31
+ logger.error(`Failed to load album ${albumId}:`, err);
30
32
  if (cancelRef.current !== token)
31
33
  return;
32
34
  setData(null);
@@ -53,7 +55,8 @@ export function useBrowse(client) {
53
55
  tracks: playlist.tracks,
54
56
  });
55
57
  }
56
- catch {
58
+ catch (err) {
59
+ logger.error(`Failed to load playlist ${playlistId}:`, err);
57
60
  if (cancelRef.current !== token)
58
61
  return;
59
62
  setData(null);
@@ -71,7 +74,8 @@ export function useBrowse(client) {
71
74
  const result = await fetchUserPlaylists(client);
72
75
  setUserPlaylists(result.items);
73
76
  }
74
- catch {
77
+ catch (err) {
78
+ logger.error('Failed to load user playlists:', err);
75
79
  setUserPlaylists(null);
76
80
  }
77
81
  finally {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-browse.js","sourceRoot":"","sources":["../../src/hooks/use-browse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { SpotifyApi } from '@spotify/web-api-ts-sdk';
2
+ import type { SpotifyDevice } from '../spotify/devices.js';
3
+ /**
4
+ * Fetches and manages the list of Spotify Connect devices while the device
5
+ * picker panel is open. Only fetches when `enabled` is true. Exposes a
6
+ * `select` action that transfers playback to the currently highlighted
7
+ * device using the "mirror current playing state" policy supplied by the
8
+ * caller.
9
+ * @param client - Authenticated Spotify API client
10
+ * @param enabled - Whether the picker is active (gates the initial fetch)
11
+ * @param shouldResume - Current playing state used to decide whether the
12
+ * transferred session should resume on the new device
13
+ * @returns Device list, loading state, and navigation / selection controls
14
+ */
15
+ export declare function useDevices(client: SpotifyApi, enabled: boolean, shouldResume: boolean): {
16
+ devices: SpotifyDevice[];
17
+ isLoading: boolean;
18
+ selectedIndex: number;
19
+ error: string | null;
20
+ up: () => void;
21
+ down: () => void;
22
+ select: () => Promise<void>;
23
+ refresh: () => Promise<void>;
24
+ };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-devices.d.ts","sourceRoot":"","sources":["../../src/hooks/use-devices.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAG1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAG3D;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO;;;;;;;;;EA2FrF"}
@@ -0,0 +1,106 @@
1
+ import { useCallback, useEffect, useRef, useState } from 'react';
2
+ import { logger } from '../logger.js';
3
+ import { fetchDevices, transferPlayback } from '../spotify/devices.js';
4
+ /**
5
+ * Fetches and manages the list of Spotify Connect devices while the device
6
+ * picker panel is open. Only fetches when `enabled` is true. Exposes a
7
+ * `select` action that transfers playback to the currently highlighted
8
+ * device using the "mirror current playing state" policy supplied by the
9
+ * caller.
10
+ * @param client - Authenticated Spotify API client
11
+ * @param enabled - Whether the picker is active (gates the initial fetch)
12
+ * @param shouldResume - Current playing state used to decide whether the
13
+ * transferred session should resume on the new device
14
+ * @returns Device list, loading state, and navigation / selection controls
15
+ */
16
+ export function useDevices(client, enabled, shouldResume) {
17
+ const [devices, setDevices] = useState([]);
18
+ const [isLoading, setIsLoading] = useState(false);
19
+ const [selectedIndex, setSelectedIndex] = useState(0);
20
+ const [error, setError] = useState(null);
21
+ const hasLoadedRef = useRef(false);
22
+ const hasSeededRef = useRef(false);
23
+ const refresh = useCallback(async () => {
24
+ try {
25
+ const list = await fetchDevices(client);
26
+ setDevices(list);
27
+ setError(null);
28
+ if (!hasSeededRef.current) {
29
+ // First load after the panel opens: place the cursor on the active
30
+ // device so "enter" is a no-op on the current device.
31
+ const activeIdx = list.findIndex((d) => d.isActive);
32
+ if (activeIdx >= 0)
33
+ setSelectedIndex(activeIdx);
34
+ hasSeededRef.current = true;
35
+ }
36
+ else {
37
+ // Subsequent refreshes: keep whatever row the user navigated to,
38
+ // just clamp if the list shrank.
39
+ setSelectedIndex((v) => Math.min(Math.max(v, 0), Math.max(list.length - 1, 0)));
40
+ }
41
+ }
42
+ catch (err) {
43
+ logger.error('Failed to fetch devices:', err);
44
+ setError(err instanceof Error ? err.message : 'Failed to load devices');
45
+ }
46
+ finally {
47
+ setIsLoading(false);
48
+ }
49
+ }, [
50
+ client,
51
+ ]);
52
+ useEffect(() => {
53
+ if (!enabled) {
54
+ hasLoadedRef.current = false;
55
+ hasSeededRef.current = false;
56
+ return;
57
+ }
58
+ if (!hasLoadedRef.current) {
59
+ setIsLoading(true);
60
+ }
61
+ refresh().then(() => {
62
+ hasLoadedRef.current = true;
63
+ });
64
+ }, [
65
+ enabled,
66
+ refresh,
67
+ ]);
68
+ const select = useCallback(async () => {
69
+ const target = devices[selectedIndex];
70
+ if (!target || target.isActive)
71
+ return;
72
+ const prev = devices;
73
+ // Optimistic: mark the chosen device as active immediately. Intentionally
74
+ // not calling fetchDevices/playback.refresh right after the transfer —
75
+ // Spotify's state has ~100-500ms propagation delay, so an immediate
76
+ // refetch would overwrite the optimistic update with a stale "old device
77
+ // still active" snapshot. The next 10s playback poll reconciles.
78
+ setDevices((list) => list.map((d) => ({
79
+ ...d,
80
+ isActive: d.id === target.id,
81
+ })));
82
+ try {
83
+ await transferPlayback(client, target.id, shouldResume);
84
+ }
85
+ catch (err) {
86
+ setDevices(prev);
87
+ logger.error(`Failed to transfer playback to ${target.name}:`, err);
88
+ setError(err instanceof Error ? err.message : 'Transfer failed');
89
+ }
90
+ }, [
91
+ client,
92
+ devices,
93
+ selectedIndex,
94
+ shouldResume,
95
+ ]);
96
+ return {
97
+ devices,
98
+ isLoading,
99
+ selectedIndex,
100
+ error,
101
+ up: () => setSelectedIndex((v) => Math.max(0, v - 1)),
102
+ down: () => setSelectedIndex((v) => Math.min(Math.max(devices.length - 1, 0), v + 1)),
103
+ select,
104
+ refresh,
105
+ };
106
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-devices.js","sourceRoot":"","sources":["../../src/hooks/use-devices.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-lyrics.d.ts","sourceRoot":"","sources":["../../src/hooks/use-lyrics.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;;;EAoDhD"}
@@ -1,4 +1,5 @@
1
1
  import type { SpotifyApi } from '@spotify/web-api-ts-sdk';
2
+ import type { DeviceType } from '../spotify/devices.js';
2
3
  import type { TrackInfo } from '../spotify/playback.js';
3
4
  /**
4
5
  * React hook that manages Spotify playback state. Polls the current track
@@ -6,8 +7,14 @@ import type { TrackInfo } from '../spotify/playback.js';
6
7
  * @param client - Authenticated Spotify API client
7
8
  * @returns Playback state, loading/error indicators, and control functions
8
9
  */
10
+ export type ActiveDeviceSnapshot = {
11
+ id: string | null;
12
+ name: string | null;
13
+ type: DeviceType | null;
14
+ };
9
15
  export declare function usePlayback(client: SpotifyApi): {
10
16
  track: TrackInfo | null;
17
+ activeDevice: ActiveDeviceSnapshot | null;
11
18
  isLoading: boolean;
12
19
  error: string | null;
13
20
  toggle: () => Promise<void>;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-playback.d.ts","sourceRoot":"","sources":["../../src/hooks/use-playback.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAI1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,KAAK,EAAc,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAmBpE;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;CACzB,CAAC;AAEF,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU;;;;;;;;;;;;;;wBAyR9B,MAAM;;EAmCrB"}
@@ -1,23 +1,28 @@
1
1
  import { useCallback, useEffect, useRef, useState } from 'react';
2
2
  import { POLL_INTERVAL_MS, SEEK_STEP_MS, TICK_INTERVAL_MS, VOLUME_STEP } from '../config.js';
3
+ import { logger } from '../logger.js';
4
+ import { fetchDevices } from '../spotify/devices.js';
3
5
  import { getCurrentTrackInfo, playUri, seek, setRepeat, setShuffle, setVolume, skipNext as skipNextTrack, skipPrevious as skipPreviousTrack, togglePlayback, } from '../spotify/playback.js';
4
6
  const NEXT_REPEAT = {
5
7
  off: 'context',
6
8
  context: 'track',
7
9
  track: 'off',
8
10
  };
9
- /**
10
- * React hook that manages Spotify playback state. Polls the current track
11
- * at a regular interval and exposes toggle/refresh controls.
12
- * @param client - Authenticated Spotify API client
13
- * @returns Playback state, loading/error indicators, and control functions
14
- */
15
11
  export function usePlayback(client) {
16
12
  const [track, setTrack] = useState(null);
13
+ const [activeDevice, setActiveDevice] = useState(null);
17
14
  const [isLoading, setIsLoading] = useState(true);
18
15
  const [error, setError] = useState(null);
19
16
  // Wall clock timestamp when we last received progress from the API
20
17
  const syncRef = useRef(null);
18
+ /**
19
+ * Reports a playback error: surfaces the message in the UI via setError
20
+ * AND logs the full error via the debug-gated logger so it isn't silently swallowed.
21
+ */
22
+ const reportError = useCallback((action, err) => {
23
+ logger.error(`Playback: failed to ${action}:`, err);
24
+ setError(err instanceof Error ? err.message : `Failed to ${action}`);
25
+ }, []);
21
26
  const refresh = useCallback(async () => {
22
27
  try {
23
28
  const info = await getCurrentTrackInfo(client);
@@ -26,18 +31,43 @@ export function usePlayback(client) {
26
31
  progressMs: info.progressMs,
27
32
  timestamp: Date.now(),
28
33
  };
34
+ setTrack(info);
35
+ setActiveDevice({
36
+ id: info.deviceId,
37
+ name: info.deviceName,
38
+ type: info.deviceType,
39
+ });
40
+ }
41
+ else {
42
+ setTrack(null);
43
+ // No active playback — fall back to the devices list so the header
44
+ // can still show whichever device Spotify considers current.
45
+ try {
46
+ const devices = await fetchDevices(client);
47
+ const active = devices.find((d) => d.isActive) ?? null;
48
+ setActiveDevice(active
49
+ ? {
50
+ id: active.id,
51
+ name: active.name,
52
+ type: active.type,
53
+ }
54
+ : null);
55
+ }
56
+ catch (err) {
57
+ logger.error('Failed to fetch fallback device list:', err);
58
+ }
29
59
  }
30
- setTrack(info);
31
60
  setError(null);
32
61
  }
33
62
  catch (err) {
34
- setError(err instanceof Error ? err.message : 'Failed to fetch playback state');
63
+ reportError('fetch playback state', err);
35
64
  }
36
65
  finally {
37
66
  setIsLoading(false);
38
67
  }
39
68
  }, [
40
69
  client,
70
+ reportError,
41
71
  ]);
42
72
  const toggle = useCallback(async () => {
43
73
  const prevTrack = track;
@@ -53,12 +83,13 @@ export function usePlayback(client) {
53
83
  }
54
84
  catch (err) {
55
85
  setTrack(prevTrack);
56
- setError(err instanceof Error ? err.message : 'Failed to toggle playback');
86
+ reportError('toggle playback', err);
57
87
  }
58
88
  }, [
59
89
  client,
60
90
  track,
61
91
  refresh,
92
+ reportError,
62
93
  ]);
63
94
  const next = useCallback(async () => {
64
95
  const deviceId = track?.deviceId;
@@ -73,12 +104,13 @@ export function usePlayback(client) {
73
104
  }
74
105
  catch (err) {
75
106
  setIsLoading(false);
76
- setError(err instanceof Error ? err.message : 'Failed to skip to next track');
107
+ reportError('skip to next track', err);
77
108
  }
78
109
  }, [
79
110
  client,
80
111
  track,
81
112
  refresh,
113
+ reportError,
82
114
  ]);
83
115
  const previous = useCallback(async () => {
84
116
  const deviceId = track?.deviceId;
@@ -93,12 +125,13 @@ export function usePlayback(client) {
93
125
  }
94
126
  catch (err) {
95
127
  setIsLoading(false);
96
- setError(err instanceof Error ? err.message : 'Failed to skip to previous track');
128
+ reportError('skip to previous track', err);
97
129
  }
98
130
  }, [
99
131
  client,
100
132
  track,
101
133
  refresh,
134
+ reportError,
102
135
  ]);
103
136
  const seekForward = useCallback(async () => {
104
137
  if (!track)
@@ -116,11 +149,12 @@ export function usePlayback(client) {
116
149
  await seek(client, newProgress, track.deviceId ?? undefined);
117
150
  }
118
151
  catch (err) {
119
- setError(err instanceof Error ? err.message : 'Failed to seek');
152
+ reportError('seek', err);
120
153
  }
121
154
  }, [
122
155
  client,
123
156
  track,
157
+ reportError,
124
158
  ]);
125
159
  const seekBackward = useCallback(async () => {
126
160
  if (!track)
@@ -138,11 +172,12 @@ export function usePlayback(client) {
138
172
  await seek(client, newProgress, track.deviceId ?? undefined);
139
173
  }
140
174
  catch (err) {
141
- setError(err instanceof Error ? err.message : 'Failed to seek');
175
+ reportError('seek', err);
142
176
  }
143
177
  }, [
144
178
  client,
145
179
  track,
180
+ reportError,
146
181
  ]);
147
182
  const volumeUp = useCallback(async () => {
148
183
  if (!track || track.volume == null)
@@ -156,11 +191,12 @@ export function usePlayback(client) {
156
191
  await setVolume(client, newVolume, track.deviceId ?? undefined);
157
192
  }
158
193
  catch (err) {
159
- setError(err instanceof Error ? err.message : 'Failed to set volume');
194
+ reportError('set volume', err);
160
195
  }
161
196
  }, [
162
197
  client,
163
198
  track,
199
+ reportError,
164
200
  ]);
165
201
  const volumeDown = useCallback(async () => {
166
202
  if (!track || track.volume == null)
@@ -174,11 +210,12 @@ export function usePlayback(client) {
174
210
  await setVolume(client, newVolume, track.deviceId ?? undefined);
175
211
  }
176
212
  catch (err) {
177
- setError(err instanceof Error ? err.message : 'Failed to set volume');
213
+ reportError('set volume', err);
178
214
  }
179
215
  }, [
180
216
  client,
181
217
  track,
218
+ reportError,
182
219
  ]);
183
220
  const toggleShuffleMode = useCallback(async () => {
184
221
  if (!track)
@@ -192,11 +229,12 @@ export function usePlayback(client) {
192
229
  await setShuffle(client, newShuffle, track.deviceId ?? undefined);
193
230
  }
194
231
  catch (err) {
195
- setError(err instanceof Error ? err.message : 'Failed to toggle shuffle');
232
+ reportError('toggle shuffle', err);
196
233
  }
197
234
  }, [
198
235
  client,
199
236
  track,
237
+ reportError,
200
238
  ]);
201
239
  const cycleRepeat = useCallback(async () => {
202
240
  if (!track)
@@ -210,11 +248,12 @@ export function usePlayback(client) {
210
248
  await setRepeat(client, nextMode, track.deviceId ?? undefined);
211
249
  }
212
250
  catch (err) {
213
- setError(err instanceof Error ? err.message : 'Failed to set repeat mode');
251
+ reportError('set repeat mode', err);
214
252
  }
215
253
  }, [
216
254
  client,
217
255
  track,
256
+ reportError,
218
257
  ]);
219
258
  // Poll Spotify API for real state
220
259
  useEffect(() => {
@@ -256,15 +295,17 @@ export function usePlayback(client) {
256
295
  await refresh();
257
296
  }
258
297
  catch (err) {
259
- setError(err instanceof Error ? err.message : 'Failed to play track');
298
+ reportError('play track', err);
260
299
  }
261
300
  }, [
262
301
  client,
263
302
  track,
264
303
  refresh,
304
+ reportError,
265
305
  ]);
266
306
  return {
267
307
  track,
308
+ activeDevice,
268
309
  isLoading,
269
310
  error,
270
311
  toggle,
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-playback.js","sourceRoot":"","sources":["../../src/hooks/use-playback.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC7F,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,EACL,mBAAmB,EACnB,OAAO,EACP,IAAI,EACJ,SAAS,EACT,UAAU,EACV,SAAS,EACT,QAAQ,IAAI,aAAa,EACzB,YAAY,IAAI,iBAAiB,EACjC,cAAc,GACf,MAAM,wBAAwB,CAAC;AAEhC,MAAM,WAAW,GAAmC;IAClD,GAAG,EAAE,SAAS;IACd,OAAO,EAAE,OAAO;IAChB,KAAK,EAAE,KAAK;CACb,CAAC;AAcF,MAAM,UAAU,WAAW,CAAC,MAAkB;IAC5C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAmB,IAAI,CAAC,CAAC;IAC3D,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAA8B,IAAI,CAAC,CAAC;IACpF,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAExD,mEAAmE;IACnE,MAAM,OAAO,GAAG,MAAM,CAGZ,IAAI,CAAC,CAAC;IAEhB;;;OAGG;IACH,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,MAAc,EAAE,GAAY,EAAE,EAAE;QAC/D,MAAM,CAAC,KAAK,CAAC,uBAAuB,MAAM,GAAG,EAAE,GAAG,CAAC,CAAC;QACpD,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,MAAM,EAAE,CAAC,CAAC;IACvE,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACrC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,mBAAmB,CAAC,MAAM,CAAC,CAAC;YAC/C,IAAI,IAAI,EAAE,CAAC;gBACT,OAAO,CAAC,OAAO,GAAG;oBAChB,UAAU,EAAE,IAAI,CAAC,UAAU;oBAC3B,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;iBACtB,CAAC;gBACF,QAAQ,CAAC,IAAI,CAAC,CAAC;gBACf,eAAe,CAAC;oBACd,EAAE,EAAE,IAAI,CAAC,QAAQ;oBACjB,IAAI,EAAE,IAAI,CAAC,UAAU;oBACrB,IAAI,EAAE,IAAI,CAAC,UAAU;iBACtB,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,QAAQ,CAAC,IAAI,CAAC,CAAC;gBACf,mEAAmE;gBACnE,6DAA6D;gBAC7D,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;oBAC3C,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC;oBACvD,eAAe,CACb,MAAM;wBACJ,CAAC,CAAC;4BACE,EAAE,EAAE,MAAM,CAAC,EAAE;4BACb,IAAI,EAAE,MAAM,CAAC,IAAI;4BACjB,IAAI,EAAE,MAAM,CAAC,IAAI;yBAClB;wBACH,CAAC,CAAC,IAAI,CACT,CAAC;gBACJ,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,CAAC,KAAK,CAAC,uCAAuC,EAAE,GAAG,CAAC,CAAC;gBAC7D,CAAC;YACH,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC,CAAC;QACjB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC;QAC3C,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC,EAAE;QACD,MAAM;QACN,WAAW;KACZ,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACpC,MAAM,SAAS,GAAG,KAAK,CAAC;QACxB,IAAI,CAAC;YACH,IAAI,KAAK,EAAE,CAAC;gBACV,QAAQ,CAAC;oBACP,GAAG,KAAK;oBACR,SAAS,EAAE,CAAC,KAAK,CAAC,SAAS;iBAC5B,CAAC,CAAC;YACL,CAAC;YACD,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;YAC7B,MAAM,OAAO,EAAE,CAAC;QAClB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,SAAS,CAAC,CAAC;YACpB,WAAW,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;QACtC,CAAC;IACH,CAAC,EAAE;QACD,MAAM;QACN,KAAK;QACL,OAAO;QACP,WAAW;KACZ,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAClC,MAAM,QAAQ,GAAG,KAAK,EAAE,QAAQ,CAAC;QACjC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,QAAQ,CAAC,yBAAyB,CAAC,CAAC;YACpC,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,YAAY,CAAC,IAAI,CAAC,CAAC;YACnB,MAAM,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YACtC,MAAM,OAAO,EAAE,CAAC;QAClB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,WAAW,CAAC,oBAAoB,EAAE,GAAG,CAAC,CAAC;QACzC,CAAC;IACH,CAAC,EAAE;QACD,MAAM;QACN,KAAK;QACL,OAAO;QACP,WAAW;KACZ,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACtC,MAAM,QAAQ,GAAG,KAAK,EAAE,QAAQ,CAAC;QACjC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,QAAQ,CAAC,yBAAyB,CAAC,CAAC;YACpC,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,YAAY,CAAC,IAAI,CAAC,CAAC;YACnB,MAAM,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YAC1C,MAAM,OAAO,EAAE,CAAC;QAClB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,WAAW,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC,EAAE;QACD,MAAM;QACN,KAAK;QACL,OAAO;QACP,WAAW;KACZ,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACzC,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,GAAG,YAAY,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;QAChF,OAAO,CAAC,OAAO,GAAG;YAChB,UAAU,EAAE,WAAW;YACvB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC;QACF,QAAQ,CAAC;YACP,GAAG,KAAK;YACR,UAAU,EAAE,WAAW;SACxB,CAAC,CAAC;QACH,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,CAAC,QAAQ,IAAI,SAAS,CAAC,CAAC;QAC/D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC,EAAE;QACD,MAAM;QACN,KAAK;QACL,WAAW;KACZ,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAC1C,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,GAAG,YAAY,EAAE,CAAC,CAAC,CAAC;QACjE,OAAO,CAAC,OAAO,GAAG;YAChB,UAAU,EAAE,WAAW;YACvB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC;QACF,QAAQ,CAAC;YACP,GAAG,KAAK;YACR,UAAU,EAAE,WAAW;SACxB,CAAC,CAAC;QACH,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,CAAC,QAAQ,IAAI,SAAS,CAAC,CAAC;QAC/D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC,EAAE;QACD,MAAM;QACN,KAAK;QACL,WAAW;KACZ,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACtC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,IAAI,IAAI;YAAE,OAAO;QAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,WAAW,EAAE,GAAG,CAAC,CAAC;QAC5D,QAAQ,CAAC;YACP,GAAG,KAAK;YACR,MAAM,EAAE,SAAS;SAClB,CAAC,CAAC;QACH,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,QAAQ,IAAI,SAAS,CAAC,CAAC;QAClE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QACjC,CAAC;IACH,CAAC,EAAE;QACD,MAAM;QACN,KAAK;QACL,WAAW;KACZ,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACxC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,IAAI,IAAI;YAAE,OAAO;QAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,WAAW,EAAE,CAAC,CAAC,CAAC;QAC1D,QAAQ,CAAC;YACP,GAAG,KAAK;YACR,MAAM,EAAE,SAAS;SAClB,CAAC,CAAC;QACH,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,QAAQ,IAAI,SAAS,CAAC,CAAC;QAClE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QACjC,CAAC;IACH,CAAC,EAAE;QACD,MAAM;QACN,KAAK;QACL,WAAW;KACZ,CAAC,CAAC;IAEH,MAAM,iBAAiB,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAC/C,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,MAAM,UAAU,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC;QAClC,QAAQ,CAAC;YACP,GAAG,KAAK;YACR,OAAO,EAAE,UAAU;SACpB,CAAC,CAAC;QACH,IAAI,CAAC;YACH,MAAM,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,QAAQ,IAAI,SAAS,CAAC,CAAC;QACpE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;QACrC,CAAC;IACH,CAAC,EAAE;QACD,MAAM;QACN,KAAK;QACL,WAAW;KACZ,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACzC,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC3C,QAAQ,CAAC;YACP,GAAG,KAAK;YACR,MAAM,EAAE,QAAQ;SACjB,CAAC,CAAC;QACH,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,SAAS,CAAC,CAAC;QACjE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;QACtC,CAAC;IACH,CAAC,EAAE;QACD,MAAM;QACN,KAAK;QACL,WAAW;KACZ,CAAC,CAAC;IAEH,kCAAkC;IAClC,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,GAAG,WAAW,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;QAClD,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;IACjC,CAAC,EAAE;QACD,OAAO;KACR,CAAC,CAAC;IAEH,mEAAmE;IACnE,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/B,QAAQ,CAAC,OAAO,GAAG,KAAK,CAAC;IAEzB,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,KAAK,EAAE,SAAS,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAC1C,OAAO;QACT,CAAC;QACD,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE;YAC1B,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;YACjC,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC;YAC7B,IAAI,OAAO,EAAE,SAAS,IAAI,IAAI,EAAE,CAAC;gBAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC;gBAC5C,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,GAAG,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;gBAC3E,QAAQ,CAAC;oBACP,GAAG,OAAO;oBACV,UAAU;iBACX,CAAC,CAAC;YACL,CAAC;QACH,CAAC,EAAE,gBAAgB,CAAC,CAAC;QACrB,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;IACjC,CAAC,EAAE;QACD,KAAK,EAAE,SAAS;KACjB,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,WAAW,CAC9B,KAAK,EAAE,GAAW,EAAE,EAAE;QACpB,MAAM,QAAQ,GAAG,KAAK,EAAE,QAAQ,CAAC;QACjC,IAAI,CAAC,QAAQ;YAAE,OAAO;QACtB,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;YACrC,MAAM,OAAO,EAAE,CAAC;QAClB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,WAAW,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QACjC,CAAC;IACH,CAAC,EACD;QACE,MAAM;QACN,KAAK;QACL,OAAO;QACP,WAAW;KACZ,CACF,CAAC;IAEF,OAAO;QACL,KAAK;QACL,YAAY;QACZ,SAAS;QACT,KAAK;QACL,MAAM;QACN,IAAI;QACJ,QAAQ;QACR,WAAW;QACX,YAAY;QACZ,QAAQ;QACR,UAAU;QACV,iBAAiB;QACjB,WAAW;QACX,YAAY;QACZ,OAAO;KACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-player-input.d.ts","sourceRoot":"","sources":["../../src/hooks/use-player-input.ts"],"names":[],"mappings":"AASA,KAAK,eAAe,GAAG;IACrB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,eAAe,QAgJvD"}
@@ -1,4 +1,5 @@
1
1
  import { useApp, useInput } from 'ink';
2
+ import { useDevicesContext } from '../contexts/devices-context.js';
2
3
  import { useLyricsContext } from '../contexts/lyrics-context.js';
3
4
  import { usePanelMode } from '../contexts/panel-mode-context.js';
4
5
  import { useQueueContext } from '../contexts/queue-context.js';
@@ -10,12 +11,14 @@ import { useSearchContext } from '../contexts/search-context.js';
10
11
  */
11
12
  export function usePlayerInput(playback) {
12
13
  const { exit } = useApp();
13
- const { toggleLyrics, toggleQueue, toggleSearch, panelMode, isInputMode, setInputMode } = usePanelMode();
14
+ const { toggleLyrics, toggleQueue, toggleSearch, toggleDevices, panelMode, isInputMode, setInputMode } = usePanelMode();
14
15
  const { offsetUp, offsetDown, scrollUp, scrollDown, isPlainText } = useLyricsContext();
15
16
  const { queueUp, queueDown, queueSelect, refresh: refreshQueue } = useQueueContext();
17
+ const { devicesUp, devicesDown, devicesSelect } = useDevicesContext();
16
18
  const { query, setQuery, navigateUp: searchUp, navigateDown: searchDown, navigateLeft: searchLeft, navigateRight: searchRight, select: searchSelect, goBack: searchGoBack, browseUserPlaylists, canGoBack: searchCanGoBack, } = useSearchContext();
17
19
  const isQueueMode = panelMode === 'queue';
18
20
  const isSearchMode = panelMode === 'search';
21
+ const isDevicesMode = panelMode === 'devices';
19
22
  const isLyricsScrollMode = panelMode === 'lyrics' && isPlainText;
20
23
  const handleSearchEscape = searchCanGoBack ? searchGoBack : toggleSearch;
21
24
  const exitInputMode = () => {
@@ -58,6 +61,7 @@ export function usePlayerInput(playback) {
58
61
  toggleLyrics,
59
62
  toggleQueue,
60
63
  toggleSearch,
64
+ toggleDevices,
61
65
  browseUserPlaylists,
62
66
  refreshQueue,
63
67
  search: {
@@ -72,6 +76,11 @@ export function usePlayerInput(playback) {
72
76
  down: queueDown,
73
77
  select: queueSelect,
74
78
  },
79
+ devices: {
80
+ up: devicesUp,
81
+ down: devicesDown,
82
+ select: devicesSelect ? () => void devicesSelect() : undefined,
83
+ },
75
84
  lyrics: {
76
85
  offsetUp,
77
86
  offsetDown,
@@ -94,6 +103,10 @@ export function usePlayerInput(playback) {
94
103
  toggleQueue();
95
104
  return;
96
105
  }
106
+ if (isDevicesMode) {
107
+ toggleDevices();
108
+ return;
109
+ }
97
110
  if (isLyricsMode) {
98
111
  toggleLyrics();
99
112
  }
@@ -124,7 +137,7 @@ export function usePlayerInput(playback) {
124
137
  * Playback shortcuts (space, n, p, s, r, seek, volume) are only active when no panel is open.
125
138
  */
126
139
  function buildBindings(params) {
127
- const { panelMode, isLyricsScrollMode, exit, playback, search, queue, lyrics } = params;
140
+ const { panelMode, isLyricsScrollMode, exit, playback, search, queue, devices, lyrics } = params;
128
141
  if (panelMode === 'search') {
129
142
  return {
130
143
  actions: {
@@ -155,6 +168,21 @@ function buildBindings(params) {
155
168
  },
156
169
  };
157
170
  }
171
+ if (panelMode === 'devices') {
172
+ return {
173
+ actions: {
174
+ q: exit,
175
+ c: params.toggleDevices,
176
+ '\r': devices.select,
177
+ },
178
+ arrowActions: {
179
+ upArrow: devices.up,
180
+ downArrow: devices.down,
181
+ leftArrow: undefined,
182
+ rightArrow: undefined,
183
+ },
184
+ };
185
+ }
158
186
  if (panelMode === 'lyrics') {
159
187
  return {
160
188
  actions: {
@@ -190,6 +218,7 @@ function buildBindings(params) {
190
218
  d: params.toggleQueue,
191
219
  '/': params.toggleSearch,
192
220
  b: params.browseUserPlaylists,
221
+ c: params.toggleDevices,
193
222
  },
194
223
  arrowActions: {
195
224
  upArrow: playback.volumeUp,
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-player-input.js","sourceRoot":"","sources":["../../src/hooks/use-player-input.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-queue.d.ts","sourceRoot":"","sources":["../../src/hooks/use-queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAI1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;CACrB,CAAC;AAsEF;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CACtB,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,eAAe,GAAG,IAAI,EAC/B,eAAe,EAAE,MAAM,GAAG,IAAI;;;;;;;EAyE/B"}
@@ -1,4 +1,5 @@
1
1
  import { useCallback, useEffect, useRef, useState } from 'react';
2
+ import { logger } from '../logger.js';
2
3
  async function resolveQueueItems(client, context, cacheRef) {
3
4
  if (context) {
4
5
  if (cacheRef.current?.contextUri === context.uri) {
@@ -8,7 +9,10 @@ async function resolveQueueItems(client, context, cacheRef) {
8
9
  subtitle: cacheRef.current.subtitle,
9
10
  };
10
11
  }
11
- const result = await fetchContextTracks(client, context).catch(() => null);
12
+ const result = await fetchContextTracks(client, context).catch((err) => {
13
+ logger.error(`Failed to fetch context tracks for ${context.uri}:`, err);
14
+ return null;
15
+ });
12
16
  if (result && result.items.length > 0) {
13
17
  cacheRef.current = {
14
18
  contextUri: context.uri,
@@ -77,8 +81,9 @@ export function useQueue(client, enabled, context, currentTrackUri) {
77
81
  setContextName(result.name);
78
82
  setContextSubtitle(result.subtitle);
79
83
  }
80
- catch {
81
- // Silently ignore - show stale data
84
+ catch (err) {
85
+ // Show stale data on failure, but surface the error so it isn't masked.
86
+ logger.error('Failed to refresh queue:', err);
82
87
  }
83
88
  finally {
84
89
  setIsLoading(false);
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-queue.js","sourceRoot":"","sources":["../../src/hooks/use-queue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-search.d.ts","sourceRoot":"","sources":["../../src/hooks/use-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAI1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAG1D;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO;;;;;;EAqE7D"}