From 40f2f0b2de62aaa85340f1bf50be436a42a0da33 Mon Sep 17 00:00:00 2001 From: landaiqing <3517283258@qq.com> Date: Wed, 2 Oct 2024 01:08:29 +0800 Subject: [PATCH] :art: update comment --- .../src/CommentInput/CommentInput.vue | 36 +++++++++------- .../CommentReply/src/CommentInput/index.scss | 7 +++- .../src/CommentList/CommentList.vue | 2 +- .../CommentReply/src/CommentList/index.scss | 4 ++ .../src/ReplyInput/ReplyInput.vue | 32 +++++++++------ .../src/ReplyReplyInput/ReplyReply.vue | 41 +++++++++++-------- src/directives/v-lazy-load.ts | 26 ++++++++++++ src/main.ts | 3 ++ 8 files changed, 105 insertions(+), 46 deletions(-) create mode 100644 src/directives/v-lazy-load.ts diff --git a/src/components/CommentReply/src/CommentInput/CommentInput.vue b/src/components/CommentReply/src/CommentInput/CommentInput.vue index 35a4daa..67a4fd5 100644 --- a/src/components/CommentReply/src/CommentInput/CommentInput.vue +++ b/src/components/CommentReply/src/CommentInput/CommentInput.vue @@ -2,7 +2,7 @@
- + @@ -46,7 +47,8 @@ @@ -62,7 +64,7 @@ ').replace(/\n/g, '
').replace(/\s/g, ' '); - const regex = /\[((1[0-6][0-6]|[1-9]?[0-9])\.gif)\]/g; // 匹配 [1.gif] 的字符串 - const contentWithEmoji = content.replace(regex, (match, p1) => { - if (emojiType.value === "qq") { - return `emoji ${p1}`; - } else if (emojiType.value === "lottie") { - return `emoji ${p1}`; - } else { - return match; - } + const regex = /\[((1[0-6][0-6]|[1-9]?[0-9])\.gif)]/g; // 匹配 [1.gif] 的字符串 + const contentWithEmoji = content.replace(regex, (_match, p1) => { + return `emoji ${p1}`; + }); + const regexWithLottieEmoji = /:((1[0-0-8]|[1-9]?[0-9])\.gif):/g; // 匹配 :1.gif: 的字符串 + const contentWithLottieEmoji = contentWithEmoji.replace(regexWithLottieEmoji, (_match, p1) => { + return `emoji ${p1}`; }); const commentParams: object = { user_id: user.user.uid, topic_id: topicId.value, - content: contentWithEmoji, + content: contentWithLottieEmoji, images: comment.imageList, author: user.user.uid, point: [point.x, point.y], diff --git a/src/components/CommentReply/src/CommentInput/index.scss b/src/components/CommentReply/src/CommentInput/index.scss index 30ea70c..094449b 100644 --- a/src/components/CommentReply/src/CommentInput/index.scss +++ b/src/components/CommentReply/src/CommentInput/index.scss @@ -1,11 +1,16 @@ +.comment-avatar { + cursor: pointer; +} + .comment-content { margin-left: 20px; .comment-text { width: 600px; } - .comment-editor{ + + .comment-editor { border: 1px solid #d9d9d9; border-radius: 8px; padding: 10px; diff --git a/src/components/CommentReply/src/CommentList/CommentList.vue b/src/components/CommentReply/src/CommentList/CommentList.vue index 6519da3..a3d2c7b 100644 --- a/src/components/CommentReply/src/CommentList/CommentList.vue +++ b/src/components/CommentReply/src/CommentList/CommentList.vue @@ -26,7 +26,7 @@ - + diff --git a/src/components/CommentReply/src/CommentList/index.scss b/src/components/CommentReply/src/CommentList/index.scss index 182851d..b5ec329 100644 --- a/src/components/CommentReply/src/CommentList/index.scss +++ b/src/components/CommentReply/src/CommentList/index.scss @@ -9,6 +9,10 @@ .reply-list { margin-top: 30px; + .reply-avatar-img { + cursor: pointer; + } + .reply-pagination { display: flex; justify-content: flex-end; diff --git a/src/components/CommentReply/src/ReplyInput/ReplyInput.vue b/src/components/CommentReply/src/ReplyInput/ReplyInput.vue index 1f4a728..15dc0ca 100644 --- a/src/components/CommentReply/src/ReplyInput/ReplyInput.vue +++ b/src/components/CommentReply/src/ReplyInput/ReplyInput.vue @@ -37,7 +37,8 @@ @@ -56,7 +57,8 @@ size="large" class="comment-emoji-item" style="width: 75px;height: 75px;"> @@ -73,7 +75,7 @@ ').replace(/\n/g, '
').replace(/\s/g, ' '); const regex = /\[((1[0-6][0-6]|[1-9]?[0-9])\.gif)\]/g; // 匹配 [1.gif] 的字符串 - const contentWithEmoji = content.replace(regex, (match, p1) => { - if (emojiType.value === "qq") { - return `emoji ${p1}`; - } else if (emojiType.value === "lottie") { - return `emoji ${p1}`; - } else { - return match; - } + const contentWithEmoji = content.replace(regex, (_match, p1) => { + return `emoji ${p1}`; + }); + const regexWithLottieEmoji = /\:((1[0-0-8]|[1-9]?[0-9])\.gif)\:/g; // 匹配 :1.gif: 的字符串 + const contentWithLottieEmoji = contentWithEmoji.replace(regexWithLottieEmoji, (_match, p1) => { + return `emoji ${p1}`; }); const replyParams: { images: any; @@ -223,7 +229,7 @@ async function replySubmit(point: any) { } = { user_id: user.user.uid, topic_id: topicId.value, - content: contentWithEmoji, + content: contentWithLottieEmoji, images: comment.imageList, author: user.user.uid, reply_id: props.item.id, diff --git a/src/components/CommentReply/src/ReplyReplyInput/ReplyReply.vue b/src/components/CommentReply/src/ReplyReplyInput/ReplyReply.vue index 7cd15a9..f94e640 100644 --- a/src/components/CommentReply/src/ReplyReplyInput/ReplyReply.vue +++ b/src/components/CommentReply/src/ReplyReplyInput/ReplyReply.vue @@ -37,10 +37,12 @@
@@ -55,10 +57,12 @@
@@ -75,7 +79,7 @@ ("qq"); async function changeEmojiType(type: string) { emojiType.value = type; } + /** * 插入表情到回复内容 * @param emoji */ async function insertEmojiToReplyReplyContent(emoji: string) { - replyReplyContent.value += "[" + emoji + "]"; + if (emojiType.value === "qq") { + replyReplyContent.value += "[" + emoji + "]"; + } else if (emojiType.value === "lottie") { + replyReplyContent.value += ":" + emoji + ":"; + } else { + return; + } } @@ -210,20 +221,18 @@ async function replyReplySubmit(point: any) { return; } const content = replyReplyContent.value.replace(/\r\n/g, '
').replace(/\n/g, '
').replace(/\s/g, ' '); - const regex = /\[((1[0-6][0-6]|[1-9]?[0-9])\.gif)\]/g; // 匹配 [1.gif] 的字符串 - const contentWithEmoji = content.replace(regex, (match, p1) => { - if (emojiType.value === "qq") { - return `emoji ${p1}`; - } else if (emojiType.value === "lottie") { - return `emoji ${p1}`; - } else { - return match; - } + const regex = /\[((1[0-6][0-6]|[1-9]?[0-9])\.gif)]/g; // 匹配 [1.gif] 的字符串 + const contentWithEmoji = content.replace(regex, (_match, p1) => { + return `emoji ${p1}`; + }); + const regexWithLottieEmoji = /:((1[0-0-8]|[1-9]?[0-9])\.gif):/g; // 匹配 :1.gif: 的字符串 + const contentWithLottieEmoji = contentWithEmoji.replace(regexWithLottieEmoji, (_match, p1) => { + return `emoji ${p1}`; }); const replyParams: ReplyCommentParams = { user_id: user.user.uid, topic_id: topicId.value, - content: contentWithEmoji, + content: contentWithLottieEmoji, images: comment.imageList, author: user.user.uid, reply_to: props.child.id, diff --git a/src/directives/v-lazy-load.ts b/src/directives/v-lazy-load.ts new file mode 100644 index 0000000..4c84b8a --- /dev/null +++ b/src/directives/v-lazy-load.ts @@ -0,0 +1,26 @@ +const defaultImg: string = 'data:image/png;base64,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' + +import {useIntersectionObserver} from '@vueuse/core'; + +export default { + mounted(el: HTMLImageElement) { + //如果不是图片的话就不触发懒加载 + if (!(el instanceof HTMLImageElement)) return; + // 把真正的地址暂存起来 + const _src = el.src; + //设置个缺省图片 + el.setAttribute('src', defaultImg); + //如果你不想用vueuse,你也可以用原生的IntersectionObserver接口来实现 + const {stop} = useIntersectionObserver(el, ([{isIntersecting}]) => { + if (isIntersecting) { + //说明到视口中了,那就把真实的地址还原回去 + el.setAttribute('src', _src); + //同时关闭Observer观察 + stop(); + } + }); + }, +}; + + + diff --git a/src/main.ts b/src/main.ts index e93396e..96c3084 100644 --- a/src/main.ts +++ b/src/main.ts @@ -9,11 +9,14 @@ import GoCaptcha from "go-captcha-vue"; import {createPinia, Pinia} from "pinia"; import piniaPluginPersistedstate from "pinia-plugin-persistedstate"; import clickOutside from '@/directives/v-click-outside.ts'; +import lazyLoad from "@/directives/v-lazy-load.ts"; import VueDOMPurifyHTML from 'vue-dompurify-html'; + const pinia: Pinia = createPinia(); pinia.use(piniaPluginPersistedstate); const app = createApp(App); app.directive('click-outside', clickOutside); +app.directive('lazy-load', lazyLoad); app.use(pinia); app.use(router); app.use(i18n);