webamp/packages/webamp-demo/js/index.tsx
Jordan Eldredge c7a282c1fd
Split demo site into its own package (#1351)
* Split demo site into its own package

Move the demo site from packages/webamp/demo/ into packages/webamp-demo/
as a standalone workspace package. This cleanly separates the library
(published to npm) from the demo site (deployed to webamp.org).

Key changes:
- Demo imports webamp source via relative paths (no aliases needed)
- Demo has its own package.json with demo-specific deps
- Simplified vite config (just nodePolyfills plugin)
- Removed vite branching from rollupPlugins.mjs (library-only now)
- Renamed build-library -> build in webamp package
- Updated turbo.json, CI, netlify config, and code-size workflow
- Removed demo-only deps from webamp package (sentry, butterchurn stays
  for the butterchurn bundle)
- Zero bundle size change for the library

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix: add type-check dependency to webamp#build task

The webamp-docs package needs type declarations from webamp to
type-check. These are generated by tsc (type-check), which must run
before the build task.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Add updated readme to webamp-demo package

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Document the live reloading dev flow in both readmes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix code-size CI: use deploy script that exists on both branches

The compressed-size-action checks out master and runs the build script.
Master doesn't have a root "build" script, so revert to using "deploy"
which exists on both branches.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-07 14:40:07 -07:00

168 lines
4.8 KiB
TypeScript

import React from "react";
import * as Sentry from "@sentry/browser";
import ReactDOM from "react-dom/client";
// @ts-ignore
import isButterchurnSupported from "butterchurn/dist/isSupported.min";
import { getWebampConfig } from "./webampConfig";
import * as SoundCloud from "./SoundCloud";
import WebampLazy from "../../webamp/js/webampLazy";
import { disableMarquee, skinUrl as configSkinUrl } from "./config";
import DemoDesktop from "./DemoDesktop";
// import { choreograph } from "./choreography";
declare global {
interface Window {
__webamp: WebampLazy;
}
}
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) {
e.preventDefault();
if (e.dataTransfer == null) {
return;
}
e.dataTransfer.effectAllowed = "none";
e.dataTransfer.dropEffect = "none";
}
window.addEventListener("dragenter", supressDragAndDrop);
window.addEventListener("dragover", supressDragAndDrop);
window.addEventListener("drop", supressDragAndDrop);
try {
// TODO: Get this working in Vite.
const COMMITHASH = undefined;
Sentry.init({
dsn: "https://12b6be8ef7c44f28ac37ab5ed98fd294@sentry.io/146021",
release: typeof COMMITHASH === "undefined" ? "DEV" : COMMITHASH,
});
} catch (e) {
// Archive.org tries to rewrite the DSN to point to a archive.org version
// since it looks like a URL. When this happens, Sentry crashes.
console.error(e);
}
async function main() {
const about = document.getElementsByClassName("about")[0] as HTMLDivElement;
if (screenshot) {
about.style.visibility = "hidden";
}
if (!WebampLazy.browserIsSupported()) {
(
document.getElementById("browser-compatibility") as HTMLDivElement
).style.display = "block";
(document.getElementById("app") as HTMLDivElement).style.visibility =
"hidden";
return;
}
about.classList.add("loaded");
if (isButterchurnSupported()) {
(
document.getElementById("butterchurn-share") as HTMLDivElement
).style.display = "flex";
}
let soundcloudPlaylist = null;
if (soundcloudPlaylistId != null) {
// @ts-ignore
soundcloudPlaylist = await SoundCloud.getPlaylist(soundcloudPlaylistId);
}
const config = await getWebampConfig(screenshot, skinUrl, soundcloudPlaylist);
const webamp = new WebampLazy(config);
if (disableMarquee || screenshot) {
webamp.store.dispatch({ type: "DISABLE_MARQUEE" });
}
if (screenshot) {
window.document.body.style.backgroundColor = "#000";
webamp.store.dispatch({ type: "TOGGLE_REPEAT" });
webamp.store.dispatch({ type: "TOGGLE_SHUFFLE" });
webamp.store.dispatch({ type: "SET_EQ_AUTO", value: true });
webamp.store.dispatch({
type: "SET_DUMMY_VIZ_DATA",
data: {
0: 11.75,
8: 11.0625,
16: 8.5,
24: 7.3125,
32: 6.75,
40: 6.4375,
48: 6.25,
56: 5.875,
64: 5.625,
72: 5.25,
80: 5.125,
88: 4.875,
96: 4.8125,
104: 4.375,
112: 3.625,
120: 1.5625,
},
});
}
webamp.onTrackDidChange((track) => {
document.title =
track == null
? DEFAULT_DOCUMENT_TITLE
: `${track.metaData.title} - ${track.metaData.artist} \u00B7 ${DEFAULT_DOCUMENT_TITLE}`;
});
// Expose a file input in the DOM for testing.
const fileInput = document.createElement("input");
fileInput.id = "webamp-file-input";
fileInput.style.display = "none";
fileInput.type = "file";
fileInput.addEventListener("change", (e) => {
// @ts-ignore We know this will always be a file input
const firstFile = e.target.files[0];
if (firstFile == null) {
return;
}
const url = URL.createObjectURL(firstFile);
webamp.setSkinFromUrl(url);
});
document.body.appendChild(fileInput);
// Expose webamp instance for debugging and integration tests.
window.__webamp = webamp;
await webamp.renderWhenReady(
document.getElementById("app") as HTMLDivElement
);
// choreograph(webamp);
if (!screenshot) {
if (backgroundColor != null) {
window.document.body.style.backgroundColor = backgroundColor;
}
const div = document.getElementById("demo-desktop");
if (div == null) {
throw new Error("Could not locate #demo-desktop div");
}
const root = ReactDOM.createRoot(div);
root.render(
<DemoDesktop webamp={webamp} soundCloudPlaylist={soundcloudPlaylist} />
);
}
}
main();