Skip to content

Commit

Permalink
Add ability to start album in context of playlist from playlist explo…
Browse files Browse the repository at this point in the history
…rer page
  • Loading branch information
CalPinSW committed Aug 2, 2024
1 parent 01f1b4e commit ad126a2
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 14 deletions.
8 changes: 7 additions & 1 deletion backend/src/dataclasses/playback_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,16 @@ class StartPlaybackRequestUriOffset(BaseModel):
uri: str


class StartPlaybackRequestAlbumIdOffset(BaseModel):
album_id: str


class StartPlaybackRequest(BaseModel):
context_uri: Optional[str] = None
uris: Optional[List[str]] = None
offset: Optional[
StartPlaybackRequestPositionOffset | StartPlaybackRequestUriOffset
StartPlaybackRequestPositionOffset
| StartPlaybackRequestUriOffset
| StartPlaybackRequestAlbumIdOffset
] = None
position_ms: Optional[int] = None
26 changes: 23 additions & 3 deletions backend/src/spotify.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import json
import requests
import os
from typing import List
from typing import List, Optional
from flask import Response, make_response, redirect
from src.dataclasses.album import Album
from src.dataclasses.playback_info import PlaybackInfo, PlaylistProgression
from src.dataclasses.playback_request import StartPlaybackRequest
from src.dataclasses.playback_request import (
StartPlaybackRequest,
StartPlaybackRequestUriOffset,
)
from src.dataclasses.playback_state import PlaybackState
from src.dataclasses.playlist import Playlist
from src.dataclasses.playlist_info import CurrentUserPlaylists, SimplifiedPlaylist
Expand Down Expand Up @@ -468,11 +471,28 @@ def pause_playback(self, access_token) -> Response:
)

def start_playback(
self, access_token, start_playback_request_body: StartPlaybackRequest = None
self,
access_token,
start_playback_request_body: Optional[StartPlaybackRequest] = None,
) -> Response:
if not start_playback_request_body:
data = None
else:
if start_playback_request_body.offset.album_id:
track_offset = StartPlaybackRequestUriOffset.model_validate(
{
"uri": (
self.get_album(
access_token=access_token,
id=start_playback_request_body.offset.album_id,
)
.tracks.items[0]
.uri
)
}
)

start_playback_request_body.offset = track_offset
data = start_playback_request_body.model_dump_json(exclude_none=True)

response = requests.put(
Expand Down
14 changes: 6 additions & 8 deletions frontend/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,18 +109,16 @@ export const pausePlayback = async (): Promise<Response> => {
return jsonRequest(`spotify/pause_playback`, RequestMethod.PUT);
};

export const startPlayback = async (
interface StartPlaybackRequest {
context_uri?: string,
uris?: string[],
offset?: {position: number} | {uri: string},
offset?: {position: number} | {uri: string} | {album_id: string},
position_ms?: number
}

export const startPlayback = async (requestBody?: StartPlaybackRequest
): Promise<Response> => {
return jsonRequest(`spotify/start_playback`, RequestMethod.PUT, {
context_uri,
uris,
offset,
position_ms
});
return jsonRequest(`spotify/start_playback`, RequestMethod.PUT, requestBody);
};

export const pauseOrStartPlayback = async (): Promise<Response> => {
Expand Down
14 changes: 12 additions & 2 deletions frontend/src/playlistExplorer/AlbumList/AlbumContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,20 @@ import PlaylistIcon from "../../components/PlaylistIcon";
import { RotatingBorderBox } from "../../components/RotatingBorderBox";
import Modal from "../../components/Modal";
import { Playlist } from "../../interfaces/Playlist";
import { addAlbumToPlaylist } from "../../api";
import { addAlbumToPlaylist, startPlayback } from "../../api";
import { useModal } from "../../hooks/useModal";
import Button from "../../components/Button";

interface AlbumContainerProps {
album: Album;
contextPlaylist: Playlist
associatedPlaylists: Playlist[];
active?: boolean;
}

export const AlbumContainer: FC<AlbumContainerProps> = ({
album,
contextPlaylist,
associatedPlaylists,
active,
}) => {
Expand All @@ -31,6 +33,7 @@ export const AlbumContainer: FC<AlbumContainerProps> = ({
<>
<Modal isModalOpen={isModalOpen} closeModal={closeModal}>
<AlbumActionsModalContent
contextPlaylist={contextPlaylist}
associatedPlaylists={associatedPlaylists}
album={album}
closeModal={closeModal}
Expand Down Expand Up @@ -80,11 +83,13 @@ export const AlbumContainer: FC<AlbumContainerProps> = ({

interface AlbumActionsModalContentProps {
album: Album;
contextPlaylist: Playlist
associatedPlaylists: Playlist[];
closeModal: () => void;
}
const AlbumActionsModalContent: FC<AlbumActionsModalContentProps> = ({
album,
contextPlaylist,
associatedPlaylists,
closeModal,
}) => {
Expand All @@ -98,7 +103,7 @@ const AlbumActionsModalContent: FC<AlbumActionsModalContentProps> = ({
<h2 className="my-auto text-m">Actions:</h2>
<button onClick={closeModal}>X</button>
</div>
<div className="my-2 space-y-2">
<div className="flex flex-col my-2 space-y-2">
{associatedPlaylists.map((associatedPlaylist) => (
<Button
onClick={() => addAlbumToAssociatedPlaylist(associatedPlaylist)}
Expand All @@ -107,6 +112,11 @@ const AlbumActionsModalContent: FC<AlbumActionsModalContentProps> = ({
Add to {associatedPlaylist.name}
</Button>
))}
<Button
onClick={() => (startPlayback({context_uri: contextPlaylist.uri, offset: {album_id: album.id} }))}
>
Play Album
</Button>
</div>
</div>
);
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/playlistExplorer/AlbumList/AlbumList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import { Playlist } from "../../interfaces/Playlist";

interface AlbumListProps {
albumList: Album[];
contextPlaylist: Playlist;
associatedPlaylists: Playlist[];
activeAlbumId?: string;
}
export const AlbumList: FC<AlbumListProps> = ({
albumList,
contextPlaylist,
associatedPlaylists,
activeAlbumId,
}) => {
Expand All @@ -21,6 +23,7 @@ export const AlbumList: FC<AlbumListProps> = ({
<AlbumContainer
album={album}
key={album.id}
contextPlaylist={contextPlaylist}
associatedPlaylists={associatedPlaylists}
active={album.id == activeAlbumId}
/>
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/playlistExplorer/PlaylistExplorer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export const PlaylistExplorer: FC = () => {
}, []);

const { playbackInfo } = usePlaybackContext();

return (
<div className="flex flex-col h-full space-y-1 ">
<div className="mx-2">
Expand Down Expand Up @@ -124,6 +125,7 @@ export const PlaylistExplorer: FC = () => {
<AlbumList
albumList={playlistAlbums}
activeAlbumId={playbackInfo?.album_id}
contextPlaylist={playlist}
associatedPlaylists={associatedPlaylists}
/>
)}
Expand Down

0 comments on commit ad126a2

Please sign in to comment.