dasher WIP / should have Prop<DasherData>
This commit is contained in:
parent
8e35253852
commit
da484d3824
|
@ -1,5 +1,6 @@
|
|||
package controllers
|
||||
|
||||
import scala.collection.breakOut
|
||||
import play.api.mvc._
|
||||
|
||||
import lila.api.Context
|
||||
|
@ -26,6 +27,10 @@ object Dasher extends LilaController {
|
|||
case Some(me) => Env.pref.api.getPref(me) map { prefs =>
|
||||
Ok {
|
||||
lila.common.LightUser.lightUserWrites.writes(me.light) ++ Json.obj(
|
||||
"lang" -> Json.obj(
|
||||
"current" -> Env.i18n.pool.lang(ctx.req).language.toString,
|
||||
"accepted" -> (ctx.req.acceptLanguages.map(_.language.toString)(breakOut): List[String]).distinct
|
||||
),
|
||||
"kid" -> me.kid,
|
||||
"coach" -> isGranted(_.Coach),
|
||||
"prefs" -> prefs,
|
||||
|
|
|
@ -53,9 +53,6 @@ trait I18nHelper {
|
|||
def commonDomain(implicit ctx: UserContext): String =
|
||||
I18nDomain(ctx.req.domain).commonDomain
|
||||
|
||||
def acceptLanguages(implicit ctx: UserContext): List[String] =
|
||||
(ctx.req.acceptLanguages.map(_.language.toString)(breakOut): List[String]).distinct
|
||||
|
||||
def acceptsLanguage(lang: Lang)(implicit ctx: UserContext): Boolean =
|
||||
ctx.req.acceptLanguages exists (_.language == lang.language)
|
||||
|
||||
|
|
|
@ -74,7 +74,6 @@ asyncJs: Boolean = false)(body: Html)(implicit ctx: Context)
|
|||
data-bg="@ctx.currentBg"
|
||||
data-asset-url="@assetBaseUrl"
|
||||
data-asset-version="@ctx.pageData.assetVersion"
|
||||
data-accept-languages="@acceptLanguages.mkString(",")"
|
||||
@ctx.zoom.map { zoom => data-zoom="@zoom" }>
|
||||
<form id="blind_mode" action="@routes.Main.toggleBlindMode" method="POST">
|
||||
<input type="hidden" name="enable" value="@ctx.blindMode.fold(0,1)" />
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import { PingCtrl, ctrl as pingCtrl } from './ping'
|
||||
import { LangsCtrl, ctrl as langsCtrl } from './langs'
|
||||
import { Redraw, Prop, prop } from './util'
|
||||
import { load } from './xhr'
|
||||
import { get } from './xhr'
|
||||
|
||||
export interface Ctrl {
|
||||
export interface DasherCtrl {
|
||||
mode: Prop<Mode>
|
||||
setMode: (m: Mode) => void
|
||||
data: Prop<DasherData>
|
||||
trans: Prop<Trans>
|
||||
ping: PingCtrl
|
||||
|
@ -20,25 +21,32 @@ export interface DasherOpts {
|
|||
playing: boolean
|
||||
}
|
||||
|
||||
export function makeCtrl(opts: DasherOpts, redraw: Redraw): Ctrl {
|
||||
export function makeCtrl(opts: DasherOpts, redraw: Redraw): DasherCtrl {
|
||||
|
||||
let mode: Prop<Mode> = prop('links' as Mode);
|
||||
let data: Prop<DasherData | undefined> = prop(undefined);
|
||||
let trans: Prop<Trans> = prop(window.lichess.trans({}));
|
||||
|
||||
function setMode(m: Mode) {
|
||||
mode(m);
|
||||
redraw();
|
||||
}
|
||||
function close() { setMode('links'); }
|
||||
|
||||
const ping = pingCtrl(trans, redraw);
|
||||
const langs = langsCtrl(redraw);
|
||||
const langs = langsCtrl('', [], redraw, close);
|
||||
|
||||
function update(d: DasherData) {
|
||||
data = d;
|
||||
if (d.i18n) trans = window.lichess.trans(d.i18n);
|
||||
if (data()) trans(window.lichess.trans(d.i18n));
|
||||
data(d);
|
||||
redraw();
|
||||
}
|
||||
|
||||
load().then(update);
|
||||
get('/dasher').then(update);
|
||||
|
||||
return {
|
||||
mode,
|
||||
setMode,
|
||||
data,
|
||||
trans,
|
||||
ping,
|
|
@ -1,28 +1,72 @@
|
|||
import { h } from 'snabbdom'
|
||||
import { VNode } from 'snabbdom/vnode'
|
||||
|
||||
import { Redraw, Prop, prop } from './util'
|
||||
|
||||
export interface LangsCtrl {
|
||||
}
|
||||
import { Redraw, Close, Prop, prop, spinner, bind } from './util'
|
||||
import { get } from './xhr'
|
||||
|
||||
export interface Lang {
|
||||
0: string,
|
||||
0: Code,
|
||||
1: string
|
||||
}
|
||||
|
||||
export function ctrl(redraw: Redraw): LangsCtrl {
|
||||
type Code = string;
|
||||
|
||||
export interface LangsCtrl {
|
||||
data: Prop<Lang[] | undefined>
|
||||
current: Code,
|
||||
accepted: Code[],
|
||||
load(): void
|
||||
close: Close
|
||||
}
|
||||
|
||||
export function ctrl(current: Code, accepted: Code[], redraw: Redraw, close: Close): LangsCtrl {
|
||||
|
||||
const data: Prop<Lang[] | undefined> = prop(undefined);
|
||||
|
||||
return {
|
||||
data
|
||||
data,
|
||||
current,
|
||||
accepted,
|
||||
load() {
|
||||
get(window.lichess.assetUrl('/assets/trans/refs.json'), true).then(d => {
|
||||
data(d);
|
||||
redraw();
|
||||
});
|
||||
},
|
||||
close
|
||||
};
|
||||
}
|
||||
|
||||
export function view(ctrl: LangsCtrl): VNode[] {
|
||||
export function view(ctrl: LangsCtrl): VNode {
|
||||
|
||||
return [
|
||||
h('div', 'langs')
|
||||
];
|
||||
const d = ctrl.data();
|
||||
|
||||
if (!d) {
|
||||
ctrl.load();
|
||||
return spinner();
|
||||
}
|
||||
|
||||
return h('div.sub.langs', [
|
||||
h('a.head.text', {
|
||||
attrs: { 'data-icon': 'I' },
|
||||
hook: bind('click', ctrl.close)
|
||||
}, 'Language'),
|
||||
h('form', {
|
||||
attrs: { method: 'post', action: '/translation/select' }
|
||||
}, [
|
||||
h('ul', d.map(langView(ctrl.current, ctrl.accepted)))
|
||||
])
|
||||
]);
|
||||
}
|
||||
|
||||
function langView(current: Code, accepted: Code[]) {
|
||||
return (l: Lang) => h('li', [
|
||||
h('button', {
|
||||
attrs: {
|
||||
type: 'submit',
|
||||
name: 'lang',
|
||||
value: l[0]
|
||||
},
|
||||
}, l[1])
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import { h } from 'snabbdom'
|
||||
import { VNode } from 'snabbdom/vnode'
|
||||
|
||||
import { Ctrl, DasherData } from './ctrl'
|
||||
import { DasherCtrl, DasherData, Mode } from './dasher'
|
||||
import { view as pingView } from './ping'
|
||||
import { bind } from './util'
|
||||
|
||||
export default function(ctrl: Ctrl, d: DasherData): VNode[] {
|
||||
export default function(ctrl: DasherCtrl, d: DasherData): VNode {
|
||||
|
||||
const trans = ctrl.trans();
|
||||
|
||||
|
@ -28,21 +29,27 @@ export default function(ctrl: Ctrl, d: DasherData): VNode[] {
|
|||
linkCfg('/coach/edit', ':'),
|
||||
'Coach manager');
|
||||
|
||||
const langs = h(
|
||||
'a.sub',
|
||||
modeCfg(ctrl, 'langs'),
|
||||
'Language')
|
||||
|
||||
const logout = h(
|
||||
'a.text',
|
||||
linkCfg('/logout', 'w'),
|
||||
trans.noarg('logOut'));
|
||||
|
||||
return [
|
||||
return h('div', [
|
||||
h('div.links', [
|
||||
profile,
|
||||
inbox,
|
||||
prefs,
|
||||
coach,
|
||||
langs,
|
||||
logout
|
||||
]),
|
||||
pingView(ctrl.ping)
|
||||
];
|
||||
]);
|
||||
}
|
||||
|
||||
function linkCfg(href: string, icon: string, more: any = undefined): any {
|
||||
|
@ -55,3 +62,12 @@ function linkCfg(href: string, icon: string, more: any = undefined): any {
|
|||
if (more) for(let i in more) cfg.attrs[i] = more[i];
|
||||
return cfg;
|
||||
}
|
||||
|
||||
function modeCfg(ctrl: DasherCtrl, m: Mode): any {
|
||||
return {
|
||||
hook: bind('click', () => ctrl.setMode(m)),
|
||||
attrs: {
|
||||
'data-icon': 'H'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import { Redraw } from './util'
|
||||
|
||||
import { Ctrl, DasherOpts, makeCtrl } from './ctrl';
|
||||
import { DasherCtrl, DasherOpts, makeCtrl } from './dasher';
|
||||
import view from './view';
|
||||
|
||||
import { init } from 'snabbdom';
|
||||
|
@ -13,7 +13,7 @@ const patch = init([klass, attributes]);
|
|||
|
||||
export default function LichessDasher(element: Element, opts: DasherOpts) {
|
||||
|
||||
let vnode: VNode, ctrl: Ctrl
|
||||
let vnode: VNode, ctrl: DasherCtrl
|
||||
|
||||
const redraw: Redraw = () => {
|
||||
vnode = patch(vnode, view(ctrl));
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { h } from 'snabbdom'
|
||||
import { VNode } from 'snabbdom/vnode'
|
||||
|
||||
export type Redraw = () => void
|
||||
export type Close = () => void
|
||||
|
||||
export interface Prop<T> {
|
||||
(): T
|
||||
|
@ -19,7 +21,20 @@ export function prop<A>(initialValue: A): Prop<A> {
|
|||
return value;
|
||||
};
|
||||
return fun as Prop<A>;
|
||||
};
|
||||
}
|
||||
|
||||
export function bind(eventName: string, f: (e: Event) => void, redraw: Redraw | undefined = undefined) {
|
||||
return {
|
||||
insert: (vnode: VNode) => {
|
||||
(vnode.elm as HTMLElement).addEventListener(eventName, e => {
|
||||
e.stopPropagation();
|
||||
f(e);
|
||||
if (redraw) redraw();
|
||||
return false;
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function spinner() {
|
||||
return h('div.spinner', [
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import { h } from 'snabbdom'
|
||||
import { VNode } from 'snabbdom/vnode'
|
||||
|
||||
import { Ctrl } from './ctrl'
|
||||
import { DasherCtrl } from './dasher'
|
||||
import links from './links'
|
||||
import { view as langsView } from './langs'
|
||||
import { spinner } from './util'
|
||||
|
||||
export default function(ctrl: Ctrl): VNode {
|
||||
export default function(ctrl: DasherCtrl): VNode {
|
||||
let d = ctrl.data();
|
||||
let content: VNode[] | undefined;
|
||||
if (!d) content = [h('div.initiating', spinner())];
|
||||
let content: VNode | undefined;
|
||||
if (!d) content = h('div.initiating', spinner());
|
||||
else switch(ctrl.mode()) {
|
||||
case 'langs':
|
||||
content = langsView(ctrl.langs);
|
||||
|
|
|
@ -2,9 +2,10 @@ const headers = {
|
|||
'Accept': 'application/vnd.lichess.v2+json'
|
||||
};
|
||||
|
||||
export function load() {
|
||||
export function get(url: string, cache: boolean = false) {
|
||||
return $.ajax({
|
||||
url: '/dasher',
|
||||
headers: headers
|
||||
})
|
||||
url: url,
|
||||
headers: headers,
|
||||
cache: cache
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue