From 95f27a2acc0ff170ea287679893813499bc6475f Mon Sep 17 00:00:00 2001
From: D0m1nos <21263344+D0m1nos@users.noreply.github.com>
Date: Wed, 9 Oct 2024 20:31:56 +0200
Subject: [PATCH 01/54] playlistView and initial addToPlaylist button
---
src/main/router/songs-pool-router.ts | 20 ++-
.../src/components/scenes/MainScene.tsx | 47 ++++----
.../src/components/song/PlaylistView.tsx | 114 ++++++++++++++++++
src/renderer/src/components/song/SongView.tsx | 3 +-
.../song/context-menu/items/AddToPlaylist.tsx | 29 +++++
.../song/context-menu/items/PlayNext.tsx | 30 ++---
6 files changed, 186 insertions(+), 57 deletions(-)
create mode 100644 src/renderer/src/components/song/PlaylistView.tsx
create mode 100644 src/renderer/src/components/song/context-menu/items/AddToPlaylist.tsx
diff --git a/src/main/router/songs-pool-router.ts b/src/main/router/songs-pool-router.ts
index f7e7fa9a..2795b2fe 100644
--- a/src/main/router/songs-pool-router.ts
+++ b/src/main/router/songs-pool-router.ts
@@ -1,20 +1,20 @@
-import { Router } from '../lib/route-pass/Router';
-import { none, some } from '../lib/rust-like-utils-backend/Optional';
-import { filter } from '../lib/song/filter';
-import order from '../lib/song/order';
-import { indexMapper } from '../lib/song/indexMapper';
-import { Storage } from '../lib/storage/Storage';
-
-
+import { Router } from "../lib/route-pass/Router";
+import { none, some } from "../lib/rust-like-utils-backend/Optional";
+import { filter } from "../lib/song/filter";
+import order from "../lib/song/order";
+import { indexMapper } from "../lib/song/indexMapper";
+import { Storage } from "../lib/storage/Storage";
Router.respond("query::songsPool::init", (_evt, payload) => {
const indexes = Storage.getTable("system").get("indexes");
+ console.log(indexes);
if (indexes.isNone) {
return none();
}
const filtered = filter(indexes.value, payload);
+ console.log(filtered);
return some({
initialIndex: 0,
@@ -22,8 +22,6 @@ Router.respond("query::songsPool::init", (_evt, payload) => {
});
});
-
-
const BUFFER_SIZE = 50;
Router.respond("query::songsPool", (_evt, request, payload) => {
@@ -59,4 +57,4 @@ Router.respond("query::songsPool", (_evt, request, payload) => {
total: songs.length,
items: songs.slice(request.index * BUFFER_SIZE, (request.index + 1) * BUFFER_SIZE)
});
-});
\ No newline at end of file
+});
diff --git a/src/renderer/src/components/scenes/MainScene.tsx b/src/renderer/src/components/scenes/MainScene.tsx
index 19d4dc1b..436e8b42 100644
--- a/src/renderer/src/components/scenes/MainScene.tsx
+++ b/src/renderer/src/components/scenes/MainScene.tsx
@@ -1,25 +1,22 @@
-import SongView from '../song/SongView';
-import { createEffect, createSignal, onMount } from 'solid-js';
-import Fa from 'solid-fa';
-import { faGear, faHeadphonesSimple, faListUl, faMusic } from '@fortawesome/free-solid-svg-icons';
-import { GLOBAL_ICON_SCALE } from '../../App';
-import SongDetail from '../song/SongDetail';
-import QueueView from '../queue/QueueView';
-import NoticeContainer from '../notice/NoticeContainer';
-import SettingsView from '../settings/SettingsView';
-
-
+import SongView from "../song/SongView";
+import { createEffect, createSignal, onMount } from "solid-js";
+import Fa from "solid-fa";
+import { faGear, faHeadphonesSimple, faListUl, faMusic } from "@fortawesome/free-solid-svg-icons";
+import { GLOBAL_ICON_SCALE } from "../../App";
+import SongDetail from "../song/SongDetail";
+import QueueView from "../queue/QueueView";
+import NoticeContainer from "../notice/NoticeContainer";
+import SettingsView from "../settings/SettingsView";
+import PlaylistView from "../song/PlaylistView";
const [active, setActive] = createSignal(0);
-export { active }
+export { active };
export const ACTIVE_ALL_SONGS = 0;
export const ACTIVE_QUEUE = 1;
export const ACTIVE_PLAYLISTS = 2;
export const ACTIVE_SETTINGS = 3;
-
-
export default function MainScene() {
let sidePane;
@@ -33,31 +30,31 @@ export default function MainScene() {
setActive(0)} title={"All songs"}>
-
+
setActive(1)} title={"Current queue"}>
-
+
setActive(2)} title={"Playlists"}>
-
+
setActive(3)} title={"Settings"}>
-
+
-
-
- Playlists
-
+
+
+
+
-
+
-
+
);
-}
\ No newline at end of file
+}
diff --git a/src/renderer/src/components/song/PlaylistView.tsx b/src/renderer/src/components/song/PlaylistView.tsx
new file mode 100644
index 00000000..80b1427b
--- /dev/null
+++ b/src/renderer/src/components/song/PlaylistView.tsx
@@ -0,0 +1,114 @@
+import { Component, createEffect, createSignal, onCleanup, onMount } from "solid-js";
+import { Optional, ResourceID, SongsQueryPayload, Tag } from "../../../../@types";
+import { SearchQueryError } from "../../../../main/lib/search-parser/@search-types";
+import { namespace } from "../../App";
+import "../../assets/css/song/song-view.css";
+import Impulse from "../../lib/Impulse";
+import { none, some } from "../../lib/rust-like-utils-client/Optional";
+import InfiniteScroller from "../InfiniteScroller";
+import Search from "../search/Search";
+import PlayNext from "./context-menu/items/PlayNext";
+import SongItem from "./SongItem";
+
+// export type SongViewProps = {
+// isAllSongs?: boolean;
+// isQueue?: boolean;
+// playlist?: string;
+// };
+
+export type PlaylistViewProps = {};
+
+const PlaylistView: Component = (props) => {
+ // const querySignal = createSignal("");
+ // const [query] = querySignal;
+
+ // const tagsSignal = createSignal([], { equals: false });
+ // const [tags] = tagsSignal;
+
+ // const [order, setOrder] = createSignal("title:asc");
+ // const [count, setCount] = createSignal(0);
+
+ // const [, setPayload] = createSignal({
+ // view: props,
+ // order: order(),
+ // tags: tags()
+ // });
+
+ // const [searchError, setSearchError] = createSignal>(none(), {
+ // equals: false
+ // });
+ // const resetListing = new Impulse();
+
+ // const searchSongs = async () => {
+ // const o = order();
+ // const t = tags();
+ // const parsedQuery = await window.api.request("parse::search", query());
+
+ // if (parsedQuery.type === "error") {
+ // setSearchError(some(parsedQuery));
+ // return;
+ // }
+
+ // setSearchError(none());
+ // setPayload({
+ // view: props,
+ // searchQuery: parsedQuery,
+ // order: o,
+ // tags: t
+ // });
+ // resetListing.pulse();
+ // };
+
+ // onMount(() => {
+ // createEffect(searchSongs);
+ // window.api.listen("songView::reset", resetListing.pulse.bind(resetListing));
+ // });
+
+ // onCleanup(() => {
+ // window.api.removeListener("songView::reset", resetListing.pulse.bind(resetListing));
+ // });
+
+ // const createQueue = async (songResource: ResourceID) => {
+ // console.log("create queue");
+
+ // await window.api.request("queue::create", {
+ // startSong: songResource,
+ // ...payload()
+ // });
+ // };
+
+ const group = namespace.create(true);
+
+ return (
+
+ yooo
+ {/*
+ */}
+ {/*
+ No songs...
}
+ builder={(s) => (
+
+
+ Add to playlist
+
+ )}
+ />
+ */}
+
+ );
+};
+
+export default PlaylistView;
diff --git a/src/renderer/src/components/song/SongView.tsx b/src/renderer/src/components/song/SongView.tsx
index 0d3e1bf4..46271ffc 100644
--- a/src/renderer/src/components/song/SongView.tsx
+++ b/src/renderer/src/components/song/SongView.tsx
@@ -9,6 +9,7 @@ import InfiniteScroller from "../InfiniteScroller";
import Search from "../search/Search";
import PlayNext from "./context-menu/items/PlayNext";
import SongItem from "./SongItem";
+import AddToPlaylist from "./context-menu/items/AddToPlaylist";
export type SongViewProps = {
isAllSongs?: boolean;
@@ -98,7 +99,7 @@ const SongView: Component = (props) => {
builder={(s) => (
- Add to playlist
+
)}
/>
diff --git a/src/renderer/src/components/song/context-menu/items/AddToPlaylist.tsx b/src/renderer/src/components/song/context-menu/items/AddToPlaylist.tsx
new file mode 100644
index 00000000..987ecce2
--- /dev/null
+++ b/src/renderer/src/components/song/context-menu/items/AddToPlaylist.tsx
@@ -0,0 +1,29 @@
+import { Component, createSignal, Show } from "solid-js";
+import { Song } from "../../../../../../@types";
+import SongContextMenuItem from "../SongContextMenuItem";
+
+type SongAddToPlaylistNextProps = {
+ song: Song;
+};
+
+const AddToPlaylist: Component = (props) => {
+ const [show, setShow] = createSignal(false);
+
+ window.api.listen("queue::created", () => {
+ setShow(true);
+ });
+
+ window.api.listen("queue::destroyed", () => {
+ setShow(false);
+ });
+
+ return (
+
+ console.log("click", props.song)}>
+ Add to Playlist
+
+
+ );
+};
+
+export default AddToPlaylist;
diff --git a/src/renderer/src/components/song/context-menu/items/PlayNext.tsx b/src/renderer/src/components/song/context-menu/items/PlayNext.tsx
index f1a1993c..fe4d59b7 100644
--- a/src/renderer/src/components/song/context-menu/items/PlayNext.tsx
+++ b/src/renderer/src/components/song/context-menu/items/PlayNext.tsx
@@ -1,20 +1,14 @@
-import { Component, createSignal, Show } from 'solid-js';
-import { Song } from '../../../../../../@types';
-import SongContextMenuItem from '../SongContextMenuItem';
-
-
+import { Component, createSignal, Show } from "solid-js";
+import { Song } from "../../../../../../@types";
+import SongContextMenuItem from "../SongContextMenuItem";
type SongPlayNextProps = {
- path: Song["path"]
-}
-
-
+ path: Song["path"];
+};
-const PlayNext: Component = props => {
+const PlayNext: Component = (props) => {
const [show, setShow] = createSignal(false);
-
-
window.api.listen("queue::created", () => {
setShow(true);
});
@@ -23,17 +17,13 @@ const PlayNext: Component = props => {
setShow(false);
});
-
-
return (
- window.api.request('queue::playNext', props.path)}
- >Play Next
+ window.api.request("queue::playNext", props.path)}>
+ Play Next
+
);
};
-
-
-export default PlayNext;
\ No newline at end of file
+export default PlayNext;
From fcaf442220c9ba5bf71cc33b27f9ce33cac6af49 Mon Sep 17 00:00:00 2001
From: D0m1nos <21263344+D0m1nos@users.noreply.github.com>
Date: Wed, 9 Oct 2024 21:43:51 +0200
Subject: [PATCH 02/54] add playlist-router and playlist storage
---
src/RequestAPI.d.ts | 5 +++++
src/main/router/import.ts | 1 +
src/main/router/playlist-router.ts | 20 +++++++++++++++++++
.../song/context-menu/items/AddToPlaylist.tsx | 4 +++-
4 files changed, 29 insertions(+), 1 deletion(-)
create mode 100644 src/main/router/playlist-router.ts
diff --git a/src/RequestAPI.d.ts b/src/RequestAPI.d.ts
index f9606e2e..38b931fe 100644
--- a/src/RequestAPI.d.ts
+++ b/src/RequestAPI.d.ts
@@ -37,6 +37,11 @@ export type RequestAPI = {
"queue::create": (payload: QueueCreatePayload) => void;
"queue::shuffle": () => void;
+ "playlist::add": (playlistName: string, song: ResourceID) => void;
+ "playlist::remove": (song: ResourceID) => void;
+ "playlist::create": (name: string) => void;
+ "playlist::delete": (name: string) => void;
+
"dir::select": () => Optional;
"dir::autoGetOsuDir": () => Optional;
"dir::submit": (dir: string) => void;
diff --git a/src/main/router/import.ts b/src/main/router/import.ts
index 21daaaf7..6fe5b71e 100644
--- a/src/main/router/import.ts
+++ b/src/main/router/import.ts
@@ -11,3 +11,4 @@ import "./queue-router";
import "./resource-router";
import "./settings-router";
import "./songs-pool-router";
+import "./playlist-router";
diff --git a/src/main/router/playlist-router.ts b/src/main/router/playlist-router.ts
new file mode 100644
index 00000000..74eb52fe
--- /dev/null
+++ b/src/main/router/playlist-router.ts
@@ -0,0 +1,20 @@
+import { Router } from "../lib/route-pass/Router";
+import { Storage } from "../lib/storage/Storage";
+
+Router.respond("playlist::add", (_evt, playlistName, song) => {
+ console.log("add this to " + playlistName + ": " + song);
+
+ const playlists = Storage.getTable("playlists");
+ let playlist = playlists.get(playlistName);
+ //temporary, playlist should already exist
+ if (playlist.isNone) {
+ // create playlist
+ playlists.write(playlistName, []);
+ }
+ playlist = playlists.get(playlistName);
+
+ playlist.value.push(song);
+ playlists.write(playlistName, playlist.value);
+ console.log("MONKA", playlists);
+ console.log(playlist.value);
+});
diff --git a/src/renderer/src/components/song/context-menu/items/AddToPlaylist.tsx b/src/renderer/src/components/song/context-menu/items/AddToPlaylist.tsx
index 987ecce2..f2bae56d 100644
--- a/src/renderer/src/components/song/context-menu/items/AddToPlaylist.tsx
+++ b/src/renderer/src/components/song/context-menu/items/AddToPlaylist.tsx
@@ -19,7 +19,9 @@ const AddToPlaylist: Component = (props) => {
return (
- console.log("click", props.song)}>
+ window.api.request("playlist::add", "PlaylistOne", props.song.path)}
+ >
Add to Playlist
From 2880308d24f2bddf914246cb5bb2f33f3da0967b Mon Sep 17 00:00:00 2001
From: D0m1nos <21263344+D0m1nos@users.noreply.github.com>
Date: Wed, 9 Oct 2024 22:23:10 +0200
Subject: [PATCH 03/54] show playlist name on the UI
---
src/RequestAPI.d.ts | 2 +
src/main/router/playlist-router.ts | 50 +++++++++++-
.../src/components/song/PlaylistView.tsx | 80 +++----------------
3 files changed, 60 insertions(+), 72 deletions(-)
diff --git a/src/RequestAPI.d.ts b/src/RequestAPI.d.ts
index 38b931fe..34124124 100644
--- a/src/RequestAPI.d.ts
+++ b/src/RequestAPI.d.ts
@@ -64,6 +64,8 @@ export type RequestAPI = {
) => InfiniteScrollerResponse;
"query::queue::init": () => InfiniteScrollerInitResponse;
"query::queue": (request: InfiniteScrollerRequest) => InfiniteScrollerResponse;
+ "query::playlists::init": () => InfiniteScrollerInitResponse;
+ "query::playlists": (request: InfiniteScrollerRequest) => InfiniteScrollerResponse;
"save::localVolume": (volume: number, song: ResourceID) => void;
diff --git a/src/main/router/playlist-router.ts b/src/main/router/playlist-router.ts
index 74eb52fe..16d861df 100644
--- a/src/main/router/playlist-router.ts
+++ b/src/main/router/playlist-router.ts
@@ -1,4 +1,5 @@
import { Router } from "../lib/route-pass/Router";
+import { none, some } from "../lib/rust-like-utils-backend/Optional";
import { Storage } from "../lib/storage/Storage";
Router.respond("playlist::add", (_evt, playlistName, song) => {
@@ -13,8 +14,55 @@ Router.respond("playlist::add", (_evt, playlistName, song) => {
}
playlist = playlists.get(playlistName);
+ //todo: check if song is already in playlist
playlist.value.push(song);
playlists.write(playlistName, playlist.value);
- console.log("MONKA", playlists);
+ console.log(
+ "MONKA",
+ playlists.getStruct(),
+ Object.keys(Storage.getTable("playlists").getStruct())
+ );
console.log(playlist.value);
});
+
+const BUFFER_SIZE = 50;
+
+Router.respond("query::playlists::init", (_evt) => {
+ const playlists = Storage.getTable("playlists").getStruct();
+ const count = Object.keys(playlists).length;
+
+ return some({
+ initialIndex: 0,
+ count: count
+ });
+});
+
+Router.respond("query::playlists", (_evt, request) => {
+ const playlists = Object.keys(Storage.getTable("playlists").getStruct());
+
+ if (request.index < 0 || request.index > Math.floor(playlists.length / BUFFER_SIZE)) {
+ return none();
+ }
+
+ const start = request.index * BUFFER_SIZE;
+
+ if (request.direction === "up") {
+ return some({
+ index: request.index - 1,
+ total: playlists.length,
+ items: playlists.slice(start, start + BUFFER_SIZE)
+ });
+ }
+
+ return some({
+ index: request.index + 1,
+ total: playlists.length,
+ items: playlists.slice(start, start + BUFFER_SIZE)
+ });
+
+ return some({
+ index: request.index + 1,
+ total: playlists.length,
+ items: playlists
+ });
+});
diff --git a/src/renderer/src/components/song/PlaylistView.tsx b/src/renderer/src/components/song/PlaylistView.tsx
index 80b1427b..50ea1acd 100644
--- a/src/renderer/src/components/song/PlaylistView.tsx
+++ b/src/renderer/src/components/song/PlaylistView.tsx
@@ -19,69 +19,14 @@ import SongItem from "./SongItem";
export type PlaylistViewProps = {};
const PlaylistView: Component = (props) => {
- // const querySignal = createSignal("");
- // const [query] = querySignal;
-
- // const tagsSignal = createSignal([], { equals: false });
- // const [tags] = tagsSignal;
-
- // const [order, setOrder] = createSignal("title:asc");
- // const [count, setCount] = createSignal(0);
-
- // const [, setPayload] = createSignal({
- // view: props,
- // order: order(),
- // tags: tags()
- // });
-
- // const [searchError, setSearchError] = createSignal>(none(), {
- // equals: false
- // });
- // const resetListing = new Impulse();
-
- // const searchSongs = async () => {
- // const o = order();
- // const t = tags();
- // const parsedQuery = await window.api.request("parse::search", query());
-
- // if (parsedQuery.type === "error") {
- // setSearchError(some(parsedQuery));
- // return;
- // }
-
- // setSearchError(none());
- // setPayload({
- // view: props,
- // searchQuery: parsedQuery,
- // order: o,
- // tags: t
- // });
- // resetListing.pulse();
- // };
-
- // onMount(() => {
- // createEffect(searchSongs);
- // window.api.listen("songView::reset", resetListing.pulse.bind(resetListing));
- // });
-
- // onCleanup(() => {
- // window.api.removeListener("songView::reset", resetListing.pulse.bind(resetListing));
- // });
-
- // const createQueue = async (songResource: ResourceID) => {
- // console.log("create queue");
-
- // await window.api.request("queue::create", {
- // startSong: songResource,
- // ...payload()
- // });
- // };
+ const [count, setCount] = createSignal(0);
+ const resetListing = new Impulse();
+ const [payload, setPayload] = createSignal({});
const group = namespace.create(true);
return (
- yooo
{/* = (props) => {
error={searchError}
/>
*/}
- {/*
No songs...
}
- builder={(s) => (
-
-
- Add to playlist
-
- )}
+ fallback={No playlists...
}
+ builder={(s) => {s}
}
/>
- */}
);
};
From ee93ab13754fd5645937fabd6545d1924114381d Mon Sep 17 00:00:00 2001
From: D0m1nos <21263344+D0m1nos@users.noreply.github.com>
Date: Wed, 9 Oct 2024 22:56:33 +0200
Subject: [PATCH 04/54] add playlistItem
---
src/main/router/playlist-router.ts | 12 ++---
.../src/components/playlist/PlaylistItem.tsx | 28 ++++++++++
.../src/components/playlist/PlaylistView.tsx | 41 +++++++++++++++
.../src/components/scenes/MainScene.tsx | 2 +-
.../src/components/song/PlaylistView.tsx | 52 -------------------
5 files changed, 75 insertions(+), 60 deletions(-)
create mode 100644 src/renderer/src/components/playlist/PlaylistItem.tsx
create mode 100644 src/renderer/src/components/playlist/PlaylistView.tsx
delete mode 100644 src/renderer/src/components/song/PlaylistView.tsx
diff --git a/src/main/router/playlist-router.ts b/src/main/router/playlist-router.ts
index 16d861df..ee592746 100644
--- a/src/main/router/playlist-router.ts
+++ b/src/main/router/playlist-router.ts
@@ -40,7 +40,11 @@ Router.respond("query::playlists::init", (_evt) => {
Router.respond("query::playlists", (_evt, request) => {
const playlists = Object.keys(Storage.getTable("playlists").getStruct());
- if (request.index < 0 || request.index > Math.floor(playlists.length / BUFFER_SIZE)) {
+ if (
+ playlists === undefined ||
+ request.index < 0 ||
+ request.index > Math.floor(playlists.length / BUFFER_SIZE)
+ ) {
return none();
}
@@ -59,10 +63,4 @@ Router.respond("query::playlists", (_evt, request) => {
total: playlists.length,
items: playlists.slice(start, start + BUFFER_SIZE)
});
-
- return some({
- index: request.index + 1,
- total: playlists.length,
- items: playlists
- });
});
diff --git a/src/renderer/src/components/playlist/PlaylistItem.tsx b/src/renderer/src/components/playlist/PlaylistItem.tsx
new file mode 100644
index 00000000..a0fc82ff
--- /dev/null
+++ b/src/renderer/src/components/playlist/PlaylistItem.tsx
@@ -0,0 +1,28 @@
+import { Component } from "solid-js";
+import SongImage from "../song/SongImage";
+
+type PlaylistItemProps = {
+ playlistName: string;
+ group: string;
+};
+
+const PlaylistItem: Component = (props) => {
+ return (
+
+
+
+
+
+
{props.playlistName}
+
727 songs
+
7 hours 27 minutes
+
+
+
+ );
+};
+
+export default PlaylistItem;
diff --git a/src/renderer/src/components/playlist/PlaylistView.tsx b/src/renderer/src/components/playlist/PlaylistView.tsx
new file mode 100644
index 00000000..6ec54d2d
--- /dev/null
+++ b/src/renderer/src/components/playlist/PlaylistView.tsx
@@ -0,0 +1,41 @@
+import { Component, createSignal } from "solid-js";
+import "../../assets/css/song/song-view.css";
+import InfiniteScroller from "../InfiniteScroller";
+import PlaylistItem from "./PlaylistItem";
+import { namespace } from "@renderer/App";
+
+export type PlaylistViewProps = {};
+
+const PlaylistView: Component = (props) => {
+ const [count, setCount] = createSignal(0);
+ // const resetListing = new Impulse();
+ // const [payload, setPayload] = createSignal({});
+
+ const group = namespace.create(true);
+
+ return (
+
+ {/*
+ */}
+ You have {count()} playlists
+ No playlists...
}
+ builder={(s) => }
+ />
+
+ );
+};
+
+export default PlaylistView;
diff --git a/src/renderer/src/components/scenes/MainScene.tsx b/src/renderer/src/components/scenes/MainScene.tsx
index 436e8b42..29b7b28c 100644
--- a/src/renderer/src/components/scenes/MainScene.tsx
+++ b/src/renderer/src/components/scenes/MainScene.tsx
@@ -7,7 +7,7 @@ import SongDetail from "../song/SongDetail";
import QueueView from "../queue/QueueView";
import NoticeContainer from "../notice/NoticeContainer";
import SettingsView from "../settings/SettingsView";
-import PlaylistView from "../song/PlaylistView";
+import PlaylistView from "../playlist/PlaylistView";
const [active, setActive] = createSignal(0);
diff --git a/src/renderer/src/components/song/PlaylistView.tsx b/src/renderer/src/components/song/PlaylistView.tsx
deleted file mode 100644
index 50ea1acd..00000000
--- a/src/renderer/src/components/song/PlaylistView.tsx
+++ /dev/null
@@ -1,52 +0,0 @@
-import { Component, createEffect, createSignal, onCleanup, onMount } from "solid-js";
-import { Optional, ResourceID, SongsQueryPayload, Tag } from "../../../../@types";
-import { SearchQueryError } from "../../../../main/lib/search-parser/@search-types";
-import { namespace } from "../../App";
-import "../../assets/css/song/song-view.css";
-import Impulse from "../../lib/Impulse";
-import { none, some } from "../../lib/rust-like-utils-client/Optional";
-import InfiniteScroller from "../InfiniteScroller";
-import Search from "../search/Search";
-import PlayNext from "./context-menu/items/PlayNext";
-import SongItem from "./SongItem";
-
-// export type SongViewProps = {
-// isAllSongs?: boolean;
-// isQueue?: boolean;
-// playlist?: string;
-// };
-
-export type PlaylistViewProps = {};
-
-const PlaylistView: Component = (props) => {
- const [count, setCount] = createSignal(0);
- const resetListing = new Impulse();
- const [payload, setPayload] = createSignal({});
-
- const group = namespace.create(true);
-
- return (
-
- {/*
- */}
- No playlists...
}
- builder={(s) => {s}
}
- />
-
- );
-};
-
-export default PlaylistView;
From 1dbb91b3aa6b166d247efa012d417370b2efeb72 Mon Sep 17 00:00:00 2001
From: D0m1nos <21263344+D0m1nos@users.noreply.github.com>
Date: Wed, 9 Oct 2024 23:22:31 +0200
Subject: [PATCH 05/54] Switched to songs instead of ResourceIDs, implemented
PlaylistSongs api
---
src/@types.d.ts | 2 +-
src/RequestAPI.d.ts | 9 ++++-
src/main/router/playlist-router.ts | 38 ++++++++++++++++++
.../components/playlist/PlaylistSongsView.tsx | 40 +++++++++++++++++++
.../src/components/playlist/PlaylistView.tsx | 1 +
.../song/context-menu/items/AddToPlaylist.tsx | 2 +-
6 files changed, 88 insertions(+), 4 deletions(-)
create mode 100644 src/renderer/src/components/playlist/PlaylistSongsView.tsx
diff --git a/src/@types.d.ts b/src/@types.d.ts
index 0b7e4430..e840d5ae 100644
--- a/src/@types.d.ts
+++ b/src/@types.d.ts
@@ -121,7 +121,7 @@ export type TableMap = {
songs: { [key: ResourceID]: Song };
audio: { [key: ResourceID]: AudioSource };
images: { [key: ResourceID]: ImageSource };
- playlists: { [key: string]: ResourceID[] };
+ playlists: { [key: string]: Song[] };
settings: Settings;
system: System;
};
diff --git a/src/RequestAPI.d.ts b/src/RequestAPI.d.ts
index 34124124..7e403ec9 100644
--- a/src/RequestAPI.d.ts
+++ b/src/RequestAPI.d.ts
@@ -37,8 +37,8 @@ export type RequestAPI = {
"queue::create": (payload: QueueCreatePayload) => void;
"queue::shuffle": () => void;
- "playlist::add": (playlistName: string, song: ResourceID) => void;
- "playlist::remove": (song: ResourceID) => void;
+ "playlist::add": (playlistName: string, song: Song) => void;
+ "playlist::remove": (song: Song) => void;
"playlist::create": (name: string) => void;
"playlist::delete": (name: string) => void;
@@ -66,6 +66,11 @@ export type RequestAPI = {
"query::queue": (request: InfiniteScrollerRequest) => InfiniteScrollerResponse;
"query::playlists::init": () => InfiniteScrollerInitResponse;
"query::playlists": (request: InfiniteScrollerRequest) => InfiniteScrollerResponse;
+ "query::playlistSongs::init": (playlistName: string) => InfiniteScrollerInitResponse;
+ "query::playlistSongs": (
+ playlistName: string,
+ request: InfiniteScrollerRequest
+ ) => InfiniteScrollerResponse;
"save::localVolume": (volume: number, song: ResourceID) => void;
diff --git a/src/main/router/playlist-router.ts b/src/main/router/playlist-router.ts
index ee592746..fea6a601 100644
--- a/src/main/router/playlist-router.ts
+++ b/src/main/router/playlist-router.ts
@@ -64,3 +64,41 @@ Router.respond("query::playlists", (_evt, request) => {
items: playlists.slice(start, start + BUFFER_SIZE)
});
});
+
+Router.respond("query::playlistSongs::init", (_evt, playlistName) => {
+ const songs = Storage.getTable("playlists").get(playlistName);
+ const count = Object.keys(songs).length;
+
+ return some({
+ initialIndex: 0,
+ count: count
+ });
+});
+
+Router.respond("query::playlistSongs", (_evt, playlistName, request) => {
+ const songs = Storage.getTable("playlists").get(playlistName).value;
+
+ if (
+ songs === undefined ||
+ request.index < 0 ||
+ request.index > Math.floor(songs.length / BUFFER_SIZE)
+ ) {
+ return none();
+ }
+
+ const start = request.index * BUFFER_SIZE;
+
+ if (request.direction === "up") {
+ return some({
+ index: request.index - 1,
+ total: songs.length,
+ items: songs.slice(start, start + BUFFER_SIZE)
+ });
+ }
+
+ return some({
+ index: request.index + 1,
+ total: songs.length,
+ items: songs.slice(start, start + BUFFER_SIZE)
+ });
+});
diff --git a/src/renderer/src/components/playlist/PlaylistSongsView.tsx b/src/renderer/src/components/playlist/PlaylistSongsView.tsx
new file mode 100644
index 00000000..f44ec72c
--- /dev/null
+++ b/src/renderer/src/components/playlist/PlaylistSongsView.tsx
@@ -0,0 +1,40 @@
+import { Component } from "solid-js";
+import InfiniteScroller from "../InfiniteScroller";
+import SongItem from "../song/SongItem";
+import SongContextMenuItem from "../song/context-menu/SongContextMenuItem";
+
+type PlaylistSongsProps = {
+ playlistName: string;
+ group: string;
+};
+
+const PlaylistSongsView: Component = (props) => {
+ return (
+
+ No queue...
}
+ builder={(s) => (
+ window.api.request("queue::play", s.path)}
+ // onDrop={onDrop(s)}
+ >
+ {/* window.api.request("queue::removeSong", s.path)}>
+ Remove from queue
+ */}
+
+ )}
+ />
+
+ );
+};
+
+export default PlaylistSongsView;
diff --git a/src/renderer/src/components/playlist/PlaylistView.tsx b/src/renderer/src/components/playlist/PlaylistView.tsx
index 6ec54d2d..09feee27 100644
--- a/src/renderer/src/components/playlist/PlaylistView.tsx
+++ b/src/renderer/src/components/playlist/PlaylistView.tsx
@@ -13,6 +13,7 @@ const PlaylistView: Component = (props) => {
const group = namespace.create(true);
+ //todo: make something like App.tsx or MainScene.tsx to load a playlist (scene signal) or something with Routers
return (
{/*
= (props) => {
return (
window.api.request("playlist::add", "PlaylistOne", props.song.path)}
+ onClick={() => window.api.request("playlist::add", "PlaylistOne", props.song)}
>
Add to Playlist
From 342e3b4387290532b33ec8b65f16d12196783473 Mon Sep 17 00:00:00 2001
From: D0m1nos <21263344+D0m1nos@users.noreply.github.com>
Date: Thu, 10 Oct 2024 19:04:49 +0200
Subject: [PATCH 06/54] changed router type from Song[] to Playlist, playlist
info shown on ui
---
src/@types.d.ts | 9 ++++-
src/RequestAPI.d.ts | 3 +-
src/main/router/playlist-router.ts | 39 +++++++++++++------
src/main/router/songs-pool-router.ts | 4 +-
.../src/components/playlist/PlaylistItem.tsx | 9 +++--
.../src/components/playlist/PlaylistView.tsx | 2 +-
6 files changed, 46 insertions(+), 20 deletions(-)
diff --git a/src/@types.d.ts b/src/@types.d.ts
index e840d5ae..758528cc 100644
--- a/src/@types.d.ts
+++ b/src/@types.d.ts
@@ -121,11 +121,18 @@ export type TableMap = {
songs: { [key: ResourceID]: Song };
audio: { [key: ResourceID]: AudioSource };
images: { [key: ResourceID]: ImageSource };
- playlists: { [key: string]: Song[] };
+ playlists: { [key: string]: Playlist };
settings: Settings;
system: System;
};
+export type Playlist = {
+ name: string;
+ count: number;
+ length: number; // total length in seconds
+ songs: Song[];
+};
+
// I guess this is definition of all binary blob files that can be access from the database code?
export type BlobMap = {
times;
diff --git a/src/RequestAPI.d.ts b/src/RequestAPI.d.ts
index 7e403ec9..c3ef8a34 100644
--- a/src/RequestAPI.d.ts
+++ b/src/RequestAPI.d.ts
@@ -5,6 +5,7 @@ import type {
InfiniteScrollerRequest,
InfiniteScrollerResponse,
Optional,
+ Playlist,
QueueCreatePayload,
ResourceID,
ResourceTables,
@@ -65,7 +66,7 @@ export type RequestAPI = {
"query::queue::init": () => InfiniteScrollerInitResponse;
"query::queue": (request: InfiniteScrollerRequest) => InfiniteScrollerResponse;
"query::playlists::init": () => InfiniteScrollerInitResponse;
- "query::playlists": (request: InfiniteScrollerRequest) => InfiniteScrollerResponse;
+ "query::playlists": (request: InfiniteScrollerRequest) => InfiniteScrollerResponse;
"query::playlistSongs::init": (playlistName: string) => InfiniteScrollerInitResponse;
"query::playlistSongs": (
playlistName: string,
diff --git a/src/main/router/playlist-router.ts b/src/main/router/playlist-router.ts
index fea6a601..95f177a0 100644
--- a/src/main/router/playlist-router.ts
+++ b/src/main/router/playlist-router.ts
@@ -1,3 +1,4 @@
+import { Playlist } from "../../@types";
import { Router } from "../lib/route-pass/Router";
import { none, some } from "../lib/rust-like-utils-backend/Optional";
import { Storage } from "../lib/storage/Storage";
@@ -5,17 +6,20 @@ import { Storage } from "../lib/storage/Storage";
Router.respond("playlist::add", (_evt, playlistName, song) => {
console.log("add this to " + playlistName + ": " + song);
+ //Storage.removeTable("playlists");
const playlists = Storage.getTable("playlists");
let playlist = playlists.get(playlistName);
//temporary, playlist should already exist
if (playlist.isNone) {
// create playlist
- playlists.write(playlistName, []);
+ const empty = { count: 0, length: 0, songs: [] };
+ playlists.write(playlistName, empty);
}
playlist = playlists.get(playlistName);
- //todo: check if song is already in playlist
- playlist.value.push(song);
+ playlist.value.songs.push(song);
+ playlist.value.count = playlist.value.count + 1;
+ playlist.value.length = playlist.value.length + song.duration;
playlists.write(playlistName, playlist.value);
console.log(
"MONKA",
@@ -40,10 +44,23 @@ Router.respond("query::playlists::init", (_evt) => {
Router.respond("query::playlists", (_evt, request) => {
const playlists = Object.keys(Storage.getTable("playlists").getStruct());
+ //todo: there has to be a better way to do this
+ const p = Storage.getTable("playlists");
+ let test: Playlist[] = [];
+ playlists.forEach((v) => {
+ const plist = p.get(v);
+ test.push({
+ name: v,
+ count: plist.value.count,
+ length: plist.value.length,
+ songs: plist.value.songs
+ });
+ });
+
if (
- playlists === undefined ||
+ test === undefined ||
request.index < 0 ||
- request.index > Math.floor(playlists.length / BUFFER_SIZE)
+ request.index > Math.floor(test.length / BUFFER_SIZE)
) {
return none();
}
@@ -53,21 +70,21 @@ Router.respond("query::playlists", (_evt, request) => {
if (request.direction === "up") {
return some({
index: request.index - 1,
- total: playlists.length,
- items: playlists.slice(start, start + BUFFER_SIZE)
+ total: test.length,
+ items: test.slice(start, start + BUFFER_SIZE)
});
}
return some({
index: request.index + 1,
- total: playlists.length,
- items: playlists.slice(start, start + BUFFER_SIZE)
+ total: test.length,
+ items: test.slice(start, start + BUFFER_SIZE)
});
});
Router.respond("query::playlistSongs::init", (_evt, playlistName) => {
const songs = Storage.getTable("playlists").get(playlistName);
- const count = Object.keys(songs).length;
+ const count = Object.keys(songs.value.songs).length;
return some({
initialIndex: 0,
@@ -76,7 +93,7 @@ Router.respond("query::playlistSongs::init", (_evt, playlistName) => {
});
Router.respond("query::playlistSongs", (_evt, playlistName, request) => {
- const songs = Storage.getTable("playlists").get(playlistName).value;
+ const songs = Storage.getTable("playlists").get(playlistName).value.songs;
if (
songs === undefined ||
diff --git a/src/main/router/songs-pool-router.ts b/src/main/router/songs-pool-router.ts
index 2795b2fe..4f30060e 100644
--- a/src/main/router/songs-pool-router.ts
+++ b/src/main/router/songs-pool-router.ts
@@ -7,14 +7,14 @@ import { Storage } from "../lib/storage/Storage";
Router.respond("query::songsPool::init", (_evt, payload) => {
const indexes = Storage.getTable("system").get("indexes");
- console.log(indexes);
+ //console.log(indexes);
if (indexes.isNone) {
return none();
}
const filtered = filter(indexes.value, payload);
- console.log(filtered);
+ // console.log(filtered);
return some({
initialIndex: 0,
diff --git a/src/renderer/src/components/playlist/PlaylistItem.tsx b/src/renderer/src/components/playlist/PlaylistItem.tsx
index a0fc82ff..ff9c8ef7 100644
--- a/src/renderer/src/components/playlist/PlaylistItem.tsx
+++ b/src/renderer/src/components/playlist/PlaylistItem.tsx
@@ -1,8 +1,9 @@
import { Component } from "solid-js";
import SongImage from "../song/SongImage";
+import { Playlist } from "src/@types";
type PlaylistItemProps = {
- playlistName: string;
+ playlist: Playlist;
group: string;
};
@@ -16,9 +17,9 @@ const PlaylistItem: Component = (props) => {
/>
-
{props.playlistName}
-
727 songs
-
7 hours 27 minutes
+
{props.playlist.name}
+
{props.playlist.count} songs
+
{props.playlist.length}
diff --git a/src/renderer/src/components/playlist/PlaylistView.tsx b/src/renderer/src/components/playlist/PlaylistView.tsx
index 09feee27..d86b1d53 100644
--- a/src/renderer/src/components/playlist/PlaylistView.tsx
+++ b/src/renderer/src/components/playlist/PlaylistView.tsx
@@ -33,7 +33,7 @@ const PlaylistView: Component = (props) => {
setCount={setCount}
// reset={resetListing}
fallback={No playlists...
}
- builder={(s) => }
+ builder={(s) => }
/>
);
From af9072422901b16d6c5d37ad2d381c24544f2f23 Mon Sep 17 00:00:00 2001
From: D0m1nos <21263344+D0m1nos@users.noreply.github.com>
Date: Fri, 11 Oct 2024 01:07:07 +0200
Subject: [PATCH 07/54] implement the other playlist request APIs
---
src/RequestAPI.d.ts | 4 +-
src/main/router/playlist-router.ts | 43 +++++++++++++++----
.../src/components/playlist/PlaylistItem.tsx | 22 +++++++++-
.../components/playlist/PlaylistSongsView.tsx | 3 +-
.../src/components/playlist/PlaylistView.tsx | 3 +-
5 files changed, 60 insertions(+), 15 deletions(-)
diff --git a/src/RequestAPI.d.ts b/src/RequestAPI.d.ts
index 61fa56cb..17a0d591 100644
--- a/src/RequestAPI.d.ts
+++ b/src/RequestAPI.d.ts
@@ -39,7 +39,7 @@ export type RequestAPI = {
"queue::shuffle": () => void;
"playlist::add": (playlistName: string, song: Song) => void;
- "playlist::remove": (song: Song) => void;
+ "playlist::remove": (playlistName: string, song: Song) => void;
"playlist::create": (name: string) => void;
"playlist::delete": (name: string) => void;
@@ -70,7 +70,7 @@ export type RequestAPI = {
"query::playlistSongs::init": (playlistName: string) => InfiniteScrollerInitResponse;
"query::playlistSongs": (
playlistName: string,
- request: InfiniteScrollerRequest
+ request: InfiniteScrollerRequest,
) => InfiniteScrollerResponse;
"save::localVolume": (volume: number, song: ResourceID) => void;
diff --git a/src/main/router/playlist-router.ts b/src/main/router/playlist-router.ts
index 95f177a0..45af8148 100644
--- a/src/main/router/playlist-router.ts
+++ b/src/main/router/playlist-router.ts
@@ -12,7 +12,7 @@ Router.respond("playlist::add", (_evt, playlistName, song) => {
//temporary, playlist should already exist
if (playlist.isNone) {
// create playlist
- const empty = { count: 0, length: 0, songs: [] };
+ const empty = { name: playlistName, count: 0, length: 0, songs: [] };
playlists.write(playlistName, empty);
}
playlist = playlists.get(playlistName);
@@ -24,11 +24,36 @@ Router.respond("playlist::add", (_evt, playlistName, song) => {
console.log(
"MONKA",
playlists.getStruct(),
- Object.keys(Storage.getTable("playlists").getStruct())
+ Object.keys(Storage.getTable("playlists").getStruct()),
);
console.log(playlist.value);
});
+Router.respond("playlist::create", (_evt, name) => {
+ console.log("create playlist " + name);
+ //todo: check if playlist already exists
+ const playlists = Storage.getTable("playlists");
+ const empty = { name: name, count: 0, length: 0, songs: [] };
+ playlists.write(name, empty);
+});
+
+Router.respond("playlist::delete", (_evt, name) => {
+ console.log("delete playlist " + name);
+ const playlists = Storage.getTable("playlists");
+ playlists.delete(name);
+});
+
+Router.respond("playlist::remove", (_evt, playlistName, song) => {
+ console.log("delete song from " + playlistName, song);
+ const playlists = Storage.getTable("playlists");
+ let playlist = playlists.get(playlistName);
+ const songIndex = playlist.value.songs.indexOf(song, 0);
+ if (songIndex > -1) {
+ playlist.value.songs.splice(songIndex, 1);
+ playlists.write(playlistName, playlist);
+ }
+});
+
const BUFFER_SIZE = 50;
Router.respond("query::playlists::init", (_evt) => {
@@ -37,7 +62,7 @@ Router.respond("query::playlists::init", (_evt) => {
return some({
initialIndex: 0,
- count: count
+ count: count,
});
});
@@ -53,7 +78,7 @@ Router.respond("query::playlists", (_evt, request) => {
name: v,
count: plist.value.count,
length: plist.value.length,
- songs: plist.value.songs
+ songs: plist.value.songs,
});
});
@@ -71,14 +96,14 @@ Router.respond("query::playlists", (_evt, request) => {
return some({
index: request.index - 1,
total: test.length,
- items: test.slice(start, start + BUFFER_SIZE)
+ items: test.slice(start, start + BUFFER_SIZE),
});
}
return some({
index: request.index + 1,
total: test.length,
- items: test.slice(start, start + BUFFER_SIZE)
+ items: test.slice(start, start + BUFFER_SIZE),
});
});
@@ -88,7 +113,7 @@ Router.respond("query::playlistSongs::init", (_evt, playlistName) => {
return some({
initialIndex: 0,
- count: count
+ count: count,
});
});
@@ -109,13 +134,13 @@ Router.respond("query::playlistSongs", (_evt, playlistName, request) => {
return some({
index: request.index - 1,
total: songs.length,
- items: songs.slice(start, start + BUFFER_SIZE)
+ items: songs.slice(start, start + BUFFER_SIZE),
});
}
return some({
index: request.index + 1,
total: songs.length,
- items: songs.slice(start, start + BUFFER_SIZE)
+ items: songs.slice(start, start + BUFFER_SIZE),
});
});
diff --git a/src/renderer/src/components/playlist/PlaylistItem.tsx b/src/renderer/src/components/playlist/PlaylistItem.tsx
index ff9c8ef7..e16058a7 100644
--- a/src/renderer/src/components/playlist/PlaylistItem.tsx
+++ b/src/renderer/src/components/playlist/PlaylistItem.tsx
@@ -7,9 +7,27 @@ type PlaylistItemProps = {
group: string;
};
+function formatPlaylistTime(seconds: number) {
+ let minutes = 0;
+ let hours = 0;
+ if (seconds > 60) {
+ minutes = Math.floor(seconds / 60);
+ if (minutes > 60) {
+ hours = Math.floor(minutes / 60);
+ }
+ }
+
+ return hours + " hours " + minutes + " minutes";
+}
+
const PlaylistItem: Component = (props) => {
return (
-
+
{
+ console.log(props.playlist.songs);
+ }}
+ >
= (props) => {
{props.playlist.name}
{props.playlist.count} songs
-
{props.playlist.length}
+
{formatPlaylistTime(Math.round(props.playlist.length))}
diff --git a/src/renderer/src/components/playlist/PlaylistSongsView.tsx b/src/renderer/src/components/playlist/PlaylistSongsView.tsx
index f44ec72c..ad7547df 100644
--- a/src/renderer/src/components/playlist/PlaylistSongsView.tsx
+++ b/src/renderer/src/components/playlist/PlaylistSongsView.tsx
@@ -13,11 +13,12 @@ const PlaylistSongsView: Component
= (props) => {
No queue...
}
+ fallback={No songs...
}
builder={(s) => (
Date: Fri, 11 Oct 2024 23:03:33 +0200
Subject: [PATCH 08/54] basic playlist functionality on new ui
---
.../src/components/playlist/PlaylistItem.tsx | 6 +-
.../src/components/playlist/PlaylistView.tsx | 25 +++++++-
.../src/components/scenes/MainScene.tsx | 60 -------------------
.../song/song-detail/SongControls.tsx | 3 +-
.../components/song/song-list/SongList.tsx | 3 +-
.../src/scenes/main-scene/MainScene.tsx | 4 ++
.../src/scenes/main-scene/main.utils.ts | 5 ++
7 files changed, 40 insertions(+), 66 deletions(-)
delete mode 100644 src/renderer/src/components/scenes/MainScene.tsx
diff --git a/src/renderer/src/components/playlist/PlaylistItem.tsx b/src/renderer/src/components/playlist/PlaylistItem.tsx
index e16058a7..b87b0033 100644
--- a/src/renderer/src/components/playlist/PlaylistItem.tsx
+++ b/src/renderer/src/components/playlist/PlaylistItem.tsx
@@ -1,6 +1,7 @@
import { Component } from "solid-js";
import SongImage from "../song/SongImage";
import { Playlist } from "src/@types";
+import IconButton from "../icon-button/IconButton";
type PlaylistItemProps = {
playlist: Playlist;
@@ -23,7 +24,7 @@ function formatPlaylistTime(seconds: number) {
const PlaylistItem: Component = (props) => {
return (
{
console.log(props.playlist.songs);
}}
@@ -38,6 +39,9 @@ const PlaylistItem: Component
= (props) => {
{props.playlist.name}
{props.playlist.count} songs
{formatPlaylistTime(Math.round(props.playlist.length))}
+ window.api.request("playlist::delete", props.playlist.name)}>
+
+
diff --git a/src/renderer/src/components/playlist/PlaylistView.tsx b/src/renderer/src/components/playlist/PlaylistView.tsx
index 1a42c3c6..2791aa46 100644
--- a/src/renderer/src/components/playlist/PlaylistView.tsx
+++ b/src/renderer/src/components/playlist/PlaylistView.tsx
@@ -4,13 +4,21 @@ import InfiniteScroller from "../InfiniteScroller";
import PlaylistItem from "./PlaylistItem";
import { namespace } from "@renderer/App";
import Impulse from "@renderer/lib/Impulse";
+import IconButton from "../icon-button/IconButton";
export type PlaylistViewProps = {};
+
const PlaylistView: Component = (props) => {
const [count, setCount] = createSignal(0);
- // const resetListing = new Impulse();
+ const resetListing = new Impulse();
// const [payload, setPayload] = createSignal({});
+ const [playlistName, setPlaylistName] = createSignal("");
+
+ const createPlaylist = () => {
+ window.api.request("playlist::create", playlistName());
+ setPlaylistName("");
+ }
const group = namespace.create(true);
@@ -25,14 +33,25 @@ const PlaylistView: Component = (props) => {
error={searchError}
/>
*/}
- You have {count()} playlists
+
+
+ {setPlaylistName(e.target.value)}} />
+
+ {createPlaylist()}}>
+
+
+
+
+
+
+ You have {count()} playlists
No playlists...}
builder={(s) => }
/>
diff --git a/src/renderer/src/components/scenes/MainScene.tsx b/src/renderer/src/components/scenes/MainScene.tsx
deleted file mode 100644
index 29b7b28c..00000000
--- a/src/renderer/src/components/scenes/MainScene.tsx
+++ /dev/null
@@ -1,60 +0,0 @@
-import SongView from "../song/SongView";
-import { createEffect, createSignal, onMount } from "solid-js";
-import Fa from "solid-fa";
-import { faGear, faHeadphonesSimple, faListUl, faMusic } from "@fortawesome/free-solid-svg-icons";
-import { GLOBAL_ICON_SCALE } from "../../App";
-import SongDetail from "../song/SongDetail";
-import QueueView from "../queue/QueueView";
-import NoticeContainer from "../notice/NoticeContainer";
-import SettingsView from "../settings/SettingsView";
-import PlaylistView from "../playlist/PlaylistView";
-
-const [active, setActive] = createSignal(0);
-
-export { active };
-export const ACTIVE_ALL_SONGS = 0;
-export const ACTIVE_QUEUE = 1;
-export const ACTIVE_PLAYLISTS = 2;
-export const ACTIVE_SETTINGS = 3;
-
-export default function MainScene() {
- let sidePane;
-
- onMount(() => {
- createEffect(() => {
- sidePane.children[active()]?.scrollIntoView();
- });
- });
-
- return (
-
-
- setActive(0)} title={"All songs"}>
-
-
- setActive(1)} title={"Current queue"}>
-
-
- setActive(2)} title={"Playlists"}>
-
-
- setActive(3)} title={"Settings"}>
-
-
-
-
-
-
-
-
-
-
-
-
- );
-}
diff --git a/src/renderer/src/components/song/song-detail/SongControls.tsx b/src/renderer/src/components/song/song-detail/SongControls.tsx
index e2c94c8d..3a5c24e8 100644
--- a/src/renderer/src/components/song/song-detail/SongControls.tsx
+++ b/src/renderer/src/components/song/song-detail/SongControls.tsx
@@ -94,7 +94,8 @@ const SongControls: Component = () => {
{/* Right part */}
-
+ {/* // TODO - modal or something so the user can select a playlist */}
+ window.api.request("playlist::add", "test", song())} title="Add to playlist">
diff --git a/src/renderer/src/components/song/song-list/SongList.tsx b/src/renderer/src/components/song/song-list/SongList.tsx
index c2c434c9..7ed064a8 100644
--- a/src/renderer/src/components/song/song-list/SongList.tsx
+++ b/src/renderer/src/components/song/song-list/SongList.tsx
@@ -4,6 +4,7 @@ import { namespace } from "../../../App";
import Impulse from "../../../lib/Impulse";
import { none, some } from "../../../lib/rust-like-utils-client/Optional";
import InfiniteScroller from "../../InfiniteScroller";
+import AddToPlaylist from "../context-menu/items/AddToPlaylist";
import PlayNext from "../context-menu/items/PlayNext";
import SongItem from "../song-item/SongItem";
import SongListSearch from "../song-list-search/SongListSearch";
@@ -91,7 +92,7 @@ const SongList: Component = (props) => {
builder={(s) => (
- Add to playlist
+
)}
/>
diff --git a/src/renderer/src/scenes/main-scene/MainScene.tsx b/src/renderer/src/scenes/main-scene/MainScene.tsx
index ebff102d..bcfcb4a4 100644
--- a/src/renderer/src/scenes/main-scene/MainScene.tsx
+++ b/src/renderer/src/scenes/main-scene/MainScene.tsx
@@ -1,3 +1,4 @@
+import PlaylistView from "@renderer/components/playlist/PlaylistView";
import SongDetail from "../../components/song/song-detail/SongDetail";
import SongList from "../../components/song/song-list/SongList";
import { mainActiveTab, setMainActiveTab, Tab, TABS } from "./main.utils";
@@ -72,6 +73,9 @@ const TabContent: Component = () => {
+
+
+
diff --git a/src/renderer/src/scenes/main-scene/main.utils.ts b/src/renderer/src/scenes/main-scene/main.utils.ts
index f8451609..e1b22072 100644
--- a/src/renderer/src/scenes/main-scene/main.utils.ts
+++ b/src/renderer/src/scenes/main-scene/main.utils.ts
@@ -12,6 +12,11 @@ export const TABS = {
value: "songs",
icon: "ri-music-fill",
},
+ PLAYLISTS: {
+ label: "Playlists",
+ value: "playlists",
+ icon: "ri-settings-fill",
+ },
SETTINGS: {
label: "Settings",
value: "settings",
From 3b360dc39a5b47f851c82b770463dc7c20c86a1a Mon Sep 17 00:00:00 2001
From: D0m1nos <21263344+D0m1nos@users.noreply.github.com>
Date: Fri, 11 Oct 2024 23:23:45 +0200
Subject: [PATCH 09/54] changed file structure to be in line with the rest
---
.../playlist/{ => playlist-item}/PlaylistItem.tsx | 4 ++--
.../PlaylistSongList.tsx} | 12 ++++++------
.../playlist/{ => playlist-view}/PlaylistView.tsx | 8 ++++----
src/renderer/src/scenes/main-scene/MainScene.tsx | 2 +-
4 files changed, 13 insertions(+), 13 deletions(-)
rename src/renderer/src/components/playlist/{ => playlist-item}/PlaylistItem.tsx (92%)
rename src/renderer/src/components/playlist/{PlaylistSongsView.tsx => playlist-song-list/PlaylistSongList.tsx} (73%)
rename src/renderer/src/components/playlist/{ => playlist-view}/PlaylistView.tsx (89%)
diff --git a/src/renderer/src/components/playlist/PlaylistItem.tsx b/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
similarity index 92%
rename from src/renderer/src/components/playlist/PlaylistItem.tsx
rename to src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
index b87b0033..c1b69572 100644
--- a/src/renderer/src/components/playlist/PlaylistItem.tsx
+++ b/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
@@ -1,7 +1,7 @@
import { Component } from "solid-js";
-import SongImage from "../song/SongImage";
+import SongImage from "../../song/SongImage";
import { Playlist } from "src/@types";
-import IconButton from "../icon-button/IconButton";
+import IconButton from "../../icon-button/IconButton";
type PlaylistItemProps = {
playlist: Playlist;
diff --git a/src/renderer/src/components/playlist/PlaylistSongsView.tsx b/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx
similarity index 73%
rename from src/renderer/src/components/playlist/PlaylistSongsView.tsx
rename to src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx
index ad7547df..1ada9266 100644
--- a/src/renderer/src/components/playlist/PlaylistSongsView.tsx
+++ b/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx
@@ -1,14 +1,14 @@
import { Component } from "solid-js";
-import InfiniteScroller from "../InfiniteScroller";
-import SongItem from "../song/SongItem";
-import SongContextMenuItem from "../song/context-menu/SongContextMenuItem";
+import InfiniteScroller from "../../InfiniteScroller";
+import SongContextMenuItem from "../../song/context-menu/SongContextMenuItem";
+import SongItem from "../../song/song-item/SongItem";
-type PlaylistSongsProps = {
+type PlaylistSongListProps = {
playlistName: string;
group: string;
};
-const PlaylistSongsView: Component = (props) => {
+const PlaylistSongList: Component = (props) => {
return (
= (props) => {
);
};
-export default PlaylistSongsView;
+export default PlaylistSongList;
diff --git a/src/renderer/src/components/playlist/PlaylistView.tsx b/src/renderer/src/components/playlist/playlist-view/PlaylistView.tsx
similarity index 89%
rename from src/renderer/src/components/playlist/PlaylistView.tsx
rename to src/renderer/src/components/playlist/playlist-view/PlaylistView.tsx
index 2791aa46..c802f61d 100644
--- a/src/renderer/src/components/playlist/PlaylistView.tsx
+++ b/src/renderer/src/components/playlist/playlist-view/PlaylistView.tsx
@@ -1,10 +1,10 @@
import { Component, createSignal, onCleanup, onMount } from "solid-js";
-import "../../assets/css/song/song-view.css";
-import InfiniteScroller from "../InfiniteScroller";
-import PlaylistItem from "./PlaylistItem";
+import "../../../assets/css/song/song-view.css";
+import InfiniteScroller from "../../InfiniteScroller";
+import PlaylistItem from "../playlist-item/PlaylistItem";
import { namespace } from "@renderer/App";
import Impulse from "@renderer/lib/Impulse";
-import IconButton from "../icon-button/IconButton";
+import IconButton from "../../icon-button/IconButton";
export type PlaylistViewProps = {};
diff --git a/src/renderer/src/scenes/main-scene/MainScene.tsx b/src/renderer/src/scenes/main-scene/MainScene.tsx
index bcfcb4a4..8cee7f04 100644
--- a/src/renderer/src/scenes/main-scene/MainScene.tsx
+++ b/src/renderer/src/scenes/main-scene/MainScene.tsx
@@ -1,4 +1,4 @@
-import PlaylistView from "@renderer/components/playlist/PlaylistView";
+import PlaylistView from "@renderer/components/playlist/playlist-view/PlaylistView";
import SongDetail from "../../components/song/song-detail/SongDetail";
import SongList from "../../components/song/song-list/SongList";
import { mainActiveTab, setMainActiveTab, Tab, TABS } from "./main.utils";
From 512a25b314f77f3010d6bd1d377f33893a4653f3 Mon Sep 17 00:00:00 2001
From: D0m1nos <21263344+D0m1nos@users.noreply.github.com>
Date: Sat, 12 Oct 2024 00:56:31 +0200
Subject: [PATCH 10/54] playlistItem styling
---
.../playlist/playlist-item/PlaylistItem.tsx | 42 ++++++++++-----
.../playlist/playlist-item/styles.css | 52 +++++++++++++++++++
.../playlist/playlist-view/PlaylistView.tsx | 4 +-
.../src/scenes/main-scene/main.utils.ts | 2 +-
4 files changed, 84 insertions(+), 16 deletions(-)
create mode 100644 src/renderer/src/components/playlist/playlist-item/styles.css
diff --git a/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx b/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
index c1b69572..18170e27 100644
--- a/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
+++ b/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
@@ -2,6 +2,7 @@ import { Component } from "solid-js";
import SongImage from "../../song/SongImage";
import { Playlist } from "src/@types";
import IconButton from "../../icon-button/IconButton";
+import "./styles.css";
type PlaylistItemProps = {
playlist: Playlist;
@@ -21,27 +22,42 @@ function formatPlaylistTime(seconds: number) {
return hours + " hours " + minutes + " minutes";
}
+function getSongImage(playlist: Playlist) {
+ const songs = playlist.songs
+ if(songs.length === 0 || songs[0].bg === undefined || songs[0].bg === "") {
+ return "";
+ } else {
+ return songs[0].bg;
+ }
+}
+
const PlaylistItem: Component = (props) => {
return (
{
console.log(props.playlist.songs);
}}
>
-
-
+
+
+
+
-
-
{props.playlist.name}
-
{props.playlist.count} songs
-
{formatPlaylistTime(Math.round(props.playlist.length))}
-
window.api.request("playlist::delete", props.playlist.name)}>
-
-
+
+
+
{props.playlist.name}
+
{props.playlist.count} songs
+ {/*
{formatPlaylistTime(Math.round(props.playlist.length))}
*/}
+
+
+ window.api.request("playlist::delete", props.playlist.name)}>
+
+
+
diff --git a/src/renderer/src/components/playlist/playlist-item/styles.css b/src/renderer/src/components/playlist/playlist-item/styles.css
new file mode 100644
index 00000000..6833846c
--- /dev/null
+++ b/src/renderer/src/components/playlist/playlist-item/styles.css
@@ -0,0 +1,52 @@
+.playlist-item {
+ --image-size: 70px;
+
+ .playlist-item-container {
+ margin-top: 20px;
+ margin-left: 8px;
+ display: flex;
+ flex-direction: row;
+
+ .playlist-item__playlist-img {
+ margin: auto 6px auto 6px;
+ border-radius: var(--rounded-lg);
+ .song-image {
+ width: var(--image-size);
+ height: var(--image-size);
+ background-size: cover;
+ background-position: center;
+ border-radius: var(--rounded-lg);
+ }
+
+ }
+
+ .playlist-item__playlist-info {
+ display: flex;
+ flex-direction: row;
+ margin-left: 6px;
+ justify-content: space-between;
+ width: 100%;
+
+ .playlist-item__playlist-info__text {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ font-weight: 300;
+ line-height: 24px;
+ }
+
+ .playlist-item__playlist-info__text h3 {
+ font-size: 28px;
+ }
+
+ .playlist-item__playlist-info__button {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ margin-right: 8px;
+ color: lightcoral;
+
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/renderer/src/components/playlist/playlist-view/PlaylistView.tsx b/src/renderer/src/components/playlist/playlist-view/PlaylistView.tsx
index c802f61d..13121b63 100644
--- a/src/renderer/src/components/playlist/playlist-view/PlaylistView.tsx
+++ b/src/renderer/src/components/playlist/playlist-view/PlaylistView.tsx
@@ -35,7 +35,7 @@ const PlaylistView: Component
= (props) => {
*/}
- You have {count()} playlists
+ {/* You have {count()} playlists
*/}
Date: Sat, 12 Oct 2024 01:40:03 +0200
Subject: [PATCH 11/54] fix static analysis failing
---
src/main/router/playlist-router.ts | 41 ++++++++++++++++++------------
1 file changed, 25 insertions(+), 16 deletions(-)
diff --git a/src/main/router/playlist-router.ts b/src/main/router/playlist-router.ts
index 45af8148..00745f5e 100644
--- a/src/main/router/playlist-router.ts
+++ b/src/main/router/playlist-router.ts
@@ -4,29 +4,17 @@ import { none, some } from "../lib/rust-like-utils-backend/Optional";
import { Storage } from "../lib/storage/Storage";
Router.respond("playlist::add", (_evt, playlistName, song) => {
- console.log("add this to " + playlistName + ": " + song);
-
- //Storage.removeTable("playlists");
const playlists = Storage.getTable("playlists");
let playlist = playlists.get(playlistName);
- //temporary, playlist should already exist
+
if (playlist.isNone) {
- // create playlist
- const empty = { name: playlistName, count: 0, length: 0, songs: [] };
- playlists.write(playlistName, empty);
+ return;
}
- playlist = playlists.get(playlistName);
playlist.value.songs.push(song);
playlist.value.count = playlist.value.count + 1;
playlist.value.length = playlist.value.length + song.duration;
playlists.write(playlistName, playlist.value);
- console.log(
- "MONKA",
- playlists.getStruct(),
- Object.keys(Storage.getTable("playlists").getStruct()),
- );
- console.log(playlist.value);
});
Router.respond("playlist::create", (_evt, name) => {
@@ -47,10 +35,15 @@ Router.respond("playlist::remove", (_evt, playlistName, song) => {
console.log("delete song from " + playlistName, song);
const playlists = Storage.getTable("playlists");
let playlist = playlists.get(playlistName);
+
+ if(playlist.isNone){
+ return;
+ }
+
const songIndex = playlist.value.songs.indexOf(song, 0);
if (songIndex > -1) {
playlist.value.songs.splice(songIndex, 1);
- playlists.write(playlistName, playlist);
+ playlists.write(playlistName, playlist.value);
}
});
@@ -74,6 +67,11 @@ Router.respond("query::playlists", (_evt, request) => {
let test: Playlist[] = [];
playlists.forEach((v) => {
const plist = p.get(v);
+
+ if(plist.isNone){
+ return;
+ }
+
test.push({
name: v,
count: plist.value.count,
@@ -109,6 +107,11 @@ Router.respond("query::playlists", (_evt, request) => {
Router.respond("query::playlistSongs::init", (_evt, playlistName) => {
const songs = Storage.getTable("playlists").get(playlistName);
+
+ if(songs.isNone){
+ return none();
+ }
+
const count = Object.keys(songs.value.songs).length;
return some({
@@ -118,7 +121,13 @@ Router.respond("query::playlistSongs::init", (_evt, playlistName) => {
});
Router.respond("query::playlistSongs", (_evt, playlistName, request) => {
- const songs = Storage.getTable("playlists").get(playlistName).value.songs;
+ const playlist = Storage.getTable("playlists").get(playlistName);
+
+ if(playlist.isNone){
+ return none();
+ }
+
+ const songs = playlist.value.songs;
if (
songs === undefined ||
From 5fc464622a2eb927bd8e28bb0d1040461c0bf915 Mon Sep 17 00:00:00 2001
From: D0m1nos <21263344+D0m1nos@users.noreply.github.com>
Date: Sat, 12 Oct 2024 01:43:54 +0200
Subject: [PATCH 12/54] fix warnings
---
.../playlist/playlist-item/PlaylistItem.tsx | 22 +++++++++----------
.../playlist-song-list/PlaylistSongList.tsx | 1 -
.../playlist/playlist-view/PlaylistView.tsx | 7 +++---
3 files changed, 14 insertions(+), 16 deletions(-)
diff --git a/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx b/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
index 18170e27..22f05890 100644
--- a/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
+++ b/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
@@ -9,18 +9,18 @@ type PlaylistItemProps = {
group: string;
};
-function formatPlaylistTime(seconds: number) {
- let minutes = 0;
- let hours = 0;
- if (seconds > 60) {
- minutes = Math.floor(seconds / 60);
- if (minutes > 60) {
- hours = Math.floor(minutes / 60);
- }
- }
+// function formatPlaylistTime(seconds: number) {
+// let minutes = 0;
+// let hours = 0;
+// if (seconds > 60) {
+// minutes = Math.floor(seconds / 60);
+// if (minutes > 60) {
+// hours = Math.floor(minutes / 60);
+// }
+// }
- return hours + " hours " + minutes + " minutes";
-}
+// return hours + " hours " + minutes + " minutes";
+// }
function getSongImage(playlist: Playlist) {
const songs = playlist.songs
diff --git a/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx b/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx
index 1ada9266..6572e841 100644
--- a/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx
+++ b/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx
@@ -1,6 +1,5 @@
import { Component } from "solid-js";
import InfiniteScroller from "../../InfiniteScroller";
-import SongContextMenuItem from "../../song/context-menu/SongContextMenuItem";
import SongItem from "../../song/song-item/SongItem";
type PlaylistSongListProps = {
diff --git a/src/renderer/src/components/playlist/playlist-view/PlaylistView.tsx b/src/renderer/src/components/playlist/playlist-view/PlaylistView.tsx
index 13121b63..3079667b 100644
--- a/src/renderer/src/components/playlist/playlist-view/PlaylistView.tsx
+++ b/src/renderer/src/components/playlist/playlist-view/PlaylistView.tsx
@@ -1,4 +1,4 @@
-import { Component, createSignal, onCleanup, onMount } from "solid-js";
+import { Component, createSignal } from "solid-js";
import "../../../assets/css/song/song-view.css";
import InfiniteScroller from "../../InfiniteScroller";
import PlaylistItem from "../playlist-item/PlaylistItem";
@@ -8,9 +8,8 @@ import IconButton from "../../icon-button/IconButton";
export type PlaylistViewProps = {};
-
-const PlaylistView: Component = (props) => {
- const [count, setCount] = createSignal(0);
+const PlaylistView: Component = () => {
+ const [_count, setCount] = createSignal(0);
const resetListing = new Impulse();
// const [payload, setPayload] = createSignal({});
const [playlistName, setPlaylistName] = createSignal("");
From e715cddbde9c6ea7e441beec979a731f8e6a3231 Mon Sep 17 00:00:00 2001
From: D0m1nos <21263344+D0m1nos@users.noreply.github.com>
Date: Sat, 12 Oct 2024 01:49:23 +0200
Subject: [PATCH 13/54] more warnings fixed
---
src/main/router/playlist-router.ts | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/main/router/playlist-router.ts b/src/main/router/playlist-router.ts
index 00745f5e..44f01986 100644
--- a/src/main/router/playlist-router.ts
+++ b/src/main/router/playlist-router.ts
@@ -5,7 +5,7 @@ import { Storage } from "../lib/storage/Storage";
Router.respond("playlist::add", (_evt, playlistName, song) => {
const playlists = Storage.getTable("playlists");
- let playlist = playlists.get(playlistName);
+ const playlist = playlists.get(playlistName);
if (playlist.isNone) {
return;
@@ -34,7 +34,7 @@ Router.respond("playlist::delete", (_evt, name) => {
Router.respond("playlist::remove", (_evt, playlistName, song) => {
console.log("delete song from " + playlistName, song);
const playlists = Storage.getTable("playlists");
- let playlist = playlists.get(playlistName);
+ const playlist = playlists.get(playlistName);
if(playlist.isNone){
return;
@@ -64,7 +64,7 @@ Router.respond("query::playlists", (_evt, request) => {
//todo: there has to be a better way to do this
const p = Storage.getTable("playlists");
- let test: Playlist[] = [];
+ const playlistsInfo: Playlist[] = [];
playlists.forEach((v) => {
const plist = p.get(v);
@@ -72,7 +72,7 @@ Router.respond("query::playlists", (_evt, request) => {
return;
}
- test.push({
+ playlistsInfo.push({
name: v,
count: plist.value.count,
length: plist.value.length,
@@ -81,9 +81,9 @@ Router.respond("query::playlists", (_evt, request) => {
});
if (
- test === undefined ||
+ playlistsInfo === undefined ||
request.index < 0 ||
- request.index > Math.floor(test.length / BUFFER_SIZE)
+ request.index > Math.floor(playlistsInfo.length / BUFFER_SIZE)
) {
return none();
}
@@ -93,15 +93,15 @@ Router.respond("query::playlists", (_evt, request) => {
if (request.direction === "up") {
return some({
index: request.index - 1,
- total: test.length,
- items: test.slice(start, start + BUFFER_SIZE),
+ total: playlistsInfo.length,
+ items: playlistsInfo.slice(start, start + BUFFER_SIZE),
});
}
return some({
index: request.index + 1,
- total: test.length,
- items: test.slice(start, start + BUFFER_SIZE),
+ total: playlistsInfo.length,
+ items: playlistsInfo.slice(start, start + BUFFER_SIZE),
});
});
From f0934f6dc00647e40cd588e1881ea063e610cb4f Mon Sep 17 00:00:00 2001
From: D0m1nos <21263344+D0m1nos@users.noreply.github.com>
Date: Sat, 12 Oct 2024 15:33:57 +0200
Subject: [PATCH 14/54] basic playlist scenes
---
src/main/router/playlist-router.ts | 8 +-
.../playlist/playlist-item/PlaylistItem.tsx | 19 +++--
.../playlist/playlist-list/PlaylistList.tsx | 81 +++++++++++++++++++
.../playlist-song-list/PlaylistSongList.tsx | 2 +-
.../playlist/playlist-view/PlaylistView.tsx | 74 ++++++-----------
.../playlist-view/playlist-view.utils.ts | 9 +++
6 files changed, 128 insertions(+), 65 deletions(-)
create mode 100644 src/renderer/src/components/playlist/playlist-list/PlaylistList.tsx
create mode 100644 src/renderer/src/components/playlist/playlist-view/playlist-view.utils.ts
diff --git a/src/main/router/playlist-router.ts b/src/main/router/playlist-router.ts
index 44f01986..8f54c0f6 100644
--- a/src/main/router/playlist-router.ts
+++ b/src/main/router/playlist-router.ts
@@ -36,7 +36,7 @@ Router.respond("playlist::remove", (_evt, playlistName, song) => {
const playlists = Storage.getTable("playlists");
const playlist = playlists.get(playlistName);
- if(playlist.isNone){
+ if (playlist.isNone) {
return;
}
@@ -68,7 +68,7 @@ Router.respond("query::playlists", (_evt, request) => {
playlists.forEach((v) => {
const plist = p.get(v);
- if(plist.isNone){
+ if (plist.isNone) {
return;
}
@@ -108,7 +108,7 @@ Router.respond("query::playlists", (_evt, request) => {
Router.respond("query::playlistSongs::init", (_evt, playlistName) => {
const songs = Storage.getTable("playlists").get(playlistName);
- if(songs.isNone){
+ if (songs.isNone) {
return none();
}
@@ -123,7 +123,7 @@ Router.respond("query::playlistSongs::init", (_evt, playlistName) => {
Router.respond("query::playlistSongs", (_evt, playlistName, request) => {
const playlist = Storage.getTable("playlists").get(playlistName);
- if(playlist.isNone){
+ if (playlist.isNone) {
return none();
}
diff --git a/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx b/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
index 22f05890..6c0d9220 100644
--- a/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
+++ b/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
@@ -1,8 +1,9 @@
-import { Component } from "solid-js";
-import SongImage from "../../song/SongImage";
-import { Playlist } from "src/@types";
import IconButton from "../../icon-button/IconButton";
+import SongImage from "../../song/SongImage";
+import { PLAYLIST_SCENE_SONGS, setPlaylistActiveScene } from "../playlist-view/playlist-view.utils";
import "./styles.css";
+import { Component } from "solid-js";
+import { Playlist } from "src/@types";
type PlaylistItemProps = {
playlist: Playlist;
@@ -23,8 +24,8 @@ type PlaylistItemProps = {
// }
function getSongImage(playlist: Playlist) {
- const songs = playlist.songs
- if(songs.length === 0 || songs[0].bg === undefined || songs[0].bg === "") {
+ const songs = playlist.songs;
+ if (songs.length === 0 || songs[0].bg === undefined || songs[0].bg === "") {
return "";
} else {
return songs[0].bg;
@@ -37,14 +38,12 @@ const PlaylistItem: Component = (props) => {
class="playlist-item"
onClick={() => {
console.log(props.playlist.songs);
+ setPlaylistActiveScene(PLAYLIST_SCENE_SONGS);
}}
>
-
+
@@ -54,7 +53,7 @@ const PlaylistItem: Component
= (props) => {
{/* {formatPlaylistTime(Math.round(props.playlist.length))}
*/}
- window.api.request("playlist::delete", props.playlist.name)}>
+ window.api.request("playlist::delete", props.playlist.name)}>
diff --git a/src/renderer/src/components/playlist/playlist-list/PlaylistList.tsx b/src/renderer/src/components/playlist/playlist-list/PlaylistList.tsx
new file mode 100644
index 00000000..02600cdc
--- /dev/null
+++ b/src/renderer/src/components/playlist/playlist-list/PlaylistList.tsx
@@ -0,0 +1,81 @@
+import "../../../assets/css/song/song-view.css";
+import InfiniteScroller from "../../InfiniteScroller";
+import IconButton from "../../icon-button/IconButton";
+import PlaylistItem from "../playlist-item/PlaylistItem";
+import {
+ PLAYLIST_SCENE_CREATE,
+ setPlaylistActiveScene,
+} from "../playlist-view/playlist-view.utils";
+import { namespace } from "@renderer/App";
+import Impulse from "@renderer/lib/Impulse";
+import { Component, createSignal } from "solid-js";
+
+export type PlaylistListProps = {};
+
+const PlaylistList: Component
= () => {
+ const [_count, setCount] = createSignal(0);
+ const resetListing = new Impulse();
+ // const [payload, setPayload] = createSignal({});
+ const [playlistName, setPlaylistName] = createSignal("");
+
+ const createPlaylist = () => {
+ // last check is probably unnecessary
+ if (playlistName().length === 0 || playlistName() === undefined || playlistName() === "") {
+ return;
+ }
+ window.api.request("playlist::create", playlistName().trim());
+ setPlaylistName("");
+ };
+
+ const group = namespace.create(true);
+
+ return (
+
+ {/*
+ */}
+
+
+ {
+ // setPlaylistName(e.target.value);
+ // }}
+ />
+
+ {
+ createPlaylist(); //TODO: remove
+ setPlaylistActiveScene(PLAYLIST_SCENE_CREATE);
+ }}
+ >
+
+
+
+
+
+
+ {/*
You have {count()} playlists
*/}
+
No playlists... }
+ builder={(s) => }
+ />
+
+ );
+};
+
+export default PlaylistList;
diff --git a/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx b/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx
index 6572e841..8c66b42c 100644
--- a/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx
+++ b/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx
@@ -1,6 +1,6 @@
-import { Component } from "solid-js";
import InfiniteScroller from "../../InfiniteScroller";
import SongItem from "../../song/song-item/SongItem";
+import { Component } from "solid-js";
type PlaylistSongListProps = {
playlistName: string;
diff --git a/src/renderer/src/components/playlist/playlist-view/PlaylistView.tsx b/src/renderer/src/components/playlist/playlist-view/PlaylistView.tsx
index 3079667b..f7873859 100644
--- a/src/renderer/src/components/playlist/playlist-view/PlaylistView.tsx
+++ b/src/renderer/src/components/playlist/playlist-view/PlaylistView.tsx
@@ -1,59 +1,33 @@
-import { Component, createSignal } from "solid-js";
-import "../../../assets/css/song/song-view.css";
-import InfiniteScroller from "../../InfiniteScroller";
-import PlaylistItem from "../playlist-item/PlaylistItem";
-import { namespace } from "@renderer/App";
-import Impulse from "@renderer/lib/Impulse";
-import IconButton from "../../icon-button/IconButton";
+import PlaylistList from "../playlist-list/PlaylistList";
+import {
+ PLAYLIST_SCENE_CREATE,
+ PLAYLIST_SCENE_SONGS,
+ PLAYLIST_SCENE_LIST,
+ playlistActiveScene,
+ setPlaylistActiveScene,
+} from "./playlist-view.utils";
+import { Component, Match, Switch } from "solid-js";
export type PlaylistViewProps = {};
const PlaylistView: Component = () => {
- const [_count, setCount] = createSignal(0);
- const resetListing = new Impulse();
- // const [payload, setPayload] = createSignal({});
- const [playlistName, setPlaylistName] = createSignal("");
-
- const createPlaylist = () => {
- window.api.request("playlist::create", playlistName());
- setPlaylistName("");
- }
-
- const group = namespace.create(true);
-
- //todo: make something like App.tsx or MainScene.tsx to load a playlist (scene signal) or something with Routers
return (
- {/*
- */}
-
-
- {setPlaylistName(e.target.value)}} />
-
- {createPlaylist()}}>
-
-
-
-
-
-
- {/*
You have {count()} playlists
*/}
-
No playlists... }
- builder={(s) => }
- />
+ idk }>
+
+
+
+
+ setPlaylistActiveScene(PLAYLIST_SCENE_LIST)}>
+ create playlist, back (click me)
+
+
+
+ setPlaylistActiveScene(PLAYLIST_SCENE_LIST)}>
+ playlist song list, back (click me)
+
+
+
);
};
diff --git a/src/renderer/src/components/playlist/playlist-view/playlist-view.utils.ts b/src/renderer/src/components/playlist/playlist-view/playlist-view.utils.ts
new file mode 100644
index 00000000..e350b5aa
--- /dev/null
+++ b/src/renderer/src/components/playlist/playlist-view/playlist-view.utils.ts
@@ -0,0 +1,9 @@
+import { createSignal } from "solid-js";
+
+const PLAYLIST_SCENE_LIST = 0;
+const PLAYLIST_SCENE_CREATE = 1;
+const PLAYLIST_SCENE_SONGS = 2;
+
+const [playlistActiveScene, setPlaylistActiveScene] = createSignal(PLAYLIST_SCENE_LIST);
+export { playlistActiveScene, setPlaylistActiveScene };
+export { PLAYLIST_SCENE_CREATE, PLAYLIST_SCENE_SONGS, PLAYLIST_SCENE_LIST };
From 43e37a65fae2566e64173309b78711a2adcd8ab8 Mon Sep 17 00:00:00 2001
From: D0m1nos <21263344+D0m1nos@users.noreply.github.com>
Date: Sat, 12 Oct 2024 16:08:39 +0200
Subject: [PATCH 15/54] show song list when clicking on a playlist
---
src/@types.d.ts | 5 +++++
src/RequestAPI.d.ts | 7 ++++--
src/main/router/playlist-router.ts | 8 +++----
.../playlist-create/PlaylistCreate.tsx | 16 ++++++++++++++
.../playlist/playlist-item/PlaylistItem.tsx | 8 +++++--
.../playlist-song-list/PlaylistSongList.tsx | 22 ++++++++++++++-----
.../playlist/playlist-view/PlaylistView.tsx | 12 +++++-----
.../playlist-view/playlist-view.utils.ts | 2 ++
8 files changed, 60 insertions(+), 20 deletions(-)
create mode 100644 src/renderer/src/components/playlist/playlist-create/PlaylistCreate.tsx
diff --git a/src/@types.d.ts b/src/@types.d.ts
index 5f433c29..a46cc842 100644
--- a/src/@types.d.ts
+++ b/src/@types.d.ts
@@ -194,6 +194,11 @@ export type QueueCreatePayload = {
startSong: ResourceID;
};
+// idk if this is necessary because i'm only passing a string
+export type PlaylistSongsQueryPayload = {
+ playlistName: string;
+};
+
export type OsuSearchAbleProperties =
| "bpm"
| "artist"
diff --git a/src/RequestAPI.d.ts b/src/RequestAPI.d.ts
index 373d4fa8..350a7746 100644
--- a/src/RequestAPI.d.ts
+++ b/src/RequestAPI.d.ts
@@ -6,6 +6,7 @@ import type {
InfiniteScrollerResponse,
Optional,
Playlist,
+ PlaylistSongsQueryPayload,
QueueCreatePayload,
ResourceID,
ResourceTables,
@@ -74,10 +75,12 @@ export type RequestAPI = {
"query::queue": (request: InfiniteScrollerRequest) => InfiniteScrollerResponse;
"query::playlists::init": () => InfiniteScrollerInitResponse;
"query::playlists": (request: InfiniteScrollerRequest) => InfiniteScrollerResponse;
- "query::playlistSongs::init": (playlistName: string) => InfiniteScrollerInitResponse;
+ "query::playlistSongs::init": (
+ payload: PlaylistSongsQueryPayload,
+ ) => InfiniteScrollerInitResponse;
"query::playlistSongs": (
- playlistName: string,
request: InfiniteScrollerRequest,
+ payload: PlaylistSongsQueryPayload,
) => InfiniteScrollerResponse;
"save::localVolume": (volume: number, song: ResourceID) => void;
diff --git a/src/main/router/playlist-router.ts b/src/main/router/playlist-router.ts
index 8f54c0f6..44403357 100644
--- a/src/main/router/playlist-router.ts
+++ b/src/main/router/playlist-router.ts
@@ -105,8 +105,8 @@ Router.respond("query::playlists", (_evt, request) => {
});
});
-Router.respond("query::playlistSongs::init", (_evt, playlistName) => {
- const songs = Storage.getTable("playlists").get(playlistName);
+Router.respond("query::playlistSongs::init", (_evt, payload) => {
+ const songs = Storage.getTable("playlists").get(payload.playlistName);
if (songs.isNone) {
return none();
@@ -120,8 +120,8 @@ Router.respond("query::playlistSongs::init", (_evt, playlistName) => {
});
});
-Router.respond("query::playlistSongs", (_evt, playlistName, request) => {
- const playlist = Storage.getTable("playlists").get(playlistName);
+Router.respond("query::playlistSongs", (_evt, request, payload) => {
+ const playlist = Storage.getTable("playlists").get(payload.playlistName);
if (playlist.isNone) {
return none();
diff --git a/src/renderer/src/components/playlist/playlist-create/PlaylistCreate.tsx b/src/renderer/src/components/playlist/playlist-create/PlaylistCreate.tsx
new file mode 100644
index 00000000..9f44c448
--- /dev/null
+++ b/src/renderer/src/components/playlist/playlist-create/PlaylistCreate.tsx
@@ -0,0 +1,16 @@
+import { PLAYLIST_SCENE_LIST, setPlaylistActiveScene } from "../playlist-view/playlist-view.utils";
+import { Component } from "solid-js";
+
+export type PlaylistCreateProps = {};
+
+const PlaylistCreate: Component = () => {
+ return (
+
+ setPlaylistActiveScene(PLAYLIST_SCENE_LIST)}>
+ create playlist, back (click me)
+
+
+ );
+};
+
+export default PlaylistCreate;
diff --git a/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx b/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
index 6c0d9220..f6a6c2cb 100644
--- a/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
+++ b/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
@@ -1,6 +1,10 @@
import IconButton from "../../icon-button/IconButton";
import SongImage from "../../song/SongImage";
-import { PLAYLIST_SCENE_SONGS, setPlaylistActiveScene } from "../playlist-view/playlist-view.utils";
+import {
+ PLAYLIST_SCENE_SONGS,
+ setActivePlaylistName,
+ setPlaylistActiveScene,
+} from "../playlist-view/playlist-view.utils";
import "./styles.css";
import { Component } from "solid-js";
import { Playlist } from "src/@types";
@@ -37,7 +41,7 @@ const PlaylistItem: Component = (props) => {
{
- console.log(props.playlist.songs);
+ setActivePlaylistName(props.playlist.name);
setPlaylistActiveScene(PLAYLIST_SCENE_SONGS);
}}
>
diff --git a/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx b/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx
index 8c66b42c..65badd1f 100644
--- a/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx
+++ b/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx
@@ -1,19 +1,31 @@
import InfiniteScroller from "../../InfiniteScroller";
import SongItem from "../../song/song-item/SongItem";
-import { Component } from "solid-js";
+import { PLAYLIST_SCENE_LIST, setPlaylistActiveScene } from "../playlist-view/playlist-view.utils";
+import { namespace } from "@renderer/App";
+import { Component, createSignal } from "solid-js";
+import { PlaylistSongsQueryPayload } from "src/@types";
type PlaylistSongListProps = {
playlistName: string;
- group: string;
};
const PlaylistSongList: Component
= (props) => {
+ const group = namespace.create(true);
+
+ const [payload, _setPlayload] = createSignal({
+ playlistName: props.playlistName,
+ });
+
return (
+
setPlaylistActiveScene(PLAYLIST_SCENE_LIST)}>
+ playlist "{props.playlistName}" song list, back (click me)
+
= (props) => {
builder={(s) => (
window.api.request("queue::play", s.path)}
+ onSelect={() => window.api.request("queue::play", s)}
// onDrop={onDrop(s)}
>
{/* window.api.request("queue::removeSong", s.path)}>
diff --git a/src/renderer/src/components/playlist/playlist-view/PlaylistView.tsx b/src/renderer/src/components/playlist/playlist-view/PlaylistView.tsx
index f7873859..7232a761 100644
--- a/src/renderer/src/components/playlist/playlist-view/PlaylistView.tsx
+++ b/src/renderer/src/components/playlist/playlist-view/PlaylistView.tsx
@@ -1,10 +1,12 @@
+import PlaylistCreate from "../playlist-create/PlaylistCreate";
import PlaylistList from "../playlist-list/PlaylistList";
+import PlaylistSongList from "../playlist-song-list/PlaylistSongList";
import {
PLAYLIST_SCENE_CREATE,
PLAYLIST_SCENE_SONGS,
PLAYLIST_SCENE_LIST,
playlistActiveScene,
- setPlaylistActiveScene,
+ activePlaylistName,
} from "./playlist-view.utils";
import { Component, Match, Switch } from "solid-js";
@@ -18,14 +20,10 @@ const PlaylistView: Component = () => {
- setPlaylistActiveScene(PLAYLIST_SCENE_LIST)}>
- create playlist, back (click me)
-
+
- setPlaylistActiveScene(PLAYLIST_SCENE_LIST)}>
- playlist song list, back (click me)
-
+
diff --git a/src/renderer/src/components/playlist/playlist-view/playlist-view.utils.ts b/src/renderer/src/components/playlist/playlist-view/playlist-view.utils.ts
index e350b5aa..f9287627 100644
--- a/src/renderer/src/components/playlist/playlist-view/playlist-view.utils.ts
+++ b/src/renderer/src/components/playlist/playlist-view/playlist-view.utils.ts
@@ -5,5 +5,7 @@ const PLAYLIST_SCENE_CREATE = 1;
const PLAYLIST_SCENE_SONGS = 2;
const [playlistActiveScene, setPlaylistActiveScene] = createSignal(PLAYLIST_SCENE_LIST);
+const [activePlaylistName, setActivePlaylistName] = createSignal("");
export { playlistActiveScene, setPlaylistActiveScene };
+export { activePlaylistName, setActivePlaylistName };
export { PLAYLIST_SCENE_CREATE, PLAYLIST_SCENE_SONGS, PLAYLIST_SCENE_LIST };
From 288b33979017b31e5a028ed8e6d4ce6de6593c0a Mon Sep 17 00:00:00 2001
From: D0m1nos <21263344+D0m1nos@users.noreply.github.com>
Date: Sat, 12 Oct 2024 18:03:42 +0200
Subject: [PATCH 16/54] play songs from playlist with working queue + styling
---
src/main/router/queue-router.ts | 19 +++-
.../playlist/playlist-item/styles.css | 86 +++++++++----------
.../playlist-song-list/PlaylistSongList.tsx | 77 +++++++++++------
.../playlist/playlist-song-list/styles.css | 38 ++++++++
4 files changed, 147 insertions(+), 73 deletions(-)
create mode 100644 src/renderer/src/components/playlist/playlist-song-list/styles.css
diff --git a/src/main/router/queue-router.ts b/src/main/router/queue-router.ts
index b62e7abd..260bd6e3 100644
--- a/src/main/router/queue-router.ts
+++ b/src/main/router/queue-router.ts
@@ -79,8 +79,23 @@ function getIndexes(view: QueueView): SongIndex[] {
}
if (view.playlist) {
- //todo get playlist
- return [];
+ const indexes = Storage.getTable("system").get("indexes");
+ const playlist = Storage.getTable("playlists").get(view.playlist);
+
+ if (indexes.isNone || playlist.isNone) {
+ return [];
+ }
+
+ const songs: SongIndex[] = [];
+ // is there a more efficient way?
+ for (let i = 0; i < playlist.value.count; ++i) {
+ let song = indexes.value.find((v) => v.id === playlist.value.songs[i].audio);
+ if (song !== undefined) {
+ songs.push(song);
+ }
+ }
+
+ return songs;
}
return [];
diff --git a/src/renderer/src/components/playlist/playlist-item/styles.css b/src/renderer/src/components/playlist/playlist-item/styles.css
index 6833846c..976da5c4 100644
--- a/src/renderer/src/components/playlist/playlist-item/styles.css
+++ b/src/renderer/src/components/playlist/playlist-item/styles.css
@@ -1,52 +1,50 @@
.playlist-item {
- --image-size: 70px;
+ --image-size: 70px;
- .playlist-item-container {
- margin-top: 20px;
- margin-left: 8px;
- display: flex;
- flex-direction: row;
-
- .playlist-item__playlist-img {
- margin: auto 6px auto 6px;
- border-radius: var(--rounded-lg);
- .song-image {
- width: var(--image-size);
- height: var(--image-size);
- background-size: cover;
- background-position: center;
- border-radius: var(--rounded-lg);
- }
+ .playlist-item-container {
+ margin-top: 20px;
+ margin-left: 8px;
+ display: flex;
+ flex-direction: row;
- }
+ .playlist-item__playlist-img {
+ margin: auto 6px auto 6px;
+ border-radius: var(--rounded-lg);
+ .song-image {
+ width: var(--image-size);
+ height: var(--image-size);
+ background-size: cover;
+ background-position: center;
+ border-radius: var(--rounded-lg);
+ }
+ }
- .playlist-item__playlist-info {
- display: flex;
- flex-direction: row;
- margin-left: 6px;
- justify-content: space-between;
- width: 100%;
+ .playlist-item__playlist-info {
+ display: flex;
+ flex-direction: row;
+ margin-left: 6px;
+ justify-content: space-between;
+ width: 100%;
- .playlist-item__playlist-info__text {
- display: flex;
- flex-direction: column;
- justify-content: center;
- font-weight: 300;
- line-height: 24px;
- }
+ .playlist-item__playlist-info__text {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ font-weight: 300;
+ line-height: 24px;
+ }
- .playlist-item__playlist-info__text h3 {
- font-size: 28px;
- }
+ .playlist-item__playlist-info__text h3 {
+ font-size: 28px;
+ }
- .playlist-item__playlist-info__button {
- display: flex;
- flex-direction: column;
- justify-content: center;
- margin-right: 8px;
- color: lightcoral;
-
- }
- }
+ .playlist-item__playlist-info__button {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ margin-right: 8px;
+ color: lightcoral;
+ }
}
-}
\ No newline at end of file
+ }
+}
diff --git a/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx b/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx
index 65badd1f..ccc7ef4a 100644
--- a/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx
+++ b/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx
@@ -1,9 +1,11 @@
import InfiniteScroller from "../../InfiniteScroller";
import SongItem from "../../song/song-item/SongItem";
import { PLAYLIST_SCENE_LIST, setPlaylistActiveScene } from "../playlist-view/playlist-view.utils";
+import "./styles.css";
import { namespace } from "@renderer/App";
+import IconButton from "@renderer/components/icon-button/IconButton";
import { Component, createSignal } from "solid-js";
-import { PlaylistSongsQueryPayload } from "src/@types";
+import { PlaylistSongsQueryPayload, ResourceID } from "src/@types";
type PlaylistSongListProps = {
playlistName: string;
@@ -16,35 +18,56 @@ const PlaylistSongList: Component = (props) => {
playlistName: props.playlistName,
});
+ const createQueue = async (songResource: ResourceID) => {
+ await window.api.request("queue::create", {
+ startSong: songResource,
+ order: "",
+ tags: [],
+ view: { playlist: props.playlistName },
+ });
+ };
+
return (
-
- setPlaylistActiveScene(PLAYLIST_SCENE_LIST)}>
- playlist "{props.playlistName}" song list, back (click me)
-
- No songs...
}
- builder={(s) => (
- window.api.request("queue::play", s)}
- // onDrop={onDrop(s)}
- >
- {/* window.api.request("queue::removeSong", s.path)}>
+
+
+
+ setPlaylistActiveScene(PLAYLIST_SCENE_LIST)}>
+
+
+
{props.playlistName}
+
+
+
+
+
+
+
+
+ No songs in playlist...
}
+ builder={(s) => (
+
+ {/* window.api.request("queue::removeSong", s.path)}>
Remove from queue
*/}
-
- )}
- />
+
+ )}
+ />
+
);
};
diff --git a/src/renderer/src/components/playlist/playlist-song-list/styles.css b/src/renderer/src/components/playlist/playlist-song-list/styles.css
new file mode 100644
index 00000000..de077913
--- /dev/null
+++ b/src/renderer/src/components/playlist/playlist-song-list/styles.css
@@ -0,0 +1,38 @@
+.playlist-song-list {
+ margin-top: 24px;
+ .playlist-song-list__top {
+ width: 100%;
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ align-items: center;
+
+ .playlist-song-list__top__left {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ margin-left: 12px;
+ font-size: 20px;
+ }
+
+ .playlist-song-list__top__left > * + * {
+ margin-left: 18px;
+ }
+
+ .playlist-song-list__top__right {
+ margin-right: 16px;
+ }
+ }
+
+ .playlist-song-list__list {
+ margin-top: 24px;
+ .song-item {
+ margin: 12px 12px;
+ }
+ }
+}
+
+.icon-button {
+ padding: 0px;
+ margin: 0px;
+}
From 728dd8f587bc6a1b3dd14467bf301607e270a304 Mon Sep 17 00:00:00 2001
From: D0m1nos <21263344+D0m1nos@users.noreply.github.com>
Date: Sat, 12 Oct 2024 18:05:33 +0200
Subject: [PATCH 17/54] lint fix
---
src/main/router/queue-router.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/router/queue-router.ts b/src/main/router/queue-router.ts
index 260bd6e3..c33aab03 100644
--- a/src/main/router/queue-router.ts
+++ b/src/main/router/queue-router.ts
@@ -89,7 +89,7 @@ function getIndexes(view: QueueView): SongIndex[] {
const songs: SongIndex[] = [];
// is there a more efficient way?
for (let i = 0; i < playlist.value.count; ++i) {
- let song = indexes.value.find((v) => v.id === playlist.value.songs[i].audio);
+ const song = indexes.value.find((v) => v.id === playlist.value.songs[i].audio);
if (song !== undefined) {
songs.push(song);
}
From d84f1a30a86205ad2cd4b96084518859b396cb4a Mon Sep 17 00:00:00 2001
From: D0m1nos <21263344+D0m1nos@users.noreply.github.com>
Date: Sat, 12 Oct 2024 21:15:13 +0200
Subject: [PATCH 18/54] implement playlist creation scene
---
.../playlist-create/PlaylistCreate.tsx | 41 +++++++++++--
.../playlist/playlist-create/styles.css | 60 +++++++++++++++++++
.../playlist/playlist-list/PlaylistList.tsx | 11 ----
.../playlist/playlist-song-list/styles.css | 5 +-
.../playlist/playlist-view/PlaylistView.tsx | 1 +
.../playlist/playlist-view/styles.css | 4 ++
6 files changed, 102 insertions(+), 20 deletions(-)
create mode 100644 src/renderer/src/components/playlist/playlist-create/styles.css
create mode 100644 src/renderer/src/components/playlist/playlist-view/styles.css
diff --git a/src/renderer/src/components/playlist/playlist-create/PlaylistCreate.tsx b/src/renderer/src/components/playlist/playlist-create/PlaylistCreate.tsx
index 9f44c448..ab049435 100644
--- a/src/renderer/src/components/playlist/playlist-create/PlaylistCreate.tsx
+++ b/src/renderer/src/components/playlist/playlist-create/PlaylistCreate.tsx
@@ -1,14 +1,45 @@
import { PLAYLIST_SCENE_LIST, setPlaylistActiveScene } from "../playlist-view/playlist-view.utils";
-import { Component } from "solid-js";
+import "./styles.css";
+import IconButton from "@renderer/components/icon-button/IconButton";
+import { Component, createSignal } from "solid-js";
export type PlaylistCreateProps = {};
const PlaylistCreate: Component = () => {
+ const [playlistName, setPlaylistName] = createSignal("");
+
+ const createPlaylist = () => {
+ // last check is probably unnecessary
+ if (playlistName().length === 0 || playlistName() === undefined || playlistName() === "") {
+ return;
+ }
+ window.api.request("playlist::create", playlistName().trim());
+ setPlaylistActiveScene(PLAYLIST_SCENE_LIST);
+ setPlaylistName("");
+ };
+
return (
-
-
setPlaylistActiveScene(PLAYLIST_SCENE_LIST)}>
- create playlist, back (click me)
-
+
+
+
+
+
Name
+
{
+ setPlaylistName(e.target.value);
+ }}
+ />
+
+
+
);
};
diff --git a/src/renderer/src/components/playlist/playlist-create/styles.css b/src/renderer/src/components/playlist/playlist-create/styles.css
new file mode 100644
index 00000000..8c046e49
--- /dev/null
+++ b/src/renderer/src/components/playlist/playlist-create/styles.css
@@ -0,0 +1,60 @@
+.playlist-create {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ height: 100%;
+ margin-left: 20px;
+ margin-right: 20px;
+ .playlist-create__top {
+ margin-top: 24px;
+ .playlist-create__top__header {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ gap: 20px;
+ font-size: 20px;
+ color: #eff1f5;
+
+ i {
+ color: #eff1f599;
+ }
+ }
+
+ .playlist-create__top__body {
+ display: flex;
+ flex-direction: column;
+ margin-top: 24px;
+ gap: 8px;
+ color: #ffffffd1;
+
+ input {
+ height: 44px;
+ border-radius: 8px;
+ background-color: #84898f33;
+ border: none;
+ color: #ffffffd1;
+ padding: 10px 16px 10px 16px;
+ }
+ }
+ }
+
+ .playlist-create__footer {
+ button {
+ width: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: center;
+ margin-bottom: 24px;
+ height: 36px;
+ background-color: white;
+ color: black;
+ font-weight: 600;
+ border-radius: 6px;
+ }
+
+ /* button:hover {
+ cursor: pointer;
+ } */
+ }
+}
diff --git a/src/renderer/src/components/playlist/playlist-list/PlaylistList.tsx b/src/renderer/src/components/playlist/playlist-list/PlaylistList.tsx
index 02600cdc..30e37fc4 100644
--- a/src/renderer/src/components/playlist/playlist-list/PlaylistList.tsx
+++ b/src/renderer/src/components/playlist/playlist-list/PlaylistList.tsx
@@ -16,16 +16,6 @@ const PlaylistList: Component
= () => {
const [_count, setCount] = createSignal(0);
const resetListing = new Impulse();
// const [payload, setPayload] = createSignal({});
- const [playlistName, setPlaylistName] = createSignal("");
-
- const createPlaylist = () => {
- // last check is probably unnecessary
- if (playlistName().length === 0 || playlistName() === undefined || playlistName() === "") {
- return;
- }
- window.api.request("playlist::create", playlistName().trim());
- setPlaylistName("");
- };
const group = namespace.create(true);
@@ -53,7 +43,6 @@ const PlaylistList: Component = () => {
{
- createPlaylist(); //TODO: remove
setPlaylistActiveScene(PLAYLIST_SCENE_CREATE);
}}
>
diff --git a/src/renderer/src/components/playlist/playlist-song-list/styles.css b/src/renderer/src/components/playlist/playlist-song-list/styles.css
index de077913..fb3d8024 100644
--- a/src/renderer/src/components/playlist/playlist-song-list/styles.css
+++ b/src/renderer/src/components/playlist/playlist-song-list/styles.css
@@ -13,10 +13,7 @@
align-items: center;
margin-left: 12px;
font-size: 20px;
- }
-
- .playlist-song-list__top__left > * + * {
- margin-left: 18px;
+ gap: 18px;
}
.playlist-song-list__top__right {
diff --git a/src/renderer/src/components/playlist/playlist-view/PlaylistView.tsx b/src/renderer/src/components/playlist/playlist-view/PlaylistView.tsx
index 7232a761..9c4dcefa 100644
--- a/src/renderer/src/components/playlist/playlist-view/PlaylistView.tsx
+++ b/src/renderer/src/components/playlist/playlist-view/PlaylistView.tsx
@@ -8,6 +8,7 @@ import {
playlistActiveScene,
activePlaylistName,
} from "./playlist-view.utils";
+import "./styles.css";
import { Component, Match, Switch } from "solid-js";
export type PlaylistViewProps = {};
diff --git a/src/renderer/src/components/playlist/playlist-view/styles.css b/src/renderer/src/components/playlist/playlist-view/styles.css
new file mode 100644
index 00000000..cc0043bc
--- /dev/null
+++ b/src/renderer/src/components/playlist/playlist-view/styles.css
@@ -0,0 +1,4 @@
+.playlist-view {
+ height: 100%;
+ overflow-y: auto;
+}
From 394ed86482a2c8001cf7d694c66f4eee0bba59d4 Mon Sep 17 00:00:00 2001
From: D0m1nos <21263344+D0m1nos@users.noreply.github.com>
Date: Sat, 12 Oct 2024 22:40:20 +0200
Subject: [PATCH 19/54] styling following the figma design
---
.../playlist/playlist-create/styles.css | 11 ++--
.../playlist/playlist-item/PlaylistItem.tsx | 2 +-
.../playlist/playlist-item/styles.css | 27 ++++++----
.../playlist/playlist-list/PlaylistList.tsx | 46 ++++++++---------
.../playlist/playlist-list/styles.css | 51 +++++++++++++++++++
.../playlist-song-list/PlaylistSongList.tsx | 10 +---
.../playlist/playlist-song-list/styles.css | 38 +++++++++-----
7 files changed, 126 insertions(+), 59 deletions(-)
create mode 100644 src/renderer/src/components/playlist/playlist-list/styles.css
diff --git a/src/renderer/src/components/playlist/playlist-create/styles.css b/src/renderer/src/components/playlist/playlist-create/styles.css
index 8c046e49..1fa82621 100644
--- a/src/renderer/src/components/playlist/playlist-create/styles.css
+++ b/src/renderer/src/components/playlist/playlist-create/styles.css
@@ -32,8 +32,11 @@
border-radius: 8px;
background-color: #84898f33;
border: none;
- color: #ffffffd1;
+ color: #ffffff;
padding: 10px 16px 10px 16px;
+ font-size: 16px;
+ line-height: 24px;
+ font-weight: 400;
}
}
}
@@ -46,11 +49,11 @@
align-items: center;
justify-content: center;
margin-bottom: 24px;
- height: 36px;
- background-color: white;
+ height: 42px;
+ background-color: #ffffffeb;
color: black;
font-weight: 600;
- border-radius: 6px;
+ border-radius: 8px;
}
/* button:hover {
diff --git a/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx b/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
index f6a6c2cb..42b747c1 100644
--- a/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
+++ b/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
@@ -58,7 +58,7 @@ const PlaylistItem: Component = (props) => {
window.api.request("playlist::delete", props.playlist.name)}>
-
+
diff --git a/src/renderer/src/components/playlist/playlist-item/styles.css b/src/renderer/src/components/playlist/playlist-item/styles.css
index 976da5c4..2dd574dd 100644
--- a/src/renderer/src/components/playlist/playlist-item/styles.css
+++ b/src/renderer/src/components/playlist/playlist-item/styles.css
@@ -1,27 +1,27 @@
.playlist-item {
- --image-size: 70px;
+ --image-size: 71px;
.playlist-item-container {
- margin-top: 20px;
- margin-left: 8px;
display: flex;
flex-direction: row;
+ gap: 16px;
.playlist-item__playlist-img {
- margin: auto 6px auto 6px;
+ /* margin: auto 6px auto 6px; */
border-radius: var(--rounded-lg);
.song-image {
width: var(--image-size);
height: var(--image-size);
background-size: cover;
background-position: center;
- border-radius: var(--rounded-lg);
+ border-radius: 8px;
}
}
.playlist-item__playlist-info {
display: flex;
flex-direction: row;
+ align-items: center;
margin-left: 6px;
justify-content: space-between;
width: 100%;
@@ -30,20 +30,29 @@
display: flex;
flex-direction: column;
justify-content: center;
- font-weight: 300;
+ font-weight: 500;
line-height: 24px;
+ font-size: 16px;
+ color: #eff1f5;
}
.playlist-item__playlist-info__text h3 {
- font-size: 28px;
+ font-size: 30px;
+ line-height: 30px;
+ font-weight: 700;
}
.playlist-item__playlist-info__button {
display: flex;
flex-direction: column;
justify-content: center;
- margin-right: 8px;
- color: lightcoral;
+ align-items: center;
+ height: 40px;
+ width: 40px;
+ color: #eff1f5;
+ border: 1px solid #f2f4fc1a;
+ border-radius: 8px;
+ z-index: 3;
}
}
}
diff --git a/src/renderer/src/components/playlist/playlist-list/PlaylistList.tsx b/src/renderer/src/components/playlist/playlist-list/PlaylistList.tsx
index 30e37fc4..94d15b1b 100644
--- a/src/renderer/src/components/playlist/playlist-list/PlaylistList.tsx
+++ b/src/renderer/src/components/playlist/playlist-list/PlaylistList.tsx
@@ -6,6 +6,7 @@ import {
PLAYLIST_SCENE_CREATE,
setPlaylistActiveScene,
} from "../playlist-view/playlist-view.utils";
+import "./styles.css";
import { namespace } from "@renderer/App";
import Impulse from "@renderer/lib/Impulse";
import { Component, createSignal } from "solid-js";
@@ -15,7 +16,6 @@ export type PlaylistListProps = {};
const PlaylistList: Component = () => {
const [_count, setCount] = createSignal(0);
const resetListing = new Impulse();
- // const [payload, setPayload] = createSignal({});
const group = namespace.create(true);
@@ -29,40 +29,38 @@ const PlaylistList: Component = () => {
error={searchError}
/>
*/}
-
-
}
- builder={(s) =>
}
- />
+
+ No playlists...
}
+ builder={(s) =>
}
+ />
+
);
};
diff --git a/src/renderer/src/components/playlist/playlist-list/styles.css b/src/renderer/src/components/playlist/playlist-list/styles.css
new file mode 100644
index 00000000..9066c77b
--- /dev/null
+++ b/src/renderer/src/components/playlist/playlist-list/styles.css
@@ -0,0 +1,51 @@
+.playlist-list {
+ margin: 24px 20px;
+ .playlist-list__header {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ margin-bottom: 24px;
+
+ .playlist-list__header__input-container {
+ height: 40px;
+ display: flex;
+ align-items: center;
+ flex: 1;
+ border: 1px solid #f2f4fc1a;
+ border-radius: 8px;
+ padding: 8px 12px;
+
+ .playlist-list__header__input {
+ flex: 1;
+ background-color: transparent;
+ border: none;
+ font-size: 16px;
+ color: white;
+ }
+
+ .playlist-list__header__search-icon {
+ font-size: 20px;
+ color: #eff1f599;
+ }
+ }
+
+ .icon-button {
+ font-size: 20px;
+ width: 20px;
+ height: 20px;
+ color: #eff1f5;
+ border: 1px solid #f2f4fc1a;
+ border-radius: 8px;
+ padding: 9px;
+ margin: 0px 0px 0px 6px; /* why is this button so weird */
+ }
+ }
+
+ .playlist-list__body {
+ .list {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+ }
+ }
+}
diff --git a/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx b/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx
index ccc7ef4a..fe3629e8 100644
--- a/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx
+++ b/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx
@@ -48,9 +48,6 @@ const PlaylistSongList: Component = (props) => {
apiData={payload()}
apiInitKey={"query::playlistSongs::init"}
apiInitData={payload()}
- // setCount={setCount}
- // reset={resetListing}
- // onLoadItems={onSongsLoad}
fallback={No songs in playlist...
}
builder={(s) => (
= (props) => {
selectable={true}
draggable={true}
onSelect={createQueue}
- // onDrop={onDrop(s)}
- >
- {/* window.api.request("queue::removeSong", s.path)}>
- Remove from queue
- */}
-
+ >
)}
/>
diff --git a/src/renderer/src/components/playlist/playlist-song-list/styles.css b/src/renderer/src/components/playlist/playlist-song-list/styles.css
index fb3d8024..20c0e176 100644
--- a/src/renderer/src/components/playlist/playlist-song-list/styles.css
+++ b/src/renderer/src/components/playlist/playlist-song-list/styles.css
@@ -1,7 +1,8 @@
.playlist-song-list {
- margin-top: 24px;
+ margin: 24px 20px;
.playlist-song-list__top {
width: 100%;
+ margin-bottom: 24px;
display: flex;
flex-direction: row;
justify-content: space-between;
@@ -11,25 +12,38 @@
display: flex;
flex-direction: row;
align-items: center;
- margin-left: 12px;
font-size: 20px;
- gap: 18px;
+ line-height: 24px;
+ font-weight: 500;
+ gap: 20px;
+
+ .icon-button {
+ font-size: 20px;
+ color: #eff1f599;
+ }
}
.playlist-song-list__top__right {
- margin-right: 16px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border: 1px solid #f2f4fc1a;
+ color: #eff1f5;
+ width: 40px;
+ height: 40px;
+ border-radius: 8px;
+
+ .icon-button {
+ font-size: 20px;
+ }
}
}
.playlist-song-list__list {
- margin-top: 24px;
- .song-item {
- margin: 12px 12px;
+ .list {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
}
}
}
-
-.icon-button {
- padding: 0px;
- margin: 0px;
-}
From 30e497d63f722267768730e979471945c666b6ff Mon Sep 17 00:00:00 2001
From: D0m1nos <21263344+D0m1nos@users.noreply.github.com>
Date: Sat, 12 Oct 2024 22:46:55 +0200
Subject: [PATCH 20/54] avoid entering playlist when deleting it (event
propagation)
---
.../src/components/playlist/playlist-item/PlaylistItem.tsx | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx b/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
index 42b747c1..2e7a9b2a 100644
--- a/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
+++ b/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
@@ -37,6 +37,11 @@ function getSongImage(playlist: Playlist) {
}
const PlaylistItem: Component = (props) => {
+ const deletePlaylist = (e: Event, playlistName: string) => {
+ e.stopPropagation();
+ window.api.request("playlist::delete", playlistName);
+ };
+
return (
= (props) => {
{/*
{formatPlaylistTime(Math.round(props.playlist.length))}
*/}
- window.api.request("playlist::delete", props.playlist.name)}>
+ deletePlaylist(e, props.playlist.name)}>
From 8b6b35452aa200c47a504d8a68ed2114c01da0af Mon Sep 17 00:00:00 2001
From: D0m1nos <21263344+D0m1nos@users.noreply.github.com>
Date: Sat, 12 Oct 2024 23:03:13 +0200
Subject: [PATCH 21/54] automatically refresh scene when deleting a playlist
---
.../playlist/playlist-item/PlaylistItem.tsx | 34 +++----------------
.../playlist-item/playlist-item.utils.ts | 30 ++++++++++++++++
.../playlist/playlist-list/PlaylistList.tsx | 7 ++--
3 files changed, 40 insertions(+), 31 deletions(-)
create mode 100644 src/renderer/src/components/playlist/playlist-item/playlist-item.utils.ts
diff --git a/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx b/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
index 2e7a9b2a..eeb34472 100644
--- a/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
+++ b/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
@@ -5,43 +5,19 @@ import {
setActivePlaylistName,
setPlaylistActiveScene,
} from "../playlist-view/playlist-view.utils";
+import { deletePlaylist, getSongImage } from "./playlist-item.utils";
import "./styles.css";
+import Impulse from "@renderer/lib/Impulse";
import { Component } from "solid-js";
import { Playlist } from "src/@types";
-type PlaylistItemProps = {
+export type PlaylistItemProps = {
playlist: Playlist;
group: string;
+ reset: Impulse;
};
-// function formatPlaylistTime(seconds: number) {
-// let minutes = 0;
-// let hours = 0;
-// if (seconds > 60) {
-// minutes = Math.floor(seconds / 60);
-// if (minutes > 60) {
-// hours = Math.floor(minutes / 60);
-// }
-// }
-
-// return hours + " hours " + minutes + " minutes";
-// }
-
-function getSongImage(playlist: Playlist) {
- const songs = playlist.songs;
- if (songs.length === 0 || songs[0].bg === undefined || songs[0].bg === "") {
- return "";
- } else {
- return songs[0].bg;
- }
-}
-
const PlaylistItem: Component = (props) => {
- const deletePlaylist = (e: Event, playlistName: string) => {
- e.stopPropagation();
- window.api.request("playlist::delete", playlistName);
- };
-
return (
= (props) => {
{/*
{formatPlaylistTime(Math.round(props.playlist.length))}
*/}
- deletePlaylist(e, props.playlist.name)}>
+ deletePlaylist(e, props)}>
diff --git a/src/renderer/src/components/playlist/playlist-item/playlist-item.utils.ts b/src/renderer/src/components/playlist/playlist-item/playlist-item.utils.ts
new file mode 100644
index 00000000..c0fcde06
--- /dev/null
+++ b/src/renderer/src/components/playlist/playlist-item/playlist-item.utils.ts
@@ -0,0 +1,30 @@
+import { PlaylistItemProps } from "./PlaylistItem";
+import { Playlist } from "src/@types";
+
+export function getSongImage(playlist: Playlist) {
+ const songs = playlist.songs;
+ if (songs.length === 0 || songs[0].bg === undefined || songs[0].bg === "") {
+ return "";
+ } else {
+ return songs[0].bg;
+ }
+}
+
+export function deletePlaylist(e: Event, props: PlaylistItemProps) {
+ e.stopPropagation();
+ window.api.request("playlist::delete", props.playlist.name);
+ props.reset.pulse();
+}
+
+// function formatPlaylistTime(seconds: number) {
+// let minutes = 0;
+// let hours = 0;
+// if (seconds > 60) {
+// minutes = Math.floor(seconds / 60);
+// if (minutes > 60) {
+// hours = Math.floor(minutes / 60);
+// }
+// }
+
+// return hours + " hours " + minutes + " minutes";
+// }
diff --git a/src/renderer/src/components/playlist/playlist-list/PlaylistList.tsx b/src/renderer/src/components/playlist/playlist-list/PlaylistList.tsx
index 94d15b1b..edb2ecdd 100644
--- a/src/renderer/src/components/playlist/playlist-list/PlaylistList.tsx
+++ b/src/renderer/src/components/playlist/playlist-list/PlaylistList.tsx
@@ -14,6 +14,7 @@ import { Component, createSignal } from "solid-js";
export type PlaylistListProps = {};
const PlaylistList: Component = () => {
+ // const [playlistSearch, setPlaylistSearch] = createSignal("");
const [_count, setCount] = createSignal(0);
const resetListing = new Impulse();
@@ -37,7 +38,7 @@ const PlaylistList: Component = () => {
class="playlist-list__header__input"
placeholder="Search in your playlists... (WIP)"
// onInput={(e) => {
- // setPlaylistName(e.target.value);
+ // setPlaylistSearch(e.target.value);
// }}
/>
@@ -58,7 +59,9 @@ const PlaylistList: Component = () => {
setCount={setCount}
reset={resetListing}
fallback={No playlists...
}
- builder={(s) => }
+ builder={(s) => (
+
+ )}
/>
From 8d3e66d341eda3afa830a854f4910906eed3ddd0 Mon Sep 17 00:00:00 2001
From: D0m1nos <21263344+D0m1nos@users.noreply.github.com>
Date: Sun, 13 Oct 2024 01:09:39 +0200
Subject: [PATCH 22/54] new playlist creation box
---
.../playlist-create/PlaylistCreateBox.tsx | 51 +++++++++++++
.../playlist/playlist-create/styles.css | 71 +++++++++++++++++++
.../playlist/playlist-list/PlaylistList.tsx | 21 ++++--
.../playlist/playlist-list/styles.css | 6 ++
4 files changed, 143 insertions(+), 6 deletions(-)
create mode 100644 src/renderer/src/components/playlist/playlist-create/PlaylistCreateBox.tsx
diff --git a/src/renderer/src/components/playlist/playlist-create/PlaylistCreateBox.tsx b/src/renderer/src/components/playlist/playlist-create/PlaylistCreateBox.tsx
new file mode 100644
index 00000000..3d838a17
--- /dev/null
+++ b/src/renderer/src/components/playlist/playlist-create/PlaylistCreateBox.tsx
@@ -0,0 +1,51 @@
+import SongImage from "@renderer/components/song/SongImage";
+import Impulse from "@renderer/lib/Impulse";
+import { Component, createSignal, Setter } from "solid-js";
+
+export type PlaylistCreateBoxProps = {
+ group: string;
+ isOpen: Setter;
+ reset: Impulse;
+};
+const PlaylistCreateBox: Component = (props) => {
+ const [playlistName, setPlaylistName] = createSignal("");
+
+ const createPlaylist = () => {
+ // last check is probably unnecessary
+ if (playlistName().length === 0 || playlistName() === undefined || playlistName() === "") {
+ return;
+ }
+ window.api.request("playlist::create", playlistName().trim());
+ setPlaylistName("");
+ props.reset.pulse();
+ props.isOpen(false);
+ };
+
+ return (
+
+
+
+
+
+
+
+ {
+ setPlaylistName(e.target.value);
+ }}
+ />
+ createPlaylist()}>Create
+
+
+
+ );
+};
+
+export default PlaylistCreateBox;
diff --git a/src/renderer/src/components/playlist/playlist-create/styles.css b/src/renderer/src/components/playlist/playlist-create/styles.css
index 1fa82621..93788e84 100644
--- a/src/renderer/src/components/playlist/playlist-create/styles.css
+++ b/src/renderer/src/components/playlist/playlist-create/styles.css
@@ -37,6 +37,7 @@
font-size: 16px;
line-height: 24px;
font-weight: 400;
+ font-family: "Nunito";
}
}
}
@@ -61,3 +62,73 @@
} */
}
}
+
+.playlist-create-box {
+ background-color: #0d0d0df2;
+ border-radius: 12px;
+ margin-bottom: 24px;
+
+ .playlist-create-box__header {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ padding: 16px;
+
+ button {
+ font-size: 20px;
+ }
+ }
+
+ .playlist-create-box__body {
+ display: flex;
+ flex-direction: row;
+ margin: 16px;
+ margin-top: 0px;
+
+ .playlist-create-box__body__image {
+ border-radius: 8px;
+ margin-right: 16px;
+ .song-image {
+ width: 83px;
+ height: 83px;
+ background-size: cover;
+ background-position: center;
+ border-radius: 8px;
+ }
+ }
+
+ .playlist-create-box__body__input {
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+ width: 100%;
+
+ input {
+ height: 36px;
+ border-radius: 8px;
+ background-color: #84898f33;
+ border: none;
+ color: #ffffff;
+ padding: 10px 0px 10px 16px;
+ font-size: 16px;
+ line-height: 24px;
+ font-weight: 400;
+ font-family: "Nunito";
+ }
+
+ button {
+ width: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: center;
+ margin-bottom: 24px;
+ height: 36px;
+ background-color: #ffffffeb;
+ color: black;
+ font-weight: 600;
+ border-radius: 8px;
+ }
+ }
+ }
+}
diff --git a/src/renderer/src/components/playlist/playlist-list/PlaylistList.tsx b/src/renderer/src/components/playlist/playlist-list/PlaylistList.tsx
index edb2ecdd..f8902994 100644
--- a/src/renderer/src/components/playlist/playlist-list/PlaylistList.tsx
+++ b/src/renderer/src/components/playlist/playlist-list/PlaylistList.tsx
@@ -1,15 +1,16 @@
import "../../../assets/css/song/song-view.css";
import InfiniteScroller from "../../InfiniteScroller";
import IconButton from "../../icon-button/IconButton";
+import PlaylistCreateBox from "../playlist-create/PlaylistCreateBox";
import PlaylistItem from "../playlist-item/PlaylistItem";
-import {
- PLAYLIST_SCENE_CREATE,
- setPlaylistActiveScene,
-} from "../playlist-view/playlist-view.utils";
+// import {
+// PLAYLIST_SCENE_CREATE,
+// setPlaylistActiveScene,
+// } from "../playlist-view/playlist-view.utils";
import "./styles.css";
import { namespace } from "@renderer/App";
import Impulse from "@renderer/lib/Impulse";
-import { Component, createSignal } from "solid-js";
+import { Component, createSignal, Match, Switch } from "solid-js";
export type PlaylistListProps = {};
@@ -17,6 +18,7 @@ const PlaylistList: Component = () => {
// const [playlistSearch, setPlaylistSearch] = createSignal("");
const [_count, setCount] = createSignal(0);
const resetListing = new Impulse();
+ const [showCreateBox, setShowCreateBox] = createSignal(false);
const group = namespace.create(true);
@@ -45,14 +47,21 @@ const PlaylistList: Component = () => {
{
- setPlaylistActiveScene(PLAYLIST_SCENE_CREATE);
+ // setPlaylistActiveScene(PLAYLIST_SCENE_CREATE);
+ setShowCreateBox(true);
}}
+ data-open={showCreateBox()}
>
+
+
+
+
+
Date: Sun, 13 Oct 2024 17:48:30 +0200
Subject: [PATCH 23/54] fix styling, playlists refresh when adding a song
---
src/ListenAPI.d.ts | 3 ++
src/main/router/playlist-router.ts | 6 ++-
.../playlist/playlist-create/styles.css | 5 ++-
.../playlist/playlist-list/PlaylistList.tsx | 27 +++++++-----
.../playlist/playlist-list/styles.css | 42 +++++++++++--------
.../playlist-song-list/PlaylistSongList.tsx | 9 +++-
.../song/song-detail/SongControls.tsx | 5 ++-
7 files changed, 64 insertions(+), 33 deletions(-)
diff --git a/src/ListenAPI.d.ts b/src/ListenAPI.d.ts
index d8499784..86c2b46b 100644
--- a/src/ListenAPI.d.ts
+++ b/src/ListenAPI.d.ts
@@ -14,6 +14,9 @@ export type ListenAPI = {
"songView::reset": () => void;
+ "playlist::resetList": () => void;
+ "playlist::resetSongList": () => void;
+
"window::maximizeChange": (maximized: boolean) => void;
notify: (notice: NoticeType) => void;
diff --git a/src/main/router/playlist-router.ts b/src/main/router/playlist-router.ts
index 44403357..53dc4d64 100644
--- a/src/main/router/playlist-router.ts
+++ b/src/main/router/playlist-router.ts
@@ -2,8 +2,10 @@ import { Playlist } from "../../@types";
import { Router } from "../lib/route-pass/Router";
import { none, some } from "../lib/rust-like-utils-backend/Optional";
import { Storage } from "../lib/storage/Storage";
+import errorIgnored from "../lib/tungsten/errorIgnored";
+import { mainWindow } from "../main";
-Router.respond("playlist::add", (_evt, playlistName, song) => {
+Router.respond("playlist::add", async (_evt, playlistName, song) => {
const playlists = Storage.getTable("playlists");
const playlist = playlists.get(playlistName);
@@ -15,6 +17,8 @@ Router.respond("playlist::add", (_evt, playlistName, song) => {
playlist.value.count = playlist.value.count + 1;
playlist.value.length = playlist.value.length + song.duration;
playlists.write(playlistName, playlist.value);
+ await Router.dispatch(mainWindow, "playlist::resetList").catch(errorIgnored);
+ await Router.dispatch(mainWindow, "playlist::resetSongList").catch(errorIgnored);
});
Router.respond("playlist::create", (_evt, name) => {
diff --git a/src/renderer/src/components/playlist/playlist-create/styles.css b/src/renderer/src/components/playlist/playlist-create/styles.css
index 93788e84..9b7f5823 100644
--- a/src/renderer/src/components/playlist/playlist-create/styles.css
+++ b/src/renderer/src/components/playlist/playlist-create/styles.css
@@ -37,7 +37,7 @@
font-size: 16px;
line-height: 24px;
font-weight: 400;
- font-family: "Nunito";
+ font-family: inherit;
}
}
}
@@ -113,7 +113,8 @@
font-size: 16px;
line-height: 24px;
font-weight: 400;
- font-family: "Nunito";
+ font-family: inherit;
+ width: 100%;
}
button {
diff --git a/src/renderer/src/components/playlist/playlist-list/PlaylistList.tsx b/src/renderer/src/components/playlist/playlist-list/PlaylistList.tsx
index f8902994..d58fa706 100644
--- a/src/renderer/src/components/playlist/playlist-list/PlaylistList.tsx
+++ b/src/renderer/src/components/playlist/playlist-list/PlaylistList.tsx
@@ -10,7 +10,7 @@ import PlaylistItem from "../playlist-item/PlaylistItem";
import "./styles.css";
import { namespace } from "@renderer/App";
import Impulse from "@renderer/lib/Impulse";
-import { Component, createSignal, Match, Switch } from "solid-js";
+import { Component, createSignal, Match, onCleanup, onMount, Switch } from "solid-js";
export type PlaylistListProps = {};
@@ -22,6 +22,11 @@ const PlaylistList: Component = () => {
const group = namespace.create(true);
+ onMount(() => window.api.listen("playlist::resetList", resetListing.pulse.bind(resetListing)));
+ onCleanup(() =>
+ window.api.removeListener("playlist::resetList", resetListing.pulse.bind(resetListing)),
+ );
+
return (
{/* = () => {
/>
- {
- // setPlaylistActiveScene(PLAYLIST_SCENE_CREATE);
- setShowCreateBox(true);
- }}
- data-open={showCreateBox()}
- >
-
-
+
diff --git a/src/renderer/src/components/playlist/playlist-list/styles.css b/src/renderer/src/components/playlist/playlist-list/styles.css
index 33ff2f39..e3015934 100644
--- a/src/renderer/src/components/playlist/playlist-list/styles.css
+++ b/src/renderer/src/components/playlist/playlist-list/styles.css
@@ -7,42 +7,48 @@
margin-bottom: 24px;
.playlist-list__header__input-container {
- height: 40px;
display: flex;
- align-items: center;
+ flex-direction: row;
+ justify-content: space-between;
flex: 1;
+ height: 40px;
+ align-items: center;
border: 1px solid #f2f4fc1a;
border-radius: 8px;
- padding: 8px 12px;
+ /* padding: 8px 12px; */
+ margin-right: 8px;
.playlist-list__header__input {
- flex: 1;
background-color: transparent;
border: none;
font-size: 16px;
color: white;
- font-family: "Nunito";
+ font-family: inherit;
+ margin-left: 12px;
+ width: 100%;
}
-
.playlist-list__header__search-icon {
font-size: 20px;
color: #eff1f599;
+ margin-right: 12px;
}
}
- .icon-button {
- font-size: 20px;
- width: 20px;
- height: 20px;
- color: #eff1f5;
- border: 1px solid #f2f4fc1a;
- border-radius: 8px;
- padding: 9px;
- margin: 0px 0px 0px 6px; /* why is this button so weird */
+ .playlist-list__header__create-playlist {
+ .icon-button {
+ font-size: 20px;
+ width: 20px;
+ height: 20px;
+ color: #eff1f5;
+ border: 1px solid #f2f4fc1a;
+ border-radius: 8px;
+ padding: 9px;
+ margin: 0px; /* why is this button so weird */
- &[data-open="true"] {
- background-color: #ffffffeb;
- color: #0d0d0df2;
+ &[data-open="true"] {
+ background-color: #ffffffeb;
+ color: #0d0d0df2;
+ }
}
}
}
diff --git a/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx b/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx
index fe3629e8..56bb52fa 100644
--- a/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx
+++ b/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx
@@ -4,7 +4,8 @@ import { PLAYLIST_SCENE_LIST, setPlaylistActiveScene } from "../playlist-view/pl
import "./styles.css";
import { namespace } from "@renderer/App";
import IconButton from "@renderer/components/icon-button/IconButton";
-import { Component, createSignal } from "solid-js";
+import Impulse from "@renderer/lib/Impulse";
+import { Component, createSignal, onCleanup, onMount } from "solid-js";
import { PlaylistSongsQueryPayload, ResourceID } from "src/@types";
type PlaylistSongListProps = {
@@ -18,6 +19,11 @@ const PlaylistSongList: Component
= (props) => {
playlistName: props.playlistName,
});
+ const reset = new Impulse();
+
+ onMount(() => window.api.listen("playlist::resetSongList", reset.pulse.bind(reset)));
+ onCleanup(() => window.api.removeListener("playlist::resetSongList", reset.pulse.bind(reset)));
+
const createQueue = async (songResource: ResourceID) => {
await window.api.request("queue::create", {
startSong: songResource,
@@ -48,6 +54,7 @@ const PlaylistSongList: Component = (props) => {
apiData={payload()}
apiInitKey={"query::playlistSongs::init"}
apiInitData={payload()}
+ reset={reset}
fallback={No songs in playlist...
}
builder={(s) => (
= () => {
{/* Right part */}
{/* // TODO - modal or something so the user can select a playlist */}
- window.api.request("playlist::add", "test", song())} title="Add to playlist">
+ window.api.request("playlist::add", "test", song())}
+ title="Add to playlist"
+ >
From af2649cb11edf2aeac11176870394874c7bd097e Mon Sep 17 00:00:00 2001
From: D0m1nos <21263344+D0m1nos@users.noreply.github.com>
Date: Sun, 13 Oct 2024 18:55:24 +0200
Subject: [PATCH 24/54] add playlist edit mode
---
src/main/router/playlist-router.ts | 11 ++++--
.../playlist/playlist-item/PlaylistItem.tsx | 2 +-
.../playlist/playlist-item/styles.css | 8 +++++
.../playlist-song-list/PlaylistSongList.tsx | 35 +++++++++++++------
.../playlist/playlist-song-list/styles.css | 25 +++++++++++++
5 files changed, 67 insertions(+), 14 deletions(-)
diff --git a/src/main/router/playlist-router.ts b/src/main/router/playlist-router.ts
index 53dc4d64..fc30b0f3 100644
--- a/src/main/router/playlist-router.ts
+++ b/src/main/router/playlist-router.ts
@@ -35,8 +35,8 @@ Router.respond("playlist::delete", (_evt, name) => {
playlists.delete(name);
});
-Router.respond("playlist::remove", (_evt, playlistName, song) => {
- console.log("delete song from " + playlistName, song);
+Router.respond("playlist::remove", async (_evt, playlistName, song) => {
+ console.log("delete " + song.title + " from " + playlistName);
const playlists = Storage.getTable("playlists");
const playlist = playlists.get(playlistName);
@@ -44,10 +44,15 @@ Router.respond("playlist::remove", (_evt, playlistName, song) => {
return;
}
- const songIndex = playlist.value.songs.indexOf(song, 0);
+ // i assume that audio is the primary key
+ const songIndex = playlist.value.songs.findIndex((s) => s.audio === song.audio);
+
if (songIndex > -1) {
playlist.value.songs.splice(songIndex, 1);
+ playlist.value.count = playlist.value.count - 1;
+ playlist.value.length = playlist.value.length - song.duration;
playlists.write(playlistName, playlist.value);
+ await Router.dispatch(mainWindow, "playlist::resetSongList").catch(errorIgnored);
}
});
diff --git a/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx b/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
index eeb34472..b42c76d6 100644
--- a/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
+++ b/src/renderer/src/components/playlist/playlist-item/PlaylistItem.tsx
@@ -38,7 +38,7 @@ const PlaylistItem: Component = (props) => {
{/* {formatPlaylistTime(Math.round(props.playlist.length))}
*/}
- deletePlaylist(e, props)}>
+ deletePlaylist(e, props)} data-open={"false"}>
diff --git a/src/renderer/src/components/playlist/playlist-item/styles.css b/src/renderer/src/components/playlist/playlist-item/styles.css
index 2dd574dd..624e9b52 100644
--- a/src/renderer/src/components/playlist/playlist-item/styles.css
+++ b/src/renderer/src/components/playlist/playlist-item/styles.css
@@ -53,6 +53,14 @@
border: 1px solid #f2f4fc1a;
border-radius: 8px;
z-index: 3;
+
+ .icon-button {
+ border-radius: 8px;
+ &[data-open="true"] {
+ background-color: #ffffffeb;
+ color: #0d0d0df2;
+ }
+ }
}
}
}
diff --git a/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx b/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx
index 56bb52fa..16e91b59 100644
--- a/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx
+++ b/src/renderer/src/components/playlist/playlist-song-list/PlaylistSongList.tsx
@@ -5,8 +5,8 @@ import "./styles.css";
import { namespace } from "@renderer/App";
import IconButton from "@renderer/components/icon-button/IconButton";
import Impulse from "@renderer/lib/Impulse";
-import { Component, createSignal, onCleanup, onMount } from "solid-js";
-import { PlaylistSongsQueryPayload, ResourceID } from "src/@types";
+import { Component, createSignal, Match, onCleanup, onMount, Switch } from "solid-js";
+import { PlaylistSongsQueryPayload, ResourceID, Song } from "src/@types";
type PlaylistSongListProps = {
playlistName: string;
@@ -19,6 +19,8 @@ const PlaylistSongList: Component = (props) => {
playlistName: props.playlistName,
});
+ const [editMode, setEditMode] = createSignal(false);
+
const reset = new Impulse();
onMount(() => window.api.listen("playlist::resetSongList", reset.pulse.bind(reset)));
@@ -33,6 +35,10 @@ const PlaylistSongList: Component = (props) => {
});
};
+ const deleteSong = async (playlistName: string, song: Song) => {
+ await window.api.request("playlist::remove", playlistName, song);
+ };
+
return (
@@ -43,7 +49,7 @@ const PlaylistSongList: Component
= (props) => {
{props.playlistName}
-
+ setEditMode(!editMode())} data-open={editMode()}>
@@ -57,13 +63,22 @@ const PlaylistSongList: Component
= (props) => {
reset={reset}
fallback={No songs in playlist...
}
builder={(s) => (
-
+
+
+
+
+ deleteSong(props.playlistName, s)}>
+
+
+
+
+
)}
/>
diff --git a/src/renderer/src/components/playlist/playlist-song-list/styles.css b/src/renderer/src/components/playlist/playlist-song-list/styles.css
index 20c0e176..3053fbe4 100644
--- a/src/renderer/src/components/playlist/playlist-song-list/styles.css
+++ b/src/renderer/src/components/playlist/playlist-song-list/styles.css
@@ -35,6 +35,11 @@
.icon-button {
font-size: 20px;
+ border-radius: 8px;
+ &[data-open="true"] {
+ background-color: #ffffffeb;
+ color: #0d0d0df2;
+ }
}
}
}
@@ -45,5 +50,25 @@
flex-direction: column;
gap: 16px;
}
+
+ .playlist-song-list__list__item {
+ display: flex;
+ width: 100%;
+ flex-direction: row;
+ align-items: center;
+ justify-content: center;
+
+ .song-item {
+ width: 100%;
+ }
+
+ .icon-button {
+ margin-left: 12px;
+ margin-right: -2px;
+ color: lightcoral;
+ border-radius: 8px;
+ border: 1px solid #f2f4fc1a;
+ }
+ }
}
}
From 7811f9db2cab826072ef02f8ae0969926d06ead9 Mon Sep 17 00:00:00 2001
From: D0m1nos <21263344+D0m1nos@users.noreply.github.com>
Date: Mon, 14 Oct 2024 20:18:48 +0200
Subject: [PATCH 25/54] tailwind my beloved
---
.../playlist-create/PlaylistCreateBox.tsx | 27 +++++--
.../playlist/playlist-item/PlaylistItem.tsx | 27 ++++---
.../playlist/playlist-item/styles.css | 67 -----------------
.../playlist/playlist-list/PlaylistList.tsx | 19 ++---
.../playlist/playlist-list/styles.css | 63 ----------------
.../playlist-song-list/PlaylistSongList.tsx | 33 ++++++---
.../playlist/playlist-song-list/styles.css | 74 -------------------
.../playlist/playlist-view/PlaylistView.tsx | 3 +-
.../playlist/playlist-view/styles.css | 4 -
.../components/song/song-item/SongItem.tsx | 2 +-
.../components/song/song-list/SongList.tsx | 1 -
11 files changed, 70 insertions(+), 250 deletions(-)
delete mode 100644 src/renderer/src/components/playlist/playlist-item/styles.css
delete mode 100644 src/renderer/src/components/playlist/playlist-list/styles.css
delete mode 100644 src/renderer/src/components/playlist/playlist-song-list/styles.css
delete mode 100644 src/renderer/src/components/playlist/playlist-view/styles.css
diff --git a/src/renderer/src/components/playlist/playlist-create/PlaylistCreateBox.tsx b/src/renderer/src/components/playlist/playlist-create/PlaylistCreateBox.tsx
index 3d838a17..cc5b88d5 100644
--- a/src/renderer/src/components/playlist/playlist-create/PlaylistCreateBox.tsx
+++ b/src/renderer/src/components/playlist/playlist-create/PlaylistCreateBox.tsx
@@ -22,26 +22,37 @@ const PlaylistCreateBox: Component = (props) => {
};
return (
-
-