From 7bd1031e2754305f72e1e72b66c02dcd7cd1c01e Mon Sep 17 00:00:00 2001 From: SrIzan10 <66965250+SrIzan10@users.noreply.github.com> Date: Thu, 17 Apr 2025 22:32:37 +0000 Subject: [PATCH] feat: playing and pausing --- package.json | 1 + src/lib/components/app/bottom-bar.svelte | 2 +- src/lib/components/app/daemon.svelte | 102 ++++++++++++++++++ src/lib/components/app/music-player.svelte | 6 -- src/lib/components/app/now-playing.svelte | 18 ++++ .../components/app/station-dropdown.svelte | 0 .../dropdown-menu-checkbox-item.svelte | 40 +++++++ .../dropdown-menu-content.svelte | 27 +++++ .../dropdown-menu-group-heading.svelte | 19 ++++ .../dropdown-menu/dropdown-menu-item.svelte | 23 ++++ .../dropdown-menu/dropdown-menu-label.svelte | 23 ++++ .../dropdown-menu-radio-item.svelte | 30 ++++++ .../dropdown-menu-separator.svelte | 16 +++ .../dropdown-menu-shortcut.svelte | 20 ++++ .../dropdown-menu-sub-content.svelte | 19 ++++ .../dropdown-menu-sub-trigger.svelte | 28 +++++ src/lib/components/ui/dropdown-menu/index.ts | 50 +++++++++ src/lib/state.svelte.ts | 22 ++++ src/lib/types.ts | 77 +++++++++++++ src/lib/utils.ts | 8 +- src/routes/+page.svelte | 26 ++++- svelte.config.js | 2 +- yarn.lock | 7 ++ 23 files changed, 554 insertions(+), 12 deletions(-) create mode 100644 src/lib/components/app/daemon.svelte delete mode 100644 src/lib/components/app/music-player.svelte create mode 100644 src/lib/components/app/now-playing.svelte create mode 100644 src/lib/components/app/station-dropdown.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte create mode 100644 src/lib/components/ui/dropdown-menu/index.ts create mode 100644 src/lib/state.svelte.ts create mode 100644 src/lib/types.ts diff --git a/package.json b/package.json index 88155d6..fcc44e4 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ }, "devDependencies": { "@lucide/svelte": "^0.488.0", + "@sveltejs/adapter-auto": "^6.0.0", "@sveltejs/adapter-cloudflare": "^5.0.1", "@sveltejs/kit": "^2.16.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", diff --git a/src/lib/components/app/bottom-bar.svelte b/src/lib/components/app/bottom-bar.svelte index 1b908f4..92e33f8 100644 --- a/src/lib/components/app/bottom-bar.svelte +++ b/src/lib/components/app/bottom-bar.svelte @@ -1,5 +1,5 @@
diff --git a/src/lib/components/app/daemon.svelte b/src/lib/components/app/daemon.svelte new file mode 100644 index 0000000..9298766 --- /dev/null +++ b/src/lib/components/app/daemon.svelte @@ -0,0 +1,102 @@ + + +{#if !state.hasInteracted} + +{/if} + +{#if !state.isLoading} + +{/if} \ No newline at end of file diff --git a/src/lib/components/app/music-player.svelte b/src/lib/components/app/music-player.svelte deleted file mode 100644 index 568aec0..0000000 --- a/src/lib/components/app/music-player.svelte +++ /dev/null @@ -1,6 +0,0 @@ - - \ No newline at end of file diff --git a/src/lib/components/app/now-playing.svelte b/src/lib/components/app/now-playing.svelte new file mode 100644 index 0000000..7e49720 --- /dev/null +++ b/src/lib/components/app/now-playing.svelte @@ -0,0 +1,18 @@ + + + \ No newline at end of file diff --git a/src/lib/components/app/station-dropdown.svelte b/src/lib/components/app/station-dropdown.svelte new file mode 100644 index 0000000..e69de29 diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte new file mode 100644 index 0000000..456741d --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte @@ -0,0 +1,40 @@ + + + + {#snippet children({ checked, indeterminate })} + + {#if indeterminate} + + {:else} + + {/if} + + {@render childrenProp?.()} + {/snippet} + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte new file mode 100644 index 0000000..00966ff --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte @@ -0,0 +1,27 @@ + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte new file mode 100644 index 0000000..84d5cca --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte @@ -0,0 +1,19 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte new file mode 100644 index 0000000..bd7492d --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte @@ -0,0 +1,23 @@ + + +svg]:size-4 [&>svg]:shrink-0", + inset && "pl-8", + className + )} + {...restProps} +/> diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte new file mode 100644 index 0000000..9837d5a --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte @@ -0,0 +1,23 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte new file mode 100644 index 0000000..bcb960d --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte @@ -0,0 +1,30 @@ + + + + {#snippet children({ checked })} + + {#if checked} + + {/if} + + {@render childrenProp?.({ checked })} + {/snippet} + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte new file mode 100644 index 0000000..32fac4b --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte @@ -0,0 +1,16 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte new file mode 100644 index 0000000..053e2a2 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte new file mode 100644 index 0000000..0bb6eea --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte @@ -0,0 +1,19 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte new file mode 100644 index 0000000..f5e1e2a --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte @@ -0,0 +1,28 @@ + + + + {@render children?.()} + + diff --git a/src/lib/components/ui/dropdown-menu/index.ts b/src/lib/components/ui/dropdown-menu/index.ts new file mode 100644 index 0000000..40c4502 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/index.ts @@ -0,0 +1,50 @@ +import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui"; +import CheckboxItem from "./dropdown-menu-checkbox-item.svelte"; +import Content from "./dropdown-menu-content.svelte"; +import GroupHeading from "./dropdown-menu-group-heading.svelte"; +import Item from "./dropdown-menu-item.svelte"; +import Label from "./dropdown-menu-label.svelte"; +import RadioItem from "./dropdown-menu-radio-item.svelte"; +import Separator from "./dropdown-menu-separator.svelte"; +import Shortcut from "./dropdown-menu-shortcut.svelte"; +import SubContent from "./dropdown-menu-sub-content.svelte"; +import SubTrigger from "./dropdown-menu-sub-trigger.svelte"; + +const Sub = DropdownMenuPrimitive.Sub; +const Root = DropdownMenuPrimitive.Root; +const Trigger = DropdownMenuPrimitive.Trigger; +const Group = DropdownMenuPrimitive.Group; +const RadioGroup = DropdownMenuPrimitive.RadioGroup; + +export { + CheckboxItem, + Content, + Root as DropdownMenu, + CheckboxItem as DropdownMenuCheckboxItem, + Content as DropdownMenuContent, + Group as DropdownMenuGroup, + GroupHeading as DropdownMenuGroupHeading, + Item as DropdownMenuItem, + Label as DropdownMenuLabel, + RadioGroup as DropdownMenuRadioGroup, + RadioItem as DropdownMenuRadioItem, + Separator as DropdownMenuSeparator, + Shortcut as DropdownMenuShortcut, + Sub as DropdownMenuSub, + SubContent as DropdownMenuSubContent, + SubTrigger as DropdownMenuSubTrigger, + Trigger as DropdownMenuTrigger, + Group, + GroupHeading, + Item, + Label, + RadioGroup, + RadioItem, + Root, + Separator, + Shortcut, + Sub, + SubContent, + SubTrigger, + Trigger, +}; diff --git a/src/lib/state.svelte.ts b/src/lib/state.svelte.ts new file mode 100644 index 0000000..666aa0a --- /dev/null +++ b/src/lib/state.svelte.ts @@ -0,0 +1,22 @@ +import type { Song, Atmosphere, Preset, Station, Background } from "./types"; // Added Preset, Station, Background + +export const state = $state({ + hasInteracted: false, + currentStation: null as number | null, + currentSong: null as Song | null, + songQueue: [] as Song[], + isPlaying: true, + volume: 0.5, + isMuted: false, + currentBackgroundId: null as string | null, + activeAtmospheres: {} as Record, // { atmosphereId: volume (0-100) } + isLoading: true, + error: null as string | null, + currentTime: 0, + duration: 0, + + presets: [] as Preset[], + stations: [] as Station[], + backgrounds: [] as Background[], + atmospheres: [] as Atmosphere[], +}); diff --git a/src/lib/types.ts b/src/lib/types.ts new file mode 100644 index 0000000..691082f --- /dev/null +++ b/src/lib/types.ts @@ -0,0 +1,77 @@ +export interface Song { + id: number + fileId: number + artists: string + title: string + image: string + likes: number + featured?: string + releaseDate: string + releaseDateText: string + duration: number + isrc: string + label: string + spotifyId: string + startTime: string + endTime: string +} + +export interface Preset { + id: number; + userId: number; + name: string; + backgroundId: string; + stationId: string; // Represented as string in JSON + atmospheres: string; // JSON stringified object + sortOrder: number; + key: string; +} + +export interface StationMetaSocials { + spotify: string | null; + apple: string | null; +} + +export interface StationMetaIcon { + static: string; +} + +// Structure within the base64 decoded 'meta' string for stations +export interface DecodedStationMeta { + shortDescription: string; + icon: StationMetaIcon; + socials: StationMetaSocials; +} + + +export interface Station { + name: string; + id: number; + meta: string; // Base64 encoded JSON string (DecodedStationMeta) +} + +export interface Background { + id: string; + name: string; + parentId: string | null; + landscapeUrl: string; + portraitUrl: string; + thumbnailUrl: string; + sortOrder: number; + isActive: number; // 0 or 1 +} + +export interface Atmosphere { + id: string; + name: string; + url: string; + sortOrder: number; + urlMobile: string; +} + +export interface ChillhopData { + presets: Preset[]; + stations: Station[]; + backgrounds: Background[]; + atmospheres: Atmosphere[]; +} \ No newline at end of file diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 44da41d..7a60f53 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -1,5 +1,6 @@ import { type ClassValue, clsx } from "clsx"; import { twMerge } from "tailwind-merge"; +import type { ChillhopData, Song } from "./types"; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); @@ -7,7 +8,12 @@ export function cn(...inputs: ClassValue[]) { export async function getGeneralData() { const res = await fetch('https://stream.chillhop.com/presets') - const data = await res.json(); + const data = await res.json() as ChillhopData; + return data; +} +export async function getStationSongs(stationId: number) { + const res = await fetch(`https://stream.chillhop.com/live/${stationId}`) + const data = await res.json() as Song[]; return data; } \ No newline at end of file diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 9a00789..6aa7f35 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,9 +1,29 @@ - - \ No newline at end of file + + +{#if state.isLoading && !state.hasInteracted} +
+ +

Loading...

+
+{:else if state.isLoading && state.hasInteracted} +
+ +

Loading...

+
+{:else if state.error} +
+

Error: {state.error}

+
+{:else} + +{/if} \ No newline at end of file diff --git a/svelte.config.js b/svelte.config.js index 89ad7ae..b025dd7 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -1,4 +1,4 @@ -import adapter from "@sveltejs/adapter-cloudflare"; +import adapter from "@sveltejs/adapter-auto"; import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; /** @type {import('@sveltejs/kit').Config} */ diff --git a/yarn.lock b/yarn.lock index 31d9676..1f83956 100644 --- a/yarn.lock +++ b/yarn.lock @@ -659,6 +659,13 @@ resolved "https://registry.yarnpkg.com/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.5.tgz#f518101d1b2e12ce80854f1cd850d3b9fb91d710" integrity sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ== +"@sveltejs/adapter-auto@^6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@sveltejs/adapter-auto/-/adapter-auto-6.0.0.tgz#aac1245053c00cb05552b8a3b0ef77643d120f03" + integrity sha512-7mR2/G7vlXakaOj6QBSG9dwBfTgWjV+UnEMB5Z6Xu0ZbdXda6c0su1fNkg0ab0zlilSkloMA2NjCna02/DR7sA== + dependencies: + import-meta-resolve "^4.1.0" + "@sveltejs/adapter-cloudflare@^5.0.1": version "5.1.0" resolved "https://registry.yarnpkg.com/@sveltejs/adapter-cloudflare/-/adapter-cloudflare-5.1.0.tgz#c51a05d0af550a85197517f99e79975f8ae557a3"