spotify state resume/capture

This commit is contained in:
yohlo
2025-09-12 11:34:21 -05:00
parent 0169468114
commit cf09014d50
9 changed files with 366 additions and 16 deletions

View File

@@ -6,6 +6,7 @@ import type {
SpotifyAuthState,
SpotifyDevice,
SpotifyPlaybackState,
SpotifyPlaybackSnapshot,
SpotifyTrack,
} from '@/lib/spotify/types';
@@ -34,6 +35,10 @@ export const SpotifyProvider: React.FC<PropsWithChildren> = ({ children }) => {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [capturedState, setCapturedState] = useState<SpotifyPlaybackSnapshot | null>(null);
const [isCaptureLoading, setIsCaptureLoading] = useState(false);
const [isResumeLoading, setIsResumeLoading] = useState(false);
const spotifyAuth = new SpotifyAuth(
import.meta.env.VITE_SPOTIFY_CLIENT_ID!,
import.meta.env.VITE_SPOTIFY_REDIRECT_URI!
@@ -63,7 +68,6 @@ export const SpotifyProvider: React.FC<PropsWithChildren> = ({ children }) => {
scopes: [],
});
// Load initial data
await Promise.all([getDevices(), refreshPlaybackState()]);
}
}
@@ -340,6 +344,51 @@ export const SpotifyProvider: React.FC<PropsWithChildren> = ({ children }) => {
return () => clearInterval(interval);
}, [authState.isAuthenticated, refreshPlaybackState]);
const capturePlaybackState = useCallback(async () => {
if (!authState.isAuthenticated) return;
setIsCaptureLoading(true);
setError(null);
try {
const response = await makeSpotifyRequest('capture', {
method: 'POST',
});
if (response.snapshot) {
setCapturedState(response.snapshot);
}
} catch (error) {
setError(error instanceof Error ? error.message : 'Failed to capture playback state');
} finally {
setIsCaptureLoading(false);
}
}, [authState.isAuthenticated]);
const resumePlaybackState = useCallback(async () => {
if (!authState.isAuthenticated || !capturedState) return;
setIsResumeLoading(true);
setError(null);
try {
await makeSpotifyRequest('resume', {
method: 'POST',
body: JSON.stringify({ snapshot: capturedState }),
});
setTimeout(refreshPlaybackState, 1000);
} catch (error) {
setError(error instanceof Error ? error.message : 'Failed to resume playback state');
} finally {
setIsResumeLoading(false);
}
}, [authState.isAuthenticated, capturedState, refreshPlaybackState]);
const clearCapturedState = useCallback(() => {
setCapturedState(null);
}, []);
const contextValue: SpotifyContextType = {
...authState,
currentTrack,
@@ -348,6 +397,10 @@ export const SpotifyProvider: React.FC<PropsWithChildren> = ({ children }) => {
activeDevice,
isLoading,
error,
// Capture/Resume state
capturedState,
isCaptureLoading,
isResumeLoading,
login,
logout,
play,
@@ -358,6 +411,10 @@ export const SpotifyProvider: React.FC<PropsWithChildren> = ({ children }) => {
getDevices,
setActiveDevice,
refreshPlaybackState,
// Capture/Resume methods
capturePlaybackState,
resumePlaybackState,
clearCapturedState,
};
if (!isAdmin) {