diff --git a/src/assets/playlist-cover.png b/src/assets/playlist-cover.png new file mode 100644 index 0000000..1467aed Binary files /dev/null and b/src/assets/playlist-cover.png differ diff --git a/src/components/AddPlaylist.tsx b/src/components/AddPlaylist.tsx index f7d1983..57b5271 100644 --- a/src/components/AddPlaylist.tsx +++ b/src/components/AddPlaylist.tsx @@ -25,7 +25,7 @@ export const AddPlaylist: React.FC<{ refresh: (id: string) => void }> = ({ const trackgroup = await createTrackGroup({ // FIXME: the POST trackgroup API endpoint requires a cover id, // which doesn't really make sense in this flow. - cover: "4903e433-f429-4ad1-9ab2-5ba962acbbd1", + cover: "ba6c693f-e2c8-44f8-8d1b-742c81a1c551", title: newPlaylistName, type: "playlist", }); diff --git a/src/components/PlaylistTitleEditing.tsx b/src/components/PlaylistTitleEditing.tsx index 0f7d319..50296ca 100644 --- a/src/components/PlaylistTitleEditing.tsx +++ b/src/components/PlaylistTitleEditing.tsx @@ -2,13 +2,17 @@ import { css } from "@emotion/css"; import React from "react"; import { FaTrash } from "react-icons/fa"; import { useNavigate } from "react-router-dom"; -import { deleteUserTrackGroup, updateTrackGroup } from "../services/Api"; +import { + deleteUserTrackGroup, + updateTrackGroup, + uploadTrackGroupCover, +} from "../services/Api"; import Button from "./common/Button"; import Input from "./common/Input"; import TextArea from "./common/TextArea"; const PlaylistTitleEditing: React.FC<{ - playlist: Trackgroup; + playlist: Release; onDone: (update?: boolean) => void; }> = ({ playlist, onDone }) => { const navigate = useNavigate(); @@ -39,6 +43,10 @@ const PlaylistTitleEditing: React.FC<{ [playlist, playlistTitle, onDone, isPrivate, about] ); + const replaceImage = React.useCallback(async (e) => { + await uploadTrackGroupCover(e.target.files[0]); + }, []); + const onDelete = React.useCallback(async () => { await deleteUserTrackGroup(playlist.id); navigate("/library"); @@ -52,55 +60,102 @@ const PlaylistTitleEditing: React.FC<{
input:not([type="checkbox"]) { - margin-bottom: 0; - margin-right: 1rem; - } - - > div { - padding: 0.5rem 1rem; - min-width: 140px; - text-align: right; - } + position: relative; `} > - -
- - -
+ Cover + +
-
- - +
input:not([type="checkbox"]) { + margin-bottom: 0; + margin-right: 1rem; + } - + > div { + padding: 0.5rem 1rem; + min-width: 140px; + text-align: right; + } + `} + > + +
+ + +
+
+ +
+ + + + +
); diff --git a/src/services/Api.ts b/src/services/Api.ts index 61bd21e..133a53d 100644 --- a/src/services/Api.ts +++ b/src/services/Api.ts @@ -218,6 +218,23 @@ export const deleteUserTrackGroup = async (id: string) => { }); }; +export const uploadTrackGroupCover = async (file: File) => { + var data = new FormData(); + const { token } = getToken(); + data.append("file", file); + return fetch("https://dash.resonate.coop/api/user/upload", { + method: "POST", + body: data, + headers: { + ...(token ? { Authorization: `Bearer ${token}` } : {}), + }, + }); +}; + +/** + * Misc user info + */ + export const fetchUserStats = async ( from: string, to: string