From a429f21367955ed48b2fac77153da0cec4d85b12 Mon Sep 17 00:00:00 2001 From: ntr Date: Fri, 6 Sep 2019 15:13:10 +1000 Subject: [PATCH] tabbed menu --- WORKLOG.md | 3 + client/assets/styles/styles.less | 10 ++ client/src/components/account.page.jsx | 4 +- ...account.management.jsx => account.top.jsx} | 0 client/src/components/collection.jsx | 89 +++++++++ client/src/components/header.jsx | 35 +--- client/src/components/inventory.jsx | 100 ----------- client/src/components/main.bottom.jsx | 30 ++++ client/src/components/main.jsx | 19 +- client/src/components/main.top.jsx | 34 ++++ client/src/components/menu.jsx | 39 ++++ client/src/components/menu.top.jsx | 31 ++++ client/src/components/play.jsx | 170 +++++++++--------- client/src/components/shop.jsx | 58 ++++++ client/src/components/stripe.buttons.jsx | 49 +++-- client/src/components/team.jsx | 132 ++++++++------ 16 files changed, 514 insertions(+), 289 deletions(-) rename client/src/components/{account.management.jsx => account.top.jsx} (100%) create mode 100644 client/src/components/collection.jsx delete mode 100644 client/src/components/inventory.jsx create mode 100644 client/src/components/main.bottom.jsx create mode 100644 client/src/components/main.top.jsx create mode 100644 client/src/components/menu.jsx create mode 100644 client/src/components/menu.top.jsx create mode 100644 client/src/components/shop.jsx diff --git a/WORKLOG.md b/WORKLOG.md index 5af518fa..da05e3ac 100644 --- a/WORKLOG.md +++ b/WORKLOG.md @@ -10,6 +10,9 @@ * treats * constructs jiggle when clicked * background colour changes depending on time of day + * hit animation wobble + * combat text scale + translate + * susbcriber gold name in instance * bot game grind * stress test diff --git a/client/assets/styles/styles.less b/client/assets/styles/styles.less index 747c36ca..cd773c0d 100644 --- a/client/assets/styles/styles.less +++ b/client/assets/styles/styles.less @@ -67,6 +67,7 @@ hr { color: #222; margin: 1.5em 0; width: 100%; + border-top: 1px solid #222; } figure { @@ -287,4 +288,13 @@ header { nav { display: none; +} + +ul { + margin-bottom: 1em; + list-style: inside; +} + +li { + margin-bottom: 0.5em; } \ No newline at end of file diff --git a/client/src/components/account.page.jsx b/client/src/components/account.page.jsx index 6b945876..c8b7563a 100644 --- a/client/src/components/account.page.jsx +++ b/client/src/components/account.page.jsx @@ -1,7 +1,7 @@ const { connect } = require('preact-redux'); const preact = require('preact'); -const Team = require('./team'); +const Collection = require('./collection'); const Header = require('./header'); const AccountManagement = require('./account.management'); @@ -26,8 +26,8 @@ function Account(args) { return (
- +
); } diff --git a/client/src/components/account.management.jsx b/client/src/components/account.top.jsx similarity index 100% rename from client/src/components/account.management.jsx rename to client/src/components/account.top.jsx diff --git a/client/src/components/collection.jsx b/client/src/components/collection.jsx new file mode 100644 index 00000000..c6441803 --- /dev/null +++ b/client/src/components/collection.jsx @@ -0,0 +1,89 @@ +const preact = require('preact'); +const { connect } = require('preact-redux'); + +const actions = require('./../actions'); +const { COLOURS } = require('./../utils'); +const { ConstructAvatar } = require('./construct'); + +const addState = connect( + function receiveState(state) { + const { ws, constructs, teamPage, teamSelect } = state; + + function sendConstructSpawn(name) { + return ws.sendMtxConstructSpawn(name); + } + + return { + constructs, + teamPage, + teamSelect, + }; + }, + function receiveDispatch(dispatch) { + function setTeam(constructIds) { + dispatch(actions.setTeamSelect(constructIds)); + } + + return { + setTeam, + }; + } +); + +function Collection(args) { + const { + constructs, + teamPage, + teamSelect, + setTeam, + } = args; + + if (!constructs) return
; + + // redux limitation + suggested workaround + // so much for dumb components + function selectConstruct(id) { + // remove + const i = teamSelect.findIndex(sid => sid === id); + if (i > -1) { + teamSelect[i] = null; + return setTeam(teamSelect); + } + + // window insert + const insert = teamSelect.findIndex(j => j === null); + if (insert === -1) return setTeam([id, null, null]); + teamSelect[insert] = id; + return setTeam(teamSelect); + } + console.log(constructs.length); + const dispConstructs = constructs.length >= ((teamPage + 1) * 6) + ? constructs.slice(teamPage * 6, (teamPage + 1) * 6) + : constructs.slice(teamPage * 6, constructs.length); + + const constructPanels = dispConstructs.map(construct => { + const colour = teamSelect.indexOf(construct.id); + const selected = colour > -1; + + const borderColour = selected ? COLOURS[colour] : '#000000'; + + return ( +
selectConstruct(construct.id)} > + +

{construct.name}

+
+ ); + }); + + return ( +
+ {constructPanels} +
+ ); +} + +module.exports = addState(Collection); diff --git a/client/src/components/header.jsx b/client/src/components/header.jsx index 8248e9ac..7c776ff8 100644 --- a/client/src/components/header.jsx +++ b/client/src/components/header.jsx @@ -2,19 +2,13 @@ const { connect } = require('preact-redux'); const preact = require('preact'); const actions = require('../actions'); -const AccountStatus = require('./account.status'); const addState = connect( function receiveState(state) { const { ws, account, - instances, - team, nav, - ping, - - game, } = state; function sendInstanceState(instance) { @@ -28,11 +22,8 @@ const addState = connect( return { account, - instances, - team, - game, - ping, nav, + sendInstanceState, sendAccountStates, }; @@ -53,29 +44,19 @@ const addState = connect( return dispatch(actions.setNav(place)); } - function hideNav() { - return dispatch(actions.setShowNav(false)); - } - return { setNav, - hideNav, }; } ); -function Nav(args) { +function Header(args) { const { account, - game, - team, nav, sendAccountStates, - sendInstanceState, - setNav, - hideNav, } = args; if (!account) return false; @@ -84,12 +65,6 @@ function Nav(args) { return setNav(p); } - function joinInstance(i) { - sendInstanceState(i); - if (game) navTo('transition'); - return true; - } - function accountClick() { sendAccountStates(); navTo('account'); @@ -104,8 +79,8 @@ function Nav(args) { MNML - - ); - - const availableMtx = (item, i) => ( -
mtxBuy(item)} > -
{item.variant}
- -
- ); - - return ( -
-
-

v{VERSION}

-

welcome to mnml

-

use the buttons on the right to join an instance.

-

- select PVP to play against other players.
- click LEARN to practice the game without time controls. -

-

- if you enjoy the game please support its development by subscribing or purchasing credits.
- glhf -

-

--ntr & mashy

-
-
-

¤ {account.balance}

- - - -
- {shop.owned.map(useMtx)} -
-
- {shop.available.map(availableMtx)} -
-
-
- ); -} - -module.exports = addState(Inventory); diff --git a/client/src/components/main.bottom.jsx b/client/src/components/main.bottom.jsx new file mode 100644 index 00000000..7f89358d --- /dev/null +++ b/client/src/components/main.bottom.jsx @@ -0,0 +1,30 @@ +const { connect } = require('preact-redux'); +const preact = require('preact'); + +const actions = require('./../actions'); + +const Team = require('./team'); +const Collection = require('./collection'); + +const addState = connect( + function receiveState(state) { + const { + nav, + } = state; + + return { + nav, + }; + }, +); + +function Bottom(args) { + const { + nav, + } = args; + + if (nav === 'account') return ; + return ; +} + +module.exports = addState(Bottom); diff --git a/client/src/components/main.jsx b/client/src/components/main.jsx index b42b9702..8441782e 100644 --- a/client/src/components/main.jsx +++ b/client/src/components/main.jsx @@ -5,14 +5,14 @@ const { connect } = require('preact-redux'); const Welcome = require('./welcome'); const Game = require('./game'); const Instance = require('./instance.component'); -const Team = require('./team'); -const Play = require('./play'); -const Account = require('./account.page'); +const Header = require('./header'); +const Top = require('./main.top'); +const Bottom = require('./main.bottom'); const addState = connect( state => { - const { game, instance, account, nav, team, constructs } = state; - return { game, instance, account, nav, team, constructs }; + const { game, instance, account, nav } = state; + return { game, instance, account, nav }; } ); @@ -37,12 +37,13 @@ function Main(props) { } if (nav === 'transition') return false; - if (nav === 'play') return ; - // if (nav === 'team') return ; - if (nav === 'account') return ; return ( - +
+
+ + +
); } diff --git a/client/src/components/main.top.jsx b/client/src/components/main.top.jsx new file mode 100644 index 00000000..64438f40 --- /dev/null +++ b/client/src/components/main.top.jsx @@ -0,0 +1,34 @@ +const { connect } = require('preact-redux'); +const preact = require('preact'); + +const actions = require('./../actions'); + +const AccountTop = require('./account.top'); +const Play = require('./play'); +const Shop = require('./shop'); + +const addState = connect( + function receiveState(state) { + const { + nav, + } = state; + + return { + nav, + }; + }, +); + +function Top(args) { + const { + nav, + } = args; + + if (nav === 'account') return ; + if (nav === 'play') return + if (nav === 'shop') return + + return false; +} + +module.exports = addState(Top); diff --git a/client/src/components/menu.jsx b/client/src/components/menu.jsx new file mode 100644 index 00000000..7c5b7717 --- /dev/null +++ b/client/src/components/menu.jsx @@ -0,0 +1,39 @@ +// eslint-disable-next-line +const preact = require('preact'); +const { connect } = require('preact-redux'); + +const Shop = require('./shop'); +const Play = require('./play'); +const Account = require('./account.page'); + +const addState = connect( + state => { + const { + account, + nav, + } = state; + + return { + account, + nav, + }; + } +); + +function Menu(props) { + const { + account, + nav, + } = props; + + // menu + if (nav === 'play') return ; + if (nav === 'shop') return ; + if (nav === 'account') return ; + + return ( + + ); +} + +module.exports = addState(Menu); diff --git a/client/src/components/menu.top.jsx b/client/src/components/menu.top.jsx new file mode 100644 index 00000000..52db35fe --- /dev/null +++ b/client/src/components/menu.top.jsx @@ -0,0 +1,31 @@ +const preact = require('preact'); +const { connect } = require('preact-redux'); + +const Shop = require('./shop'); +const Play = require('./play'); +const Account = require('./account.page'); + +const addState = connect( + state => { + const { game, instance, account, nav } = state; + return { game, instance, account, nav }; + } +); + +function Menu(props) { + const { + account, + nav, + } = props; + + // menu + if (nav === 'play') return ; + if (nav === 'shop') return ; + if (nav === 'account') return ; + + return ( + + ); +} + +module.exports = addState(Menu); diff --git a/client/src/components/play.jsx b/client/src/components/play.jsx index 38efb8bc..9ebd4d9e 100644 --- a/client/src/components/play.jsx +++ b/client/src/components/play.jsx @@ -1,120 +1,128 @@ -const { connect } = require('preact-redux'); +// const { connect } = require('preact-redux'); const preact = require('preact'); +const { connect } = require('preact-redux'); +const { Elements } = require('react-stripe-elements'); -const { stringSort } = require('./../utils'); -const { ConstructAvatar } = require('./construct'); -const actions = require('./../actions'); -const Inventory = require('./inventory'); const Header = require('./header'); +const Team = require('./team'); +const StripeBtns = require('./stripe.buttons'); -const idSort = stringSort('id'); +const actions = require('./../actions'); + +const VERSION = process.env.npm_package_version; const addState = connect( function receiveState(state) { const { ws, - constructs, - constructRename, - team, - mtxActive, + account, + shop, } = state; - function sendInstancePractice() { - return ws.sendInstancePractice(); - } - - function sendConstructAvatarReroll(id) { - console.log('using', mtxActive, 'on', id); - return ws.sendMtxApply(id, mtxActive, ''); - } - - function sendConstructRename(id, name) { - ws.sendMtxApply(id, 'Rename', name); + function mtxBuy(mtx) { + return ws.sendMtxBuy(mtx.variant); } return { - constructs, - mtxActive, - constructRename, - team, - sendConstructRename, - sendInstancePractice, - sendConstructAvatarReroll, + account, + shop, + mtxBuy, }; }, function receiveDispatch(dispatch) { - function setConstructRename(id) { - dispatch(actions.setConstructRename(id)); + function setMtxActive(mtx) { + dispatch(actions.setConstructRename(null)); + dispatch(actions.setMtxActive(mtx)); + return true; } - function clearMtxRename() { - dispatch(actions.setConstructRename(null)); - dispatch(actions.setMtxActive(null)); + function setNav(place) { + return dispatch(actions.setNav(place)); } return { - clearMtxRename, - setConstructRename, + setMtxActive, + setNav, }; } - ); function Play(args) { const { - team, - constructRename, - clearMtxRename, - setConstructRename, - sendConstructRename, - mtxActive, - sendConstructAvatarReroll, + account, + shop, + mtxBuy, + + setMtxActive, + setNav, } = args; - const constructPanels = team - .map(construct => { - const constructName = constructRename === construct.id - ? - :

{construct.name}

; + if (!shop) return false; - const confirm = constructRename === construct.id - ? - : false; + const useMtx = (item, i) => ( +
setMtxActive(item)} > +
{item}
+ +
+ ); + + const availableMtx = (item, i) => ( +
mtxBuy(item)} > +
{item.variant}
+ +
+ ); + + const subscription = account.subscribed + ? + : ; - const cancel = constructRename === construct.id - ? - : false; - return ( -
{ - if (!mtxActive) return false; - if (mtxActive === 'Rename') return setConstructRename(construct.id); - return sendConstructAvatarReroll(construct.id); - }} - class="construct"> - - {constructName} - {confirm} - {cancel} -
- ); - }); return ( -
-
- -
- {constructPanels} +
+
+

mnml v{VERSION}

+

use the buttons on the right to join an instance.

+

+ select PVP to play against other players.
+ click LEARN to practice the game without time controls. +

+

+ if you enjoy the game please support its development by subscribing or purchasing credits.
+ glhf +

+

--ntr & mashy

-
+
+

¤ {account.balance}

+
+ {subscription} + +
+
+
+ {shop.owned.map(useMtx)} +
+
+ {shop.available.map(availableMtx)} +
+
+ ); } diff --git a/client/src/components/shop.jsx b/client/src/components/shop.jsx new file mode 100644 index 00000000..da0de7af --- /dev/null +++ b/client/src/components/shop.jsx @@ -0,0 +1,58 @@ +// const { connect } = require('preact-redux'); +const preact = require('preact'); +const { connect } = require('preact-redux'); +const { Elements } = require('react-stripe-elements'); + +const StripeBtns = require('./stripe.buttons'); +const actions = require('./../actions'); + +const addState = connect( + function receiveState(state) { + const { + ws, + account, + } = state; + + return { + account, + }; + }, +); + +function Shop(args) { + const { + account, + } = args; + + return ( +
+
+

support the game

+

+ credits are in game currency that can be used to purchase: +

    +
  • img sets
  • +
  • construct renames
  • +
  • new constructs
  • +
+

+

+ subscriptions grant extra benefits: +

    +
  • additional credits
  • +
  • chat wheel (soon ™)
  • +
  • account icons (soon ™)
  • +
+

+
+
+

¤ {account.balance}

+ + + +
+
+ ); +} + +module.exports = addState(Shop); diff --git a/client/src/components/stripe.buttons.jsx b/client/src/components/stripe.buttons.jsx index ef72c5a9..15b3411a 100644 --- a/client/src/components/stripe.buttons.jsx +++ b/client/src/components/stripe.buttons.jsx @@ -6,8 +6,16 @@ function subPlan() { return 'prod_FWSA8RoyMMV3st'; } -function bitsSku() { - if (window.location.host === 'mnml.gg') return 'sku_Fjdu7zOy3sLGc5'; +function bitsSku(d) { + if (window.location.host === 'mnml.gg') { + if (d === 50) return 'sku_Fl5tLCWogUsgus'; + if (d === 20) return 'sku_Fl5qegnxYRv7Cy'; + if (d === 10) return 'sku_Fl5qVosoDsUVgy'; + if (d === 5) return 'sku_Fjdu7zOy3sLGc5'; + + // !!!! + return 'sku_Fjdu7zOy3sLGc5'; + } return 'sku_FjuNxONdWewjH2'; } @@ -16,6 +24,7 @@ function BitsBtn(args) { stripe, account, } = args; + function subscribeClick() { stripe.redirectToCheckout({ items: [{ plan: subPlan(), quantity: 1 }], @@ -25,9 +34,9 @@ function BitsBtn(args) { }); } - function bitsClick() { + function bitsClick(d) { stripe.redirectToCheckout({ - items: [{ sku: bitsSku(), quantity: 1 }], + items: [{ sku: bitsSku(d), quantity: 1 }], successUrl: window.location.origin, cancelUrl: window.location.origin, clientReferenceId: account.id, @@ -48,15 +57,29 @@ function BitsBtn(args) { ; return ( -
- {subscription} - -
+
+
+ {subscription} +
+
+
bitsClick(5)} > +
$5 AUD
+ +
+
bitsClick(10)} > +
$10 AUD
+ +
+
bitsClick(20)} > +
$20 AUD
+ +
+
bitsClick(50)} > +
$50 AUD
+ +
+
+
); } diff --git a/client/src/components/team.jsx b/client/src/components/team.jsx index 682e29ed..dd821890 100644 --- a/client/src/components/team.jsx +++ b/client/src/components/team.jsx @@ -1,88 +1,112 @@ -const preact = require('preact'); const { connect } = require('preact-redux'); +const preact = require('preact'); -const actions = require('./../actions'); -const { COLOURS } = require('./../utils'); const { ConstructAvatar } = require('./construct'); +const actions = require('./../actions'); const addState = connect( function receiveState(state) { - const { ws, constructs, teamPage, teamSelect } = state; + const { + ws, + constructs, + constructRename, + team, + mtxActive, + } = state; - function sendConstructSpawn(name) { - return ws.sendMtxConstructSpawn(name); + function sendInstancePractice() { + return ws.sendInstancePractice(); + } + + function sendConstructAvatarReroll(id) { + console.log('using', mtxActive, 'on', id); + return ws.sendMtxApply(id, mtxActive, ''); + } + + function sendConstructRename(id, name) { + ws.sendMtxApply(id, 'Rename', name); } return { constructs, - teamPage, - teamSelect, + mtxActive, + constructRename, + team, + sendConstructRename, + sendInstancePractice, + sendConstructAvatarReroll, }; }, + function receiveDispatch(dispatch) { - function setTeam(constructIds) { - dispatch(actions.setTeamSelect(constructIds)); + function setConstructRename(id) { + dispatch(actions.setConstructRename(id)); + } + + function clearMtxRename() { + dispatch(actions.setConstructRename(null)); + dispatch(actions.setMtxActive(null)); } return { - setTeam, + clearMtxRename, + setConstructRename, }; } + ); function Team(args) { const { - constructs, - teamPage, - teamSelect, - setTeam, + team, + constructRename, + clearMtxRename, + setConstructRename, + sendConstructRename, + mtxActive, + sendConstructAvatarReroll, } = args; - if (!constructs) return
; + const constructPanels = team + .map(construct => { + const constructName = constructRename === construct.id + ? + :

{construct.name}

; - // redux limitation + suggested workaround - // so much for dumb components - function selectConstruct(id) { - // remove - const i = teamSelect.findIndex(sid => sid === id); - if (i > -1) { - teamSelect[i] = null; - return setTeam(teamSelect); - } + const confirm = constructRename === construct.id + ? + : false; - // window insert - const insert = teamSelect.findIndex(j => j === null); - if (insert === -1) return setTeam([id, null, null]); - teamSelect[insert] = id; - return setTeam(teamSelect); - } - console.log(constructs.length); - const dispConstructs = constructs.length >= ((teamPage + 1) * 6) - ? constructs.slice(teamPage * 6, (teamPage + 1) * 6) - : constructs.slice(teamPage * 6, constructs.length); + const cancel = constructRename === construct.id + ? + : false; - const constructPanels = dispConstructs.map(construct => { - const colour = teamSelect.indexOf(construct.id); - const selected = colour > -1; - - const borderColour = selected ? COLOURS[colour] : '#000000'; - - return ( -
selectConstruct(construct.id)} > - -

{construct.name}

-
- ); - }); + return ( +
{ + if (!mtxActive) return false; + if (mtxActive === 'Rename') return setConstructRename(construct.id); + return sendConstructAvatarReroll(construct.id); + }} + class="construct"> + + {constructName} + {confirm} + {cancel} +
+ ); + }); return ( -
+
{constructPanels} -
+
); }