From ef1af77dff39d0525c4b1071ec23e625b0e934ab Mon Sep 17 00:00:00 2001 From: Yusuf Bera Ertan Date: Sun, 23 Apr 2023 07:06:52 +0300 Subject: [PATCH] feat: implement better track view, fix virtual list issue, implement icons --- package.json | 3 + pnpm-lock.yaml | 166 +++++++++++++++++++++++++++++++++++ src/app.d.ts | 4 +- src/comms.ts | 10 ++- src/components/a.svelte | 2 +- src/components/navbar.svelte | 12 ++- src/components/track.svelte | 36 ++++++-- src/routes/+layout.svelte | 39 ++++---- src/routes/+page.svelte | 27 ++++-- src/types.ts | 3 +- vite.config.ts | 8 +- 11 files changed, 263 insertions(+), 47 deletions(-) diff --git a/package.json b/package.json index 3e24aea..b50de03 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,8 @@ "format": "prettier --plugin-search-dir . --write ." }, "devDependencies": { + "@iconify-json/line-md": "^1.1.24", + "@iconify-json/mdi": "^1.1.50", "@skeletonlabs/skeleton": "^1.2.0", "@sveltejs/adapter-auto": "^2.0.0", "@sveltejs/adapter-static": "^2.0.2", @@ -30,6 +32,7 @@ "tailwindcss": "^3.3.1", "tslib": "^2.5.0", "typescript": "^5.0.4", + "unplugin-icons": "^0.16.1", "vite": "^4.2.1" }, "type": "module", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ad4519e..c9548b1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,6 +9,12 @@ dependencies: version: 2.0.5 devDependencies: + '@iconify-json/line-md': + specifier: ^1.1.24 + version: 1.1.24 + '@iconify-json/mdi': + specifier: ^1.1.50 + version: 1.1.50 '@skeletonlabs/skeleton': specifier: ^1.2.0 version: 1.2.0 @@ -63,12 +69,26 @@ devDependencies: typescript: specifier: ^5.0.4 version: 5.0.4 + unplugin-icons: + specifier: ^0.16.1 + version: 0.16.1 vite: specifier: ^4.2.1 version: 4.2.1 packages: + /@antfu/install-pkg@0.1.1: + resolution: {integrity: sha512-LyB/8+bSfa0DFGC06zpCEfs89/XoWZwws5ygEa5D+Xsm3OfI+aXQ86VgVG7Acyef+rSZ5HE7J8rrxzrQeM3PjQ==} + dependencies: + execa: 5.1.1 + find-up: 5.0.0 + dev: true + + /@antfu/utils@0.7.2: + resolution: {integrity: sha512-vy9fM3pIxZmX07dL+VX1aZe7ynZ+YyB0jY+jE6r3hOK6GNY2t6W8rzpFC4tgpbXUYABkFQwgJq2XYXlxbXAI0g==} + dev: true + /@esbuild/android-arm64@0.17.16: resolution: {integrity: sha512-QX48qmsEZW+gcHgTmAj+x21mwTz8MlYQBnzF6861cNdQGvj2jzzFjqH0EBabrIa/WVZ2CHolwMoqxVryqKt8+Q==} engines: {node: '>=12'} @@ -324,6 +344,35 @@ packages: resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} dev: true + /@iconify-json/line-md@1.1.24: + resolution: {integrity: sha512-vHQnRZ3ZVDnrFoj8BMU0iTYR9404TrePP4UhCjkfOqkH4gibFoyM6JGO5OiIHv5m/GQvu4nteTICjklsRFUKpA==} + dependencies: + '@iconify/types': 2.0.0 + dev: true + + /@iconify-json/mdi@1.1.50: + resolution: {integrity: sha512-SgbT5w5eHCdOG74ZWPz7HlTGk6VsifIJhNi6lAsxj/5Nlqt6Cz4LlQmSa9eecU9p075Jub2aAx/o7YI+GCahRQ==} + dependencies: + '@iconify/types': 2.0.0 + dev: true + + /@iconify/types@2.0.0: + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + dev: true + + /@iconify/utils@2.1.5: + resolution: {integrity: sha512-6MvDI+I6QMvXn5rK9KQGdpEE4mmLTcuQdLZEiX5N+uZB+vc4Yw9K1OtnOgkl8mp4d9X0UrILREyZgF1NUwUt+Q==} + dependencies: + '@antfu/install-pkg': 0.1.1 + '@antfu/utils': 0.7.2 + '@iconify/types': 2.0.0 + debug: 4.3.4 + kolorist: 1.8.0 + local-pkg: 0.4.3 + transitivePeerDependencies: + - supports-color + dev: true + /@jridgewell/gen-mapping@0.3.3: resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} engines: {node: '>=6.0.0'} @@ -1028,6 +1077,21 @@ packages: engines: {node: '>=0.10.0'} dev: true + /execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + dev: true + /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} dev: true @@ -1111,6 +1175,11 @@ packages: resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} dev: true + /get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + dev: true + /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -1194,6 +1263,11 @@ packages: function-bind: 1.1.1 dev: true + /human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + dev: true + /ignore@5.2.4: resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} engines: {node: '>= 4'} @@ -1262,6 +1336,11 @@ packages: engines: {node: '>=8'} dev: true + /is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: true + /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: true @@ -1295,6 +1374,10 @@ packages: engines: {node: '>=6'} dev: true + /kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + dev: true + /levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -1312,6 +1395,11 @@ packages: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} dev: true + /local-pkg@0.4.3: + resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} + engines: {node: '>=14'} + dev: true + /locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -1344,6 +1432,10 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: true + /merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: true + /merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -1363,6 +1455,11 @@ packages: hasBin: true dev: true + /mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + dev: true + /min-indent@1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} @@ -1435,6 +1532,13 @@ packages: engines: {node: '>=0.10.0'} dev: true + /npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + dependencies: + path-key: 3.1.1 + dev: true + /object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -1451,6 +1555,13 @@ packages: wrappy: 1.0.2 dev: true + /onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + dependencies: + mimic-fn: 2.1.0 + dev: true + /optionator@0.9.1: resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==} engines: {node: '>= 0.8.0'} @@ -1732,6 +1843,10 @@ packages: engines: {node: '>=8'} dev: true + /signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: true + /sirv@2.0.2: resolution: {integrity: sha512-4Qog6aE29nIjAOKe/wowFTxOdmbEZKb+3tsLljaBRzJwtqto0BChD2zzH0LhgCSXiI+V7X+Y45v14wBZQ1TK3w==} engines: {node: '>= 10'} @@ -1773,6 +1888,11 @@ packages: ansi-regex: 5.0.1 dev: true + /strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + dev: true + /strip-indent@3.0.0: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} @@ -2026,6 +2146,43 @@ packages: busboy: 1.6.0 dev: true + /unplugin-icons@0.16.1: + resolution: {integrity: sha512-qTunFUkpAyDnwzwV7YV1ZgCWRYfLuURcCurhhXOWMy2ipY88qx1pADvral2hJu4Xymh0X0t3Zcll3BIru2AVLQ==} + peerDependencies: + '@svgr/core': '>=7.0.0' + '@vue/compiler-sfc': ^3.0.2 || ^2.7.0 + vue-template-compiler: ^2.6.12 + vue-template-es2015-compiler: ^1.9.0 + peerDependenciesMeta: + '@svgr/core': + optional: true + '@vue/compiler-sfc': + optional: true + vue-template-compiler: + optional: true + vue-template-es2015-compiler: + optional: true + dependencies: + '@antfu/install-pkg': 0.1.1 + '@antfu/utils': 0.7.2 + '@iconify/utils': 2.1.5 + debug: 4.3.4 + kolorist: 1.8.0 + local-pkg: 0.4.3 + unplugin: 1.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /unplugin@1.3.1: + resolution: {integrity: sha512-h4uUTIvFBQRxUKS2Wjys6ivoeofGhxzTe2sRWlooyjHXVttcVfV/JiavNd3d4+jty0SVV0dxGw9AkY9MwiaCEw==} + dependencies: + acorn: 8.8.2 + chokidar: 3.5.3 + webpack-sources: 3.2.3 + webpack-virtual-modules: 0.5.0 + dev: true + /update-browserslist-db@1.0.10(browserslist@4.21.5): resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} hasBin: true @@ -2091,6 +2248,15 @@ packages: vite: 4.2.1 dev: true + /webpack-sources@3.2.3: + resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + engines: {node: '>=10.13.0'} + dev: true + + /webpack-virtual-modules@0.5.0: + resolution: {integrity: sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==} + dev: true + /which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} diff --git a/src/app.d.ts b/src/app.d.ts index f59b884..2bc1360 100644 --- a/src/app.d.ts +++ b/src/app.d.ts @@ -1,5 +1,7 @@ // See https://kit.svelte.dev/docs/types#app // for information about these interfaces +/// +/// declare global { namespace App { // interface Error {} @@ -9,4 +11,4 @@ declare global { } } -export {}; +export { }; diff --git a/src/comms.ts b/src/comms.ts index 9fa34bd..bab87b8 100644 --- a/src/comms.ts +++ b/src/comms.ts @@ -16,6 +16,8 @@ interface Message { type MessageType = 'request' | 'response' | 'broadcast'; type RequestCallback = (arg0: Message | null) => void; +type Category = 'album' | 'artist' | 'album_artist' | 'genre' | 'playlist'; + interface Callbacks { onDisconnect: (authenticated: boolean, reason: string) => void; onConnect: (initial: Message) => void; @@ -111,9 +113,11 @@ export class MetadataCommunicator { id: t.id, track: { title: t.title, - album_id: t.album_id, - artist_id: t.artist_id, track_num: t.track, + album_title: t.album, + album_id: t.album_id, + artist_name: t.artist, + artist_id: t.artist_id, thumbnail_id: t.thumbnail_id, } }))); @@ -159,7 +163,7 @@ export class MetadataCommunicator { ); } - onConnect(cb: () => void) { + onConnect(cb: () => Promise) { if (!this.isClosed() && this.authenticated) { cb(); } else { diff --git a/src/components/a.svelte b/src/components/a.svelte index 6fb429b..b78936c 100644 --- a/src/components/a.svelte +++ b/src/components/a.svelte @@ -6,6 +6,6 @@ $: isOnPage = href === $page.route.id; - + diff --git a/src/components/navbar.svelte b/src/components/navbar.svelte index cced898..c3b627b 100644 --- a/src/components/navbar.svelte +++ b/src/components/navbar.svelte @@ -1,10 +1,14 @@ diff --git a/src/components/track.svelte b/src/components/track.svelte index 81dd3d7..10eb2e5 100644 --- a/src/components/track.svelte +++ b/src/components/track.svelte @@ -1,20 +1,42 @@ -
- -
+
+ +
+ #{track.track_num} - {track.title} +
+ {track.album_title ? `from ${track.album_title}` : ''} + {track.artist_name ? `by ${track.artist_name}` : ''} +
- {track.track_num} - {track.title}
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index f2f867d..2b7d168 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -34,28 +34,23 @@ } }); comm.connect($address, $token); - comm.onConnect(() => { - comm - .fetchTracksCount() - .then((count) => { - let remaining = count; - console.log(count); - while (remaining > 0) { - const offset = count - remaining; - comm.fetchTracks(500, offset).then((ts) => { - tracks.update((map) => { - ts.forEach((t) => map.set(t.id, t.track)); - return map; - }); - tracksSorted.update((map) => { - ts.forEach((t, index) => map.set(index + offset, t.id)); - return map; - }); - }); - remaining -= 500; - } - }) - .catch(() => null); + comm.onConnect(async () => { + const count = await comm.fetchTracksCount(); + + let remaining = count; + while (remaining > 0) { + const offset = count - remaining; + const ts = await comm.fetchTracks(500, offset); + tracks.update((map) => { + ts.forEach((t) => map.set(t.id, t.track)); + return map; + }); + tracksSorted.update((map) => { + ts.forEach((t, index) => map.set(index + offset, t.id)); + return map; + }); + remaining -= 500; + } }); diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index b4a1725..ee84bae 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,14 +1,27 @@ - -
- -
-
+
+ +
+
+
+
+
diff --git a/src/types.ts b/src/types.ts index 3d3f88e..50ccd1b 100644 --- a/src/types.ts +++ b/src/types.ts @@ -3,7 +3,9 @@ export type ResourceId = bigint; export interface Track { title: string, track_num: number, + album_title: string, album_id: ResourceId, + artist_name: string, artist_id: ResourceId, thumbnail_id: ResourceId, } @@ -20,5 +22,4 @@ export interface Artist { export interface Album { title: string, artist_id: ResourceId, - thumbnail_id: ResourceId, } \ No newline at end of file diff --git a/vite.config.ts b/vite.config.ts index bbf8c7d..3af8dd8 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,6 +1,12 @@ import { sveltekit } from '@sveltejs/kit/vite'; import { defineConfig } from 'vite'; +import Icons from 'unplugin-icons/vite' export default defineConfig({ - plugins: [sveltekit()] + plugins: [ + sveltekit(), + Icons({ + compiler: 'svelte', + }) + ] });