♻️ update emoji function

This commit is contained in:
landaiqing
2024-10-01 17:21:19 +08:00
parent f358e0d26a
commit 20d78afe80
306 changed files with 872 additions and 236 deletions

View File

@@ -11,9 +11,9 @@
</div>
</template>
<script setup lang="ts">
import CommentInput from "@/components/CommentReply/Components/CommentInput/CommentInput.vue";
import CommentInput from "@/components/CommentReply/src/CommentInput/CommentInput.vue";
import {useI18n} from "vue-i18n";
import CommentList from "@/components/CommentReply/Components/CommentList/CommentList.vue";
import CommentList from "@/components/CommentReply/src/CommentList/CommentList.vue";
const {t} = useI18n();
</script>

View File

@@ -9,15 +9,21 @@
v-model:value="commentContent"
@keyup.ctrl.enter="showSlideCaptcha"
:placeholder="commentTextAreaPlaceholder" allow-clear :showCount="false"/>
<AFlex :vertical="false" align="center" justify="space-between" class="comment-actions"
v-if="showCommentActions">
<AFlex :vertical="false" align="center">
<AFlex :vertical="false" align="center" class="comment-action-item">
<APopover trigger="click" placement="bottom">
<template #content>
<div style="width: 170px;height: 200px;overflow: auto;">
<template v-for="(item) in EMOJI" :key="item">
<AButton @click="insertEmoji(item)" type="text" size="large">{{ item }}</AButton>
<div style="width: 210px;height: 200px;overflow: auto;">
<template v-for="(item) in comment.emojiList" :key="item">
<AButton @click="insertEmoji(item.name)" type="text" shape="circle" size="large"
class="comment-emoji-item">
<template #icon>
<AAvatar shape="circle" size="default" :src="item.path"/>
</template>
</AButton>
</template>
</div>
</template>
@@ -37,11 +43,11 @@
:show-upload-list="false"
:custom-request="comment.customUploadRequest"
:before-upload="comment.beforeUpload"
:disabled="comment.imageList.length >= 3"
:disabled="comment.imageList.length >= 3 || comment.uploadLoading"
>
<ABadge :count="comment.imageList.length">
<AButton type="text" size="small" :icon="h(PictureOutlined)"
class="comment-action-icon">
class="comment-action-icon" :loading="comment.uploadLoading">
{{ t('comment.picture') }}
</AButton>
</ABadge>
@@ -84,7 +90,6 @@
</template>
<script lang="ts" setup>
import EMOJI from "@/constant/emoji.js";
import {h, ref} from "vue";
import {PictureOutlined, SmileOutlined} from "@ant-design/icons-vue";
import {useI18n} from "vue-i18n";
@@ -118,6 +123,7 @@ const commentSlideCaptchaEvent = {
},
};
/**
* 聚焦事件
*/
@@ -130,7 +136,7 @@ async function onFocusHandler() {
* @param emoji
*/
async function insertEmoji(emoji: string) {
commentContent.value += emoji;
commentContent.value += "[" + emoji + "]";
}
@@ -152,11 +158,18 @@ async function commentSubmit(point: any) {
return;
}
const content = commentContent.value.replace(/\r\n/g, '<br/>').replace(/\n/g, '<br/>').replace(/\s/g, ' ');
const regex = /\[(\d+\.gif)\]/g; // [1.gif]
const contentWithEmoji = content.replace(regex, (match, p1) => {
const path = comment.emojiMap[p1];
if (path) {
return `<img style="width: 30px; height: 30px;" src="${path}" alt="emoji ${p1}" />`;
}
return match;
});
const commentParams: object = {
user_id: user.user.uid,
topic_id: topicId.value,
content: content,
content: contentWithEmoji,
images: comment.imageList,
author: user.user.uid,
point: [point.x, point.y],

View File

@@ -5,6 +5,12 @@
.comment-text {
width: 600px;
}
.comment-editor{
border: 1px solid #d9d9d9;
border-radius: 8px;
padding: 10px;
width: 580px;
}
.comment-actions {
margin-top: 10px;
@@ -13,6 +19,12 @@
cursor: pointer;
color: #767779;
.comment-emoji-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.comment-action-icon {
font-size: 14px;

View File

@@ -46,20 +46,15 @@
<AFlex :vertical="false" align="center">
<ACard class="reply-card" :body-style="{padding: '10px'}">
<div class="reply-text" v-html="item.content">
<div class="reply-text" v-dompurify-html="item.content">
</div>
<AFlex :vertical="false" align="center" class="reply-images" v-if="item.images">
<AImagePreviewGroup>
<AAvatar shape="square" size="large"
v-for="(image, index) in item.images" :key="index">
<template #icon>
<AImage :width="40" :height="40" :src="image">
<template #previewMask>
<EyeOutlined style="font-size: 18px;"/>
</template>
</AImage>
<AImage :width="80" :height="80" v-for="(image, index) in item.images" :key="index" :src="image">
<template #previewMask>
<EyeOutlined style="font-size: 20px;"/>
</template>
</AAvatar>
</AImage>
</AImagePreviewGroup>
</AFlex>
<AFlex :vertical="false" justify="space-between" align="center">
@@ -138,6 +133,7 @@
:default-page-size="comment.commentList.size"
:show-less-items="true"/>
</div>
<AEmpty :description="null" v-show="!comment.commentList.comments"/>
</ASkeleton>
</div>
</template>
@@ -159,8 +155,8 @@ import {
import {useThrottleFn} from "@vueuse/core";
import useStore from "@/store";
import {useRouter} from "vue-router";
import ReplyInput from "@/components/CommentReply/Components/ReplyInput/ReplyInput.vue";
import ReplyList from "@/components/CommentReply/Components/ReplyList/ReplyList.vue";
import ReplyInput from "@/components/CommentReply/src/ReplyInput/ReplyInput.vue";
import ReplyList from "@/components/CommentReply/src/ReplyList/ReplyList.vue";
const {t} = useI18n();

View File

@@ -44,6 +44,9 @@
.reply-card {
width: 600px;
//margin-top: 5px;
.reply-text {
overflow: auto;
}
.reply-images {
margin-top: 5px;
@@ -111,9 +114,5 @@
}
}
}

View File

@@ -25,10 +25,13 @@
<AFlex :vertical="false" align="center" class="comment-action-item-reply">
<APopover trigger="click" placement="bottom">
<template #content>
<div style="width: 170px;height: 200px;overflow: auto;">
<template v-for="(emoji) in EMOJI" :key="emoji">
<AButton @click="insertEmojiToReplyContent(emoji)" type="text" size="large">
{{ emoji }}
<div style="width: 210px;height: 200px;overflow: auto;">
<template v-for="(item) in comment.emojiList" :key="item">
<AButton @click="insertEmojiToReplyContent(item.name)" type="text" shape="circle" size="large"
class="comment-emoji-item">
<template #icon>
<AAvatar shape="circle" size="default" :src="item.path"/>
</template>
</AButton>
</template>
</div>
@@ -50,11 +53,11 @@
:show-upload-list="false"
:custom-request="comment.customUploadRequest"
:before-upload="comment.beforeUpload"
:disabled="comment.imageList.length >= 3"
:disabled="comment.imageList.length >= 3 || comment.uploadLoading"
>
<ABadge :count="comment.imageList.length">
<AButton type="text" size="small" :icon="h(PictureOutlined)"
class="comment-action-icon-reply">
class="comment-action-icon-reply" :loading="comment.uploadLoading">
{{ t('comment.picture') }}
</AButton>
</ABadge>
@@ -101,7 +104,6 @@
import {h, ref} from "vue";
import {message} from "ant-design-vue";
import {CloseOutlined, PictureOutlined, SmileOutlined} from "@ant-design/icons-vue";
import EMOJI from "@/constant/emoji.ts";
import {useI18n} from "vue-i18n";
import useStore from "@/store";
import {useDebounceFn, useThrottleFn} from "@vueuse/core";
@@ -137,7 +139,7 @@ const commentSlideCaptchaEvent = {
* @param emoji
*/
async function insertEmojiToReplyContent(emoji: string) {
replyContent.value += emoji;
replyContent.value += "[" + emoji + "]";
}
@@ -159,7 +161,14 @@ async function replySubmit(point: any) {
return;
}
const content = replyContent.value.replace(/\r\n/g, '<br/>').replace(/\n/g, '<br/>').replace(/\s/g, ' ');
const regex = /\[(\d+\.gif)\]/g; // [1.gif]
const contentWithEmoji = content.replace(regex, (match, p1) => {
const path = comment.emojiMap[p1];
if (path) {
return `<img style="width: 30px; height: 30px;" src="${path}" alt="emoji ${p1}" />`;
}
return match;
});
const replyParams: {
images: any;
reply_id: number;
@@ -173,7 +182,7 @@ async function replySubmit(point: any) {
} = {
user_id: user.user.uid,
topic_id: topicId.value,
content: content,
content: contentWithEmoji,
images: comment.imageList,
author: user.user.uid,
reply_id: props.item.id,

View File

@@ -25,20 +25,17 @@
</AFlex>
<AFlex :vertical="true" align="center">
<ACard class="reply-card-child" :body-style="{padding: '10px'}">
<div class="reply-text-child" v-html="child.content">
<div class="reply-text-child" v-dompurify-html="child.content">
</div>
<AFlex :vertical="false" align="center" class="reply-images" v-if="child.images">
<AImagePreviewGroup>
<AAvatar shape="square" size="large"
v-for="(image, index) in child.images" :key="index">
<template #icon>
<AImage :width="40" :height="40" :src="image">
<template #previewMask>
<EyeOutlined style="font-size: 18px;"/>
</template>
</AImage>
</template>
</AAvatar>
<AImagePreviewGroup>
<AImage :width="80" :height="80" v-for="(image, index) in child.images" :key="index" :src="image">
<template #previewMask>
<EyeOutlined style="font-size: 20px;"/>
</template>
</AImage>
</AImagePreviewGroup>
</AImagePreviewGroup>
</AFlex>
<AFlex :vertical="false" justify="space-between" align="center">
@@ -112,6 +109,7 @@
/>
</AFlex>
<AEmpty :description="null" v-show="!comment.replyList.comments"/>
</ASpin>
</AFlex>
</template>
@@ -128,7 +126,7 @@ import {
} from "@ant-design/icons-vue";
import {useI18n} from "vue-i18n";
import useStore from "@/store";
import ReplyReply from "@/components/CommentReply/Components/ReplyReplyInput/ReplyReply.vue";
import ReplyReply from "@/components/CommentReply/src/ReplyReplyInput/ReplyReply.vue";
import {useThrottleFn} from "@vueuse/core";
const {t} = useI18n();

View File

@@ -28,10 +28,14 @@
<AFlex :vertical="false" align="center" class="comment-action-item-reply-child">
<APopover trigger="click" placement="bottom">
<template #content>
<div style="width: 170px;height: 200px;overflow: auto;">
<template v-for="(emoji) in EMOJI" :key="emoji">
<AButton @click="insertEmojiToReplyReplyContent(emoji)" type="text"
size="large">{{ emoji }}
<div style="width: 210px;height: 200px;overflow: auto;">
<template v-for="(item) in comment.emojiList" :key="item">
<AButton @click="insertEmojiToReplyReplyContent(item.name)" type="text" shape="circle"
size="large"
class="comment-emoji-item">
<template #icon>
<AAvatar shape="circle" size="default" :src="item.path"/>
</template>
</AButton>
</template>
</div>
@@ -53,11 +57,11 @@
:show-upload-list="false"
:custom-request="comment.customUploadRequest"
:before-upload="comment.beforeUpload"
:disabled="comment.imageList.length >= 3"
:disabled="comment.imageList.length >= 3 || comment.uploadLoading"
>
<ABadge :count="comment.imageList.length">
<AButton type="text" size="small" :icon="h(PictureOutlined)"
class="comment-action-icon-reply-child">
class="comment-action-icon-reply-child" :loading="comment.uploadLoading">
{{ t('comment.picture') }}
</AButton>
</ABadge>
@@ -105,7 +109,6 @@
import {h, ref} from "vue";
import {CloseOutlined, PictureOutlined, SmileOutlined} from "@ant-design/icons-vue";
import EMOJI from "@/constant/emoji.ts";
import {useI18n} from "vue-i18n";
import useStore from "@/store";
import {message} from "ant-design-vue";
@@ -149,7 +152,7 @@ const commentSlideCaptchaEvent = {
* @param emoji
*/
async function insertEmojiToReplyReplyContent(emoji: string) {
replyReplyContent.value += emoji;
replyReplyContent.value += "[" + emoji + "]";
}
@@ -171,11 +174,18 @@ async function replyReplySubmit(point: any) {
return;
}
const content = replyReplyContent.value.replace(/\r\n/g, '<br/>').replace(/\n/g, '<br/>').replace(/\s/g, ' ');
const regex = /\[(\d+\.gif)\]/g; // [1.gif]
const contentWithEmoji = content.replace(regex, (match, p1) => {
const path = comment.emojiMap[p1];
if (path) {
return `<img style="width: 30px; height: 30px;" src="${path}" alt="emoji ${p1}" />`;
}
return match;
});
const replyParams: ReplyCommentParams = {
user_id: user.user.uid,
topic_id: topicId.value,
content: content,
content: contentWithEmoji,
images: comment.imageList,
author: user.user.uid,
reply_to: props.child.id,