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) {
|
function once(eventType: any, listener: (arg0: any) => void) {
|
||||||
on(eventType, handleEventOnce);
|
on(eventType, handleEventOnce);
|
||||||
|
|
||||||
function handleEventOnce(event) {
|
function handleEventOnce(event: any) {
|
||||||
listener(event);
|
listener(event);
|
||||||
off(eventType, handleEventOnce);
|
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 CSS from "csstype";
|
||||||
import { on } from "./events";
|
import { on } from "./events";
|
||||||
import ws from "./ws";
|
import ws from "./ws";
|
||||||
|
@ -11,6 +11,9 @@ export default function Playlists() {
|
||||||
|
|
||||||
const [playlists, setPlaylists] = useState<Playlist[]>([]);
|
const [playlists, setPlaylists] = useState<Playlist[]>([]);
|
||||||
const [active, setActive] = useState("");
|
const [active, setActive] = useState("");
|
||||||
|
const [title, setTitle] = useState("");
|
||||||
|
const [url, setUrl] = useState("");
|
||||||
|
const [output, setOutput] = useState("");
|
||||||
|
|
||||||
const activeStyle: CSS.Properties = {
|
const activeStyle: CSS.Properties = {
|
||||||
backgroundColor: "burlywood",
|
backgroundColor: "burlywood",
|
||||||
|
@ -31,7 +34,6 @@ export default function Playlists() {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const Play = (e: any) => {
|
const Play = (e: any) => {
|
||||||
console.log(e.target.dataset);
|
|
||||||
ws.send(
|
ws.send(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
event: "load_playlist",
|
event: "load_playlist",
|
||||||
|
@ -48,30 +50,81 @@ 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) => {
|
on("dnd:song_info", (e: any) => {
|
||||||
setActive(e.detail.playlist);
|
setActive(e.detail.playlist);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
on("dnd:new_playlist", (e: any) => {
|
||||||
|
fetchPlaylists();
|
||||||
|
setOutput("New playlist was added: " + e.details.title);
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section>
|
<>
|
||||||
<div id="items" className="item-container">
|
<section>
|
||||||
{playlists.map((playlist) => {
|
<div id="items" className="item-container">
|
||||||
return (
|
{playlists.map((playlist) => {
|
||||||
<div
|
return (
|
||||||
key={playlist.Id}
|
<div
|
||||||
onClick={Play}
|
key={playlist.Id}
|
||||||
className="item"
|
onClick={Play}
|
||||||
data-id={playlist.Id}
|
className="item"
|
||||||
style={playlist.Id == active ? activeStyle : {}}
|
data-id={playlist.Id}
|
||||||
>
|
style={playlist.Id == active ? activeStyle : {}}
|
||||||
{playlist.Title}
|
>
|
||||||
</div>
|
{playlist.Title}
|
||||||
);
|
</div>
|
||||||
})}
|
);
|
||||||
<div className="item locked stop" onClick={Stop} data-id="reset">
|
})}
|
||||||
Stop
|
<div className="item locked stop" onClick={Stop} data-id="reset">
|
||||||
|
Stop
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
</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 { trigger, on } from "./events";
|
||||||
import Playlists from "./playlist";
|
import Playlists from "./playlist";
|
||||||
import ws from "./ws";
|
import ws from "./ws";
|
||||||
|
import Controls from "./controls";
|
||||||
|
|
||||||
function Content() {
|
function Content() {
|
||||||
ws.onmessage = (e) => {
|
ws.onmessage = (e) => {
|
||||||
|
@ -14,6 +15,7 @@ function Content() {
|
||||||
<>
|
<>
|
||||||
<h2 className="bot">Playlists</h2>
|
<h2 className="bot">Playlists</h2>
|
||||||
<Playlists />
|
<Playlists />
|
||||||
|
<Controls />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue