import * as React from 'react'; import { observer, inject } from 'mobx-react'; // Utils import { getRect, i18n } from '../utils'; // config import config from '../config/base'; interface MenuContainerProps { id?: string | number; store?: any; parent: React.Component | any; } @inject('store') @observer export default class MenuContainer extends React.Component { id: string | number = undefined; volume: HTMLElement; increaseOffset: HTMLElement; decreaseOffset: HTMLElement; increasePlayRate: HTMLElement; decreasePlayRate: HTMLElement; constructor(props: MenuContainerProps) { super(props); this.id = props.id; } /* life cycles */ componentDidMount() { this.volume.addEventListener('click', this.onVolumeContainerClick); this.increaseOffset.addEventListener('click', this.onIncreaseOffsetClick); this.decreaseOffset.addEventListener('click', this.onDecreaseOffsetClick); this.increasePlayRate.addEventListener( 'click', this.onIncreasePlayRateClick ); this.decreasePlayRate.addEventListener( 'click', this.onDecreasePlayRateClick ); } componentWillUnmount() { this.volume.removeEventListener('click', this.onVolumeContainerClick); this.increaseOffset.removeEventListener( 'click', this.onIncreaseOffsetClick ); this.decreaseOffset.removeEventListener( 'click', this.onDecreaseOffsetClick ); this.increasePlayRate.removeEventListener( 'click', this.onIncreasePlayRateClick ); this.decreasePlayRate.removeEventListener( 'click', this.onDecreasePlayRateClick ); } isDesktop(): boolean { const userAgentInfo = navigator.userAgent, agents = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod']; let flag = true; agents.forEach(agent => { if (userAgentInfo.indexOf(agent) > 0) { flag = false; return; } }); return flag; } /* event listeners */ onLoopTogglerClick = (e: any) => { e.stopPropagation(); const { store } = this.props; store.toggleLoop(); }; onFullscreenTogglerClick = (e: any) => { e.stopPropagation(); const { store, parent } = this.props; // firefox compatibility if (parent.player.mozRequestFullScreen) { parent.getFullscreenState() ? (document as any).mozCancelFullScreen() : parent.player.mozRequestFullScreen(); } store.toggleFullscreen(); }; onVolumeContainerClick = (e: any) => { e.preventDefault(); e.stopPropagation(); const rect = getRect(this.volume), { store } = this.props, vol = (e.clientX - rect.left) / this.volume.offsetWidth; store.slideVolume(vol > 1 ? 1 : vol); }; onIncreaseOffsetClick = (e: any) => { e.preventDefault(); e.stopPropagation(); this.props.store.setLyricOffset(0.5); }; onDecreaseOffsetClick = (e: any) => { e.preventDefault(); e.stopPropagation(); this.props.store.setLyricOffset(-0.5); }; onIncreasePlayRateClick = (e: any) => { e.preventDefault(); e.stopPropagation(); this.props.store.setPlayRate(0.1); }; onDecreasePlayRateClick = (e: any) => { e.preventDefault(); e.stopPropagation(); this.props.store.setPlayRate(-0.1); }; onStopClick = (e: any) => { const { store } = this.props; e.preventDefault(); e.stopPropagation(); store.playerStop(); }; onDebugModeTogglerClick = () => { const { parent } = this.props, { lang } = this.props.store; if (confirm(i18n('devModeAlert', lang))) { parent.player.removeEventListener( 'contextmenu', parent.onPlayerContextMenu ); parent.player.removeEventListener( 'touchstart', parent.onMobileTouchStart ); parent.player.removeEventListener( 'touchend', parent.onMobileTouchEnd ); // inject eruda console for mobile devices const win: any = window as any; if (win.eruda || this.isDesktop()) { return; } const scriptTag: HTMLElement = document.createElement('script'); scriptTag.setAttribute('src', 'https://unpkg.com/eruda/eruda.min.js'); document.body.appendChild(scriptTag); win.intv = setInterval(() => { if (win.eruda) { window.clearInterval(win.intv); win.eruda.init(); console.log('Eruda console has been injected successfully: https://github.com/liriliri/eruda'); } }, 500); } }; render() { const { isMenuOpen, isLoop, isFullscreen, volume, playRate, offset, parent, lang } = this.props.store; return (
{i18n('stop', lang)}
{i18n('modulation', lang)}
(this.volume = ref)} >
{i18n('setLyricOffset', lang)}({i18n('currentLyricOffset', lang)}:{offset}s)
(this.increaseOffset = ref)}> + {i18n('forward', lang)} 0.5s (this.decreaseOffset = ref)}> - {i18n('backward', lang)} 0.5s
{i18n('playRate', lang)}(x {playRate}) (this.increasePlayRate = ref)} className={playRate >= 3.9 ? 'muse-menu__playrate-disabled' : ''} > + (this.decreasePlayRate = ref)} className={playRate <= 0.1 ? 'muse-menu__playrate-disabled' : ''} > -
{i18n('looping', lang)}:{isLoop ? i18n('enabled', lang) : i18n('disabled', lang)}
{isFullscreen ? i18n('exit', lang) : ''} {i18n('fullscreenMode', lang)}
{i18n('devMode', lang)}
{ window.open('https://github.com/moefront/muse'); }} > {config.MUSE_VERSION !== parent.latest ? i18n('updateAvailable', lang) + ':MUSE ' + parent.latest : 'MUSE Player ver.' + config.MUSE_VERSION}
); } }