diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index 4f5d807e6..7ef3f4f6c 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "3.13.1", + "version": "3.13.2", "bin": "bin/hydrooj.js", "main": "src/loader", "module": "src/loader", diff --git a/packages/hydrooj/src/handler/compat.ts b/packages/hydrooj/src/handler/compat.ts new file mode 100644 index 000000000..f25fb23d6 --- /dev/null +++ b/packages/hydrooj/src/handler/compat.ts @@ -0,0 +1,11 @@ +import { Handler, Route } from '../service/server'; + +class ProblemCategoryCompatHandler extends Handler { + async get({ category }) { + this.response.redirect = this.url('problem_main', { query: { q: `category:${category}` } }); + } +} + +global.Hydro.handler.compat = () => { + Route('problem_category_compat', '/p/category/:category', ProblemCategoryCompatHandler); +}; diff --git a/packages/hydrooj/src/handler/index.ts b/packages/hydrooj/src/handler/index.ts index c72beb7f5..d70cd464f 100644 --- a/packages/hydrooj/src/handler/index.ts +++ b/packages/hydrooj/src/handler/index.ts @@ -14,3 +14,4 @@ import './domain'; import './status'; import './api'; import './blog'; +import './compat'; diff --git a/packages/hydrooj/src/handler/problem.ts b/packages/hydrooj/src/handler/problem.ts index 5c1a8638b..6110cef7c 100644 --- a/packages/hydrooj/src/handler/problem.ts +++ b/packages/hydrooj/src/handler/problem.ts @@ -1,7 +1,7 @@ import AdmZip from 'adm-zip'; import { readFile, statSync } from 'fs-extra'; import { isBinaryFile } from 'isbinaryfile'; -import { intersection, isSafeInteger } from 'lodash'; +import { flattenDeep, intersection, isSafeInteger } from 'lodash'; import { FilterQuery, ObjectID } from 'mongodb'; import { nanoid } from 'nanoid'; import { sortFiles, streamToBuffer } from '@hydrooj/utils/lib/utils'; @@ -125,7 +125,7 @@ export class ProblemHandler extends Handler { page, ppcount, pcount, pdocs, psdict, qs, }), this.renderHTML('partials/problem_stat.html', { pcount, pcountRelation }), - this.renderHTML('partials/problem_lucky.html', { category }), + this.renderHTML('partials/problem_lucky.html', { qs }), ])).map((i) => ({ html: i })), raw: { page, pcount, ppcount, pdocs, psdict, category, @@ -138,8 +138,7 @@ export class ProblemHandler extends Handler { export class ProblemMainHandler extends ProblemHandler { @param('page', Types.PositiveInt, true) @param('q', Types.Content, true) - @param('category', Types.Name, true, null, parseCategory) - async get(domainId: string, page = 1, q = '', category = []) { + async get(domainId: string, page = 1, q = '') { this.response.template = 'problem_main.html'; // eslint-disable-next-line @typescript-eslint/no-shadow const query = buildQuery(this.user); @@ -148,11 +147,15 @@ export class ProblemMainHandler extends ProblemHandler { let sort: string[]; let fail = false; let pcountRelation = 'eq'; + const category = flattenDeep(decodeURIComponent(q).split(' ') + .filter((i) => i.startsWith('category:')) + .map((i) => i.split(':')[1]?.split(','))); + const text = q.split(' ').filter((i) => !i.startsWith('category:')).join(' '); if (category.length) query.$and = category.map((tag) => ({ tag })); - if (q) category.push(q); + if (text) category.push(text); if (category.length) this.UiContext.extraTitleContent = category.join(','); let total = 0; - if (q) { + if (text) { if (search) { const result = await search(domainId, q, { skip: (page - 1) * system.get('pagination.problem') }); total = result.total; @@ -166,7 +169,7 @@ export class ProblemMainHandler extends ProblemHandler { }), }); sort = result.hits; - } else query.$text = { $search: q }; + } else query.$text = { $search: text }; } await bus.serial('problem/list', query, this); // eslint-disable-next-line prefer-const @@ -209,7 +212,7 @@ export class ProblemMainHandler extends ProblemHandler { pdocs, psdict, category: category.join(','), - qs: q ? `q=${encodeURIComponent(q)}` : '', + qs: q, }; } @@ -281,8 +284,12 @@ export class ProblemMainHandler extends ProblemHandler { } export class ProblemRandomHandler extends ProblemHandler { - @param('category', Types.Name, true, null, parseCategory) - async get(domainId: string, category: string[] = []) { + @param('q', Types.Content, true) + async get(domainId: string, qs = '') { + const category = flattenDeep(decodeURIComponent(qs).split(' ') + .filter((i) => i.startsWith('category:')) + .map((i) => i.split(':')[1]?.split(','))); + console.log(qs, category); const q = buildQuery(this.user); if (category.length) q.$and = category.map((tag) => ({ tag })); await bus.serial('problem/list', q, this); @@ -906,7 +913,6 @@ export class ProblemPrefixListHandler extends Handler { export async function apply() { Route('problem_main', '/p', ProblemMainHandler, PERM.PERM_VIEW_PROBLEM); - Route('problem_category', '/p/category/:category', ProblemMainHandler, PERM.PERM_VIEW_PROBLEM); Route('problem_random', '/problem/random', ProblemRandomHandler, PERM.PERM_VIEW_PROBLEM); Route('problem_detail', '/p/:pid', ProblemDetailHandler, PERM.PERM_VIEW_PROBLEM); Route('problem_submit', '/p/:pid/submit', ProblemSubmitHandler, PERM.PERM_SUBMIT_PROBLEM); diff --git a/packages/hydrooj/src/service/layers/renderer.ts b/packages/hydrooj/src/service/layers/renderer.ts index 6c6d0ae3c..e7544fcce 100644 --- a/packages/hydrooj/src/service/layers/renderer.ts +++ b/packages/hydrooj/src/service/layers/renderer.ts @@ -40,7 +40,7 @@ export default (router, logger) => async (ctx: KoaContext, next) => { } for (const key in kwargs.query || {}) { if (query[key] instanceof ObjectID) query[key] = kwargs.query[key].toHexString(); - else query[key] = encodeURIComponent(kwargs.query[key].toString()); + else query[key] = kwargs.query[key].toString(); } try { const { anchor } = args; diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index d54dd3a30..948b62655 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/ui-default", - "version": "4.36.1", + "version": "4.36.2", "author": "undefined ", "license": "AGPL-3.0", "main": "hydro.js", diff --git a/packages/ui-default/pages/problem_main.page.js b/packages/ui-default/pages/problem_main.page.js index 33f299941..df9823b28 100644 --- a/packages/ui-default/pages/problem_main.page.js +++ b/packages/ui-default/pages/problem_main.page.js @@ -7,7 +7,6 @@ import Dropdown from 'vj/components/dropdown/Dropdown'; import createHint from 'vj/components/hint'; import { downloadProblemSet } from 'vj/components/zipDownloader'; import pjax from 'vj/utils/pjax'; -import substitute from 'vj/utils/substitute'; import request from 'vj/utils/request'; import tpl from 'vj/utils/tpl'; import delay from 'vj/utils/delay'; @@ -52,19 +51,13 @@ async function updateSelection(sendRequest = true) { .map((s) => s.split(',')[0])); // drop the category if its subcategory is selected const requestTags = _.uniq(_.pullAll(selections, requestCategoryTags)); - let url; - if (requestTags.length === 0) { - url = UiContext.getProblemUrlWithoutCategory; - } else { - url = substitute(decodeURIComponent(UiContext.getProblemUrlWithCategory), { - category: requestTags - .map((tag) => tag.split(',').map(encodeURIComponent).join(',')) - .join(','), // build a beautiful URL - }); - } - const q = $('[name="q"]').val(); - if (q) url += `?q=${q}`; - pjax.request({ url }); + let q = $('[name="q"]').val().split(' ').filter((i) => !i.startsWith('category:')).join(' '); + if (requestTags.length) q = requestTags.map((i) => `category:${i}`).join(' ') + (q ? ` ${q}` : ''); + const url = new URL(window.location.href); + if (!q) url.searchParams.delete('q'); + else url.searchParams.set('q', q); + pjax.request({ url: url.toString() }); + $('[name="q"]').val(q); } } @@ -230,7 +223,7 @@ function processElement(ele) { createHint('Hint::icon::difficulty', $(ele).find('th.col--difficulty')); } -const page = new NamedPage(['problem_main', 'problem_category'], () => { +const page = new NamedPage(['problem_main'], () => { const doc = document.body; doc.className += ' display-mode'; $('.section.display-mode').removeClass('display-mode'); diff --git a/packages/ui-default/templates/components/problem.html b/packages/ui-default/templates/components/problem.html index fda06daca..d81ca4366 100644 --- a/packages/ui-default/templates/components/problem.html +++ b/packages/ui-default/templates/components/problem.html @@ -21,7 +21,7 @@ {%- if pdoc.tag|length > 0 %} {%- if not inline %}{% endif -%} {%- else -%} diff --git a/packages/ui-default/templates/partials/category.html b/packages/ui-default/templates/partials/category.html index d7ec78f0b..fd507f421 100644 --- a/packages/ui-default/templates/partials/category.html +++ b/packages/ui-default/templates/partials/category.html @@ -2,13 +2,13 @@ {%- for category, sub_categories in model.system.get('problem.categories')|parseYaml -%}
  • - {{ category }} + {{ category }}

    {% if sub_categories | length > 0 %}
      {%- for sub_category in sub_categories -%}
    1. - {{ sub_category }} + {{ sub_category }}
    2. {%- endfor -%}
    diff --git a/packages/ui-default/templates/partials/problem-sidebar-information.html b/packages/ui-default/templates/partials/problem-sidebar-information.html index 7700ade61..42c5d28a6 100644 --- a/packages/ui-default/templates/partials/problem-sidebar-information.html +++ b/packages/ui-default/templates/partials/problem-sidebar-information.html @@ -11,24 +11,6 @@
    {{ pdoc.config.memoryMax if pdoc.config.memoryMax == pdoc.config.memoryMin else pdoc.config.memoryMin+'~'+pdoc.config.memoryMax }}MiB
    {{ _('Difficulty') }}
    {{ pdoc['difficulty'] or lib.difficulty(pdoc.nSubmit, pdoc.nAccept) or _('(None)') }}
    -
    {{ _('Category') }}
    -
    - {% if pdoc['category'] %} - - {%- for category in pdoc['category'] -%} - {{ category }} - {% if loop.index < pdoc['category']|length %} - {{ _('problem-subcategory-delim') }} - {% endif %} - {%- endfor -%} - - - {{ _('page.problem_detail.sidebar.show_category') }} - - {% else %} - {{ _('(None)') }} - {% endif %} -
    {{ _('Tags') }}
    {{ problem.render_problem_tags(pdoc, true) }} diff --git a/packages/ui-default/templates/partials/problem_lucky.html b/packages/ui-default/templates/partials/problem_lucky.html index 19e5c466d..9413a2526 100644 --- a/packages/ui-default/templates/partials/problem_lucky.html +++ b/packages/ui-default/templates/partials/problem_lucky.html @@ -1,6 +1,6 @@

    - + {{ _('Lucky') }}

    diff --git a/packages/ui-default/templates/problem_main.html b/packages/ui-default/templates/problem_main.html index 9621521ab..f80888050 100644 --- a/packages/ui-default/templates/problem_main.html +++ b/packages/ui-default/templates/problem_main.html @@ -3,8 +3,6 @@ {% extends "layout/basic.html" %} {% block content %} {{ set(UiContext, { - getProblemUrlWithCategory: url('problem_category', category='{category}'), - getProblemUrlWithoutCategory: url('problem_main'), currentCategory: category }) }}
    @@ -13,7 +11,7 @@