user-complete refactors, challenge complete
parent
f007638922
commit
eedbf9e0bc
|
@ -69,7 +69,10 @@ object mine {
|
|||
ctx.isAuth option div(
|
||||
h2(cls := "ninja-title", "Or invite a Lichess user:"),
|
||||
br,
|
||||
postForm(cls := "user-invite", action := routes.Challenge.toFriend(c.id))(
|
||||
postForm(
|
||||
cls := "user-invite complete-parent",
|
||||
action := routes.Challenge.toFriend(c.id)
|
||||
)(
|
||||
input(
|
||||
name := "username",
|
||||
cls := "friend-autocomplete",
|
||||
|
|
|
@ -16,6 +16,7 @@ interface Lichess {
|
|||
jsModule(name: string): string;
|
||||
loadScript(url: string, opts?: AssetUrlOpts): Promise<void>;
|
||||
hopscotch: any;
|
||||
userComplete: () => Promise<UserComplete>;
|
||||
slider(): Promise<void>;
|
||||
makeChat(data: any): any;
|
||||
idleTimer(delay: number, onIdle: () => void, onWakeUp: () => void): void;
|
||||
|
@ -35,7 +36,6 @@ interface Lichess {
|
|||
socket: any;
|
||||
sound: any;
|
||||
soundBox: SoundBoxI;
|
||||
userAutocomplete($input: Cash, opts?: UserAutocompleteOpts): Promise<void>;
|
||||
miniBoard: {
|
||||
init(node: HTMLElement): void;
|
||||
initAll(): void;
|
||||
|
@ -81,10 +81,13 @@ interface Lichess {
|
|||
|
||||
type RedirectTo = string | { url: string, cookie: Cookie };
|
||||
|
||||
interface UserAutocompleteOpts {
|
||||
type UserComplete = (opts: UserCompleteOpts) => void;
|
||||
|
||||
interface UserCompleteOpts {
|
||||
input: HTMLInputElement,
|
||||
tag?: 'a' | 'span';
|
||||
minLength?: number;
|
||||
select?: (value: string | { id: string; name: string }) => string;
|
||||
select?: (result: LightUser) => string;
|
||||
focus?: boolean;
|
||||
friend?: boolean;
|
||||
tour?: string;
|
||||
|
|
|
@ -5,8 +5,8 @@ const li = window.lichess;
|
|||
export function app($wrap: Cash, toggle: () => void) {
|
||||
const $input = $wrap.find('input');
|
||||
|
||||
li.loadScript(li.jsModule('user-autocomplete')).then(() => {
|
||||
window.LichessUserAutocomplete({
|
||||
li.userComplete().then(uac => {
|
||||
uac({
|
||||
input: $input[0] as HTMLInputElement,
|
||||
friend: true,
|
||||
focus: true
|
||||
|
|
|
@ -54,7 +54,12 @@ export default function <Result>(opts: Opts<Result>) {
|
|||
results.forEach(result =>
|
||||
$(opts.render(result))
|
||||
.on('click', () => {
|
||||
opts.input.value = opts.select(result);
|
||||
/* crazy shit here
|
||||
just `opts.input.value = opts.select(result);`
|
||||
does nothing. `opts.select` is not called.
|
||||
*/
|
||||
const newValue = opts.select(result);
|
||||
opts.input.value = newValue;
|
||||
return true;
|
||||
})
|
||||
.appendTo($container)
|
||||
|
|
|
@ -158,9 +158,9 @@ export default rollupProject({
|
|||
input: 'src/gameSearch.ts',
|
||||
output: 'game-search'
|
||||
},
|
||||
userAutocomplete: {
|
||||
input: 'src/user-autocomplete.ts',
|
||||
output: 'user-autocomplete',
|
||||
name: 'LichessUserAutocomplete'
|
||||
userComplete: {
|
||||
input: 'src/user-complete.ts',
|
||||
output: 'user-complete',
|
||||
name: 'UserComplete'
|
||||
}
|
||||
});
|
||||
|
|
|
@ -22,6 +22,7 @@ export default function(opts: ChallengeOpts) {
|
|||
xhr.text(opts.xhrUrl).then(html => {
|
||||
$(selector).replaceWith($(html).find(selector));
|
||||
init();
|
||||
li.pubsub.emit('content_loaded', $(selector));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -41,15 +42,19 @@ export default function(opts: ChallengeOpts) {
|
|||
$(this).html('<span class="ddloader"></span>');
|
||||
});
|
||||
$(selector).find('input.friend-autocomplete').each(function(this: HTMLInputElement) {
|
||||
const $input = $(this);
|
||||
li.userAutocomplete($input, {
|
||||
focus: true,
|
||||
friend: true,
|
||||
tag: 'span',
|
||||
onSelect() {
|
||||
$input.parents('form').trigger('submit');
|
||||
}
|
||||
});
|
||||
const input = this;
|
||||
li.userComplete().then(uac =>
|
||||
uac({
|
||||
input: input,
|
||||
friend: true,
|
||||
tag: 'span',
|
||||
focus: true,
|
||||
select: r => {
|
||||
setTimeout(() => (input.parentNode as HTMLFormElement).submit(), 100);
|
||||
return r.name;
|
||||
}
|
||||
})
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -9,8 +9,7 @@ export const assetUrl = (path: string, opts: AssetUrlOpts = {}) => {
|
|||
|
||||
export const soundUrl = assetUrl('sound', { version: '000003' });
|
||||
|
||||
const loadedCss = new Map();
|
||||
|
||||
const loadedCss = new Map<string, true>();
|
||||
export const loadCss = (url: string) => {
|
||||
if (!loadedCss.has(url)) {
|
||||
loadedCss.set(url, true);
|
||||
|
@ -27,8 +26,16 @@ export const loadCssPath = (key: string) =>
|
|||
export const jsModule = (name: string) =>
|
||||
`compiled/${name}${$('body').data('dev') ? '' : '.min'}.js`;
|
||||
|
||||
export const loadScript = (url: string, opts: AssetUrlOpts = {}): Promise<void> =>
|
||||
xhr.script(assetUrl(url, opts));
|
||||
const loadedScript = new Map<string, Promise<void>>();
|
||||
export const loadScript = (url: string, opts: AssetUrlOpts = {}): Promise<void> => {
|
||||
if (!loadedScript.has(url)) loadedScript.set(url, xhr.script(assetUrl(url, opts)));
|
||||
return loadedScript.get(url)!;
|
||||
}
|
||||
|
||||
export const userComplete = (): Promise<UserComplete> => {
|
||||
loadCssPath('complete');
|
||||
return loadScript(jsModule('user-complete')).then(_ => window.UserComplete);
|
||||
}
|
||||
|
||||
export const hopscotch = () => {
|
||||
loadCss('vendor/hopscotch/dist/css/hopscotch.min.css');
|
||||
|
|
|
@ -6,7 +6,7 @@ import spinnerHtml from './component/spinner';
|
|||
import sri from './component/sri';
|
||||
import { storage, tempStorage } from "./component/storage";
|
||||
import powertip from "./component/powertip";
|
||||
import { assetUrl, soundUrl, loadCss, loadCssPath, jsModule, loadScript, hopscotch } from "./component/assets";
|
||||
import { assetUrl, soundUrl, loadCss, loadCssPath, jsModule, loadScript, hopscotch, userComplete } from "./component/assets";
|
||||
import widget from "./component/widget";
|
||||
import idleTimer from "./component/idle-timer";
|
||||
import pubsub from "./component/pubsub";
|
||||
|
@ -38,6 +38,7 @@ export default function() {
|
|||
l.jsModule = jsModule;
|
||||
l.loadScript = loadScript;
|
||||
l.hopscotch = hopscotch;
|
||||
l.userComplete = userComplete;
|
||||
l.makeChat = makeChat;
|
||||
l.idleTimer = idleTimer;
|
||||
l.pubsub = pubsub;
|
||||
|
|
|
@ -13,7 +13,7 @@ import timeago from "./component/timeago";
|
|||
import topBar from "./component/top-bar";
|
||||
import loadInfiniteScroll from "./component/infinite-scroll";
|
||||
import { storage } from "./component/storage";
|
||||
import { assetUrl } from "./component/assets";
|
||||
import { assetUrl, userComplete } from "./component/assets";
|
||||
import serviceWorker from "./component/service-worker";
|
||||
import loadClockWidget from "./component/clock-widget";
|
||||
import info from "./component/info";
|
||||
|
@ -81,14 +81,14 @@ li.load.then(() => {
|
|||
|
||||
$('.user-autocomplete').each(function(this: HTMLInputElement) {
|
||||
const focus = !!this.autofocus;
|
||||
const start = () => li.loadScript(li.jsModule('user-autocomplete')).then(() => {
|
||||
window.LichessUserAutocomplete({
|
||||
const start = () => userComplete().then(uac =>
|
||||
uac({
|
||||
input: this,
|
||||
friend: $(this).data('friend'),
|
||||
tag: $(this).data('tag'),
|
||||
focus
|
||||
});
|
||||
});
|
||||
})
|
||||
);
|
||||
if (focus) start();
|
||||
else $(this).one('focus', start);
|
||||
});
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { loadCssPath } from "./component/assets";
|
||||
import debounce from 'debounce-promise';
|
||||
import * as xhr from 'common/xhr';
|
||||
import complete from 'common/complete';
|
||||
|
@ -18,9 +17,7 @@ interface Opts {
|
|||
swiss?: string;
|
||||
}
|
||||
|
||||
export default function(opts: Opts) {
|
||||
|
||||
loadCssPath('complete');
|
||||
export default function(opts: Opts): void {
|
||||
|
||||
complete<Result>({
|
||||
input: opts.input,
|
Loading…
Reference in New Issue