From ed8ae6ba6983a5682828e7e224c50e906bc29784 Mon Sep 17 00:00:00 2001 From: undefined Date: Fri, 10 Sep 2021 23:01:04 +0800 Subject: [PATCH] ui: remember scratchpad panel visibility --- packages/hydrooj/package.json | 2 +- packages/hydrooj/src/handler/user.ts | 10 ++++----- packages/hydrooj/src/model/record.ts | 22 ++++++++++--------- packages/hydrooj/src/service/db.ts | 20 ++++++++++++++++- .../components/scratchpad/reducers/ui.js | 6 +++-- packages/ui-default/package.json | 2 +- 6 files changed, 41 insertions(+), 21 deletions(-) diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index 0c67d60af..9300fe9ef 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "2.34.1", + "version": "2.34.2", "bin": "bin/hydrooj.js", "main": "src/loader", "module": "src/loader", diff --git a/packages/hydrooj/src/handler/user.ts b/packages/hydrooj/src/handler/user.ts index 41ad02ea3..836655c5f 100644 --- a/packages/hydrooj/src/handler/user.ts +++ b/packages/hydrooj/src/handler/user.ts @@ -1,8 +1,8 @@ import moment from 'moment-timezone'; import { - BlacklistedError, - InvalidTokenError, LoginError, - SystemError, UserAlreadyExistError, UserFacingError, UserNotFoundError, VerifyPasswordError, + BlacklistedError, InvalidTokenError, LoginError, + SystemError, UserAlreadyExistError, UserFacingError, + UserNotFoundError, VerifyPasswordError, } from '../error'; import { User } from '../interface'; import avatar from '../lib/avatar'; @@ -18,9 +18,7 @@ import * as system from '../model/system'; import task from '../model/task'; import token from '../model/token'; import user from '../model/user'; -import { - Handler, param, post, - Route, Types } from '../service/server'; +import { Handler, param, post, Route, Types } from '../service/server'; import { registerResolver, registerValue } from './api'; registerValue('User', [ diff --git a/packages/hydrooj/src/model/record.ts b/packages/hydrooj/src/model/record.ts index 211686e17..523f94785 100644 --- a/packages/hydrooj/src/model/record.ts +++ b/packages/hydrooj/src/model/record.ts @@ -2,14 +2,15 @@ import { omit, sum } from 'lodash'; import moment from 'moment'; import { - Collection, FilterQuery, - MatchKeysAndValues, ObjectID, OnlyFieldsOfType, - PushOperator, UpdateQuery, + Collection, FilterQuery, MatchKeysAndValues, + ObjectID, OnlyFieldsOfType, PushOperator, + UpdateQuery, } from 'mongodb'; import { ProblemNotFoundError } from '../error'; import { ContestInfo, ExternalProblemId, FileInfo, - ProblemConfigFile, RecordDoc } from '../interface'; + ProblemConfigFile, RecordDoc, +} from '../interface'; import * as bus from '../service/bus'; import db from '../service/db'; import { MaybeArray } from '../typeutils'; @@ -221,7 +222,7 @@ class RecordModel { @ArgMethod static getByUid(domainId: string, uid: number, limit: number): Promise { return RecordModel.coll.find({ - domainId, uid, hidden: false, 'contest.tid': null, + domainId, 'contest.tid': null, hidden: false, uid, }).sort({ _id: -1 }).limit(limit).toArray(); } } @@ -234,11 +235,12 @@ bus.on('domain/delete', (domainId) => Promise.all([ ])); bus.on('app/started', () => { - RecordModel.coll.createIndexes([ - { key: { 'contest.tid': 1, hidden: 1, _id: -1 }, name: 'basic' }, - { key: { 'contest.tid': 1, hidden: 1, uid: 1, _id: -1 }, name: 'withUser' }, - { key: { 'contest.tid': 1, hidden: 1, pid: 1, _id: -1 }, name: 'withProblem' }, - ]); + return db.ensureIndexes( + RecordModel.coll, + { key: { domainId: 1, 'contest.tid': 1, hidden: 1, _id: -1 }, name: 'basic' }, + { key: { domainId: 1, 'contest.tid': 1, hidden: 1, uid: 1, _id: -1 }, name: 'withUser' }, + { key: { domainId: 1, 'contest.tid': 1, hidden: 1, pid: 1, _id: -1 }, name: 'withProblem' }, + ); }); export default RecordModel; diff --git a/packages/hydrooj/src/service/db.ts b/packages/hydrooj/src/service/db.ts index ba1747991..f0033dcde 100644 --- a/packages/hydrooj/src/service/db.ts +++ b/packages/hydrooj/src/service/db.ts @@ -1,7 +1,10 @@ -import { Collection, Db, MongoClient } from 'mongodb'; +import { Collection, Db, IndexSpecification, MongoClient } from 'mongodb'; import { BaseService, Collections } from '../interface'; +import { Logger } from '../logger'; import * as bus from './bus'; +const logger = new Logger('mongo'); + interface MongoConfig { protocol?: string, username?: string, @@ -44,6 +47,21 @@ class MongoService implements BaseService { if (this.opts.prefix) return this.db.collection(`${this.opts.prefix}.${c}`); return this.db.collection(c); } + + public async ensureIndexes(coll: Collection, ...args: IndexSpecification[]) { + const existed = await coll.listIndexes().toArray(); + for (const index of args) { + const i = existed.find(t => t.name == index.name); + if (!i) { + logger.info('Indexing %s.%s with key %o', coll.collectionName, index.name, index.key); + await coll.createIndexes([index]); + } else if (i.v < 2 || JSON.stringify(i.key) !== JSON.stringify(index.key)) { + logger.info('Re-Index %s.%s with key %o', coll.collectionName, index.name, index.key); + await coll.dropIndex(index.name); + await coll.createIndexes([index]); + } + } + } } const service = new MongoService(); diff --git a/packages/ui-default/components/scratchpad/reducers/ui.js b/packages/ui-default/components/scratchpad/reducers/ui.js index 7cad461d4..29f59ffe9 100644 --- a/packages/ui-default/components/scratchpad/reducers/ui.js +++ b/packages/ui-default/components/scratchpad/reducers/ui.js @@ -6,11 +6,11 @@ export default function reducer(state = { size: '50%', }, pretest: { - visible: false, + visible: localStorage.getItem('scratchpad/pretest') === 'true', size: 200, }, records: { - visible: UiContext.canViewRecord, + visible: UiContext.canViewRecord && localStorage.getItem('scratchpad/records') === 'true', size: 200, isLoading: false, }, @@ -29,6 +29,7 @@ export default function reducer(state = { } case 'SCRATCHPAD_UI_SET_VISIBILITY': { const { uiElement, visibility } = action.payload; + localStorage.setItem(`scratchpad/${uiElement}`, visibility.toString()); return { ...state, [uiElement]: { @@ -39,6 +40,7 @@ export default function reducer(state = { } case 'SCRATCHPAD_UI_TOGGLE_VISIBILITY': { const { uiElement } = action.payload; + localStorage.setItem(`scratchpad/${uiElement}`, (!state[uiElement].visible).toString()); return { ...state, [uiElement]: { diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index e611574c8..11ba1549a 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/ui-default", - "version": "4.20.0", + "version": "4.20.1", "author": "undefined ", "license": "AGPL-3.0", "main": "hydro.js",