const LogRocket = require('logrocket'); const querystring = require('query-string'); const eachSeries = require('async/eachSeries'); const sample = require('lodash/sample'); const actions = require('./actions'); const { TIMES } = require('./constants'); const animations = require('./animations.utils'); const { infoToast, errorToast } = require('./utils'); const { tutorialVbox } = require('./tutorial.utils'); function registerEvents(store) { function notify(msg) { if (window.Notification && window.Notification.permission === 'granted') { const n = new Notification('MNML', { body: msg, tag: 'MNML', }); } return infoToast(msg); } function error(msg) { return errorToast(msg); } function setPing(ping) { store.dispatch(actions.setPing(ping)); } function setPvp(v) { store.dispatch(actions.setPvp(v)); } function setNav(v) { store.dispatch(actions.setNav(v)); } function setTeam(team) { store.dispatch(actions.setTeam(team)); const { nav } = store.getState(); if (nav !== 'reshape') setNav('play'); } function setSubscription(sub) { const { subscription } = store.getState(); if (subscription && sub.cancel_at_period_end) { notify('Your subscription has been cancelled. Thank you for your support.'); } store.dispatch(actions.setSubscription(sub)); } function setConstructList(constructs) { store.dispatch(actions.setConstructs(constructs)); } function setNewConstruct(construct) { const { constructs } = store.getState(); constructs.push(construct); store.dispatch(actions.setConstructs(constructs)); } function setWs(ws) { store.dispatch(actions.setWs(ws)); } function setGame(game) { const { game: currentGame, account, ws, animating } = store.getState(); if (animating) return false; if (game && currentGame) { if (game.resolved.length !== currentGame.resolved.length) { store.dispatch(actions.setAnimating(true)); store.dispatch(actions.setGameSkillInfo(null)); // stop fetching the game state til animations are done const newRes = game.resolved.slice(currentGame.resolved.length); return eachSeries(newRes, (r, cb) => { if (!r.event) return cb(); const timeout = animations.getTime(r.stages); const anims = animations.getObjects(r, game, account); const text = animations.getText(r); store.dispatch(actions.setAnimFocus(animations.getFocusTargets(r, game))); if (anims.animSkill) store.dispatch(actions.setAnimSkill(anims.animSkill)); if (r.stages.includes('START_SKILL') && anims.animSource) { store.dispatch(actions.setAnimSource(anims.animSource)); } if (r.stages.includes('END_SKILL') && anims.animTarget) { store.dispatch(actions.setAnimTarget(anims.animTarget)); if (animations.isCbAnim(anims.animSkill)) store.dispatch(actions.setAnimCb(cb)); } if (r.stages.includes('POST_SKILL') && text) { // timeout to prevent text classes from being added too soon if (timeout === TIMES.POST_SKILL_DURATION_MS) { store.dispatch(actions.setAnimText(text)); } else { setTimeout( () => store.dispatch(actions.setAnimText(text)), timeout - TIMES.POST_SKILL_DURATION_MS ); } } return setTimeout(() => { store.dispatch(actions.setAnimSkill(null)); store.dispatch(actions.setAnimSource(null)); store.dispatch(actions.setAnimTarget(null)); store.dispatch(actions.setAnimText(null)); store.dispatch(actions.setAnimFocus([])); if (r.stages.includes('END_SKILL') && animations.isCbAnim(anims.animSkill)) return true; return cb(); }, timeout); }, err => { if (err) return console.error(err); // clear animation state store.dispatch(actions.setAnimSkill(null)); store.dispatch(actions.setAnimSource(null)); store.dispatch(actions.setAnimTarget(null)); store.dispatch(actions.setAnimText(null)); store.dispatch(actions.setAnimating(false)); store.dispatch(actions.setGameEffectInfo(null)); // set the game state so resolutions don't fire twice store.dispatch(actions.setGame(game)); ws.sendGameState(game.id); return true; }); } } return store.dispatch(actions.setGame(game)); } function setAccount(account) { if (account && process.env.NODE_ENV !== 'development') { LogRocket.init('yh0dy3/mnml'); LogRocket.identify(account.id, account); if (window.Notification) { window.Notification.requestPermission(); } } store.dispatch(actions.setAccount(account)); } function setEmail(email) { store.dispatch(actions.setEmail(email)); } function setShop(v) { store.dispatch(actions.setShop(v)); } function clearConstructRename() { store.dispatch(actions.setConstructRename(null)); } function clearMtxActive() { store.dispatch(actions.setMtxActive(null)); } function setActiveSkill(skill) { store.dispatch(actions.setActiveSkill(skill)); } function setActiveItem(v) { store.dispatch(actions.setActiveItem(v)); } function clearInfo() { store.dispatch(actions.setInfo(null)); console.log('event clear item'); } function clearInstance() { store.dispatch(actions.setActiveSkill(null)); store.dispatch(actions.setInfo(null)); store.dispatch(actions.setItemUnequip([])); store.dispatch(actions.setVboxSelected({ storeSelect: [], stashSelect: [] })); } function setAccountInstances(v) { store.dispatch(actions.setMtxActive(null)); return store.dispatch(actions.setInstances(v)); } function setInvite(code) { if (!code) return store.dispatch(actions.setInvite(null)); navigator.clipboard.writeText(code).then(() => { notify(`your invite code ${code} was copied to the clipboard.`); }, () => {}); return store.dispatch(actions.setInvite(code)); } function setInstance(v) { const { account, ws, tutorial } = store.getState(); if (v) { setInvite(null); setPvp(false); const player = v.players.find(p => p.id === account.id); store.dispatch(actions.setPlayer(player)); const skip = v.time_control === 'Practice' && v.phase === 'Lobby'; if (skip) { ws.sendInstanceReady(v.id); } if (v.phase === 'Finished') { ws.sendAccountInstances(); } // instance.mobile.less hides info at @media 1000 if (localStorage.getItem('tutorial-complete') || window.innerWidth <= 1100) { store.dispatch(actions.setTutorial(null)); } else if (v.time_control === 'Practice' && v.rounds.length === 1 && tutorial) { tutorialVbox(player, store, tutorial); } } return store.dispatch(actions.setInstance(v)); } function setInstanceChat(v) { return store.dispatch(actions.setInstanceChat(v)); } function setChatWheel(v) { return store.dispatch(actions.setChatWheel(v)); } function setItemInfo(v) { return store.dispatch(actions.setItemInfo(v)); } function setDemo(d) { const vboxDemo = { players: d, combiner: [], equipped: false, equipping: false, }; const startDemo = () => { const { account, itemInfo } = store.getState(); if (account) return false; if (!itemInfo || itemInfo.items.length === 0) return setTimeout(startDemo, 500); store.dispatch(actions.setAnimTarget(null)); const bases = ['Attack', 'Stun', 'Buff', 'Debuff', 'Block']; const combo = sample(itemInfo.combos.filter(i => bases.some(b => i.components.includes(b)))); vboxDemo.combo = combo.item; vboxDemo.items = combo.components; store.dispatch(actions.setDemo(vboxDemo)); setTimeout(() => store.dispatch(actions.setDemo(Object.assign({}, vboxDemo, { combiner: [0] }))), 500); setTimeout(() => store.dispatch(actions.setDemo(Object.assign({}, vboxDemo, { combiner: [0, 1] }))), 1000); setTimeout(() => store.dispatch(actions.setDemo(Object.assign({}, vboxDemo, { combiner: [0, 1, 2] }))), 1500); setTimeout(() => store.dispatch(actions.setDemo(Object.assign({}, vboxDemo, { combiner: [], items: [vboxDemo.combo, '', ''] }))), 2500); setTimeout(() => store.dispatch(actions.setDemo(Object.assign({}, vboxDemo, { combiner: [0], items: [vboxDemo.combo, '', ''], equipping: true }))), 3000); setTimeout(() => store.dispatch(actions.setDemo(Object.assign({}, vboxDemo, { combiner: [], items: ['', '', ''], equipped: true, equipping: false }))), 4000); setTimeout(() => { return store.dispatch(actions.setAnimTarget({ skill: sample(itemInfo.items.filter(i => i.skill)).item, constructId: d[1].constructs[0].id, player: false, direction: 0, })); }, 500); setTimeout(() => { return store.dispatch(actions.setAnimTarget({ skill: sample(itemInfo.items.filter(i => i.skill)).item, constructId: d[1].constructs[1].id, player: true, direction: 0, })); }, 3000); return setTimeout(startDemo, 5000); }; startDemo(); } // events.on('SET_PLAYER', setInstance); // events.on('SEND_SKILL', function skillActive(gameId, constructId, targetConstructId, skill) { // ws.sendGameSkill(gameId, constructId, targetConstructId, skill); // setConstructStatusUpdate(constructId, skill, targetConstructId); // }); // events.on('CONSTRUCT_ACTIVE', function constructActiveCb(construct) { // for (let i = 0; i < constructs.length; i += 1) { // if (constructs[i].id === construct.id) constructs[i].active = !constructs[i].active; // } // return setConstructs(constructs); // }); /* function errorPrompt(type) { const message = errMessages[type]; const OK_BUTTON = ''; toast.error({ theme: 'dark', color: 'black', timeout: false, drag: false, position: 'center', maxWidth: window.innerWidth / 2, close: false, buttons: [ [OK_BUTTON, (instance, thisToast) => instance.hide({ transitionOut: 'fadeOut' }, thisToast)], ], message, }); } */ // setup / localstorage function urlHashChange() { const { ws } = store.getState(); const cmds = querystring.parse(location.hash); if (cmds.join) ws.sendInstanceJoin(cmds.join); return true; } window.addEventListener('hashchange', urlHashChange, false); return { clearConstructRename, clearInfo, clearInstance, clearMtxActive, setAccount, setAccountInstances, setActiveItem, setActiveSkill, setChatWheel, setDemo, setConstructList, setNewConstruct, setGame, setEmail, setInstance, setInstanceChat, setItemInfo, setInvite, setPing, setPvp, setShop, setTeam, setSubscription, setWs, urlHashChange, notify, }; } module.exports = registerEvents;