import 'core-js/fn/object/assign'; /* React */ import * as React from 'react'; import { render as reactDOMRender, unmountComponentAtNode } from 'react-dom'; /* honoka library for fetch() polyfill */ import honoka from 'honoka'; /* Player core */ import PlayerContainer from './containers'; import { PlayerInstancesModel, Item } from './models'; import config from './config/base'; // This is an example for custom layouts inside the project. // Alternatively, you can also requires your layout file outside. // Read the wiki and find out how to extend your MUSE Player. import './layouts/landscape/landscape.styl'; import { construct as landscapeLayoutConstructor } from './layouts/landscape/construct'; // import React devtools when in anujs env if (process.env.REACT_DISTRO === 'anujs') { require('anujs/lib/devtools'); } const store = new PlayerInstancesModel(); const render = (Component: React.ReactElement, node: Element): void => { // Render the main component into the dom reactDOMRender(Component, node); }; export const MuseDOM: any = { // Do not modify them directly. _instances: [], _layouts: ['muse-layout-default'], _middlewares: { afterRender: [], onMusicChange: [], onToggleMenu: [], onToggleFullscreen: [], onToggleDrawer: [], onTogglePlay: [], onPlayerResize: [], onLyricUpdate: [] }, _version: config.MUSE_VERSION, _public: { React, honoka }, /* MUSE Player API start */ // high-level APIs: getInstance(), getState(), changeState() // Warning: these APIs are directly related to Component, you'd better not use them unless you need. getInstance(id: string | number) { return this._instances[id] ? this._instances[id] : null; }, getState(id: string | number, key: string) { return store.getInstance(id)[key]; }, changeState(id: string | number, key: string, val: any) { return (store.getInstance(id)[key] = val); }, // Player action APIs // These APIs are connected to PlayerActions. Dispatching all of them should have an ID of player instance. play(id: string | number) { (store.getInstance(id) as any).togglePlay(true); }, pause(id: string | number) { store.getInstance(id).togglePlay(false); }, stop(id: string | number) { store.getInstance(id).playerStop(); }, togglePlay(id: string | number) { store.getInstance(id).togglePlay(); }, toggleLoop(id: string | number) { store.getInstance(id).toggleLoop(); }, toggleDrawer(id: string | number) { store.getInstance(id).toggleDrawer(); }, togglePanel(id: string | number, panel: string) { store.getInstance(id).togglePanel(panel); }, setCurrentMusic(id: string | number, index: number) { setTimeout(() => store.getInstance(id).togglePlay(false), 0); store.getInstance(id).setCurrentMusic(index); setTimeout(() => store.getInstance(id).togglePlay(true), 10); }, setLyricOffset(id: string | number, offset: number) { store.getInstance(id).setLyricOffset(offset); }, addMusicToList(id: string | number, item: Item) { store.getInstance(id).addMusicToList(item); }, removeMusicFromList(id: string | number, index: number) { store.getInstance(id).removeMusicFromList(index); }, changePlayerLayout(id: string | number, layout: string) { store.getInstance(id).changePlayerLayout(layout); }, setPlayerLanguage(id: string | number, target: string) { store.getInstance(id).setPlayerLanguage(target); }, setCoverImage(id: string | number, target: string) { store.getInstance(id).setCoverImage(target); }, /* MUSE Player API end */ /* Middleware related */ registerLayout(name: string, construct: (...args: any[]) => any) { this._layouts.push(name); construct(); }, registerMiddleware(hook: string, func: (...args: any[]) => any) { if (!this._middlewares[hook]) { return; } this._middlewares[hook].push(func); }, destroyMiddleware(hook: string, func: (...args: any[]) => any) { const cmp = (ele: any) => ele === func; this._middlewares[hook].splice(this._middlewares[hook].find(cmp)); }, /* MUSE Player life cycle */ destroy(id: string | number, par: any) { const parent = par === undefined ? document.getElementById(id as string).parentNode : par; let listLength = this.getState(id, 'playList').length; unmountComponentAtNode(parent); while (listLength--) { this.removeMusicFromList(id, 0); } }, render(playList: Item[], node: Element, options: any) { if (options === undefined) { options = {}; } if (!options.layout) { options.layout = 'muse-layout-default'; } const playerID = 'muse-player-' + Date.parse(new Date() as any) + '-' + Math.ceil(Math.random() * 233); const componentProps = { id: playerID, playList, ...options }, Component = ; interface MUSEPlayerInstance { component: React.ReactElement; ref: Element; id: string | number; } const muse: MUSEPlayerInstance = { component: Component, ref: undefined, id: playerID }; if (node !== undefined) { render(Component, node); muse.ref = document.getElementById(playerID); } return muse; }, checkMUSEUpdate() { honoka.get('https://raw.githubusercontent.com/moefront/muse/master/package.json') .then(data => { data = JSON.parse(data); store.setLatestVersion(data.version); if (Number(parseFloat(data.version) - parseFloat(MuseDOM._version)) >= 0.1) { console.warn( 'Tips: You are using an outdated version of MUSE.\n' + 'The latest version of MUSE is ' + data.version + ', ' + 'while you are using ' + MuseDOM._version + '.\n' + 'Please consider upgrading your player: https://github.com/moefront/muse' ); } }); } }; (window as any).MUSE = (window as any).YMPlayer = MuseDOM; // layout register MuseDOM.registerLayout('muse-layout-landscape', landscapeLayoutConstructor); // check update MuseDOM.checkMUSEUpdate(); export default MuseDOM; export { PlayerContainer } from './containers';