界面语言切换功能,修复nav异常

This commit is contained in:
masnn committed 2020-06-10 23:20:36 +08:00
1 parent 7e7dee4074
commit 0923d6e72b
16 files changed
+53 -36

No files matched your search

+2 -2
View File
@@ -21,9 +21,9 @@ class DomainRankHandler extends Handler {
udocs = await Promise.all(udocs); udocs = await Promise.all(udocs);
const path = [ const path = [
['Hydro', '/'], ['Hydro', '/'],
['domain_rank', null], ['ranking', null],
]; ];
this.response.template = 'domain_rank.html'; this.response.template = 'ranking.html';
this.response.body = { this.response.body = {
udocs, upcount, ucount, page, path, udocs, upcount, ucount, page, path,
}; };
+3 -2
View File
@@ -56,9 +56,10 @@ class SystemScriptHandler extends SystemHandler {
this.response.body.path.push(['manage_script', null]); this.response.body.path.push(['manage_script', null]);
} }
async post({ id, args }) { async post({ id, args = '{}' }) {
args = JSON.parse(args);
// TODO Do not use console.log // TODO Do not use console.log
await global.Hydro.script[id].run(JSON.parse(args), console.log); await global.Hydro.script[id].run(args, console.log);
this.back(); this.back();
} }
} }
+5 -2
View File
@@ -1,6 +1,7 @@
const { PERM_JUDGE } = require('../permission'); const { PERM_JUDGE, PERM_LOGGEDIN } = require('../permission');
const file = require('../model/file'); const file = require('../model/file');
const user = require('../model/user');
const db = require('../service/db'); const db = require('../service/db');
const { Route, Handler } = require('../service/server'); const { Route, Handler } = require('../service/server');
@@ -47,7 +48,9 @@ class StatusUpdateHandler extends Handler {
class SwitchLanguageHandler extends Handler { class SwitchLanguageHandler extends Handler {
async get({ lang }) { async get({ lang }) {
this.session.language = lang; if (this.user.hasPerm(PERM_LOGGEDIN)) await user.setById(this.user._id, { viewLang: lang });
else this.session.viewLang = lang;
this.back();
} }
} }
+3 -8
View File
@@ -138,8 +138,7 @@ class UserLostPassWithCodeHandler extends Handler {
class UserDetailHandler extends Handler { class UserDetailHandler extends Handler {
async get({ domainId, uid }) { async get({ domainId, uid }) {
const isSelfProfile = this.user._id === uid; const isSelfProfile = this.user._id === uid;
const udoc = await user.getById(domainId, uid); const udoc = await user.getById(domainId, uid, true);
if (!udoc) throw new UserNotFoundError(uid);
const sdoc = await token.getMostRecentSessionByUid(uid); const sdoc = await token.getMostRecentSessionByUid(uid);
this.response.template = 'user_detail.html'; this.response.template = 'user_detail.html';
this.response.body = { isSelfProfile, udoc, sdoc }; this.response.body = { isSelfProfile, udoc, sdoc };
@@ -151,12 +150,8 @@ class UserSearchHandler extends Handler {
let udocs; let udocs;
if (exactMatch) udocs = []; if (exactMatch) udocs = [];
else udocs = await user.getPrefixList(q, 20); else udocs = await user.getPrefixList(q, 20);
try { const udoc = await user.getById(domainId, parseInt(q));
const udoc = await user.getById(domainId, parseInt(q)); if (udoc) udocs.push(udoc);
if (udoc) udocs.push(udoc);
} catch (e) {
/* Ignore */
}
for (const i in udocs) { for (const i in udocs) {
if (udocs[i].gravatar) { if (udocs[i].gravatar) {
udocs[i].gravatar_url = misc.gravatar(udocs[i].gravatar); udocs[i].gravatar_url = misc.gravatar(udocs[i].gravatar);
+3 -3
View File
@@ -8,20 +8,20 @@ const Item = (path, name, prefix, perm, checker) => {
checker = ((_chk) => (handler) => _chk(handler) && handler.user.hasPerm(perm))(checker); checker = ((_chk) => (handler) => _chk(handler) && handler.user.hasPerm(perm))(checker);
} else if (perm) { } else if (perm) {
checker = (handler) => handler.user.hasPerm(perm); checker = (handler) => handler.user.hasPerm(perm);
} else checker = trueChecker; } else if (!checker) checker = trueChecker;
global.Hydro.ui.nav.push({ global.Hydro.ui.nav.push({
path, name, prefix, checker, path, name, prefix, checker,
}); });
}; };
Item('/', 'domain_main', 'domain_main'); Item('/', 'homepage', 'homepage');
Item('/p', 'problem_main', 'problem', permission.PERM_VIEW_PROBLEM); Item('/p', 'problem_main', 'problem', permission.PERM_VIEW_PROBLEM);
Item('/t', 'training_main', 'training', permission.PERM_VIEW_TRAINING); Item('/t', 'training_main', 'training', permission.PERM_VIEW_TRAINING);
Item('/homework', 'homework_main', 'homework', permission.PERM_VIEW_HOMEWORK); Item('/homework', 'homework_main', 'homework', permission.PERM_VIEW_HOMEWORK);
Item('/discuss', 'discussion_main', 'discussion', permission.PERM_VIEW_DISCUSSION); Item('/discuss', 'discussion_main', 'discussion', permission.PERM_VIEW_DISCUSSION);
Item('/c', 'contest_main', 'contest', permission.PERM_VIEW_CONTEST); Item('/c', 'contest_main', 'contest', permission.PERM_VIEW_CONTEST);
Item('/record', 'record_main', 'record'); Item('/record', 'record_main', 'record');
Item('/ranking', 'domain_rank', 'domain_rank'); Item('/ranking', 'ranking', 'ranking');
Item('/domain/dashboard', 'domain_dashboard', 'domain', permission.PERM_MANAGE); Item('/domain/dashboard', 'domain_dashboard', 'domain', permission.PERM_MANAGE);
Item('/manage/dashboard', 'manage', 'manage', null, (handler) => handler.user.priv === 1); Item('/manage/dashboard', 'manage', 'manage', null, (handler) => handler.user.priv === 1);
+2 -3
View File
@@ -171,7 +171,7 @@ const builtinHandler = [
const builtinScript = [ const builtinScript = [
'install', 'uninstall', 'rating', 'recalcRating', 'register', 'install', 'uninstall', 'rating', 'recalcRating', 'register',
'blacklist', 'blacklist', 'setSuperadmin',
]; ];
async function loadAsMaster() { async function loadAsMaster() {
@@ -313,6 +313,7 @@ async function load() {
}; };
global.onDestory = []; global.onDestory = [];
Error.stackTraceLimit = 50; Error.stackTraceLimit = 50;
process.on('unhandledRejection', (e) => console.error(e));
if (cluster.isMaster) { if (cluster.isMaster) {
console.log(`Master ${process.pid} Starting`); console.log(`Master ${process.pid} Starting`);
process.stdin.setEncoding('utf8'); process.stdin.setEncoding('utf8');
@@ -325,7 +326,6 @@ async function load() {
console.warn(e); console.warn(e);
} }
}); });
process.on('unhandledRejection', (e) => console.log(e));
process.on('SIGINT', terminate); process.on('SIGINT', terminate);
await loadAsMaster(); await loadAsMaster();
cluster.on('exit', (worker, code, signal) => { cluster.on('exit', (worker, code, signal) => {
@@ -340,7 +340,6 @@ async function load() {
cluster.on('online', (worker) => { cluster.on('online', (worker) => {
console.log(`Worker ${worker.process.pid} is online`); console.log(`Worker ${worker.process.pid} is online`);
}); });
// FIXME this requires lots of memory
for (let i = 0; i < numCPUs; i++) { for (let i = 0; i < numCPUs; i++) {
cluster.fork(); cluster.fork();
} }
+3 -5
View File
@@ -203,11 +203,10 @@ const CATEGORIES = {
}; };
const FOOTER_EXTRA_HTMLS = []; const FOOTER_EXTRA_HTMLS = [];
const VIEW_LANGS = [ const VIEW_LANGS = [
{ code: 'zh-CN', name: 'zh-CN' }, { code: 'zh_CN', name: '简体中文' },
{ code: 'zh_TW', name: '正體中文' },
{ code: 'en', name: 'English' },
]; ];
const LANGS = {
cc: 'cpp',
};
const LANG_TEXTS = { const LANG_TEXTS = {
c: 'C', c: 'C',
cc: 'C++', cc: 'C++',
@@ -296,7 +295,6 @@ global.Hydro.model.builtin = module.exports = {
CATEGORIES, CATEGORIES,
VIEW_LANGS, VIEW_LANGS,
FOOTER_EXTRA_HTMLS, FOOTER_EXTRA_HTMLS,
LANGS,
LANG_TEXTS, LANG_TEXTS,
LANG_HIGHLIGHT_ID, LANG_HIGHLIGHT_ID,
STATUS, STATUS,
+11 -3
View File
@@ -19,7 +19,7 @@ class USER {
this.salt = () => udoc.salt; this.salt = () => udoc.salt;
this.hash = () => udoc.hash; this.hash = () => udoc.hash;
this.priv = udoc.priv; this.priv = udoc.priv;
this.viewLang = udoc.language || 'zh_CN'; this.viewLang = udoc.viewLang || 'zh_CN';
this.codeLang = udoc.codeLang || 'c'; this.codeLang = udoc.codeLang || 'c';
this.codeTemplate = udoc.codeTemplate || ''; this.codeTemplate = udoc.codeTemplate || '';
this.regat = udoc.regat; this.regat = udoc.regat;
@@ -55,9 +55,12 @@ async function getInDomain(domainId, udoc) {
return dudoc; return dudoc;
} }
async function getById(domainId, _id) { async function getById(domainId, _id, throwError = false) {
const udoc = await coll.findOne({ _id }); const udoc = await coll.findOne({ _id });
if (!udoc) throw new UserNotFoundError(_id); if (!udoc) {
if (throwError) throw new UserNotFoundError(_id);
else return null;
}
const dudoc = await getInDomain(domainId, udoc); const dudoc = await getInDomain(domainId, udoc);
return new USER(udoc, dudoc); return new USER(udoc, dudoc);
} }
@@ -224,6 +227,10 @@ function ban(uid) {
]); ]);
} }
function setSuperAdmin(uid) {
return setById(uid, { priv: 1 });
}
function ensureIndexes() { function ensureIndexes() {
return Promise.all([ return Promise.all([
coll.createIndex('unameLower', { unique: true }), coll.createIndex('unameLower', { unique: true }),
@@ -255,6 +262,7 @@ global.Hydro.model.user = module.exports = {
getInDomain, getInDomain,
addRole, addRole,
deleteRoles, deleteRoles,
setSuperAdmin,
ban, ban,
ensureIndexes, ensureIndexes,
}; };
+1 -1
View File
@@ -35,7 +35,7 @@ async function run({ domainId, isSub = false }, report) {
} }
const tasks = []; const tasks = [];
for (const uid in udict) { for (const uid in udict) {
tasks.push(user.setInDomain(domainId, uid, { rating: udict[uid] })); tasks.push(user.setInDomain(domainId, parseInt(uid), { rating: udict[uid] }));
} }
await Promise.all(tasks); await Promise.all(tasks);
return true; return true;
+2
View File
@@ -5,6 +5,8 @@ async function run({
uname, password, mail, uid, uname, password, mail, uid,
}) { }) {
if (!uid) uid = await system.inc('user'); if (!uid) uid = await system.inc('user');
else uid = parseInt(uid);
if (Number.isNaN(uid)) throw new Error('uid');
await user.create({ await user.create({
uid, uname, password, mail, regip: '127.0.0.1', uid, uname, password, mail, regip: '127.0.0.1',
}); });
+12
View File
@@ -0,0 +1,12 @@
const user = require('../model/user');
async function run({
uid,
}) {
uid = parseInt(uid);
if (Number.isNaN(uid)) throw new Error('uid');
await user.setSuperAdmin(uid);
return uid;
}
global.Hydro.script.setSuperadmin = module.exports = { run };
+3 -4
View File
@@ -130,7 +130,7 @@ class Handler {
this.hasPerm = (perm) => this.user.hasPerm(perm); this.hasPerm = (perm) => this.user.hasPerm(perm);
const res = await template.render(name, Object.assign(context, { const res = await template.render(name, Object.assign(context, {
handler: this, handler: this,
_: (str) => (str ? str.toString().translate(this.user.language) : ''), _: (str) => (str ? str.toString().translate(this.user.viewLang || this.session.viewLang) : ''),
user: this.user, user: this.user,
})); }));
console.timeEnd(name); console.timeEnd(name);
@@ -173,7 +173,7 @@ class Handler {
} }
translate(str) { translate(str) {
return str ? str.toString().translate(this.user.language) : ''; return str ? str.toString().translate(this.user.viewLang || this.session.viewLang) : '';
} }
binary(data, name) { binary(data, name) {
@@ -364,11 +364,10 @@ class ConnectionHandler {
} }
async renderHTML(name, context) { async renderHTML(name, context) {
console.time(name);
this.hasPerm = (perm) => this.user.hasPerm(perm); this.hasPerm = (perm) => this.user.hasPerm(perm);
const res = await template.render(name, Object.assign(context, { const res = await template.render(name, Object.assign(context, {
handler: this, handler: this,
_: (str) => (str ? str.toString().translate(this.user.language) : ''), _: (str) => (str ? str.toString().translate(this.user.viewLang || this.session.viewLang) : ''),
user: this.user, user: this.user,
})); }));
return res; return res;
+1 -1
View File
@@ -156,7 +156,7 @@ async function setup() {
else resolve(); else resolve();
}); });
}); });
console.log('Done! Please restart.'); console.log('Done! Restarting...');
} }
module.exports = { setup }; module.exports = { setup };
+1 -1
View File
@@ -1,5 +1,5 @@
{% set no_path_section = true %} {% set no_path_section = true %}
{% set page_name = "domain_main" %} {% set page_name = "homepage" %}
{% extends "layout/basic.html" %} {% extends "layout/basic.html" %}
{% import "components/contest.html" as contest with context %} {% import "components/contest.html" as contest with context %}
{% block content %} {% block content %}
+1 -1
View File
@@ -54,7 +54,7 @@
<span><span class="icon icon-global"></span> Language <span class="icon icon-expand_less"></span></span> <span><span class="icon icon-global"></span> Language <span class="icon icon-expand_less"></span></span>
<ol class="dropdown-target menu" id="menu-footer-lang"> <ol class="dropdown-target menu" id="menu-footer-lang">
{% for item in model.builtin.VIEW_LANGS %} {% for item in model.builtin.VIEW_LANGS %}
<li class="menu__item"><a class="menu__link" href="/lang/{{ item.code }}">{{ item.name }}</a></li> <li class="menu__item"><a class="menu__link" href="/language/{{ item.code }}">{{ item.name }}</a></li>
{% endfor %} {% endfor %}
</ol> </ol>
</li> </li>
File renamed without changes.