puzzle streak description
parent
252b474e1c
commit
cf6dee7f07
|
@ -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,
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
});
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in New Issue