mirror of
https://github.com/nagisa77/OpenIsle.git
synced 2026-04-21 11:27:27 +08:00
feat: 评论嵌套规则修复
This commit is contained in:
@@ -10,7 +10,11 @@
|
|||||||
<div class="info-content">
|
<div class="info-content">
|
||||||
<div class="common-info-content-header">
|
<div class="common-info-content-header">
|
||||||
<div class="info-content-header-left">
|
<div class="info-content-header-left">
|
||||||
<div class="user-name">{{ comment.userName }}</div>
|
<span class="user-name">{{ comment.userName }}</span>
|
||||||
|
<span v-if="level >= 2">
|
||||||
|
<i class="fas fa-reply reply-icon"></i>
|
||||||
|
<span class="user-name reply-user-name">{{ comment.parentUserName }}</span>
|
||||||
|
</span>
|
||||||
<div class="post-time">{{ comment.time }}</div>
|
<div class="post-time">{{ comment.time }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-content-header-right">
|
<div class="info-content-header-right">
|
||||||
@@ -33,33 +37,23 @@
|
|||||||
</ReactionsGroup>
|
</ReactionsGroup>
|
||||||
</div>
|
</div>
|
||||||
<div class="comment-editor-wrapper">
|
<div class="comment-editor-wrapper">
|
||||||
<CommentEditor v-if="showEditor" @submit="submitReply" :loading="isWaitingForReply" :disabled="!loggedIn" :show-login-overlay="!loggedIn" />
|
<CommentEditor v-if="showEditor" @submit="submitReply" :loading="isWaitingForReply" :disabled="!loggedIn"
|
||||||
|
:show-login-overlay="!loggedIn" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="replyCount" class="reply-toggle" @click="toggleReplies">
|
<div v-if="replyCount && level < 2" class="reply-toggle" @click="toggleReplies">
|
||||||
<i v-if="showReplies" class="fas fa-chevron-up reply-toggle-icon"></i>
|
<i v-if="showReplies" class="fas fa-chevron-up reply-toggle-icon"></i>
|
||||||
<i v-else class="fas fa-chevron-down reply-toggle-icon"></i>
|
<i v-else class="fas fa-chevron-down reply-toggle-icon"></i>
|
||||||
{{ replyCount }}条回复
|
{{ replyCount }}条回复
|
||||||
</div>
|
</div>
|
||||||
<div v-if="showReplies" class="reply-list">
|
<div v-if="showReplies && level < 2" class="reply-list">
|
||||||
<BaseTimeline :items="comment.reply">
|
<BaseTimeline :items="replyList">
|
||||||
<template #item="{ item }">
|
<template #item="{ item }">
|
||||||
<CommentItem :key="item.id" :comment="item" :level="level + 1" :default-show-replies="item.openReplies" />
|
<CommentItem :key="item.id" :comment="item" :level="level + 1" :default-show-replies="item.openReplies" />
|
||||||
</template>
|
</template>
|
||||||
</BaseTimeline>
|
</BaseTimeline>
|
||||||
<!-- <CommentItem
|
|
||||||
v-for="r in comment.reply"
|
|
||||||
:key="r.id"
|
|
||||||
:comment="r"
|
|
||||||
:level="level + 1"
|
|
||||||
:default-show-replies="r.openReplies"
|
|
||||||
/> -->
|
|
||||||
</div>
|
</div>
|
||||||
<vue-easy-lightbox
|
<vue-easy-lightbox :visible="lightboxVisible" :imgs="lightboxImgs" :index="lightboxIndex"
|
||||||
:visible="lightboxVisible"
|
@hide="lightboxVisible = false" />
|
||||||
:imgs="lightboxImgs"
|
|
||||||
:index="lightboxIndex"
|
|
||||||
@hide="lightboxVisible = false"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -118,6 +112,27 @@ const CommentItem = {
|
|||||||
const toggleEditor = () => {
|
const toggleEditor = () => {
|
||||||
showEditor.value = !showEditor.value
|
showEditor.value = !showEditor.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 合并所有子回复为一个扁平数组
|
||||||
|
const flattenReplies = (list) => {
|
||||||
|
let result = []
|
||||||
|
for (const r of list) {
|
||||||
|
result.push(r)
|
||||||
|
if (r.reply && r.reply.length > 0) {
|
||||||
|
result = result.concat(flattenReplies(r.reply))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
const replyList = computed(() => {
|
||||||
|
if (props.level < 1) {
|
||||||
|
return props.comment.reply
|
||||||
|
}
|
||||||
|
|
||||||
|
return flattenReplies(props.comment.reply || [])
|
||||||
|
})
|
||||||
|
|
||||||
const isAuthor = computed(() => authState.username === props.comment.userName)
|
const isAuthor = computed(() => authState.username === props.comment.userName)
|
||||||
const isAdmin = computed(() => authState.role === 'ADMIN')
|
const isAdmin = computed(() => authState.role === 'ADMIN')
|
||||||
const commentMenuItems = computed(() =>
|
const commentMenuItems = computed(() =>
|
||||||
@@ -208,7 +223,7 @@ const CommentItem = {
|
|||||||
lightboxVisible.value = true
|
lightboxVisible.value = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { showReplies, toggleReplies, showEditor, toggleEditor, submitReply, copyCommentLink, renderMarkdown, isWaitingForReply, commentMenuItems, deleteComment, lightboxVisible, lightboxIndex, lightboxImgs, handleContentClick, loggedIn, replyCount }
|
return { showReplies, toggleReplies, showEditor, toggleEditor, submitReply, copyCommentLink, renderMarkdown, isWaitingForReply, commentMenuItems, deleteComment, lightboxVisible, lightboxIndex, lightboxImgs, handleContentClick, loggedIn, replyCount, replyList }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,6 +264,15 @@ export default CommentItem
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.reply-icon {
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-left: 10px;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-user-name {
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes highlight {
|
@keyframes highlight {
|
||||||
from {
|
from {
|
||||||
|
|||||||
@@ -216,17 +216,18 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapComment = (c, level = 0) => ({
|
const mapComment = (c, parentUserName = '', level = 0) => ({
|
||||||
id: c.id,
|
id: c.id,
|
||||||
userName: c.author.username,
|
userName: c.author.username,
|
||||||
time: TimeManager.format(c.createdAt),
|
time: TimeManager.format(c.createdAt),
|
||||||
avatar: c.author.avatar,
|
avatar: c.author.avatar,
|
||||||
text: c.content,
|
text: c.content,
|
||||||
reactions: c.reactions || [],
|
reactions: c.reactions || [],
|
||||||
reply: (c.replies || []).map(r => mapComment(r, level + 1)),
|
reply: (c.replies || []).map(r => mapComment(r, c.author.username, level + 1)),
|
||||||
openReplies: level === 0,
|
openReplies: level === 0,
|
||||||
src: c.author.avatar,
|
src: c.author.avatar,
|
||||||
iconClick: () => router.push(`/users/${c.author.id}`)
|
iconClick: () => router.push(`/users/${c.author.id}`),
|
||||||
|
parentUserName: parentUserName
|
||||||
})
|
})
|
||||||
|
|
||||||
const getTopRelativeTo = (el, container) => {
|
const getTopRelativeTo = (el, container) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user