diff --git a/netlify.toml b/netlify.toml index 28c17043..fa7d226b 100644 --- a/netlify.toml +++ b/netlify.toml @@ -7,6 +7,11 @@ from = "/changelog" to = "/#%7B\"initialTracks\"%3A%5B%7B\"url\"%3A\"https%3A%2F%2Fcdn.changelog.com%2Fuploads%2Fpodcast%2F291%2Fthe-changelog-291.mp3\"%2C\"metaData\"%3A%7B\"artist\"%3A\"Changelog%20Podcast\"%2C\"title\"%3A\"Winamp2-js\"%7D%7D%5D%7D" +# A short URL for LuigiHann's Poolside.fm skin +[[redirects]] + from = "/poolside" + to = "/?bg=%2362639f&scPlaylist=1040356177&skinUrl=https://cdn.webampskins.org/skins/1b3138a9ea05e917049a4eab7b73d069.wsz" + [[redirects]] from = "/about" to = "https://github.com/captbaritone/webamp" diff --git a/packages/webamp/demo/images/icons/soundcloud-32x32.png b/packages/webamp/demo/images/icons/soundcloud-32x32.png new file mode 100644 index 00000000..01b29af1 Binary files /dev/null and b/packages/webamp/demo/images/icons/soundcloud-32x32.png differ diff --git a/packages/webamp/demo/js/DemoDesktop.tsx b/packages/webamp/demo/js/DemoDesktop.tsx index 19279b3c..47f7c565 100644 --- a/packages/webamp/demo/js/DemoDesktop.tsx +++ b/packages/webamp/demo/js/DemoDesktop.tsx @@ -8,10 +8,13 @@ import { useWindowSize } from "../../js/hooks"; import avaliableSkins from "./avaliableSkins"; import DesktopLinkIcon from "./DesktopLinkIcon"; import museumIcon from "../images/icons/internet-folder-32x32.png"; +import soundcloudIcon from "../images/icons/soundcloud-32x32.png"; +import { SoundCloudPlaylist } from "./SoundCloud"; // import MilkIcon from "./MilkIcon"; interface Props { webamp: WebampLazy; + soundCloudPlaylist: SoundCloudPlaylist | null; } const ICON_WIDTH = 75; @@ -19,7 +22,7 @@ const ICON_HEIGHT = 100; const VERTICAL_MARGIN = 30; const HORIZONTAL_MARGIN = 10; -const DemoDesktop = ({ webamp }: Props) => { +const DemoDesktop = ({ webamp, soundCloudPlaylist }: Props) => { const { width } = useWindowSize(); const visibleWidth = width - VERTICAL_MARGIN * 2; @@ -52,6 +55,15 @@ const DemoDesktop = ({ webamp }: Props) => { href={"https://skins.webamp.org"} /> ); + if (soundCloudPlaylist != null) { + icons.push( + + ); + } } return (
{ + const result = await fetch( + `https://api.soundcloud.com/playlists/${playlistId}?client_id=${CLIENT_ID}`, + { + headers: { + accept: "application/json, text/javascript, */*; q=0.1", + }, + mode: "cors", + credentials: "omit", + } + ); + + // eslint-disable-next-line no-return-await + return await result.json(); +} + +export function tracksFromPlaylist(playlist: SoundCloudPlaylist): Track[] { + return playlist.tracks.map((track) => { + return { + metaData: { + artist: track.user.username, + title: track.title, + }, + url: `${track.stream_url}?client_id=${CLIENT_ID}`, + duration: track.duration / 1000, + }; + }); +} diff --git a/packages/webamp/demo/js/index.tsx b/packages/webamp/demo/js/index.tsx index d302d934..af71bdaf 100644 --- a/packages/webamp/demo/js/index.tsx +++ b/packages/webamp/demo/js/index.tsx @@ -3,6 +3,7 @@ import ReactDOM from "react-dom"; // @ts-ignore import isButterchurnSupported from "butterchurn/lib/isSupported.min"; import { getWebampConfig } from "./webampConfig"; +import * as SoundCloud from "./SoundCloud"; import { WebampLazy, @@ -29,10 +30,14 @@ const DEFAULT_DOCUMENT_TITLE = document.title; let screenshot = false; let skinUrl = configSkinUrl; +let backgroundColor: null | string = null; +let soundcloudPlaylistId: null | string = null; if ("URLSearchParams" in window) { const params = new URLSearchParams(location.search); screenshot = Boolean(params.get("screenshot")); skinUrl = params.get("skinUrl") || skinUrl; + backgroundColor = params.get("bg"); + soundcloudPlaylistId = params.get("scPlaylist"); } function supressDragAndDrop(e: DragEvent) { @@ -51,7 +56,7 @@ window.addEventListener("drop", supressDragAndDrop); try { Sentry.init({ dsn: SENTRY_DSN, - release: COMMITHASH ?? "DEV", + release: typeof COMMITHASH === "undefined" ? "DEV" : COMMITHASH, }); } catch (e) { // Archive.org tries to rewrite the DSN to point to a archive.org version @@ -79,8 +84,13 @@ async function main() { "butterchurn-share" ) as HTMLDivElement).style.display = "flex"; } + let soundcloudPlaylist = null; + if (soundcloudPlaylistId != null) { + soundcloudPlaylist = await SoundCloud.getPlaylist(soundcloudPlaylistId); + } + const config = await getWebampConfig(screenshot, skinUrl, soundcloudPlaylist); - const webamp = new WebampLazy(getWebampConfig(screenshot, skinUrl)); + const webamp = new WebampLazy(config); if (disableMarquee || screenshot) { webamp.store.dispatch({ type: DISABLE_MARQUEE }); @@ -146,8 +156,11 @@ async function main() { ); if (!screenshot) { + if (backgroundColor != null) { + window.document.body.style.backgroundColor = backgroundColor; + } ReactDOM.render( - , + , document.getElementById("demo-desktop") ); } diff --git a/packages/webamp/demo/js/webampConfig.ts b/packages/webamp/demo/js/webampConfig.ts index a83110c2..f4fb881d 100644 --- a/packages/webamp/demo/js/webampConfig.ts +++ b/packages/webamp/demo/js/webampConfig.ts @@ -4,6 +4,7 @@ import createMiddleware from "redux-sentry-middleware"; // @ts-ignore import isButterchurnSupported from "butterchurn/lib/isSupported.min"; import { loggerMiddleware } from "./eventLogger"; +import * as SoundCloud from "./SoundCloud"; import { Action, @@ -55,10 +56,11 @@ const sentryMiddleware = createMiddleware(Sentry, { stateTransformer: getDebugData, }); -export function getWebampConfig( +export async function getWebampConfig( screenshot: boolean, - skinUrl: string | null -): Options & PrivateOptions { + skinUrl: string | null, + soundCloudPlaylist: SoundCloud.SoundCloudPlaylist | null +): Promise { let __butterchurnOptions; let __initialWindowLayout: WindowLayout | undefined; if (isButterchurnSupported()) { @@ -90,7 +92,12 @@ export function getWebampConfig( return { initialSkin, - initialTracks: screenshot ? undefined : initialTracks, + // eslint-disable-next-line no-nested-ternary + initialTracks: screenshot + ? undefined + : soundCloudPlaylist != null + ? SoundCloud.tracksFromPlaylist(soundCloudPlaylist) + : initialTracks, availableSkins, filePickers: [dropboxFilePicker], enableHotkeys: true, diff --git a/packages/webamp/js/__tests__/__image_snapshots__/baseline-integration-test-js-can-set-a-background-color-via-the-query-params-1-snap.png b/packages/webamp/js/__tests__/__image_snapshots__/baseline-integration-test-js-can-set-a-background-color-via-the-query-params-1-snap.png new file mode 100644 index 00000000..04f42a4c Binary files /dev/null and b/packages/webamp/js/__tests__/__image_snapshots__/baseline-integration-test-js-can-set-a-background-color-via-the-query-params-1-snap.png differ diff --git a/packages/webamp/js/__tests__/baseline.integration-test.js b/packages/webamp/js/__tests__/baseline.integration-test.js index ae6b0b65..63f3d16d 100644 --- a/packages/webamp/js/__tests__/baseline.integration-test.js +++ b/packages/webamp/js/__tests__/baseline.integration-test.js @@ -35,6 +35,20 @@ test("can load a skin via the query params", async () => { expect(await page.screenshot()).toMatchImageSnapshot(snapshotOptions); }); +test("can set a background color via the query params", async () => { + await page.goto(`${DOMAIN}/?bg=%23ff0000#{"disableMarquee":true}`); + await page.evaluate(() => window.__webamp.skinIsLoaded()); + expect(await page.screenshot()).toMatchImageSnapshot(snapshotOptions); +}); + +// This seems to fail hard for some other reason. Disable for now. +test.skip("can set soundcloud playlist via the query params", async () => { + // If this test starts to fail, it might be flakyiness coming from the SoundCloud API, or that Poolside FM has changed their playlist. + await page.goto(`${DOMAIN}/?scPlaylist=1040356177#{"disableMarquee":true}`); + await page.evaluate(() => window.__webamp.skinIsLoaded()); + expect(await page.screenshot()).toMatchImageSnapshot(snapshotOptions); +}); + test("should render the Topaz skin", async () => { await page.goto(`${DOMAIN}/#{"disableMarquee":true}`); await expect(page).toUploadFile(