diff --git a/package.json b/package.json index 46e006e32..893cb41ff 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "@ffmpeg/ffmpeg": "^0.12.10", "@ffmpeg/util": "^0.12.1", "@intrnl/xxhash64": "^0.1.2", - "@song-spotlight/api": "^2.1.3", + "@song-spotlight/api": "^2.2.0", "@streamparser/json": "^0.0.22", "@types/less": "^3.0.8", "@types/stylus": "^0.48.42", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cc0d40c38..fa8bb4848 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -21,8 +21,8 @@ importers: specifier: ^0.1.2 version: 0.1.2 '@song-spotlight/api': - specifier: ^2.1.3 - version: 2.1.3(typescript@6.0.3) + specifier: ^2.2.0 + version: 2.2.0(typescript@6.0.3) '@streamparser/json': specifier: ^0.0.22 version: 0.0.22 @@ -575,8 +575,8 @@ packages: resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} - '@song-spotlight/api@2.1.3': - resolution: {integrity: sha512-Wai7JHd9lrHtM/lkhfWQIFjIWKtP8iD+zj4Lnwbs/ykELR0MB2k56TDnQaRAelvu8XOygt27wfDBDQSEepPqdA==} + '@song-spotlight/api@2.2.0': + resolution: {integrity: sha512-zKH9X+G1uRYmEHFgluExPEFJWtA87PG8C39Xng0XG7Oh42ycOHjZtqtyEbfGM+hs+QEVos4wOoySeBAggnK7Iw==} peerDependencies: typescript: ^5 @@ -2698,7 +2698,7 @@ snapshots: '@sindresorhus/merge-streams@4.0.0': {} - '@song-spotlight/api@2.1.3(typescript@6.0.3)': + '@song-spotlight/api@2.2.0(typescript@6.0.3)': dependencies: typescript: 6.0.3 optionalDependencies: @@ -2958,10 +2958,10 @@ snapshots: array-includes@3.1.9: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 define-properties: 1.2.1 - es-abstract: 1.24.1 + es-abstract: 1.24.2 es-object-atoms: 1.1.2 get-intrinsic: 1.3.0 is-string: 1.1.1 @@ -2978,10 +2978,10 @@ snapshots: array.prototype.findlastindex@1.2.6: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 call-bound: 1.0.4 define-properties: 1.2.1 - es-abstract: 1.24.1 + es-abstract: 1.24.2 es-errors: 1.3.0 es-object-atoms: 1.1.2 es-shim-unscopables: 1.1.0 @@ -2995,9 +2995,9 @@ snapshots: array.prototype.flat@1.3.3: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 - es-abstract: 1.24.1 + es-abstract: 1.24.2 es-shim-unscopables: 1.1.0 array.prototype.flatmap@1.3.3: @@ -4298,9 +4298,9 @@ snapshots: object.groupby@1.0.3: dependencies: - call-bind: 1.0.8 + call-bind: 1.0.9 define-properties: 1.2.1 - es-abstract: 1.24.1 + es-abstract: 1.24.2 object.values@1.2.1: dependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 0b52f44eb..c6cfde866 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -17,3 +17,5 @@ allowBuilds: esbuild: true pmOnFail: warn verifyDepsBeforeRun: prompt +minimumReleaseAgeExclude: + - '@song-spotlight/api@2.2.0' diff --git a/src/equicordplugins/songSpotlight.desktop/index.tsx b/src/equicordplugins/songSpotlight.desktop/index.tsx index 8e9f99f40..c0e9f2fbb 100644 --- a/src/equicordplugins/songSpotlight.desktop/index.tsx +++ b/src/equicordplugins/songSpotlight.desktop/index.tsx @@ -12,7 +12,6 @@ import definePlugin from "@utils/types"; import { useAuthorizationStore } from "./lib/stores/AuthorizationStore"; import { useSongStore } from "./lib/stores/SongStore"; -import { Native } from "./service"; import settings from "./settings"; import ProfileSongs from "./ui/songs/ProfileSongs"; import WidgetSongs from "./ui/songs/WidgetSongs"; @@ -48,12 +47,6 @@ export default definePlugin({ }, }, start() { - // the cache lives in native.ts so it persists between reloads and - // only gets cleared on full restart. we don't want that since - // audio preview URLs expire very fast, so we just clear it on - // plugin restart instead - Native.clearCache(); - useSongStore.getState().$refresh(); useAuthorizationStore.persist.rehydrate(); }, diff --git a/src/equicordplugins/songSpotlight.desktop/native.ts b/src/equicordplugins/songSpotlight.desktop/native.ts index ea8fc1929..6092795c5 100644 --- a/src/equicordplugins/songSpotlight.desktop/native.ts +++ b/src/equicordplugins/songSpotlight.desktop/native.ts @@ -20,7 +20,3 @@ export async function renderSong(_: IpcMainInvokeEvent, song: Song) { export async function validateSong(_: IpcMainInvokeEvent, song: Song) { return handlers.validateSong(song); } - -export function clearCache() { - return handlers.clearCache(); -} diff --git a/src/equicordplugins/songSpotlight.desktop/settings.tsx b/src/equicordplugins/songSpotlight.desktop/settings.tsx index c374c6612..b9d554723 100644 --- a/src/equicordplugins/songSpotlight.desktop/settings.tsx +++ b/src/equicordplugins/songSpotlight.desktop/settings.tsx @@ -22,6 +22,13 @@ export default definePluginSettings({ default: apiConstants.songLimit, markers: makeRange(1, 3), }, + previewVolume: { + type: OptionType.SLIDER, + description: "Volume of song previews when played", + markers: [0, 25, 50, 100], + default: 100, + stickToMarkers: false + }, manager: { type: OptionType.COMPONENT, component: () => , diff --git a/src/equicordplugins/songSpotlight.desktop/style.css b/src/equicordplugins/songSpotlight.desktop/style.css index bb44f9aaa..8897eb8b8 100644 --- a/src/equicordplugins/songSpotlight.desktop/style.css +++ b/src/equicordplugins/songSpotlight.desktop/style.css @@ -145,6 +145,7 @@ gap: 6px; &.vc-songspotlight-songs-container-sidebar { + margin: 12px 16px 0; padding: 12px; } } @@ -201,10 +202,6 @@ padding: 8px; } -.user-profile-popout:not(.custom-user-profile-theme) .vc-songspotlight-song-container { - background: var(--opacity-16); -} - .vc-songspotlight-song { height: 100%; animation: songspotlight-fade-in var(--time) linear forwards; @@ -301,7 +298,7 @@ .vc-songspotlight-song-progress { position: absolute; inset: 0; - color: white; + color: var(--icon-default); pointer-events: none; > circle { @@ -369,4 +366,4 @@ from { opacity: 0; } -} +} \ No newline at end of file diff --git a/src/equicordplugins/songSpotlight.desktop/ui/components/AudioPlayer.tsx b/src/equicordplugins/songSpotlight.desktop/ui/components/AudioPlayer.tsx index 144efb75f..904625837 100644 --- a/src/equicordplugins/songSpotlight.desktop/ui/components/AudioPlayer.tsx +++ b/src/equicordplugins/songSpotlight.desktop/ui/components/AudioPlayer.tsx @@ -5,109 +5,138 @@ */ import { logger } from "@equicordplugins/songSpotlight.desktop/lib/utils"; -import { RenderInfoEntry } from "@song-spotlight/api/handlers"; +import settings from "@equicordplugins/songSpotlight.desktop/settings"; +import { RenderInfoEntry, RenderInfoEntryAudio } from "@song-spotlight/api/handlers"; import { showToast, Toasts, useCallback, useEffect, useMemo, useRef } from "@webpack/common"; import { RefObject } from "react"; +interface AudioItemProps { + audio: RenderInfoEntryAudio; + index: number; + handleRef(index: number, node: HTMLAudioElement | null): void; + handleLoaded(index: number, state: boolean): void; + handleStopped(index: number, ended?: boolean): void; +} + +function AudioItem({ audio, index, handleRef, handleLoaded, handleStopped }: AudioItemProps) { + const refCallback = useCallback((node: HTMLAudioElement | null) => handleRef(index, node), [index, handleRef]); + const loadedCallback = useCallback(() => handleLoaded(index, true), [index, handleLoaded]); + const erroredCallback = useCallback(() => handleLoaded(index, false), [index, handleLoaded]); + const pausedCallback = useCallback(() => handleStopped(index), [index, handleStopped]); + const endedCallback = useCallback(() => handleStopped(index, true), [index, handleStopped]); + + return