core&ui: support reaction

This commit is contained in:
undefined committed 2022-02-07 01:59:19 +08:00
1 parent 48565ce711
commit 913658d144
12 files changed
+180 -37

No files matched your search

@@ -27,6 +27,37 @@ $downvote-color = red
&:first-child
border-top: 0
.reactions
display: flex
flex-direction: row
width: 100%
flex-wrap: wrap
margin-top: 0.25rem
overflow: visible
.reaction
display: flex
flex-direction: row
height: 1.75rem
white-space: nowrap
width: auto
margin: 0.125rem
padding: 0 0.5rem
border: 2px solid transparent
border-radius: 1.75rem
font-weight: 500
overflow: visible
border-color: lighten(blue, 75%)
&.active
background-color: lighten(blue, 60%)
&:hover
background-color: lighten(blue, 75%) !important
p
padding-top: 0px
margin-top: 0px
padding-left: 0px
margin-right: 2px
line-height: 1.5
.dczcomments__reply
>.media
@@ -1,5 +1,8 @@
import 'jquery.easing';
import * as React from 'react';
import ReactDOM from 'react-dom';
import { Popover } from '@blueprintjs/core';
import { AutoloadPage } from 'vj/misc/Page';
import CommentBox from 'vj/components/discussion/CommentBox';
import { ConfirmDialog } from 'vj/components/dialog';
@@ -9,6 +12,7 @@ import { slideDown, slideUp } from 'vj/utils/slide';
import request from 'vj/utils/request';
import i18n from 'vj/utils/i18n';
import tpl from 'vj/utils/tpl';
import { chunk } from 'lodash';
const $replyTemplate = $('.commentbox-container').eq(0).clone();
@@ -72,7 +76,7 @@ function onClickDummyBox(ev) {
.focus();
}
async function onCommentClickReplyComment(ev, options = {}) {
async function onCommentClickReplyComment(ev, options: any = {}) {
const $evTarget = $(ev.currentTarget);
if (CommentBox.get($evTarget)) {
@@ -184,14 +188,85 @@ function onCommentClickDeleteReply(ev) {
onCommentClickDelete('reply', ev);
}
function renderReactions(reactions, self, rootEle) {
let html = '';
for (const key in reactions) {
if (!reactions[key]) continue;
html += `<div class="reaction${self[key] ? ' active' : ''}"><p>${key} ${reactions[key]}</p></div>`;
}
rootEle.html(html);
}
async function handleEmojiClick(payload, emoji, ele) {
const res = await request.post('', { ...payload, emoji });
renderReactions(res.doc?.react, res.sdoc?.react, ele);
}
function getRow(count) {
if (count <= 2) return 2;
if (count <= 3) return 3;
if (count <= 4) return 4;
if (count <= 6) return 6;
return 12;
}
function Reaction({ payload, ele }) {
const emojiList: string[] = (UiContext.emojiList || '👍 👎 😄 😕 ❤️ 🤔 🤣 🌿 🍋 🕊️ 👀 🤣').split(' ');
const elesPerRow = getRow(Math.sqrt(emojiList.length));
const [focus, updateFocus] = React.useState(false);
const [finish, updateFinish] = React.useState(false);
if (finish) setTimeout(() => updateFinish(false), 1000);
return (
// eslint-disable-next-line no-nested-ternary
<Popover usePortal interactionKind="hover" isOpen={finish ? false : (focus ? true : undefined)}>
<span className="icon icon-emoji"></span>
<div>
{chunk(emojiList, elesPerRow).map((line, i) => (
<div className="row" key={+i} style={{ paddingBottom: 4, paddingTop: 4 }}>
{line.map((emoji) => (
<div
key={emoji}
className={`medium-${12 / elesPerRow} columns`}
onClick={() => handleEmojiClick(payload, emoji, ele).then(() => updateFinish(true))}
>
{emoji}
</div>
))}
</div>
))}
<div className="row" style={{ paddingTop: 7, paddingBottom: 4 }}>
<div className="medium-12 columns">
<input name="emojiSuggest" onFocus={() => updateFocus(true)} onBlur={() => updateFocus(false)}></input>
</div>
</div>
</div>
</Popover>
);
}
const commentsPage = new AutoloadPage('commentsPage', () => {
$(document).on('click', '[name="dczcomments__dummy-box"]', onClickDummyBox);
$(document).on('click', '[name="dczcomments__op-reply-comment"]', onCommentClickReplyComment);
$(document).on('click', '[name="dczcomments__op-reply-reply"]', onCommentClickReplyReply);
$(document).on('click', '[name="dczcomments__op-edit-comment"]', onCommentClickEditComment);
$(document).on('click', '[name="dczcomments__op-edit-reply"]', onCommentClickEditReply);
$(document).on('click', '[name="dczcomments__op-delete-comment"]', onCommentClickDeleteComment);
$(document).on('click', '[name="dczcomments__op-delete-reply"]', onCommentClickDeleteReply);
$(document).on('click', '[data-op="reply"][data-type="comment"]', onCommentClickReplyComment);
$(document).on('click', '[data-op="reply"][data-type="reply"]', onCommentClickReplyReply);
$(document).on('click', '[data-op="edit"][data-type="comment"]', onCommentClickEditComment);
$(document).on('click', '[data-op="edit"][data-type="reply"]', onCommentClickEditReply);
$(document).on('click', '[data-op="delete"][data-type="comment"]', onCommentClickDeleteComment);
$(document).on('click', '[data-op="delete"][data-type="reply"]', onCommentClickDeleteReply);
$('[data-op="react"]').each((i, e) => {
ReactDOM.render(<Reaction payload={$(e).data('form')} ele={$(e).closest('.media__body').find('.reactions')} />, e);
});
$(document).on('click', '.reaction', async (e) => {
const target = $(e.currentTarget);
const res = await request.post('', {
operation: 'reaction',
type: 'drid',
id: target.parent().parent().data('drid'),
emoji: target.text().trim().split(' ')[0],
reverse: target.hasClass('active'),
});
renderReactions(res.doc?.react, res.sdoc?.react, target.parent());
});
});
export default commentsPage;