Skip to content

Commit

Permalink
Let user edit playlist info
Browse files Browse the repository at this point in the history
  • Loading branch information
Arikatsu committed Nov 24, 2022
1 parent ce8c5af commit f292141
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 24 deletions.
32 changes: 29 additions & 3 deletions src/backend/playlist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@ export async function getPlaylistById(playlistId: string): Promise<Playlist|null
*/
export async function renamePlaylist(playlistId: string, name: string): Promise<boolean> {
const response = await fetch(`${targetRoute}/playlist/${playlistId}?type=rename`, {
method: "PATCH", headers: { Authorization: token() },
method: "PATCH", headers: {
Authorization: token(),
"Content-Type": "application/json"
},
body: JSON.stringify({ name })
});

Expand All @@ -71,21 +74,44 @@ export async function renamePlaylist(playlistId: string, name: string): Promise<
*/
export async function describePlaylist(playlistId: string, description: string): Promise<boolean> {
const response = await fetch(`${targetRoute}/playlist/${playlistId}?type=describe`, {
method: "PATCH", headers: { Authorization: token() },
method: "PATCH", headers: {
Authorization: token(),
"Content-Type": "application/json"
},
body: JSON.stringify({ description })
});

return response.status != 200;
}

/**
* Changes the playlist's icon.
* @param playlistId The ID of the playlist.
* @param icon The new icon URl of the playlist.
*/
export async function setPlaylistIcon(playlistId: string, icon: string): Promise<boolean> {
const response = await fetch(`${targetRoute}/playlist/${playlistId}?type=icon`, {
method: "PATCH", headers: {
Authorization: token(),
"Content-Type": "application/json"
},
body: JSON.stringify({ icon })
});

return response.status != 200;
}

/**
* Changes the playlist's visibility.
* @param playlistId The ID of the playlist.
* @param isPrivate Whether the playlist should be private.
*/
export async function setPlaylistVisibility(playlistId: string, isPrivate: boolean): Promise<boolean> {
const response = await fetch(`${targetRoute}/playlist/${playlistId}?type=privacy`, {
method: "PATCH", headers: { Authorization: token() },
method: "PATCH", headers: {
Authorization: token(),
"Content-Type": "application/json"
},
body: JSON.stringify({ isPrivate })
});

Expand Down
6 changes: 4 additions & 2 deletions src/css/App.scss
Original file line number Diff line number Diff line change
Expand Up @@ -218,12 +218,13 @@ h1 {
font-size: 16px;
color: #dcdcdc;
margin-bottom: 10px;
margin-top: 20px;
}

img {
width: 100%;
height: 100%;
margin-bottom: 20px;
margin-bottom: 10px;
}

input {
Expand All @@ -235,6 +236,7 @@ h1 {
font-size: 16px;
color: #fff;
background: #181c3b;
margin-bottom: 10px;

&:focus {
outline: none;
Expand All @@ -252,7 +254,7 @@ h1 {
}

textarea {
margin-top: 10px;
margin-bottom: 10px;
width: 100%;
height: 100px;
border-radius: 5px;
Expand Down
2 changes: 1 addition & 1 deletion src/css/Playlist.scss
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@
}
}

#BannerUpload {
#PlaylistSettingsButton {
position: absolute;
z-index: 100000;
right: 0;
Expand Down
77 changes: 59 additions & 18 deletions src/ui/pages/PlaylistPage.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React from "react";

import { Playlist } from "@backend/types";
import { fetchPlaylist } from "@backend/playlist";
import { fetchPlaylist, renamePlaylist, describePlaylist, setPlaylistIcon, setPlaylistVisibility } from "@backend/playlist";
import Router from "@components/common/Router";

import AnimatePages from "@components/common/AnimatePages";
import PlaylistTracks from "@components/playlist/PlaylistTracks";

import { faUpload } from "@fortawesome/free-solid-svg-icons";
import { faCog } from "@fortawesome/free-solid-svg-icons";
import Button from "@components/common/Button";
import Modal, { displayModal } from "@components/common/Modal";

Expand All @@ -30,25 +30,57 @@ class PlaylistPage extends React.Component<any, IState> {
};
}

displayUploadButton = () => {
const button = document.getElementById("BannerUpload");
displaySettingsButton = () => {
const button = document.getElementById("PlaylistSettingsButton");
button.style.display = "block";
};

hideUploadButton = () => {
const button = document.getElementById("BannerUpload");
hideSettingsButton = () => {
const button = document.getElementById("PlaylistSettingsButton");
button.style.display = "none";
};

setBanner = async () => {
const url = document.getElementById("BannerURL") as HTMLInputElement;
await localStorage.setItem(`playlist-${this.state.playlist.id}-banner`, url.value);
this.setState({ banner: url.value });
editPlaylist = async () => {
const name = (document.getElementById("PlaylistNameInput") as HTMLInputElement).value;
const description = (document.getElementById("PlaylistDescriptionInput") as HTMLInputElement).value;
const icon = (document.getElementById("PlaylistIconURLInput") as HTMLInputElement).value;
const isPrivate = (document.getElementById("PlaylistPrivateInput") as HTMLInputElement).checked;
const banner = (document.getElementById("PlaylistBannerURLInput") as HTMLInputElement).value;

if (name !== this.state.playlist.name) {
await renamePlaylist(this.state.playlist.id, name);
console.log("Renamed playlist to " + name);
}
if (description !== this.state.playlist.description) {
await describePlaylist(this.state.playlist.id, description);
console.log("Changed playlist description to " + description);
}
if (icon !== this.state.playlist.icon) {
await setPlaylistIcon(this.state.playlist.id, icon);
console.log("Changed playlist icon to " + icon);
}
if (isPrivate !== this.state.playlist.isPrivate) {
await setPlaylistVisibility(this.state.playlist.id, isPrivate);
console.log("Changed playlist visibility to " + isPrivate);
}
localStorage.setItem(`playlist-${this.state.playlist.id}-banner`, banner);

this.setState({
banner: banner,
playlist: {
name: name,
description: description,
icon: icon,
isPrivate: isPrivate,
tracks: this.state.playlist.tracks,
}
});

this.hideModal();
};

hideModal = () => {
const modal = document.getElementById("PlaylistModal");
const modal = document.getElementById("PlaylistSettingsModal");
modal.style.display = "none";
};

Expand Down Expand Up @@ -87,8 +119,8 @@ class PlaylistPage extends React.Component<any, IState> {
<div className="PlaylistContainer">
<div
className="PlaylistHeader"
onMouseOver={this.displayUploadButton}
onMouseLeave={this.hideUploadButton}
onMouseOver={this.displaySettingsButton}
onMouseLeave={this.hideSettingsButton}
>
<div
className="PlaylistHeaderBG"
Expand All @@ -99,11 +131,7 @@ class PlaylistPage extends React.Component<any, IState> {
<h2>{this.state.playlist.name}</h2>
<p>{this.state.playlist.description}</p>
</div>
<Button id="BannerUpload" icon={faUpload} onClick={() => displayModal("PlaylistModal")} />
<Modal id="PlaylistModal" onSubmit={this.setBanner}>
<h2>Upload a banner</h2>
<input type="text" id="BannerURL" placeholder="Image URL" />
</Modal>
<Button id="PlaylistSettingsButton" icon={faCog} onClick={() => displayModal("PlaylistSettingsModal")} />
</div>
<div className="PlaylistContent">
{this.state.playlist.tracks.length > 0 ? (
Expand All @@ -113,6 +141,19 @@ class PlaylistPage extends React.Component<any, IState> {
)}
</div>
</div>
<Modal id="PlaylistSettingsModal" onSubmit={this.editPlaylist}>
<h2>Edit Playlist</h2>
<p>Name</p>
<input type="text" id="PlaylistNameInput" defaultValue={this.state.playlist.name} />
<p>Description</p>
<textarea id="PlaylistDescriptionInput" defaultValue={this.state.playlist.description} />
<p>Icon image URL</p>
<input type="text" id="PlaylistIconURLInput" defaultValue={this.state.playlist.icon} />
<p>Set as Private</p>
<input type="checkbox" id="PlaylistPrivateInput" defaultChecked={this.state.playlist.isPrivate} />
<p>Banner image URL</p>
<input type="text" id="PlaylistBannerURLInput" placeholder="Banner Url" />
</Modal>
</AnimatePages>
);
}
Expand Down

0 comments on commit f292141

Please sign in to comment.