fixup! Time for React!
parent
8a019c0817
commit
05931eb8e9
|
@ -0,0 +1,98 @@
|
|||
import React, { useState } from "react";
|
||||
import CSS from "csstype";
|
||||
import { on } from "./events";
|
||||
import ws from "./ws";
|
||||
|
||||
export default function Controls() {
|
||||
const [channel, setChannel] = useState("");
|
||||
const [title, setTitle] = useState("");
|
||||
const [pos, setPos] = useState(0);
|
||||
const [len, setLen] = useState(0);
|
||||
const [song, setSong] = useState("");
|
||||
const [pause, setPause] = useState(true);
|
||||
|
||||
const linkStyle: CSS.Properties = {
|
||||
textDecoration: "none",
|
||||
};
|
||||
|
||||
const Next = () => {
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
event: "next",
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const Prev = () => {
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
event: "next",
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const msToTime = (duration: number) => {
|
||||
var milliseconds = (duration % 1000) / 100,
|
||||
seconds = Math.floor((duration / 1000) % 60),
|
||||
minutes = Math.floor((duration / (1000 * 60)) % 60),
|
||||
minutes = minutes < 10 ? 0 + minutes : minutes;
|
||||
seconds = seconds < 10 ? 0 + seconds : seconds;
|
||||
|
||||
return (
|
||||
minutes.toString().padStart(2, "0") +
|
||||
":" +
|
||||
seconds.toString().padStart(2, "0")
|
||||
);
|
||||
};
|
||||
|
||||
on("dnd:song_info", (e: any) => {
|
||||
setChannel(e.detail.channel);
|
||||
setTitle(e.detail.current);
|
||||
setPos(e.detail.position);
|
||||
setLen(e.detail.len);
|
||||
setSong("https://youtu.be/" + e.detail.song);
|
||||
setPause(e.detail.pause);
|
||||
});
|
||||
|
||||
on("dnd:song_position", (e: any) => {
|
||||
setPos(e.detail.position);
|
||||
setLen(e.detail.len);
|
||||
});
|
||||
|
||||
return (
|
||||
<section>
|
||||
<div id="info">
|
||||
<a
|
||||
href={song}
|
||||
id="link"
|
||||
style={linkStyle}
|
||||
className={pause ? "u-hidden" : ""}
|
||||
>
|
||||
<span id="channel">{channel}</span>
|
||||
<span> - </span>
|
||||
<span id="title">{title}</span>
|
||||
</a>
|
||||
|
||||
<div className="controls">
|
||||
<input
|
||||
id="prev"
|
||||
name="prev"
|
||||
type="button"
|
||||
value="prev"
|
||||
onClick={Prev}
|
||||
/>
|
||||
<span id="time" className={pause ? "u-hidden" : ""}>
|
||||
{msToTime(pos)} / {msToTime(len)}
|
||||
</span>
|
||||
<input
|
||||
id="next"
|
||||
name="next"
|
||||
type="button"
|
||||
value="next"
|
||||
onClick={Next}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
|
@ -9,7 +9,7 @@ function on(eventType: any, listener: { (event: any): void; (this: Document, ev:
|
|||
function once(eventType: any, listener: (arg0: any) => void) {
|
||||
on(eventType, handleEventOnce);
|
||||
|
||||
function handleEventOnce(event) {
|
||||
function handleEventOnce(event: any) {
|
||||
listener(event);
|
||||
off(eventType, handleEventOnce);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useEffect, useState, useCallback } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import CSS from "csstype";
|
||||
import { on } from "./events";
|
||||
import ws from "./ws";
|
||||
|
@ -11,6 +11,9 @@ export default function Playlists() {
|
|||
|
||||
const [playlists, setPlaylists] = useState<Playlist[]>([]);
|
||||
const [active, setActive] = useState("");
|
||||
const [title, setTitle] = useState("");
|
||||
const [url, setUrl] = useState("");
|
||||
const [output, setOutput] = useState("");
|
||||
|
||||
const activeStyle: CSS.Properties = {
|
||||
backgroundColor: "burlywood",
|
||||
|
@ -31,7 +34,6 @@ export default function Playlists() {
|
|||
}, []);
|
||||
|
||||
const Play = (e: any) => {
|
||||
console.log(e.target.dataset);
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
event: "load_playlist",
|
||||
|
@ -48,11 +50,33 @@ export default function Playlists() {
|
|||
);
|
||||
};
|
||||
|
||||
const AddPlaylist = () => {
|
||||
if (title == "" || url == "") {
|
||||
setOutput("Title or Url is empty!");
|
||||
}
|
||||
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
event: "add_playlist",
|
||||
payload: {
|
||||
title: title,
|
||||
url: url,
|
||||
},
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
on("dnd:song_info", (e: any) => {
|
||||
setActive(e.detail.playlist);
|
||||
});
|
||||
|
||||
on("dnd:new_playlist", (e: any) => {
|
||||
fetchPlaylists();
|
||||
setOutput("New playlist was added: " + e.details.title);
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<section>
|
||||
<div id="items" className="item-container">
|
||||
{playlists.map((playlist) => {
|
||||
|
@ -73,5 +97,34 @@ export default function Playlists() {
|
|||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<div id="inputplaylist" className="input-container">
|
||||
<input
|
||||
className="u-full-width"
|
||||
name="title"
|
||||
type="text"
|
||||
placeholder="Enter name.."
|
||||
onChange={(e) => setTitle(e.target.value)}
|
||||
/>
|
||||
<input
|
||||
className="u-full-width"
|
||||
name="url"
|
||||
type="text"
|
||||
placeholder="https://youtube.com/playlist?list=..."
|
||||
onChange={(e) => setUrl(e.target.value)}
|
||||
/>
|
||||
<input
|
||||
id="addplaylist"
|
||||
name="submit"
|
||||
value="Add"
|
||||
type="submit"
|
||||
onClick={AddPlaylist}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<p>{output}</p>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import { createRoot } from "react-dom/client";
|
|||
import { trigger, on } from "./events";
|
||||
import Playlists from "./playlist";
|
||||
import ws from "./ws";
|
||||
import Controls from "./controls";
|
||||
|
||||
function Content() {
|
||||
ws.onmessage = (e) => {
|
||||
|
@ -14,6 +15,7 @@ function Content() {
|
|||
<>
|
||||
<h2 className="bot">Playlists</h2>
|
||||
<Playlists />
|
||||
<Controls />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue