improve game expiration UI

scalafixDisable
Thibault Duplessis 2017-10-22 17:45:53 -05:00
parent d3c9827223
commit 9cdcf79f74
9 changed files with 34 additions and 27 deletions

View File

@ -19,7 +19,6 @@ trans.accept,
trans.decline,
trans.takebackPropositionSent,
trans.yourOpponentProposesATakeback,
trans.youHaveNbSecondsToMakeYourFirstMove,
trans.thisPlayerUsesChessComputerAssistance,
trans.gameAborted,
trans.checkmate,

View File

@ -507,7 +507,8 @@ case class Game(
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 {
Centis.ofMillis(movedAt.getMillis - nowMillis + timeForFirstMove.millis).nonNeg

View File

@ -23,6 +23,7 @@ object Source {
val byId = all map { v => (v.id, v) } toMap
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
}

View File

@ -667,7 +667,6 @@ val `nbFollowers` = new Translated("nbFollowers", Site)
val `nbFollowing` = new Translated("nbFollowing", Site)
val `lessThanNbMinutes` = new Translated("lessThanNbMinutes", Site)
val `playedXTimes` = new Translated("playedXTimes", Site)
val `youHaveNbSecondsToMakeYourFirstMove` = new Translated("youHaveNbSecondsToMakeYourFirstMove", Site)
val `nbGamesInPlay` = new Translated("nbGamesInPlay", Site)
val `maximumNbCharacters` = new Translated("maximumNbCharacters", Site)
val `blocks` = new Translated("blocks", Site)

View File

@ -17,5 +17,9 @@
"bugs": {
"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"
}
}

View File

@ -443,10 +443,6 @@ body.piece_letter .lichess_ground .replay move {
color: #d85000!important;
font-weight: bold;
}
.lichess_ground .expiration {
margin: 10px 0;
text-align: center;
}
.lichess_ground .result_wrap {
width: 100%;
}
@ -764,6 +760,7 @@ div.control .button.disabled {
.lichess_ground .negotiation {
padding: 10px 7px;
background: #d0d0d0;
text-align: center;
}
.lichess_ground .suggestion p {
margin-bottom: 7px;
@ -771,6 +768,10 @@ div.control .button.disabled {
.lichess_ground .suggestion .button {
display: block;
}
.lichess_ground .expiration.emerg {
background: #dc322f!important;
color: #fff!important;
}
.lichess_ground .pending {
display: flex;
align-items: center;

View File

@ -451,10 +451,6 @@ a computer analysis, a game chat and a shareable URL.</string>
<string name="retryThisPuzzle">Retry this puzzle</string>
<string name="thisPuzzleIsCorrect">This puzzle is correct and interesting</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">
<item quantity="one">%s game in play</item>
<item quantity="other">%s games in play</item>

View File

@ -1,13 +1,24 @@
import { h } from 'snabbdom'
import { VNode } from 'snabbdom/vnode'
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;
if (!d) return;
const timeLeft = Math.max(0, d.movedAt - Date.now() + d.millisToMove);
return h('div.expiration', [
Math.round(timeLeft / 1000),
' seconds to move'
]);
const timeLeft = Math.max(0, d.movedAt - Date.now() + d.millisToMove),
myTurn = game.isPlayerTurn(ctrl.data),
emerg = myTurn && timeLeft < 8000;
return [
h('div.expiration.suggestion', {
class: { emerg }
}, [
h('div.text', {
}, [
h('strong', '' + Math.round(timeLeft / 1000)),
' seconds to move'
])
]),
myTurn
];
}

View File

@ -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) {
const d = ctrl.data,
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.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] : [
button.forceResign(ctrl),
button.threefoldClaimDraw(ctrl),
@ -80,10 +74,11 @@ function renderTablePlay(ctrl: RoundController) {
button.answerOpponentDrawOffer(ctrl),
button.cancelTakebackProposition(ctrl),
button.answerOpponentTakebackProposition(ctrl),
(d.tournament && game.nbMoves(d, d.player.color) === 0) ? tournamentStartWarning(ctrl) : null
expiration && expiration[1] ? expiration[0] : null
]);
return [
renderExpiration(ctrl) || renderReplay(ctrl),
expiration && !expiration[1] ? expiration[0] : null,
renderReplay(ctrl),
h('div.control.icons', {
class: { 'confirm': !!(ctrl.drawConfirm || ctrl.resignConfirm) }
}, icons),