mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
core&ui: support reaction
This commit is contained in:
1 parent
48565ce711
commit
913658d144
12 files changed
+180
-37
No files matched your search
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "hydrooj",
|
||||
"version": "3.4.6",
|
||||
"version": "3.4.7",
|
||||
"bin": "bin/hydrooj.js",
|
||||
"main": "src/loader",
|
||||
"module": "src/loader",
|
||||
@@ -20,6 +20,8 @@
|
||||
"cac": "^6.7.12",
|
||||
"cookies": "^0.8.0",
|
||||
"detect-browser": "^5.3.0",
|
||||
"emoji-regex": "^10.0.0",
|
||||
"emojis-list": "2.1.0",
|
||||
"esbuild": "0.14.3",
|
||||
"fs-extra": "^10.0.0",
|
||||
"graphql": "^16.3.0",
|
||||
|
||||
@@ -179,6 +179,11 @@ class DiscussionDetailHandler extends DiscussionHandler {
|
||||
for (const drdoc of drdocs) {
|
||||
if (drdoc.reply) uids.push(...drdoc.reply.map((drrdoc) => drrdoc.owner));
|
||||
}
|
||||
const reactions = { [did.toHexString()]: dsdoc?.react || {} };
|
||||
await Promise.all(drdocs.map((drdoc) =>
|
||||
discussion.getReaction(domainId, document.TYPE_DISCUSSION_REPLY, drdoc._id, this.user._id).then((reaction) => {
|
||||
reactions[drdoc._id.toHexString()] = reaction;
|
||||
})));
|
||||
const udict = await user.getList(domainId, uids);
|
||||
if (!dsdoc?.view) {
|
||||
await Promise.all([
|
||||
@@ -194,7 +199,7 @@ class DiscussionDetailHandler extends DiscussionHandler {
|
||||
];
|
||||
this.response.template = 'discussion_detail.html';
|
||||
this.response.body = {
|
||||
path, ddoc: this.ddoc, dsdoc, drdocs, page, pcount, drcount, udict, vnode: this.vnode,
|
||||
path, ddoc: this.ddoc, dsdoc, drdocs, page, pcount, drcount, udict, vnode: this.vnode, reactions,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -203,12 +208,14 @@ class DiscussionDetailHandler extends DiscussionHandler {
|
||||
}
|
||||
|
||||
@param('type', Types.Range(['did', 'drid']))
|
||||
@param('did', Types.ObjectID)
|
||||
@param('id', Types.Name)
|
||||
@param('id', Types.ObjectID)
|
||||
@param('emoji', Types.Emoji)
|
||||
@param('reverse', Types.Boolean)
|
||||
async postReaction(domainId: string, type: string, did: ObjectID, id: string, reverse = false) {
|
||||
this.checkPerm(PERM.PERM_ADD_REACTION);
|
||||
await discussion.react(domainId, type === 'did' ? document.TYPE_DISCUSSION : document.TYPE_DISCUSSION_REPLY, did, id, this.user._id, reverse);
|
||||
const docType = type === 'did' ? document.TYPE_DISCUSSION : document.TYPE_DISCUSSION_REPLY;
|
||||
const [doc, sdoc] = await discussion.react(domainId, docType, did, id, this.user._id, reverse);
|
||||
this.response.body = { doc, sdoc };
|
||||
this.back();
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ export const PROJECTION_LIST: DiscussionDoc.Field[] = [
|
||||
'parentId', 'parentType', 'title',
|
||||
];
|
||||
export const PROJECTION_PUBLIC: DiscussionDoc.Field[] = [
|
||||
...PROJECTION_LIST, 'content', 'history',
|
||||
...PROJECTION_LIST, 'content', 'history', 'react', 'maintainer',
|
||||
];
|
||||
|
||||
export const typeDisplay = {
|
||||
@@ -184,8 +184,16 @@ export function getListReply(domainId: string, did: ObjectID): Promise<Discussio
|
||||
}
|
||||
|
||||
export async function react(domainId: string, docType: keyof document.DocType, did: ObjectID, id: string, uid: number, reverse = false) {
|
||||
const updated = await document.setIfNotStatus(domainId, docType, did, uid, `react.${id}`, reverse ? 0 : 1, reverse ? 0 : 1, {});
|
||||
if (updated) await document.inc(domainId, docType, did, `react.${id}`, reverse ? -1 : 1);
|
||||
let doc;
|
||||
const sdoc = await document.setIfNotStatus(domainId, docType, did, uid, `react.${id}`, reverse ? 0 : 1, reverse ? 0 : 1, {});
|
||||
if (sdoc) doc = await document.inc(domainId, docType, did, `react.${id}`, reverse ? -1 : 1);
|
||||
else doc = await document.get(domainId, docType, did, ['react']);
|
||||
return [doc, sdoc];
|
||||
}
|
||||
|
||||
export async function getReaction(domainId: string, docType: keyof document.DocType, did: ObjectID, uid: number) {
|
||||
const doc = await document.getStatus(domainId, docType, did, uid);
|
||||
return doc?.react || {};
|
||||
}
|
||||
|
||||
export async function addTailReply(
|
||||
@@ -357,6 +365,7 @@ global.Hydro.model.discussion = {
|
||||
editTailReply,
|
||||
delTailReply,
|
||||
react,
|
||||
getReaction,
|
||||
setStar,
|
||||
getStatus,
|
||||
setStatus,
|
||||
|
||||
@@ -292,7 +292,7 @@ export class ProblemModel {
|
||||
const q: any = { docId: { $in: pids } };
|
||||
let pdocs = await document.getMulti(domainId, document.TYPE_PROBLEM, q)
|
||||
.project(buildProjection(projection)).toArray();
|
||||
if (group.length > 0) {
|
||||
if (group.length > 0 && canViewHidden !== true) {
|
||||
pdocs = pdocs.filter((i) => !i.assign?.length || Set.intersection(group, i.assign).size);
|
||||
}
|
||||
if (canViewHidden !== true) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import http from 'http';
|
||||
import { PassThrough } from 'stream';
|
||||
import cac from 'cac';
|
||||
import Cookies from 'cookies';
|
||||
import emojiRegex from 'emoji-regex';
|
||||
import Koa, { Context } from 'koa';
|
||||
import Body from 'koa-body';
|
||||
import Compress from 'koa-compress';
|
||||
@@ -86,6 +87,7 @@ export interface Types {
|
||||
NumericArray: Type,
|
||||
CommaSeperatedArray: Type,
|
||||
Set: Type,
|
||||
Emoji: Type,
|
||||
}
|
||||
|
||||
export const Types: Types = {
|
||||
@@ -172,6 +174,10 @@ export const Types: Types = {
|
||||
if (v instanceof Array) return new Set(v);
|
||||
return v ? new Set([v]) : new Set();
|
||||
}, null],
|
||||
Emoji: [
|
||||
(v: string) => v.matchAll(emojiRegex()).next().value[0],
|
||||
(v) => emojiRegex().test(v),
|
||||
],
|
||||
};
|
||||
|
||||
function _buildParam(name: string, source: 'get' | 'post' | 'all' | 'route', ...args: Array<Type | boolean | Validator | Converter>) {
|
||||
|
||||
Reference in new issue
Block a user