ui: pageLoader: support moduleName

This commit is contained in:
undefined committed 2022-03-15 13:59:16 +08:00
1 parent 0569a98739
commit ab3cad57b8
6 files changed
+56 -33

No files matched your search

+4 -2
View File
@@ -8,16 +8,18 @@ export async function inc(op: string, ident: string, periodSecs: number, maxOper
const now = new Date().getTime(); const now = new Date().getTime();
const expireAt = new Date(now - (now % (periodSecs * 1000)) + periodSecs * 1000); const expireAt = new Date(now - (now % (periodSecs * 1000)) + periodSecs * 1000);
try { try {
await coll.findOneAndUpdate({ const res = await coll.findOneAndUpdate({
op, op,
ident, ident,
expireAt, expireAt,
opcount: { $lt: maxOperations }, opcount: { $lt: maxOperations },
}, { $inc: { opcount: 1 } }, { upsert: true }); }, { $inc: { opcount: 1 } }, { upsert: true, returnDocument: 'after' });
return res.value.opcount;
} catch (e) { } catch (e) {
if (e.message.includes('duplicate')) throw new OpcountExceededError(op, periodSecs, maxOperations); if (e.message.includes('duplicate')) throw new OpcountExceededError(op, periodSecs, maxOperations);
throw e; throw e;
} }
return -1;
} }
bus.once('app/started', () => db.ensureIndexes( bus.once('app/started', () => db.ensureIndexes(
@@ -55,16 +55,15 @@ export default function reducer(state = {
case 'SCRATCHPAD_POST_SUBMIT_PENDING': { case 'SCRATCHPAD_POST_SUBMIT_PENDING': {
return { return {
...state, ...state,
records: {
...state.records,
visible: true,
},
isPosting: true, isPosting: true,
}; };
} }
case 'SCRATCHPAD_POST_PRETEST_FULFILLED': case 'SCRATCHPAD_POST_PRETEST_FULFILLED':
case 'SCRATCHPAD_POST_SUBMIT_FULFILLED': { case 'SCRATCHPAD_POST_SUBMIT_FULFILLED': {
Notification.success(i18n('Submitted.')); Notification.success(i18n('Submitted.'));
if (action.type === 'SCRATCHPAD_POST_SUBMIT_FULFILLED') {
state.records.visible = true;
}
return { return {
...state, ...state,
isPosting: false, isPosting: false,
+13 -4
View File
@@ -50,10 +50,19 @@ async function load() {
...buildSequence(includedPages, 'after'), ...buildSequence(includedPages, 'after'),
...buildSequence(currentPage, 'after'), ...buildSequence(currentPage, 'after'),
]; ];
const loadPage = (depth: number, type: 'before' | 'after') => async (name: string) => {
if (depth > 32) {
console.error('loadPage depth', depth);
return;
}
for (const { func } of buildSequence(pageLoader.getPage(name), type)) {
await func(name, loadPage(depth + 1, type));
}
};
for (const { page, func, type } of loadSequence) { for (const { page, func, type } of loadSequence) {
const ts = new Date().getTime(); const ts = Date.now();
try { try {
await func(currentPageName); await func(currentPageName, loadPage(1, type));
} catch (e) { } catch (e) {
Notification.warn(`Failed to call '${type}Loading' of ${page.name}`); Notification.warn(`Failed to call '${type}Loading' of ${page.name}`);
console.error(`Failed to call '${type}Loading' of ${page.name}\n${e.stack}`); console.error(`Failed to call '${type}Loading' of ${page.name}\n${e.stack}`);
@@ -61,7 +70,7 @@ async function load() {
if (process.env.NODE_ENV !== 'production') { if (process.env.NODE_ENV !== 'production') {
console.time(`${page.name}: ${type}Loading`); console.time(`${page.name}: ${type}Loading`);
} }
const time = new Date().getTime() - ts; const time = Date.now() - ts;
if ((process.env.NODE_ENV !== 'production' && time > 16) || time > 256) { if ((process.env.NODE_ENV !== 'production' && time > 16) || time > 256) {
console.log(`${page.name}: ${type}Loading took ${time}ms`); console.log(`${page.name}: ${type}Loading took ${time}ms`);
} }
@@ -71,7 +80,7 @@ async function load() {
$element: $(section), $element: $(section),
})); }));
$('.page-loader').hide(); $('.page-loader').hide();
console.log('done! %d ms', new Date().getTime() - start.getTime()); console.log('done! %d ms', Date.now() - start.getTime());
for (const { $element, shouldDelay } of sections) { for (const { $element, shouldDelay } of sections) {
$element.addClass('visible'); $element.addClass('visible');
if (shouldDelay) await delay(50); if (shouldDelay) await delay(50);
+23 -10
View File
@@ -1,15 +1,29 @@
type callback = (pagename: string, loadPage: (name: string) => Promise<any>) => any;
export class Page { export class Page {
constructor(public name: string | string[], public autoload: boolean, public afterLoading, public beforeLoading) { moduleName?: string;
autoload = false;
afterLoading?: callback;
beforeLoading?: callback;
constructor(pagename: string | string[], afterLoading: callback, beforeLoading: callback);
constructor(pagename: string | string[], moduleName: string, afterLoading: callback, beforeLoading: callback);
constructor(pagename: string | string[], ...args: any[]);
constructor(public name: string | string[], ...args: any[]) {
if (typeof args[0] === 'string') {
[this.moduleName, this.afterLoading, this.beforeLoading] = args;
} else {
[this.afterLoading, this.beforeLoading] = args;
}
if (process.env.NODE_ENV !== 'production') { if (process.env.NODE_ENV !== 'production') {
if (typeof name !== 'string' && !(name instanceof Array)) { if (typeof name !== 'string' && !(name instanceof Array)) {
// eslint-disable-next-line quotes // eslint-disable-next-line quotes
throw new Error(`'name' should be a string or string[]`); throw new Error(`'name' should be a string or string[]`);
} }
if (typeof afterLoading !== 'function' && afterLoading != null) { if (typeof this.afterLoading !== 'function' && this.afterLoading != null) {
// eslint-disable-next-line quotes // eslint-disable-next-line quotes
throw new Error(`'afterLoading' should be a function`); throw new Error(`'afterLoading' should be a function`);
} }
if (typeof beforeLoading !== 'function' && beforeLoading != null) { if (typeof this.beforeLoading !== 'function' && this.beforeLoading != null) {
// eslint-disable-next-line quotes // eslint-disable-next-line quotes
throw new Error(`'beforeLoading' should be a function`); throw new Error(`'beforeLoading' should be a function`);
} }
@@ -23,15 +37,14 @@ export class Page {
} }
} }
export class NamedPage extends Page { export class NamedPage extends Page { }
constructor(name: string | string[], afterLoading: (pagename: string) => any = null, beforeLoading = null) {
super(name, false, afterLoading, beforeLoading);
}
}
export class AutoloadPage extends Page { export class AutoloadPage extends Page {
constructor(name: string | string[], afterLoading: (pagename: string) => any = null, beforeLoading = null) { constructor(pagename: string | string[], afterLoading: callback, beforeLoading: callback);
super(name, true, afterLoading, beforeLoading); constructor(pagename: string | string[], moduleName: string, afterLoading: callback, beforeLoading: callback);
constructor(pagename: string | string[], ...args: any[]) {
super(pagename, ...args);
this.autoload = true;
} }
} }
+12 -12
View File
@@ -5,18 +5,14 @@ export default class PageLoader {
const pages = require.context('../pages/', true, /\.page\.[jt]sx?$/i); const pages = require.context('../pages/', true, /\.page\.[jt]sx?$/i);
const components = require.context('../components/', true, /\.page\.[jt]sx?$/i); const components = require.context('../components/', true, /\.page\.[jt]sx?$/i);
this.pageInstances = [ this.pageInstances = [
...pages.keys().map((key) => { ...pages.keys().map((key) => pages(key)),
const page = pages(key).default; ...components.keys().map((key) => components(key)),
if (!page || !(page instanceof Page)) return null; ...window.Hydro.extraPages,
return page; ].map((page) => {
}), page = page?.default || page;
...components.keys().map((key) => { if (!page || !(page instanceof Page)) return null;
const page = components(key).default; return page;
if (!page || !(page instanceof Page)) return null; }).filter((i) => i);
return page;
}),
];
if (window.Hydro.extraPages) this.pageInstances.push(...window.Hydro.extraPages.filter((i) => i instanceof Page));
window.Hydro.pageInstances = this.pageInstances; window.Hydro.pageInstances = this.pageInstances;
window.Hydro.extraPages.filter((i) => !(i instanceof Page)).forEach((i) => i()); window.Hydro.extraPages.filter((i) => !(i instanceof Page)).forEach((i) => i());
} }
@@ -28,4 +24,8 @@ export default class PageLoader {
getNamedPage(pageName) { getNamedPage(pageName) {
return this.pageInstances.filter((page) => page && page.isNameMatch(pageName)); return this.pageInstances.filter((page) => page && page.isNameMatch(pageName));
} }
getPage(moduleName) {
return this.pageInstances.filter((page) => page && page.moduleName === moduleName);
}
} }
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@hydrooj/ui-default", "name": "@hydrooj/ui-default",
"version": "4.34.5", "version": "4.34.6",
"author": "undefined <i@undefined.moe>", "author": "undefined <i@undefined.moe>",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"main": "hydro.js", "main": "hydro.js",