Compare commits

...

4 Commits

Author SHA1 Message Date
Tim
13cc981421 feat: show placeholder when timeline empty 2025-09-17 21:19:36 +08:00
Tim
efc8589ca0 Merge pull request #996 from nagisa77/codex/implement-reaction-group-gradient-sorting-zszqdc
feat: sort reactions by popularity
2025-09-17 20:58:31 +08:00
Tim
940690889c feat: sort reactions by popularity 2025-09-17 20:36:18 +08:00
Tim
d46420ef81 Merge pull request #993 from nagisa77/codex/fix-compilation-error-in-postservicetest
Fix PostServiceTest constructor parameters
2025-09-17 14:23:44 +08:00
2 changed files with 48 additions and 10 deletions

View File

@@ -107,14 +107,52 @@ const likeCount = computed(() => counts.value['LIKE'] || 0)
const userReacted = (type) =>
reactions.value.some((r) => r.type === type && r.user === authState.username)
const displayedReactions = computed(() => {
return Object.entries(counts.value)
.sort((a, b) => b[1] - a[1])
.slice(0, 3)
.map(([type]) => ({ type }))
const baseReactionOrder = computed(() => {
if (reactionTypes.value.length) return [...reactionTypes.value]
const order = []
const seen = new Set()
for (const reaction of reactions.value) {
if (!seen.has(reaction.type)) {
seen.add(reaction.type)
order.push(reaction.type)
}
}
return order
})
const panelTypes = computed(() => reactionTypes.value.filter((t) => t !== 'LIKE'))
const sortedReactionTypes = computed(() => {
const baseOrder = [...baseReactionOrder.value]
for (const type of Object.keys(counts.value)) {
if (!baseOrder.includes(type)) baseOrder.push(type)
}
const withMetadata = baseOrder.map((type, index) => ({
type,
count: counts.value[type] || 0,
index,
}))
const nonZero = withMetadata
.filter((item) => item.count > 0)
.sort((a, b) => {
if (b.count !== a.count) return b.count - a.count
return a.index - b.index
})
const zero = withMetadata.filter((item) => item.count === 0)
return [...nonZero, ...zero].map((item) => item.type)
})
const displayedReactions = computed(() => {
return sortedReactionTypes.value
.filter((type) => counts.value[type] > 0)
.slice(0, 3)
.map((type) => ({ type }))
})
const panelTypes = computed(() => sortedReactionTypes.value.filter((t) => t !== 'LIKE'))
const panelVisible = ref(false)
let hideTimer = null

View File

@@ -122,7 +122,8 @@
<l-hatch size="28" stroke="4" speed="3.5" color="var(--primary-color)"></l-hatch>
</div>
<div v-else class="comments-container">
<BaseTimeline :items="timelineItems">
<BasePlaceholder v-if="timelineItems.length === 0" text="暂无评论" icon="inbox" />
<BaseTimeline v-else :items="timelineItems">
<template #item="{ item }">
<CommentItem
v-if="item.kind === 'comment'"
@@ -184,6 +185,7 @@ import { useRoute } from 'vue-router'
import CommentItem from '~/components/CommentItem.vue'
import CommentEditor from '~/components/CommentEditor.vue'
import BaseTimeline from '~/components/BaseTimeline.vue'
import BasePlaceholder from '~/components/BasePlaceholder.vue'
import PostChangeLogItem from '~/components/PostChangeLogItem.vue'
import ArticleTags from '~/components/ArticleTags.vue'
import ArticleCategory from '~/components/ArticleCategory.vue'
@@ -813,9 +815,7 @@ const fetchCommentsAndChangeLog = async () => {
for (const item of data) {
const mappedPayload =
item.kind === 'comment'
? mapComment(item.payload)
: mapChangeLog(item.payload)
item.kind === 'comment' ? mapComment(item.payload) : mapChangeLog(item.payload)
newTimelineItemList.push(mappedPayload)
if (item.kind === 'comment') {