improve game expiration UI
parent
d3c9827223
commit
9cdcf79f74
|
@ -19,7 +19,6 @@ trans.accept,
|
||||||
trans.decline,
|
trans.decline,
|
||||||
trans.takebackPropositionSent,
|
trans.takebackPropositionSent,
|
||||||
trans.yourOpponentProposesATakeback,
|
trans.yourOpponentProposesATakeback,
|
||||||
trans.youHaveNbSecondsToMakeYourFirstMove,
|
|
||||||
trans.thisPlayerUsesChessComputerAssistance,
|
trans.thisPlayerUsesChessComputerAssistance,
|
||||||
trans.gameAborted,
|
trans.gameAborted,
|
||||||
trans.checkmate,
|
trans.checkmate,
|
||||||
|
|
|
@ -507,7 +507,8 @@ case class Game(
|
||||||
else base
|
else base
|
||||||
}
|
}
|
||||||
|
|
||||||
def expirable = playable && !bothPlayersHaveMoved && nonAi && hasClock
|
def expirable =
|
||||||
|
source.exists(Source.expirable.contains) && playable && !bothPlayersHaveMoved && nonAi && hasClock
|
||||||
|
|
||||||
def timeBeforeExpiration: Option[Centis] = expirable option {
|
def timeBeforeExpiration: Option[Centis] = expirable option {
|
||||||
Centis.ofMillis(movedAt.getMillis - nowMillis + timeForFirstMove.millis).nonNeg
|
Centis.ofMillis(movedAt.getMillis - nowMillis + timeForFirstMove.millis).nonNeg
|
||||||
|
|
|
@ -23,6 +23,7 @@ object Source {
|
||||||
val byId = all map { v => (v.id, v) } toMap
|
val byId = all map { v => (v.id, v) } toMap
|
||||||
|
|
||||||
val searchable = List(Lobby, Friend, Ai, Position, Import, Tournament, Simul, Pool)
|
val searchable = List(Lobby, Friend, Ai, Position, Import, Tournament, Simul, Pool)
|
||||||
|
val expirable: Set[Source] = Set(Lobby, Tournament, Pool)
|
||||||
|
|
||||||
def apply(id: Int): Option[Source] = byId get id
|
def apply(id: Int): Option[Source] = byId get id
|
||||||
}
|
}
|
||||||
|
|
|
@ -667,7 +667,6 @@ val `nbFollowers` = new Translated("nbFollowers", Site)
|
||||||
val `nbFollowing` = new Translated("nbFollowing", Site)
|
val `nbFollowing` = new Translated("nbFollowing", Site)
|
||||||
val `lessThanNbMinutes` = new Translated("lessThanNbMinutes", Site)
|
val `lessThanNbMinutes` = new Translated("lessThanNbMinutes", Site)
|
||||||
val `playedXTimes` = new Translated("playedXTimes", Site)
|
val `playedXTimes` = new Translated("playedXTimes", Site)
|
||||||
val `youHaveNbSecondsToMakeYourFirstMove` = new Translated("youHaveNbSecondsToMakeYourFirstMove", Site)
|
|
||||||
val `nbGamesInPlay` = new Translated("nbGamesInPlay", Site)
|
val `nbGamesInPlay` = new Translated("nbGamesInPlay", Site)
|
||||||
val `maximumNbCharacters` = new Translated("maximumNbCharacters", Site)
|
val `maximumNbCharacters` = new Translated("maximumNbCharacters", Site)
|
||||||
val `blocks` = new Translated("blocks", Site)
|
val `blocks` = new Translated("blocks", Site)
|
||||||
|
|
|
@ -17,5 +17,9 @@
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/ornicar/lila/issues"
|
"url": "https://github.com/ornicar/lila/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://lichess.org"
|
"homepage": "https://lichess.org",
|
||||||
|
"dependencies": {
|
||||||
|
"fs-extra": "^4.0.2",
|
||||||
|
"xml2js": "^0.4.19"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -443,10 +443,6 @@ body.piece_letter .lichess_ground .replay move {
|
||||||
color: #d85000!important;
|
color: #d85000!important;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
.lichess_ground .expiration {
|
|
||||||
margin: 10px 0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.lichess_ground .result_wrap {
|
.lichess_ground .result_wrap {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
@ -764,6 +760,7 @@ div.control .button.disabled {
|
||||||
.lichess_ground .negotiation {
|
.lichess_ground .negotiation {
|
||||||
padding: 10px 7px;
|
padding: 10px 7px;
|
||||||
background: #d0d0d0;
|
background: #d0d0d0;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
.lichess_ground .suggestion p {
|
.lichess_ground .suggestion p {
|
||||||
margin-bottom: 7px;
|
margin-bottom: 7px;
|
||||||
|
@ -771,6 +768,10 @@ div.control .button.disabled {
|
||||||
.lichess_ground .suggestion .button {
|
.lichess_ground .suggestion .button {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
.lichess_ground .expiration.emerg {
|
||||||
|
background: #dc322f!important;
|
||||||
|
color: #fff!important;
|
||||||
|
}
|
||||||
.lichess_ground .pending {
|
.lichess_ground .pending {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
|
@ -451,10 +451,6 @@ a computer analysis, a game chat and a shareable URL.</string>
|
||||||
<string name="retryThisPuzzle">Retry this puzzle</string>
|
<string name="retryThisPuzzle">Retry this puzzle</string>
|
||||||
<string name="thisPuzzleIsCorrect">This puzzle is correct and interesting</string>
|
<string name="thisPuzzleIsCorrect">This puzzle is correct and interesting</string>
|
||||||
<string name="thisPuzzleIsWrong">This puzzle is wrong or boring</string>
|
<string name="thisPuzzleIsWrong">This puzzle is wrong or boring</string>
|
||||||
<plurals name="youHaveNbSecondsToMakeYourFirstMove">
|
|
||||||
<item quantity="one">You have %s second to make your first move!</item>
|
|
||||||
<item quantity="other">You have %s seconds to make your first move!</item>
|
|
||||||
</plurals>
|
|
||||||
<plurals name="nbGamesInPlay">
|
<plurals name="nbGamesInPlay">
|
||||||
<item quantity="one">%s game in play</item>
|
<item quantity="one">%s game in play</item>
|
||||||
<item quantity="other">%s games in play</item>
|
<item quantity="other">%s games in play</item>
|
||||||
|
|
|
@ -1,13 +1,24 @@
|
||||||
import { h } from 'snabbdom'
|
import { h } from 'snabbdom'
|
||||||
import { VNode } from 'snabbdom/vnode'
|
import { VNode } from 'snabbdom/vnode'
|
||||||
import RoundController from '../ctrl';
|
import RoundController from '../ctrl';
|
||||||
|
import { game } from 'game';
|
||||||
|
|
||||||
export default function(ctrl: RoundController): VNode | undefined {
|
export default function(ctrl: RoundController): [VNode, boolean] | undefined {
|
||||||
const d = ctrl.data.expiration;
|
const d = ctrl.data.expiration;
|
||||||
if (!d) return;
|
if (!d) return;
|
||||||
const timeLeft = Math.max(0, d.movedAt - Date.now() + d.millisToMove);
|
const timeLeft = Math.max(0, d.movedAt - Date.now() + d.millisToMove),
|
||||||
return h('div.expiration', [
|
myTurn = game.isPlayerTurn(ctrl.data),
|
||||||
Math.round(timeLeft / 1000),
|
emerg = myTurn && timeLeft < 8000;
|
||||||
' seconds to move'
|
return [
|
||||||
]);
|
h('div.expiration.suggestion', {
|
||||||
|
class: { emerg }
|
||||||
|
}, [
|
||||||
|
h('div.text', {
|
||||||
|
}, [
|
||||||
|
h('strong', '' + Math.round(timeLeft / 1000)),
|
||||||
|
' seconds to move'
|
||||||
|
])
|
||||||
|
]),
|
||||||
|
myTurn
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,13 +56,6 @@ function renderTableWatch(ctrl: RoundController) {
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function tournamentStartWarning(ctrl: RoundController) {
|
|
||||||
return h('div.suggestion', [
|
|
||||||
h('div.text', { attrs: {'data-icon': 'j'} },
|
|
||||||
ctrl.trans('youHaveNbSecondsToMakeYourFirstMove', ctrl.data.tournament!.nbSecondsForFirstMove))
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderTablePlay(ctrl: RoundController) {
|
function renderTablePlay(ctrl: RoundController) {
|
||||||
const d = ctrl.data,
|
const d = ctrl.data,
|
||||||
loading = isLoading(ctrl),
|
loading = isLoading(ctrl),
|
||||||
|
@ -73,6 +66,7 @@ function renderTablePlay(ctrl: RoundController) {
|
||||||
ctrl.drawConfirm ? button.drawConfirm(ctrl) : button.standard(ctrl, ctrl.canOfferDraw, '2', 'offerDraw', 'draw-yes', () => ctrl.offerDraw(true)),
|
ctrl.drawConfirm ? button.drawConfirm(ctrl) : button.standard(ctrl, ctrl.canOfferDraw, '2', 'offerDraw', 'draw-yes', () => ctrl.offerDraw(true)),
|
||||||
ctrl.resignConfirm ? button.resignConfirm(ctrl) : button.standard(ctrl, game.resignable, 'b', 'resign', 'resign-confirm', () => ctrl.resign(true))
|
ctrl.resignConfirm ? button.resignConfirm(ctrl) : button.standard(ctrl, game.resignable, 'b', 'resign', 'resign-confirm', () => ctrl.resign(true))
|
||||||
],
|
],
|
||||||
|
expiration = renderExpiration(ctrl),
|
||||||
buttons: MaybeVNodes = loading ? [loader()] : (submit ? [submit] : [
|
buttons: MaybeVNodes = loading ? [loader()] : (submit ? [submit] : [
|
||||||
button.forceResign(ctrl),
|
button.forceResign(ctrl),
|
||||||
button.threefoldClaimDraw(ctrl),
|
button.threefoldClaimDraw(ctrl),
|
||||||
|
@ -80,10 +74,11 @@ function renderTablePlay(ctrl: RoundController) {
|
||||||
button.answerOpponentDrawOffer(ctrl),
|
button.answerOpponentDrawOffer(ctrl),
|
||||||
button.cancelTakebackProposition(ctrl),
|
button.cancelTakebackProposition(ctrl),
|
||||||
button.answerOpponentTakebackProposition(ctrl),
|
button.answerOpponentTakebackProposition(ctrl),
|
||||||
(d.tournament && game.nbMoves(d, d.player.color) === 0) ? tournamentStartWarning(ctrl) : null
|
expiration && expiration[1] ? expiration[0] : null
|
||||||
]);
|
]);
|
||||||
return [
|
return [
|
||||||
renderExpiration(ctrl) || renderReplay(ctrl),
|
expiration && !expiration[1] ? expiration[0] : null,
|
||||||
|
renderReplay(ctrl),
|
||||||
h('div.control.icons', {
|
h('div.control.icons', {
|
||||||
class: { 'confirm': !!(ctrl.drawConfirm || ctrl.resignConfirm) }
|
class: { 'confirm': !!(ctrl.drawConfirm || ctrl.resignConfirm) }
|
||||||
}, icons),
|
}, icons),
|
||||||
|
|
Loading…
Reference in New Issue