noImplicitAny for ui/site

pull/9418/head
Benedikt Werner 2021-07-15 16:11:31 +02:00
parent 41d9b6b3e0
commit 55c2e9b512
No known key found for this signature in database
GPG Key ID: 1DBFF0F8E9E121EB
20 changed files with 80 additions and 60 deletions

View File

@ -255,6 +255,7 @@ interface Window {
palantir?: { palantir?: {
palantir(opts: PalantirOpts): Palantir; palantir(opts: PalantirOpts): Palantir;
}; };
LichessChat(element: Element, opts: any): unknown;
[key: string]: any; // TODO [key: string]: any; // TODO
} }
@ -275,6 +276,10 @@ interface LightUser extends LightUserNoId {
id: string; id: string;
} }
interface LightUserOnline extends LightUser {
online: boolean;
}
interface Navigator { interface Navigator {
deviceMemory?: number; // https://developer.mozilla.org/en-US/docs/Web/API/Navigator/deviceMemory deviceMemory?: number; // https://developer.mozilla.org/en-US/docs/Web/API/Navigator/deviceMemory
} }

View File

@ -12,7 +12,10 @@ function init() {
$input = $captcha.find('input').val(''), $input = $captcha.find('input').val(''),
cg = domData.get($board[0]!, 'chessground'); cg = domData.get($board[0]!, 'chessground');
if (!cg) return (failed = true); if (!cg) {
failed = true;
return;
}
const fen = cg.getFen(), const fen = cg.getFen(),
destsObj = $board.data('moves'), destsObj = $board.data('moves'),

View File

@ -4,6 +4,8 @@ import { loadScript } from './component/assets';
import extendTablesortNumber from './component/tablesort-number'; import extendTablesortNumber from './component/tablesort-number';
import * as xhr from 'common/xhr'; import * as xhr from 'common/xhr';
import type { Result as UserCompleteResult } from './userComplete';
lichess.load.then(() => { lichess.load.then(() => {
$('table.sortable').each(function (this: HTMLElement) { $('table.sortable').each(function (this: HTMLElement) {
tablesort(this, { tablesort(this, {
@ -47,14 +49,14 @@ lichess.load.then(() => {
}) })
) )
.then( .then(
res => { (res: UserCompleteResult) => {
const current = currentUserIds(); const current = currentUserIds();
callback(res.result.filter(t => !current.includes(t.id))); callback(res.result.filter(t => !current.includes(t.id)));
}, },
_ => callback([]) _ => callback([])
); );
}, },
template: o => template: (o: LightUserOnline) =>
'<span class="ulpt user-link' + '<span class="ulpt user-link' +
(o.online ? ' online' : '') + (o.online ? ' online' : '') +
'" href="/@/' + '" href="/@/' +
@ -66,7 +68,7 @@ lichess.load.then(() => {
(o.title ? '<span class="utitle">' + o.title + '</span>&nbsp;' : '') + (o.title ? '<span class="utitle">' + o.title + '</span>&nbsp;' : '') +
o.name + o.name +
'</span>', '</span>',
replace: o => '$1' + o.name + '\n', replace: (o: LightUserOnline) => '$1' + o.name + '\n',
}, },
]); ]);

View File

@ -1,10 +1,10 @@
import { loadCssPath } from './assets'; import { loadCssPath } from './assets';
const chat = data => const chat = (data: any) =>
new Promise(resolve => new Promise(resolve =>
requestAnimationFrame(() => { requestAnimationFrame(() => {
data.loadCss = loadCssPath; data.loadCss = loadCssPath;
resolve(window.LichessChat(document.querySelector('.mchat'), data)); resolve(window.LichessChat(document.querySelector('.mchat')!, data));
}) })
); );

View File

@ -30,7 +30,9 @@ export default class OnlineFriends {
this.trans = trans(JSON.parse(this.el.getAttribute('data-i18n')!)); this.trans = trans(JSON.parse(this.el.getAttribute('data-i18n')!));
this.users = new Map(); this.users = new Map();
pubsub.on('socket.in.following_onlines', this.receive); pubsub.on('socket.in.following_onlines', this.receive);
['enters', 'leaves', 'playing', 'stopped_playing'].forEach(k => pubsub.on('socket.in.following_' + k, this[k])); (['enters', 'leaves', 'playing', 'stopped_playing'] as const).forEach(k =>
pubsub.on('socket.in.following_' + k, this[k])
);
} }
receive = (friends: TitleName[], msg: { playing: string[]; patrons: string[] }) => { receive = (friends: TitleName[], msg: { playing: string[]; patrons: string[] }) => {
this.users.clear(); this.users.clear();

View File

@ -7,12 +7,12 @@ export default function moduleLaunchers() {
else if (li.study || li.practice || li.relay) startAnalyse(li.study || li.practice || li.relay); else if (li.study || li.practice || li.relay) startAnalyse(li.study || li.practice || li.relay);
} }
function startUserAnalysis(cfg) { function startUserAnalysis(cfg: any) {
cfg.$side = $('.analyse__side').clone(); cfg.$side = $('.analyse__side').clone();
startAnalyse(cfg); startAnalyse(cfg);
} }
function startAnalyse(cfg) { function startAnalyse(cfg: any) {
lichess.socket = new StrongSocket(cfg.socketUrl || '/analysis/socket/v5', cfg.socketVersion, { lichess.socket = new StrongSocket(cfg.socketUrl || '/analysis/socket/v5', cfg.socketVersion, {
receive: (t: string, d: any) => analyse.socketReceive(t, d), receive: (t: string, d: any) => analyse.socketReceive(t, d),
}); });

View File

@ -1,21 +1,21 @@
const subs: Array<() => void> = []; const subs: Dictionary<(() => void)[]> = Object.create(null);
const pubsub: Pubsub = { const pubsub: Pubsub = {
on(name: string, cb) { on(name: string, cb) {
subs[name] = subs[name] || []; (subs[name] = subs[name] || []).push(cb);
subs[name].push(cb);
}, },
off(name: string, cb) { off(name: string, cb) {
if (subs[name]) const cbs = subs[name];
for (const i in subs[name]) { if (cbs)
if (subs[name][i] === cb) { for (const i in cbs) {
subs[name].splice(i); if (cbs[i] === cb) {
cbs.splice(+i);
break; break;
} }
} }
}, },
emit(name: string, ...args: any[]) { emit(name: string, ...args: any[]) {
if (subs[name]) for (const i in subs[name]) subs[name][i].apply(null, args); for (const fn of subs[name] || []) fn.apply(null, args);
}, },
}; };

View File

@ -1,15 +1,20 @@
let redirectInProgress: false | string = false; let redirectInProgress: false | string = false;
export const redirect = obj => { interface Opts {
let url; url: string;
if (typeof obj == 'string') url = obj; cookie: Cookie;
}
export const redirect = (opts: string | Opts) => {
let url: string;
if (typeof opts == 'string') url = opts;
else { else {
url = obj.url; url = opts.url;
if (obj.cookie) { if (opts.cookie) {
const domain = document.domain.replace(/^.+(\.[^.]+\.[^.]+)$/, '$1'); const domain = document.domain.replace(/^.+(\.[^.]+\.[^.]+)$/, '$1');
const cookie = [ const cookie = [
encodeURIComponent(obj.cookie.name) + '=' + obj.cookie.value, encodeURIComponent(opts.cookie.name) + '=' + opts.cookie.value,
'; max-age=' + obj.cookie.maxAge, '; max-age=' + opts.cookie.maxAge,
'; path=/', '; path=/',
'; domain=' + domain, '; domain=' + domain,
].join(''); ].join('');

View File

@ -21,11 +21,11 @@ export default function () {
const store = storage.make('push-subscribed'); const store = storage.make('push-subscribed');
const vapid = document.body.getAttribute('data-vapid'); const vapid = document.body.getAttribute('data-vapid');
if (vapid && Notification.permission == 'granted') if (vapid && Notification.permission == 'granted')
return reg.pushManager.getSubscription().then(sub => { reg.pushManager.getSubscription().then(sub => {
const resub = parseInt(store.get() || '0', 10) + 43200000 < Date.now(); // 12 hours const resub = parseInt(store.get() || '0', 10) + 43200000 < Date.now(); // 12 hours
const applicationServerKey = Uint8Array.from(atob(vapid), c => c.charCodeAt(0)); const applicationServerKey = Uint8Array.from(atob(vapid), c => c.charCodeAt(0));
if (!sub || resub) { if (!sub || resub) {
return reg.pushManager reg.pushManager
.subscribe({ .subscribe({
userVisibleOnly: true, userVisibleOnly: true,
applicationServerKey: applicationServerKey, applicationServerKey: applicationServerKey,

View File

@ -36,7 +36,7 @@ export default function () {
{ {
// challengeApp // challengeApp
let instance, booted: boolean; let instance: any, booted: boolean;
const $toggle = $('#challenge-toggle'); const $toggle = $('#challenge-toggle');
$toggle.one('mouseover click', () => load()); $toggle.one('mouseover click', () => load());
const load = function (data?: any) { const load = function (data?: any) {
@ -69,7 +69,7 @@ export default function () {
{ {
// notifyApp // notifyApp
let instance, booted: boolean; let instance: any, booted: boolean;
const $toggle = $('#notify-toggle'), const $toggle = $('#notify-toggle'),
selector = '#notify-app'; selector = '#notify-app';

View File

@ -21,10 +21,13 @@ export default function watchers(element: HTMLElement) {
lichess.pubsub.on('socket.in.crowd', data => set(data.watchers || data)); lichess.pubsub.on('socket.in.crowd', data => set(data.watchers || data));
const set = (data: Data) => { const set = (data: Data): void => {
watchersData = data; watchersData = data;
if (!data || !data.nb) return $element.addClass('none'); if (!data || !data.nb) {
$element.addClass('none');
return;
}
$numberEl.text('' + data.nb); $numberEl.text('' + data.nb);

View File

@ -1,7 +1,7 @@
import * as data from 'common/data'; import * as data from 'common/data';
const widget = (name: string, prototype: any) => { const widget = (name: string, prototype: any) => {
const constructor = ($[name] = function (options: any, element: HTMLElement) { const constructor: any = (($ as any)[name] = function (options: any, element: HTMLElement) {
const self: any = this; const self: any = this;
self.element = $(element); self.element = $(element);
(element as any)[name] = this; (element as any)[name] = this;
@ -9,7 +9,7 @@ const widget = (name: string, prototype: any) => {
self._create(); self._create();
}); });
constructor.prototype = prototype; constructor.prototype = prototype;
$.fn[name] = function (method: string) { ($.fn as any)[name] = function (method: string) {
const args = Array.prototype.slice.call(arguments, 1); const args = Array.prototype.slice.call(arguments, 1);
if (typeof method === 'string') if (typeof method === 'string')
this.each(function (this: HTMLElement) { this.each(function (this: HTMLElement) {

View File

@ -3,6 +3,7 @@ import { sparkline } from '@fnando/sparkline';
import throttle from 'common/throttle'; import throttle from 'common/throttle';
import resizeHandle from 'common/resize'; import resizeHandle from 'common/resize';
import * as cg from 'chessground/types'; import * as cg from 'chessground/types';
import { Api as ChessgroundApi } from 'chessground/api';
type CoordModifier = 'new' | 'next' | 'current' | 'resolved'; type CoordModifier = 'new' | 'next' | 'current' | 'resolved';
@ -12,7 +13,7 @@ lichess.load.then(() => {
const $board = $('.coord-trainer__board .cg-wrap'); const $board = $('.coord-trainer__board .cg-wrap');
const $coordsSvg = $('.coords-svg'); const $coordsSvg = $('.coords-svg');
const $coordTexts = $coordsSvg.find('.coord text'); const $coordTexts = $coordsSvg.find('.coord text');
let ground; let ground: ChessgroundApi;
const $side = $('.coord-trainer__side'); const $side = $('.coord-trainer__side');
const $right = $('.coord-trainer__table'); const $right = $('.coord-trainer__table');
const $bar = $trainer.find('.progress_bar'); const $bar = $trainer.find('.progress_bar');
@ -25,9 +26,9 @@ lichess.load.then(() => {
const tickDelay = 50; const tickDelay = 50;
const resizePref = $trainer.data('resize-pref'); const resizePref = $trainer.data('resize-pref');
let colorPref = $trainer.data('color-pref'); let colorPref = $trainer.data('color-pref');
let color; let color: Color;
let startAt, score; let startAt: Date, score: number;
let wrongTimeout; let wrongTimeout: number;
let ply = 0; let ply = 0;
const showColor = function () { const showColor = function () {
@ -127,7 +128,7 @@ lichess.load.then(() => {
$coordTexts.text(''); $coordTexts.text('');
}; };
const newCoord = function (prevCoord) { const newCoord = function (prevCoord: Key): Key {
// disallow the previous coordinate's row or file from being selected // disallow the previous coordinate's row or file from being selected
let files = 'abcdefgh'; let files = 'abcdefgh';
const fileIndex = files.indexOf(prevCoord[0]); const fileIndex = files.indexOf(prevCoord[0]);
@ -137,9 +138,8 @@ lichess.load.then(() => {
const rowIndex = rows.indexOf(prevCoord[1]); const rowIndex = rows.indexOf(prevCoord[1]);
rows = rows.slice(0, rowIndex) + rows.slice(rowIndex + 1, 8); rows = rows.slice(0, rowIndex) + rows.slice(rowIndex + 1, 8);
return ( return (files[Math.round(Math.random() * (files.length - 1))] +
files[Math.round(Math.random() * (files.length - 1))] + rows[Math.round(Math.random() * (rows.length - 1))] rows[Math.round(Math.random() * (rows.length - 1))]) as Key;
);
}; };
const coordClass = (modifier: CoordModifier) => `coord--${modifier}`; const coordClass = (modifier: CoordModifier) => `coord--${modifier}`;
@ -152,7 +152,7 @@ lichess.load.then(() => {
coordEl('current').removeClass(coordClass('current')).addClass(coordClass('resolved')); coordEl('current').removeClass(coordClass('current')).addClass(coordClass('resolved'));
coordEl('next').removeClass(coordClass('next')).addClass(coordClass('current')); coordEl('next').removeClass(coordClass('next')).addClass(coordClass('current'));
coordTextEl('new').text(newCoord(coordTextEl('current').text())); coordTextEl('new').text(newCoord(coordTextEl('current').text() as Key));
coordEl('new').removeClass(coordClass('new')).addClass(coordClass('next')); coordEl('new').removeClass(coordClass('new')).addClass(coordClass('next'));
resolvedEl.removeClass(coordClass('resolved')).addClass(coordClass('new')).appendTo($coordsSvg); resolvedEl.removeClass(coordClass('resolved')).addClass(coordClass('new')).appendTo($coordsSvg);
@ -165,7 +165,7 @@ lichess.load.then(() => {
$trainer.removeClass('wrong'); $trainer.removeClass('wrong');
ground.set({ ground.set({
events: { events: {
select: false, select: undefined,
}, },
}); });
if (scoreUrl) if (scoreUrl)
@ -181,7 +181,7 @@ lichess.load.then(() => {
}; };
const tick = function () { const tick = function () {
const spent = Math.min(duration, new Date().getTime() - startAt); const spent = Math.min(duration, new Date().getTime() - +startAt);
const left = ((duration - spent) / 1000).toFixed(1); const left = ((duration - spent) / 1000).toFixed(1);
if (+left < 10) { if (+left < 10) {
$timer.addClass('hurry'); $timer.addClass('hurry');
@ -203,7 +203,7 @@ lichess.load.then(() => {
clearCoords(); clearCoords();
centerRight(); centerRight();
score = 0; score = 0;
$score.text(score); $score.text(score.toString());
$bar.css('width', 0); $bar.css('width', 0);
setTimeout(function () { setTimeout(function () {
startAt = new Date(); startAt = new Date();
@ -213,7 +213,7 @@ lichess.load.then(() => {
const hit = key == coordEl('current').text(); const hit = key == coordEl('current').text();
if (hit) { if (hit) {
score++; score++;
$score.text(score); $score.text(score.toString());
advanceCoords(); advanceCoords();
} else { } else {
clearTimeout(wrongTimeout); clearTimeout(wrongTimeout);

View File

@ -57,7 +57,7 @@ lichess.load.then(() => {
[ [
{ {
match: /(^|\s)@(|[a-zA-Z_-][\w-]{0,19})$/, match: /(^|\s)@(|[a-zA-Z_-][\w-]{0,19})$/,
search: function (term: string, callback) { search: function (term: string, callback: (names: string[]) => void) {
// Initially we only autocomplete by participants in the thread. As the user types more, // Initially we only autocomplete by participants in the thread. As the user types more,
// we can autocomplete against all users on the site. // we can autocomplete against all users on the site.
threadParticipants.then(function (participants) { threadParticipants.then(function (participants) {
@ -77,7 +77,7 @@ lichess.load.then(() => {
} }
}); });
}, },
replace: mention => '$1@' + mention + ' ', replace: (mention: string) => '$1@' + mention + ' ',
}, },
], ],
{ {

View File

@ -14,9 +14,9 @@ lichess.load.then(() => {
return us; return us;
} }
function userChoices(row) { function userChoices(row: HTMLTableRowElement) {
const options = ["<option value=''></option>"]; const options = ["<option value=''></option>"];
const isSelected = function (row, rowClassName, user, dataKey) { const isSelected = function (row: HTMLTableRowElement, rowClassName: string, user: string, dataKey: string) {
const player = $form.data(dataKey); const player = $form.data(dataKey);
return row.classList.contains(rowClassName) && player.length && user == player ? 'selected' : ''; return row.classList.contains(rowClassName) && player.length && user == player ? 'selected' : '';
}; };

View File

@ -74,7 +74,7 @@ export function queues(data: any) {
const cfg = merge( const cfg = merge(
{ {
...conf(room.name, data.common.xaxis), ...conf(room.name, data.common.xaxis),
series: room.series.map(s => ({ series: room.series.map((s: any) => ({
...s, ...s,
name: `Score: ${s.name}`, name: `Score: ${s.name}`,
})), })),

View File

@ -23,9 +23,9 @@ lichess.load.then(() => {
id: 'team', id: 'team',
match: /(^|\s)(.+)$/, match: /(^|\s)(.+)$/,
index: 2, index: 2,
search(term: string, callback: (res: any[]) => void) { search(term: string, callback: (res: Team[]) => void) {
xhr.json(xhr.url('/team/autocomplete', { term }), { cache: 'default' }).then( xhr.json(xhr.url('/team/autocomplete', { term }), { cache: 'default' }).then(
res => { (res: Team[]) => {
const current = textarea.value const current = textarea.value
.split('\n') .split('\n')
.map(t => t.split(' ')[0]) .map(t => t.split(' ')[0])

View File

@ -2,16 +2,16 @@ import * as xhr from 'common/xhr';
import complete from 'common/complete'; import complete from 'common/complete';
import debounce from 'debounce-promise'; import debounce from 'debounce-promise';
interface Result extends LightUser { export interface Result {
online: boolean; result: LightUserOnline[];
} }
interface Opts { interface Opts {
input: HTMLInputElement; input: HTMLInputElement;
tag?: 'a' | 'span'; tag?: 'a' | 'span';
minLength?: number; minLength?: number;
populate?: (result: Result) => string; populate?: (result: LightUserOnline) => string;
onSelect?: (result: Result) => void; onSelect?: (result: LightUserOnline) => void;
focus?: boolean; focus?: boolean;
friend?: boolean; friend?: boolean;
tour?: string; tour?: string;
@ -31,14 +31,14 @@ export default function (opts: Opts): void {
object: 1, object: 1,
}) })
) )
.then(r => ({ term, ...r })), .then((r: Result) => ({ term, ...r })),
150 150
); );
complete<Result>({ complete<LightUserOnline>({
input: opts.input, input: opts.input,
fetch: t => debounced(t).then(({ term, result }) => (t == term ? result : Promise.reject('Debounced ' + t))), fetch: t => debounced(t).then(({ term, result }) => (t == term ? result : Promise.reject('Debounced ' + t))),
render(o: Result) { render(o: LightUserOnline) {
const tag = opts.tag || 'a'; const tag = opts.tag || 'a';
return ( return (
'<' + '<' +

View File

@ -1,7 +1,6 @@
{ {
"extends": "../tsconfig.base.json", "extends": "../tsconfig.base.json",
"compilerOptions": { "compilerOptions": {
"noImplicitAny": false,
"noImplicitReturns": false, "noImplicitReturns": false,
"esModuleInterop": true "esModuleInterop": true
} }

1
ui/site/types/tablesort.d.ts vendored 100644
View File

@ -0,0 +1 @@
declare module 'tablesort';