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(