fixup! Time for React!

Stein Ivar Berghei 2023-10-27 11:35:04 +02:00
parent 8a019c0817
commit 05931eb8e9
4 changed files with 175 additions and 22 deletions

98
src/app/controls.tsx Normal file
View File

@ -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>
);
}

View File

@ -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);
}

View File

@ -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>
</>
);
}

View File

@ -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 />
</>
);
}