Merge branch 'develop' of ssh://git.mnml.gg:40022/~/mnml into develop
This commit is contained in:
@@ -53,7 +53,7 @@ aside {
|
||||
border-color: forestgreen;
|
||||
}
|
||||
|
||||
&:active, &:focus {
|
||||
&:active, &:focus, &.enabled {
|
||||
background: forestgreen;
|
||||
color: black;
|
||||
border-color: forestgreen;
|
||||
|
||||
@@ -286,3 +286,9 @@ li {
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
#clipboard {
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0px;
|
||||
}
|
||||
+2
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mnml-client",
|
||||
"version": "1.4.4",
|
||||
"version": "1.4.5",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
@@ -29,6 +29,7 @@
|
||||
"preact-compat": "^3.19.0",
|
||||
"preact-context": "^1.1.3",
|
||||
"preact-redux": "^2.1.0",
|
||||
"query-string": "^6.8.3",
|
||||
"react-string-replace": "^0.4.4",
|
||||
"react-stripe-elements": "^3.0.0",
|
||||
"redux": "^4.0.0"
|
||||
|
||||
@@ -19,6 +19,7 @@ export const setConstructRename = value => ({ type: 'SET_CONSTRUCT_RENAME', valu
|
||||
export const setGame = value => ({ type: 'SET_GAME', value });
|
||||
export const setInfo = value => ({ type: 'SET_INFO', value });
|
||||
export const setEmail = value => ({ type: 'SET_EMAIL', value });
|
||||
export const setInvite = value => ({ type: 'SET_INVITE', value });
|
||||
export const setInstance = value => ({ type: 'SET_INSTANCE', value });
|
||||
export const setInstances = value => ({ type: 'SET_INSTANCES', value });
|
||||
export const setItemEquip = value => ({ type: 'SET_ITEM_EQUIP', value });
|
||||
|
||||
@@ -76,11 +76,13 @@ function Controls(args) {
|
||||
background: displayColour,
|
||||
};
|
||||
|
||||
const timer = (
|
||||
<div class="timer-container">
|
||||
<div class="timer" style={timerStyles} > </div>
|
||||
</div>
|
||||
);
|
||||
const timer = instance.phase !== 'InProgress'
|
||||
? null
|
||||
: (
|
||||
<div class="timer-container">
|
||||
<div class="timer" style={timerStyles} > </div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const ready = instance.phase !== 'Finished'
|
||||
? <button class="ready" onClick={() => sendReady()}>Ready</button>
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
const preact = require('preact');
|
||||
const { connect } = require('preact-redux');
|
||||
|
||||
const { errorToast, infoToast } = require('../utils');
|
||||
|
||||
const addState = connect(
|
||||
function receiveState(state) {
|
||||
const {
|
||||
ws,
|
||||
instances,
|
||||
invite,
|
||||
} = state;
|
||||
|
||||
function sendInstanceState(id) {
|
||||
@@ -20,12 +23,18 @@ const addState = connect(
|
||||
ws.sendInstanceQueue();
|
||||
}
|
||||
|
||||
function sendInstanceInvite() {
|
||||
ws.sendInstanceInvite();
|
||||
}
|
||||
|
||||
return {
|
||||
instances,
|
||||
invite,
|
||||
|
||||
sendInstanceState,
|
||||
sendInstanceQueue,
|
||||
sendInstancePractice,
|
||||
sendInstanceInvite,
|
||||
};
|
||||
}
|
||||
);
|
||||
@@ -33,10 +42,12 @@ const addState = connect(
|
||||
function JoinButtons(args) {
|
||||
const {
|
||||
instances,
|
||||
invite,
|
||||
|
||||
sendInstanceState,
|
||||
sendInstanceQueue,
|
||||
sendInstancePractice,
|
||||
sendInstanceInvite,
|
||||
} = args;
|
||||
|
||||
if (instances.length) {
|
||||
@@ -55,6 +66,48 @@ function JoinButtons(args) {
|
||||
);
|
||||
}
|
||||
|
||||
const inviteBtn = () => {
|
||||
if (!invite) {
|
||||
return (
|
||||
<button
|
||||
class='pvp ready'
|
||||
onClick={() => sendInstanceInvite()}
|
||||
type="submit">
|
||||
Invite
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
function copyClick(e) {
|
||||
const link = `${document.location.origin}#join=${invite}`;
|
||||
const textArea = document.createElement('textarea', { id: '#clipboard' });
|
||||
textArea.value = link;
|
||||
document.body.appendChild(textArea);
|
||||
textArea.focus();
|
||||
textArea.select();
|
||||
|
||||
try {
|
||||
document.execCommand('copy');
|
||||
infoToast('Invite link copied.');
|
||||
} catch (err) {
|
||||
console.error('link copy error', err);
|
||||
errorToast('Invite link copy error.');
|
||||
}
|
||||
|
||||
document.body.removeChild(textArea);
|
||||
return true;
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
class='pvp ready enabled'
|
||||
onClick={copyClick}
|
||||
type="submit">
|
||||
Copy Link
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<aside class='play-ctrl'>
|
||||
<div class="timer-container"></div>
|
||||
@@ -65,6 +118,7 @@ function JoinButtons(args) {
|
||||
type="submit">
|
||||
PVP
|
||||
</button>
|
||||
{inviteBtn()}
|
||||
<button
|
||||
class='practice ready'
|
||||
onClick={() => sendInstancePractice()}
|
||||
|
||||
@@ -92,13 +92,14 @@ function Play(args) {
|
||||
<section class="top">
|
||||
<div class="news">
|
||||
<h1>v{VERSION}</h1>
|
||||
<p>use the buttons on the right to join an instance.</p>
|
||||
<p>Use the buttons on the right to join an instance.</p>
|
||||
<p>
|
||||
select <b>PVP</b> to play against other players.<br />
|
||||
click <b>LEARN</b> to practice the game without time controls.
|
||||
Select <b>PVP</b> to play against other players.<br />
|
||||
Select <b>INVITE</b> then click <b>COPY LINK</b> to generate an instance invitation for a friend.<br />
|
||||
Click <b>LEARN</b> to practice the game without time controls.
|
||||
</p>
|
||||
<p>
|
||||
if you enjoy the game please support its development by <b>subscribing</b> or purchasing <b>credits</b>.<br />
|
||||
If you enjoy the game please support its development by <b>subscribing</b> or purchasing <b>credits</b>.<br />
|
||||
glhf
|
||||
</p>
|
||||
<p>--ntr & mashy</p>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
const querystring = require('query-string');
|
||||
|
||||
const eachSeries = require('async/eachSeries');
|
||||
const sample = require('lodash/sample');
|
||||
|
||||
@@ -168,9 +170,20 @@ function registerEvents(store) {
|
||||
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, instance, ws } = store.getState();
|
||||
if (v) {
|
||||
setInvite(null);
|
||||
const player = v.players.find(p => p.id === account.id);
|
||||
store.dispatch(actions.setPlayer(player));
|
||||
|
||||
@@ -272,6 +285,16 @@ function registerEvents(store) {
|
||||
} */
|
||||
// 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 {
|
||||
clearCombiner,
|
||||
clearConstructRename,
|
||||
@@ -289,12 +312,15 @@ function registerEvents(store) {
|
||||
setEmail,
|
||||
setInstance,
|
||||
setItemInfo,
|
||||
setInvite,
|
||||
setPing,
|
||||
setShop,
|
||||
setTeam,
|
||||
setSubscription,
|
||||
setWs,
|
||||
|
||||
urlHashChange,
|
||||
|
||||
notify,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ module.exports = {
|
||||
constructRename: createReducer(null, 'SET_CONSTRUCT_RENAME'),
|
||||
game: createReducer(null, 'SET_GAME'),
|
||||
email: createReducer(null, 'SET_EMAIL'),
|
||||
invite: createReducer(null, 'SET_INVITE'),
|
||||
info: createReducer(null, 'SET_INFO'),
|
||||
instance: createReducer(null, 'SET_INSTANCE'),
|
||||
instances: createReducer([], 'SET_INSTANCES'),
|
||||
|
||||
@@ -126,6 +126,14 @@ function createSocket(events) {
|
||||
send(['InstanceQueue', {}]);
|
||||
}
|
||||
|
||||
function sendInstanceInvite() {
|
||||
send(['InstanceInvite', {}]);
|
||||
}
|
||||
|
||||
function sendInstanceJoin(code) {
|
||||
send(['InstanceJoin', { code }]);
|
||||
}
|
||||
|
||||
function sendInstanceReady(instanceId) {
|
||||
send(['InstanceReady', { instance_id: instanceId }]);
|
||||
}
|
||||
@@ -239,6 +247,9 @@ function createSocket(events) {
|
||||
|
||||
QueueRequested: () => events.notify('pvp queue request received'),
|
||||
QueueJoined: () => events.notify('you have joined the pvp queue'),
|
||||
InviteRequested: () => events.notify('pvp queue request received'),
|
||||
Invite: code => events.setInvite(code),
|
||||
Joining: () => events.notify('searching for instance...'),
|
||||
|
||||
Error: errHandler,
|
||||
};
|
||||
@@ -284,6 +295,8 @@ function createSocket(events) {
|
||||
sendPing();
|
||||
sendItemInfo();
|
||||
|
||||
events.urlHashChange();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -318,6 +331,7 @@ function createSocket(events) {
|
||||
ws.addEventListener('message', onMessage);
|
||||
ws.addEventListener('error', onError);
|
||||
ws.addEventListener('close', onClose);
|
||||
|
||||
return ws;
|
||||
}
|
||||
|
||||
@@ -338,6 +352,8 @@ function createSocket(events) {
|
||||
sendInstancePractice,
|
||||
sendInstanceQueue,
|
||||
sendInstanceState,
|
||||
sendInstanceInvite,
|
||||
sendInstanceJoin,
|
||||
|
||||
sendVboxAccept,
|
||||
sendVboxApply,
|
||||
|
||||
Reference in New Issue
Block a user