Skip to content

Commit 1edd3e4

Browse files
committed
fix(revert): only commit desired changes for 65e63c4
This reverts commit 65e63c4.
1 parent 3d0cd57 commit 1edd3e4

File tree

1 file changed

+147
-129
lines changed

1 file changed

+147
-129
lines changed

src/exporter.ts

Lines changed: 147 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -7,135 +7,6 @@ import { APP_NAME } from "./appInfo";
77
import { showPromptDialog } from "./dialogs";
88
import { showErrorToast, showSuccessToast, showWarningToast } from "./toast";
99

10-
export async function updateQueueFromSnapshot(
11-
snapshot: Snapshot,
12-
mode: "append" | "replace",
13-
buttonEl?: HTMLButtonElement,
14-
): Promise<void> {
15-
const opName = mode === "replace" ? "Replace" : "Append to";
16-
const opVerb = mode === "replace" ? "Replacing" : "Appending";
17-
const opNoun = mode === "replace" ? "replace" : "append";
18-
19-
try {
20-
if (!snapshot.items.length) {
21-
showWarningToast("Snapshot is empty");
22-
return;
23-
}
24-
if (buttonEl) {
25-
buttonEl.disabled = true;
26-
setButtonLabel(buttonEl, `${opVerb}…`);
27-
}
28-
29-
const itemsToQueue = snapshot.items.slice();
30-
let playbackStarted = false;
31-
32-
if (mode === "replace") {
33-
const first = itemsToQueue.shift()!;
34-
35-
try {
36-
await Spicetify.Platform.PlayerAPI.clearQueue();
37-
} catch (e) {
38-
console.warn(`${APP_NAME}: clearQueue failed (non-fatal)`, e);
39-
}
40-
41-
if (first.startsWith("spotify:local:")) {
42-
try {
43-
await Spicetify.Platform.PlayerAPI.play(
44-
{
45-
uri: "spotify:internal:local-files",
46-
pages: [{ items: [{ uri: first }] }],
47-
},
48-
{},
49-
{ skipTo: { index: 0 } },
50-
);
51-
playbackStarted = true;
52-
} catch (eLocal) {
53-
console.warn(`${APP_NAME}: local fallback failed`, eLocal);
54-
}
55-
} else {
56-
try {
57-
await Spicetify.Player.playUri(first);
58-
playbackStarted = true;
59-
} catch (e1) {
60-
try {
61-
await Spicetify.Platform.PlayerAPI.play({ uri: first }, {}, {});
62-
playbackStarted = true;
63-
} catch (e2) {
64-
console.warn(`${APP_NAME}: failed to start first track`, e2);
65-
}
66-
}
67-
}
68-
69-
if (!playbackStarted) {
70-
throw new Error("Failed to start playback");
71-
}
72-
73-
// Give the player a brief moment to switch track
74-
await new Promise(r => setTimeout(r, 250));
75-
}
76-
77-
// Enqueue remaining items in order
78-
let addedToQueue = 0;
79-
for (let i = 0; i < itemsToQueue.length; i += 100) {
80-
const chunkUris = itemsToQueue.slice(i, i + 100);
81-
const chunk = chunkUris.map(uri => ({ uri }));
82-
try {
83-
await Spicetify.Platform.PlayerAPI.addToQueue(chunk);
84-
addedToQueue += chunk.length;
85-
} catch (err) {
86-
console.warn(`${APP_NAME}: addToQueue chunk failed`, err);
87-
for (const uri of chunkUris) {
88-
try {
89-
await Spicetify.Platform.PlayerAPI.addToQueue([{ uri }]);
90-
addedToQueue += 1;
91-
} catch (singleErr) {
92-
console.warn(`${APP_NAME}: addToQueue single failed`, { uri, error: singleErr });
93-
}
94-
}
95-
}
96-
}
97-
98-
const totalExpected = snapshot.items.length;
99-
if (mode === "replace") {
100-
const totalInQueue = (playbackStarted ? 1 : 0) + addedToQueue;
101-
if (totalInQueue === totalExpected) {
102-
showSuccessToast(`Queue replaced (${totalExpected} items)`);
103-
} else {
104-
showWarningToast(`Replaced; some items couldn't be queued (${totalInQueue}/${totalExpected})`);
105-
}
106-
} else {
107-
// append
108-
if (addedToQueue === totalExpected) {
109-
showSuccessToast(`Added ${totalExpected} ${totalExpected === 1 ? "item" : "items"} to queue`);
110-
} else if (addedToQueue > 0) {
111-
showWarningToast(`Added ${addedToQueue}/${totalExpected} items to queue`);
112-
} else {
113-
showErrorToast("Failed to queue snapshot items");
114-
}
115-
}
116-
117-
try {
118-
console.log(`${APP_NAME}: ${opName} result`, {
119-
snapshotId: snapshot.id,
120-
totalExpected,
121-
added: mode === "replace" ? (playbackStarted ? 1 : 0) + addedToQueue : addedToQueue,
122-
});
123-
} catch {}
124-
} catch (e) {
125-
console.error(`${APP_NAME}: ${opNoun} queue failed`, e);
126-
if (mode === "replace" && (e as Error)?.message === "Failed to start playback") {
127-
showErrorToast("Failed to start playback");
128-
} else {
129-
showErrorToast(`Failed to ${opNoun} queue`);
130-
}
131-
} finally {
132-
if (buttonEl) {
133-
buttonEl.disabled = false;
134-
setButtonLabel(buttonEl, `${opName} queue`);
135-
}
136-
}
137-
}
138-
13910
export async function createManualSnapshot(): Promise<void> {
14011
try {
14112
const items = await getQueueFromSpicetify();
@@ -256,4 +127,151 @@ export async function exportSnapshotToPlaylist(snapshot: Snapshot, buttonEl?: HT
256127
setButtonLabel(buttonEl, "Export");
257128
}
258129
}
130+
}
131+
132+
export async function appendSnapshotToQueue(snapshot: Snapshot, buttonEl?: HTMLButtonElement): Promise<void> {
133+
try {
134+
if (!snapshot.items.length) {
135+
showWarningToast("Snapshot is empty");
136+
return;
137+
}
138+
139+
if (buttonEl) {
140+
buttonEl.disabled = true;
141+
setButtonLabel(buttonEl, "Appending…");
142+
}
143+
144+
const items = snapshot.items.slice();
145+
let added = 0;
146+
147+
for (let i = 0; i < items.length; i += 100) {
148+
const chunkUris = items.slice(i, i + 100);
149+
const chunk = chunkUris.map(uri => ({ uri }));
150+
try {
151+
await Spicetify.Platform.PlayerAPI.addToQueue(chunk);
152+
added += chunk.length;
153+
} catch (err) {
154+
console.warn(`${APP_NAME}: addToQueue chunk failed`, err);
155+
for (const uri of chunkUris) {
156+
try {
157+
await Spicetify.Platform.PlayerAPI.addToQueue([{ uri }]);
158+
added += 1;
159+
} catch (singleErr) {
160+
console.warn(`${APP_NAME}: addToQueue single failed`, { uri, error: singleErr });
161+
}
162+
}
163+
}
164+
}
165+
166+
const totalExpected = items.length;
167+
168+
if (added === totalExpected) {
169+
showSuccessToast(`Added ${totalExpected} ${totalExpected === 1 ? "item" : "items"} to queue`);
170+
} else if (added > 0) {
171+
showWarningToast(`Added ${added}/${totalExpected} items to queue`);
172+
} else {
173+
showErrorToast("Failed to queue snapshot items");
174+
}
175+
176+
try {
177+
console.log(`${APP_NAME}: Append result`, {
178+
snapshotId: snapshot.id,
179+
totalExpected,
180+
added,
181+
});
182+
} catch {}
183+
} catch (e) {
184+
console.error(`${APP_NAME}: append queue failed`, e);
185+
showErrorToast("Failed to append to queue");
186+
} finally {
187+
if (buttonEl) {
188+
buttonEl.disabled = false;
189+
setButtonLabel(buttonEl, "Append to queue");
190+
}
191+
}
192+
}
193+
194+
export async function replaceQueueWithSnapshot(snapshot: Snapshot, buttonEl?: HTMLButtonElement): Promise<void> {
195+
try {
196+
if (!snapshot.items.length) {
197+
showWarningToast("Snapshot is empty");
198+
return;
199+
}
200+
if (buttonEl) {
201+
buttonEl.disabled = true;
202+
setButtonLabel(buttonEl, "Replacing…");
203+
}
204+
205+
const items = snapshot.items.slice();
206+
const first = items.shift()!;
207+
208+
try {
209+
await Spicetify.Platform.PlayerAPI.clearQueue();
210+
} catch (e) {
211+
console.warn(`${APP_NAME}: clearQueue failed (non-fatal)`, e);
212+
}
213+
214+
if (first.startsWith("spotify:local:")) {
215+
try {
216+
await Spicetify.Platform.PlayerAPI.play({
217+
uri: "spotify:internal:local-files",
218+
pages: [
219+
{
220+
items: [{ uri: first }],
221+
},
222+
],
223+
}, {}, {
224+
skipTo: {
225+
index: 0,
226+
},
227+
});
228+
} catch (eLocal) {
229+
console.warn(`${APP_NAME}: local fallback failed`, eLocal);
230+
showErrorToast("Failed to start playback");
231+
return;
232+
}
233+
} else {
234+
// Start playback with the first item
235+
try {
236+
await Spicetify.Player.playUri(first);
237+
} catch (e1) {
238+
try {
239+
await Spicetify.Platform.PlayerAPI.play({ uri: first }, {}, {});
240+
} catch (e2) {
241+
console.warn(`${APP_NAME}: failed to start first track`, e2);
242+
showErrorToast("Failed to start playback");
243+
return;
244+
}
245+
}
246+
}
247+
248+
// Give the player a brief moment to switch track
249+
await new Promise(r => setTimeout(r, 250));
250+
251+
// Enqueue remaining items in order
252+
let added = 0;
253+
for (let i = 0; i < items.length; i += 100) {
254+
const chunk = items.slice(i, i + 100).map(u => ({ uri: u }));
255+
try {
256+
await Spicetify.Platform.PlayerAPI.addToQueue(chunk);
257+
added += chunk.length;
258+
} catch (e) {
259+
console.warn(`${APP_NAME}: addToQueue chunk failed`, e);
260+
}
261+
}
262+
263+
if (added === items.length) {
264+
showSuccessToast(`Queue replaced (${snapshot.items.length} items)`);
265+
} else {
266+
showWarningToast(`Replaced; some items couldn't be queued (${added + 1}/${snapshot.items.length})`);
267+
}
268+
} catch (e) {
269+
console.error(`${APP_NAME}: replace queue failed`, e);
270+
showErrorToast("Failed to replace queue");
271+
} finally {
272+
if (buttonEl) {
273+
buttonEl.disabled = false;
274+
setButtonLabel(buttonEl, "Replace queue");
275+
}
276+
}
259277
}

0 commit comments

Comments
 (0)