diff --git a/client/assets/styles/controls.less b/client/assets/styles/controls.less index 678fb29f..1d52b4c1 100644 --- a/client/assets/styles/controls.less +++ b/client/assets/styles/controls.less @@ -14,7 +14,7 @@ aside { padding-left: 1em; - .game-controls { + .instance-ctrl { grid-template-rows: 1fr 1fr 1fr min-content; } @@ -100,15 +100,16 @@ aside { padding: 0 0.75em 0 0.75em; } -.abandon { +.abandon:not([disabled]) { &:hover { color: @red; border-color: @red; + border: 2px solid @red; }; &:active, &.confirming { background: @red; color: black; - border: 1px solid black; + border: 2px solid black; } } \ No newline at end of file diff --git a/client/src/components/game.ctrl.jsx b/client/src/components/game.ctrl.jsx index 8da239bf..0aa4220f 100644 --- a/client/src/components/game.ctrl.jsx +++ b/client/src/components/game.ctrl.jsx @@ -4,6 +4,7 @@ const { connect } = require('preact-redux'); const actions = require('../actions'); const PlayerBox = require('./player.box'); +const InstanceCtrlBtns = require('./instance.ctrl.btns'); const addState = connect( function receiveState(state) { @@ -122,14 +123,11 @@ function Controls(args) { return ( ); diff --git a/client/src/components/instance.ctrl.btns.jsx b/client/src/components/instance.ctrl.btns.jsx new file mode 100644 index 00000000..91638f98 --- /dev/null +++ b/client/src/components/instance.ctrl.btns.jsx @@ -0,0 +1,75 @@ +const preact = require('preact'); +const { connect } = require('preact-redux'); + +const actions = require('../actions'); + +const addState = connect( + function receiveState(state) { + const { + ws, + game, + instance, + animating, + } = state; + + function sendReady() { + document.activeElement.blur(); + return ws.sendGameReady(game.id); + } + + function sendGameSkillClear() { + return ws.sendGameSkillClear(game.id); + } + + function sendAbandon() { + return ws.sendInstanceAbandon(instance.id); + } + + return { + game, + instance, + animating, + + sendAbandon, + sendGameSkillClear, + }; + }, +); + +function InstanceCtrlBtns(args) { + const { + sendAbandon, + animating, + sendGameSkillClear, + + game, + instance, + } = args; + + const finished = instance.phase === 'Finished'; + + const { abandonState } = this.state; + + const cancelAbandon = e => { + e.stopPropagation(); + return this.setState({ abandonState: false }); + }; + + const abandonStateTrue = e => { + e.stopPropagation(); + this.setState({ abandonState: true }); + setTimeout(() => this.setState({ abandonState: false }), 2000); + }; + + const abandonClasses = `abandon ${abandonState ? 'confirming' : ''}`; + const abandonAction = abandonState ? sendAbandon : abandonStateTrue; + + return ( +
+ {game ? : null} + +
+ ); +} + +module.exports = addState(InstanceCtrlBtns); diff --git a/client/src/components/instance.ctrl.jsx b/client/src/components/instance.ctrl.jsx index 7a2762c5..faa38afb 100644 --- a/client/src/components/instance.ctrl.jsx +++ b/client/src/components/instance.ctrl.jsx @@ -2,8 +2,8 @@ const preact = require('preact'); const { connect } = require('preact-redux'); const actions = require('../actions'); - const PlayerBox = require('./player.box'); +const InstanceCtrlBtns = require('./instance.ctrl.btns'); const addState = connect( function receiveState(state) { @@ -87,13 +87,15 @@ function Controls(args) { : const abandon = instance.phase !== 'Finished' ? sendAbandon : false; + return ( ); diff --git a/server/src/instance.rs b/server/src/instance.rs index 3e489c39..7b0eac07 100644 --- a/server/src/instance.rs +++ b/server/src/instance.rs @@ -748,6 +748,13 @@ pub fn pvp(tx: &mut Transaction, a: &Account, b: &Account) -> Result Result { let mut instance = instance_get(tx, instance_id)?; + + if let Some(game_id) = instance.current_game_id() { + let mut game = game_get(tx, game_id)?; + game.player_by_id(account.id)?.forfeit(); + game_update(tx, &game)?; + } + instance.account_player(account.id)?.set_lose(); instance.account_opponent(account.id)?.set_win(); instance.next_round();