Skip to content

Commit

Permalink
Handle pause-play decision on backend to stop requests erroring on qu…
Browse files Browse the repository at this point in the history
…ick successive clicks
  • Loading branch information
CalPinSW committed Jul 24, 2024
1 parent 8f82157 commit 38c1ceb
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 20 deletions.
7 changes: 6 additions & 1 deletion backend/src/controllers/spotify.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,12 @@ def pause_playback():
def start_playback():
access_token = request.cookies.get("spotify_access_token")
request_body = request.json
start_playback_request_body = StartPlaybackRequest.model_validate(request_body)
start_playback_request_body = StartPlaybackRequest.model_validate(request_body) if request_body else None
return spotify.start_playback(access_token, start_playback_request_body)

@spotify_controller.route("pause_or_start_playback", methods=["PUT"])
def pause_or_start_playback():
access_token = request.cookies.get("spotify_access_token")
return spotify.pause_or_start_playback(access_token)

return spotify_controller
18 changes: 11 additions & 7 deletions backend/src/spotify.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,19 +469,17 @@ def pause_playback(self, access_token) -> Response:
},
auth=BearerAuth(access_token),
)
foo = self.response_handler(
return self.response_handler(
make_response("", response.status_code), jsonify=False
)
return foo

def start_playback(
self, access_token, start_playback_request_body: StartPlaybackRequest = None
) -> Response:
request_json = start_playback_request_body.model_dump_json(exclude_none=True)
if request_json == {}:
if not start_playback_request_body:
data = None
else:
data = request_json
data = start_playback_request_body.model_dump_json(exclude_none=True)

response = requests.put(
url="https://api.spotify.com/v1/me/player/play",
Expand All @@ -491,10 +489,16 @@ def start_playback(
},
auth=BearerAuth(access_token),
)
foo = self.response_handler(
return self.response_handler(
make_response("", response.status_code), jsonify=False
)
return foo

def pause_or_start_playback(self, access_token) -> Response:
is_playing = self.get_current_playback(access_token).is_playing
if is_playing:
return self.pause_playback(access_token)
else:
return self.start_playback(access_token)


def get_playlist_duration(playlist_info: List[PlaylistTrackObject]) -> int:
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,8 @@ export const startPlayback = async (
offset,
position_ms
});
};

export const pauseOrStartPlayback = async (): Promise<Response> => {
return jsonRequest(`spotify/pause_or_start_playback`, RequestMethod.PUT);
};
7 changes: 3 additions & 4 deletions frontend/src/context/PlaybackContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@ import React, {
useState,
} from "react";
import { PlaybackInfo, PlaylistProgress } from "../interfaces/PlaybackInfo";
import { QueryObserverResult, RefetchOptions, useQuery } from "@tanstack/react-query";
import { useQuery } from "@tanstack/react-query";
import { getPlaybackInfo, getPlaylistProgress } from "../api";

interface PlaybackContext {
playbackInfo?: PlaybackInfo;
refetchPlaybackInfo?: (options?: RefetchOptions) => Promise<QueryObserverResult<PlaybackInfo, Error>>
playlistProgress?: PlaylistProgress;
}

Expand All @@ -25,7 +24,7 @@ export const PlaybackContextProvider: FC<PlaybackContextProviderProps> = ({
children,
}) => {
const [playbackRefetchInterval, setPlaybackRefetchInterval] = useState(5000);
const { data: playbackInfo, refetch: refetchPlaybackInfo } = useQuery<PlaybackInfo>({
const { data: playbackInfo } = useQuery<PlaybackInfo>({
queryKey: ["playbackInfo"],
queryFn: () => {
return getPlaybackInfo();
Expand All @@ -51,7 +50,7 @@ export const PlaybackContextProvider: FC<PlaybackContextProviderProps> = ({
});

return (
<PlaybackContext.Provider value={{ playbackInfo, playlistProgress, refetchPlaybackInfo }}>
<PlaybackContext.Provider value={{ playbackInfo, playlistProgress }}>
{children}
</PlaybackContext.Provider>
);
Expand Down
11 changes: 3 additions & 8 deletions frontend/src/presentational/PlaybackFooter.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useQuery } from "@tanstack/react-query";
import React, { FC, useEffect, useState } from "react";
import { getPlaybackInfo, getPlaylistProgress, pausePlayback, startPlayback } from "../api";
import { getPlaybackInfo, getPlaylistProgress, pauseOrStartPlayback, pausePlayback, startPlayback } from "../api";
import { PlaybackInfo, PlaylistProgress } from "../interfaces/PlaybackInfo";
import { ProgressCircle } from "../components/ProgressCircle";
import useWindowSize from "../hooks/useWindowSize";
Expand All @@ -12,17 +12,12 @@ import { Link } from "react-router-dom";

const PlaybackFooter: FC = () => {
const { isMobileView } = useWindowSize();
const { playbackInfo, playlistProgress, refetchPlaybackInfo } = usePlaybackContext();
const { playbackInfo, playlistProgress } = usePlaybackContext();

if (!playbackInfo) return null;

const handlePausePlayClick = (): void => {
if (playbackInfo.is_playing) {
pausePlayback()
} else {
startPlayback()
}
refetchPlaybackInfo?.()
pauseOrStartPlayback()
}

return (
Expand Down

0 comments on commit 38c1ceb

Please sign in to comment.