puzzle streak description

streak
Thibault Duplessis 2021-03-28 19:16:34 +02:00
parent 252b474e1c
commit cf6dee7f07
6 changed files with 61 additions and 30 deletions

View File

@ -106,6 +106,7 @@ object bits {
private val streakI18nKeys: List[MessageKey] =
List(
trans.storm.skip,
trans.puzzle.streakDescription,
trans.puzzle.yourStreakX,
trans.puzzle.streakSkipExplanation,
trans.puzzle.continueTheStreak,

View File

@ -1843,6 +1843,7 @@ val `strengths` = new I18nKey("puzzle:strengths")
val `history` = new I18nKey("puzzle:history")
val `solved` = new I18nKey("puzzle:solved")
val `failed` = new I18nKey("puzzle:failed")
val `streakDescription` = new I18nKey("puzzle:streakDescription")
val `yourStreakX` = new I18nKey("puzzle:yourStreakX")
val `streakSkipExplanation` = new I18nKey("puzzle:streakSkipExplanation")
val `continueTheStreak` = new I18nKey("puzzle:continueTheStreak")

View File

@ -50,6 +50,7 @@
<string name="history">Puzzle history</string>
<string name="solved">solved</string>
<string name="failed">failed</string>
<string name="streakDescription">Solve progressively harder puzzles and build a win streak. There is no clock, so take your time. One wrong move, and it's game over! But you can skip one move per session.</string>
<string name="yourStreakX">Your streak: %s</string>
<string name="streakSkipExplanation">Skip this move to preserve your streak! Only works once per run.</string>
<string name="continueTheStreak">Continue the streak</string>

View File

@ -44,23 +44,13 @@
background: $c-bg-box;
padding: 2vmin;
&__rating,
&__streak {
&__rating {
strong {
display: block;
text-align: center;
font-size: 3.5em;
}
}
&__streak {
@extend %flex-center-nowrap;
justify-content: center;
font-size: 4em;
&::before {
font-size: 0.9em;
margin-right: 0.3ch;
}
}
.rp {
font-size: 1.3rem;
@ -76,6 +66,31 @@
}
}
&__streak {
&__info {
h1 {
color: $c-brag;
@extend %flex-center-nowrap;
font-size: 2.2rem;
margin-bottom: 1rem;
&::before {
font-size: 1.5em;
}
}
}
&__score {
color: $c-brag;
@extend %flex-center-nowrap;
justify-content: center;
font-size: 4em;
&::before {
font-size: 0.9em;
}
}
}
&__config {
@extend %box-neat;
@ -134,6 +149,7 @@
&::before {
@extend %box-radius;
z-index: 0;
content: '';
position: absolute;
@ -144,8 +160,10 @@
background: mix($c-bg-page, $c-primary, 40%)
linear-gradient(180deg, rgba(255%, 255%, 255%, 0.15) 0%, transparent 35%);
animation: bar-glider-anim 3s linear infinite;
@include transition(width, 1s);
}
&::after {
z-index: 1;
content: attr(data-text);

View File

@ -30,8 +30,6 @@ export function onInsert<A extends HTMLElement>(f: (element: A) => void): Hooks
};
}
export function dataIcon(icon: string) {
return {
'data-icon': icon,
};
}
export const dataIcon = (icon: string) => ({
'data-icon': icon,
});

View File

@ -1,8 +1,9 @@
import { Controller, Puzzle, PuzzleGame, MaybeVNode, PuzzleDifficulty, PuzzlePlayer } from '../interfaces';
import { Controller, Puzzle, PuzzleGame, MaybeVNode, PuzzleDifficulty } from '../interfaces';
import { dataIcon, onInsert } from '../util';
import { h } from 'snabbdom';
import { numberFormat } from 'common/number';
import { VNode } from 'snabbdom/vnode';
import PuzzleStreak from '../streak';
export function puzzleBox(ctrl: Controller): VNode {
var data = ctrl.getData();
@ -82,7 +83,7 @@ function gameInfos(ctrl: Controller, game: PuzzleGame, puzzle: Puzzle): VNode {
{
attrs: { href: '/@/' + p.userId },
},
playerName(p)
p.title && p.title != 'BOT' ? [h('span.utitle', p.title), ' ' + p.name] : p.name
)
: p.name
)
@ -93,9 +94,28 @@ function gameInfos(ctrl: Controller, game: PuzzleGame, puzzle: Puzzle): VNode {
);
}
function playerName(p: PuzzlePlayer) {
return p.title && p.title != 'BOT' ? [h('span.utitle', p.title), ' ' + p.name] : p.name;
}
const renderStreak = (streak: PuzzleStreak, noarg: TransNoArg) =>
h(
'div.puzzle__side__streak',
streak.current == 0
? h('div.puzzle__side__streak__info', [
h(
'h1.text',
{
attrs: dataIcon('}'),
},
'Puzzle Streak'
),
h('p', noarg('streakDescription')),
])
: h(
'div.puzzle__side__streak__score.text',
{
attrs: dataIcon('}'),
},
streak.current
)
);
export function userBox(ctrl: Controller): VNode {
const data = ctrl.getData();
@ -107,15 +127,7 @@ export function userBox(ctrl: Controller): VNode {
const diff = ctrl.vm.round?.ratingDiff;
return h('div.puzzle__side__user', [
ctrl.streak
? h(
'div.puzzle__side__user__streak',
{
attrs: {
'data-icon': '}',
},
},
ctrl.streak.current
)
? renderStreak(ctrl.streak, ctrl.trans.noarg)
: h(
'div.puzzle__side__user__rating',
ctrl.trans.vdom(