/* global SENTRY_DSN */ import Raven from "raven-js"; import React from "react"; import ReactDOM from "react-dom"; import createMiddleware from "raven-for-redux"; import isButterchurnSupported from "butterchurn/lib/isSupported.min"; import base from "../../skins/base-2.91-png.wsz"; import { WINDOWS } from "../../js/constants"; import * as Selectors from "../../js/selectors"; import WebampLazy from "../../js/webampLazy"; import { STEP_MARQUEE, UPDATE_TIME_ELAPSED, UPDATE_WINDOW_POSITIONS, SET_VOLUME, SET_BALANCE, SET_BAND_VALUE, DISABLE_MARQUEE, TOGGLE_REPEAT, TOGGLE_SHUFFLE, SET_EQ_AUTO, SET_DUMMY_VIZ_DATA, } from "../../js/actionTypes"; import { loadFilesFromReferences } from "../../js/actionCreators"; import { bindToIndexedDB } from "./indexedDB"; import { getButterchurnOptions } from "./butterchurnOptions"; import dropboxFilePicker from "./dropboxFilePicker"; import availableSkins from "./avaliableSkins"; import { skinUrl as configSkinUrl, initialTracks, initialState, disableMarquee, } from "./config"; import WebampIcon from "./WebampIcon"; import enableMediaSession from "./mediaSession"; import screenshotInitialState from "./screenshotInitialState"; const DEFAULT_DOCUMENT_TITLE = document.title; const NOISY_ACTION_TYPES = new Set([ STEP_MARQUEE, UPDATE_TIME_ELAPSED, UPDATE_WINDOW_POSITIONS, SET_VOLUME, SET_BALANCE, SET_BAND_VALUE, ]); const MIN_MILKDROP_WIDTH = 725; let screenshot = false; let clearState = false; let useState = false; let skinUrl = configSkinUrl; let library = false; if ("URLSearchParams" in window) { const params = new URLSearchParams(location.search); screenshot = params.get("screenshot"); library = Boolean(params.get("library")); // The default skin CSS baked into the JS library does not have full Media // Library support. If we are going to show the library we have to load a // skin at start time. if (library && skinUrl == null) { skinUrl = base; } skinUrl = params.get("skinUrl") || skinUrl; clearState = Boolean(params.get("clearState")); useState = Boolean(params.get("useState")); } function supressDragAndDrop(e) { e.preventDefault(); e.dataTransfer.effectAllowed = "none"; e.dataTransfer.dropEffect = "none"; } window.addEventListener("dragenter", supressDragAndDrop); window.addEventListener("dragover", supressDragAndDrop); window.addEventListener("drop", supressDragAndDrop); let lastActionType = null; // Filter out consecutive common actions function filterBreadcrumbActions(action) { const noisy = NOISY_ACTION_TYPES.has(action.type) && NOISY_ACTION_TYPES.has(lastActionType); lastActionType = action.type; return !noisy; } Raven.config(SENTRY_DSN, { /* global COMMITHASH */ release: typeof COMMITHASH !== "undefined" ? COMMITHASH : "DEV", }).install(); const ravenMiddleware = createMiddleware(Raven, { filterBreadcrumbActions, stateTransformer: Selectors.getDebugData, }); // Don't prompt user to install Webamp. It's probably not // what they want. window.addEventListener("beforeinstallprompt", e => { // TODO: we could add this as a context menu item, or something. e.preventDefault(); }); Raven.context(async () => { window.Raven = Raven; const about = document.getElementsByClassName("about")[0]; if (screenshot) { about.style.visibility = "hidden"; } if (!WebampLazy.browserIsSupported()) { document.getElementById("browser-compatibility").style.display = "block"; document.getElementById("app").style.visibility = "hidden"; return; } about.classList.add("loaded"); let __butterchurnOptions = null; let __initialWindowLayout = null; if (isButterchurnSupported()) { const startWithMilkdropHidden = library || document.body.clientWidth < MIN_MILKDROP_WIDTH || skinUrl != null || screenshot; __butterchurnOptions = getButterchurnOptions(startWithMilkdropHidden); if (library) { __initialWindowLayout = { [WINDOWS.MAIN]: { position: { x: 0, y: 0 } }, [WINDOWS.EQUALIZER]: { position: { x: 0, y: 116 } }, [WINDOWS.PLAYLIST]: { position: { x: 0, y: 232 }, size: [0, 4] }, [WINDOWS.MEDIA_LIBRARY]: { position: { x: 275, y: 0 }, size: [7, 12] }, }; } else if (startWithMilkdropHidden) { __initialWindowLayout = { [WINDOWS.MAIN]: { position: { x: 0, y: 0 } }, [WINDOWS.EQUALIZER]: { position: { x: 0, y: 116 } }, [WINDOWS.PLAYLIST]: { position: { x: 0, y: 232 }, size: [0, 0] }, [WINDOWS.MILKDROP]: { position: { x: 0, y: 348 }, size: [0, 0] }, }; } else { __initialWindowLayout = { [WINDOWS.MAIN]: { position: { x: 0, y: 0 } }, [WINDOWS.EQUALIZER]: { position: { x: 0, y: 116 } }, [WINDOWS.PLAYLIST]: { position: { x: 0, y: 232 }, size: [0, 4] }, [WINDOWS.MILKDROP]: { position: { x: 275, y: 0 }, size: [7, 12] }, }; } document.getElementById("butterchurn-share").style.display = "flex"; } const initialSkin = !skinUrl ? null : { url: skinUrl }; const webamp = new WebampLazy({ initialSkin, initialTracks: screenshot ? null : initialTracks, availableSkins, filePickers: [dropboxFilePicker], enableHotkeys: true, requireJSZip: () => import(/* webpackChunkName: "jszip" */ "jszip/dist/jszip"), requireMusicMetadata: () => import(/* webpackChunkName: "music-metadata-browser" */ "music-metadata-browser/dist/index"), __enableMediaLibrary: library, __initialWindowLayout, __initialState: screenshot ? screenshotInitialState : initialState, __butterchurnOptions, __customMiddlewares: [ravenMiddleware], }); 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}`; }); enableMediaSession(webamp); // 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.value = null; fileInput.addEventListener("change", e => { webamp.store.dispatch(loadFilesFromReferences(e.target.files)); }); document.body.appendChild(fileInput); // Expose webamp instance for debugging and integration tests. window.__webamp = webamp; await bindToIndexedDB(webamp, clearState, useState); await webamp.renderWhenReady(document.getElementById("app")); ReactDOM.render( , document.getElementById("webamp-icon") ); });