Skip to content

Commit ecc047b

Browse files
committed
🐞 fix: 修复抱一抱和列表评论切换
Closes #976
1 parent 6efb989 commit ecc047b

9 files changed

Lines changed: 200 additions & 138 deletions

File tree

src/components/List/CommentList.vue

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
<template>
22
<Transition name="fade" mode="out-in">
3-
<n-flex v-if="data.length > 0" :size="20" :class="['comment-list', { transparent }]" vertical>
3+
<n-flex v-if="data.length > 0" key="content" :size="20" :class="['comment-list', { transparent }]" vertical>
44
<n-flex
55
v-for="(item, index) in data"
66
:key="index"
77
:size="0"
88
class="comments"
9-
@dblclick="handleDoubleClick(item)"
109
>
1110
<div v-if="!transparent && !hiddenCover" class="user">
1211
<div class="avatar">
@@ -68,6 +67,10 @@
6867
<SvgIcon name="IP" :depth="3" />
6968
<n-text :depth="3">{{ item.ip.location }}</n-text>
7069
</div>
70+
<!-- 抱一抱 -->
71+
<div class="item hug" @click="handleHug(item)">
72+
<SvgIcon name="FavoriteBorder" :depth="3" />
73+
</div>
7174
<!-- 点赞 -->
7275
<div class="item like" @click="likeComment(item)">
7376
<SvgIcon
@@ -86,11 +89,11 @@
8689
</n-button>
8790
</n-flex>
8891
</n-flex>
89-
<div v-else-if="loading" :class="['comment-list', { transparent }]">
92+
<div v-else-if="loading" key="loading" :class="['comment-list', { transparent }]">
9093
<n-skeleton :repeat="20" />
9194
</div>
9295
<!-- 空列表 -->
93-
<n-empty v-else description="空空如也,怎么什么都没有啊" size="large" />
96+
<n-empty v-else key="empty" description="空空如也,怎么什么都没有啊" size="large" />
9497
</Transition>
9598
</template>
9699

@@ -163,8 +166,8 @@ const likeComment = debounce(async (data: CommentType) => {
163166
}
164167
}, 300);
165168
166-
// 双击抱一抱
167-
const handleDoubleClick = debounce(async (item: CommentType) => {
169+
// 抱一抱
170+
const handleHug = debounce(async (item: CommentType) => {
168171
if (!isLogin()) {
169172
openUserLogin();
170173
return;
@@ -305,8 +308,19 @@ const handleDoubleClick = debounce(async (item: CommentType) => {
305308
margin-right: 4px;
306309
}
307310
}
308-
.like {
311+
.hug {
309312
margin-left: auto;
313+
cursor: pointer;
314+
&:hover {
315+
.n-icon {
316+
color: var(--primary-hex);
317+
:deep(svg) {
318+
opacity: 1;
319+
}
320+
}
321+
}
322+
}
323+
.like {
310324
cursor: pointer;
311325
&:hover {
312326
.n-icon,

src/components/List/ListComment.vue

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,22 +76,27 @@ const commentPage = ref<number>(1);
7676
const commentHasMore = ref<boolean>(true);
7777
const commentTotalCount = ref<number>(0);
7878
79+
// 当前请求的 id,用于竞态保护
80+
const currentRequestId = ref<number>(0);
81+
7982
// 获取热门评论
80-
const getHotCommentData = async () => {
83+
const getHotCommentData = async (requestId: number) => {
8184
if (!props.id) return;
8285
try {
8386
const result = await getHotComment(props.id, props.type);
87+
if (currentRequestId.value !== requestId) return;
8488
const formatData = formatCommentList(result.hotComments);
8589
commentHotData.value = formatData?.length > 0 ? formatData : null;
8690
} catch (error) {
8791
console.error("Error getting hot comment data:", error);
88-
commentHotData.value = null;
92+
if (currentRequestId.value === requestId) commentHotData.value = null;
8993
}
9094
};
9195
9296
// 获取评论数据
9397
const getCommentData = async (clean: boolean = true) => {
9498
if (!props.id) return;
99+
const requestId = clean ? ++currentRequestId.value : currentRequestId.value;
95100
try {
96101
commentLoading.value = true;
97102
if (clean) {
@@ -100,14 +105,16 @@ const getCommentData = async (clean: boolean = true) => {
100105
commentHasMore.value = true;
101106
}
102107
// 获取热门评论
103-
await getHotCommentData();
108+
await getHotCommentData(requestId);
109+
if (currentRequestId.value !== requestId) return;
104110
// 分页参数
105111
const cursor =
106112
commentPage.value > 1 && commentData.value?.length > 0
107113
? commentData.value[commentData.value.length - 1]?.time
108114
: undefined;
109115
// 获取评论
110116
const result = await getComment(props.id, props.type, commentPage.value, 20, 3, cursor);
117+
if (currentRequestId.value !== requestId) return;
111118
// 更新评论总数
112119
if (result.data?.totalCount != null) {
113120
commentTotalCount.value = result.data.totalCount;
@@ -124,6 +131,7 @@ const getCommentData = async (clean: boolean = true) => {
124131
commentHasMore.value = result.data.hasMore;
125132
commentLoading.value = false;
126133
} catch (error) {
134+
if (currentRequestId.value !== requestId) return;
127135
console.error("Error getting comment data:", error);
128136
window.$message.error("获取评论数据失败");
129137
commentLoading.value = false;
@@ -153,11 +161,11 @@ watch(
153161
{ immediate: true },
154162
);
155163
156-
// 如果高度是 auto,停止计算高度
164+
// 传入固定高度时不需要 ResizeObserver
157165
watch(
158166
() => props.height,
159167
(newHeight) => {
160-
if (newHeight === "auto") stopCalcHeight();
168+
if (newHeight != null) stopCalcHeight();
161169
},
162170
{ immediate: true },
163171
);

src/components/List/ListDetail.vue

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,14 @@ const settingStore = useSettingStore();
296296
// 当前 tab
297297
const currentTab = ref<"songs" | "comments">("songs");
298298
299+
// 切换资源时重置 tab
300+
watch(
301+
() => props.detailData?.id,
302+
() => {
303+
currentTab.value = "songs";
304+
},
305+
);
306+
299307
// 标题文本
300308
const titleText = computed(() => {
301309
if (props.titleText) return props.titleText;

src/components/Player/PlayerComponents/PlayerComment.vue

Lines changed: 70 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -44,21 +44,26 @@
4444
</div>
4545
</n-flex>
4646
<n-scrollbar ref="commentScroll" class="comment-scroll">
47-
<template v-if="filteredCommentHotData && filteredCommentHotData.length > 0">
48-
<div class="placeholder">
49-
<div class="title">
50-
<SvgIcon name="Fire" />
51-
<span>热门评论</span>
47+
<Transition name="fade">
48+
<div
49+
v-if="filteredCommentHotData && filteredCommentHotData.length > 0"
50+
class="hot-comments"
51+
>
52+
<div class="placeholder">
53+
<div class="title">
54+
<SvgIcon name="Fire" />
55+
<span>热门评论</span>
56+
</div>
5257
</div>
58+
<CommentList
59+
:data="filteredCommentHotData"
60+
:loading="false"
61+
:type="songType"
62+
:res-id="songId"
63+
transparent
64+
/>
5365
</div>
54-
<CommentList
55-
:data="filteredCommentHotData"
56-
:loading="commentHotData?.length === 0"
57-
:type="songType"
58-
:res-id="songId"
59-
transparent
60-
/>
61-
</template>
66+
</Transition>
6267
<div class="placeholder">
6368
<div class="title">
6469
<SvgIcon name="Message" />
@@ -112,7 +117,7 @@ const songType = computed<0 | 1 | 7 | 2 | 3 | 4 | 5 | 6>(() =>
112117
// 评论数据
113118
const commentLoading = ref<boolean>(true);
114119
const commentData = ref<CommentType[]>([]);
115-
const commentHotData = ref<CommentType[] | null>([]);
120+
const commentHotData = ref<CommentType[] | null>(null);
116121
const commentPage = ref<number>(1);
117122
const commentHasMore = ref<boolean>(true);
118123
@@ -149,11 +154,14 @@ const filteredCommentData = computed(() => filterComments(commentData.value));
149154
const filteredCommentHotData = computed(() => filterComments(commentHotData.value));
150155
151156
// 获取热门评论
152-
const getHotCommentData = async () => {
157+
const getHotCommentData = async (id?: number) => {
158+
const targetId = id ?? songId.value;
153159
// 本地歌曲无法获取评论
154-
if (!songId.value || typeof songId.value !== "number") return;
160+
if (!targetId || typeof targetId !== "number") return;
155161
// 获取评论
156-
const result = await getHotComment(songId.value);
162+
const result = await getHotComment(targetId);
163+
// 确保返回时歌曲未再次变化
164+
if (targetId !== songId.value) return;
157165
// 处理数据
158166
const formatData = formatCommentList(result.hotComments);
159167
commentHotData.value = formatData?.length > 0 ? formatData : null;
@@ -162,29 +170,44 @@ const getHotCommentData = async () => {
162170
};
163171
164172
// 获取歌曲评论
165-
const getAllComment = async () => {
173+
const getAllComment = async (id?: number, reset?: boolean) => {
174+
const targetId = id ?? songId.value;
166175
// 本地歌曲无法获取评论
167-
if (!songId.value || typeof songId.value !== "number") return;
168-
commentLoading.value = true;
176+
if (!targetId || typeof targetId !== "number") return;
177+
// 仅在首次加载时显示骨架屏(追加分页不显示)
178+
if (reset || commentData.value.length === 0) {
179+
commentLoading.value = true;
180+
}
169181
// 分页参数
182+
const page = reset ? 1 : commentPage.value;
170183
const cursor =
171-
commentPage.value > 1 && commentData.value?.length > 0
184+
!reset && page > 1 && commentData.value?.length > 0
172185
? commentData.value[commentData.value.length - 1]?.time
173186
: undefined;
174187
// 获取评论
175-
const result = await getComment(songId.value, songType.value, commentPage.value, 20, 3, cursor);
188+
const result = await getComment(
189+
targetId,
190+
musicStore.playSong.type === "radio" ? 4 : 0,
191+
page,
192+
20,
193+
3,
194+
cursor,
195+
);
196+
// 确保返回时歌曲未再次变化
197+
if (targetId !== songId.value) return;
176198
// 更新评论总数
177199
if (result.data?.totalCount != null) {
178200
statusStore.songCommentCount = result.data.totalCount;
179201
}
180202
if (isEmpty(result.data?.comments)) {
181203
commentHasMore.value = false;
182204
commentLoading.value = false;
205+
if (reset) commentData.value = [];
183206
return;
184207
}
185208
// 处理数据
186209
const formatData = formatCommentList(result.data.comments);
187-
commentData.value = commentData.value.concat(formatData);
210+
commentData.value = reset ? formatData : commentData.value.concat(formatData);
188211
// 是否还有
189212
commentHasMore.value = result.data.hasMore;
190213
commentLoading.value = false;
@@ -196,18 +219,31 @@ const loadMoreComment = () => {
196219
getAllComment();
197220
};
198221
222+
// 重置并加载评论
223+
const resetAndFetch = (id?: number | string) => {
224+
const targetId = id ?? songId.value;
225+
commentPage.value = 1;
226+
commentHasMore.value = true;
227+
statusStore.songCommentCount = 0;
228+
getHotCommentData(typeof targetId === "number" ? targetId : undefined);
229+
getAllComment(typeof targetId === "number" ? targetId : undefined, true);
230+
};
231+
199232
// 歌曲id变化
200233
watch(
201234
() => songId.value,
202-
() => {
203-
commentData.value = [];
204-
commentHotData.value = [];
205-
commentPage.value = 1;
206-
commentHasMore.value = true;
207-
statusStore.songCommentCount = 0;
208-
if (!isShowComment.value) return;
209-
getHotCommentData();
210-
getAllComment();
235+
(newId) => {
236+
if (!isShowComment.value) {
237+
// 不在评论页时,仅标记数据过期,打开时再加载
238+
commentData.value = [];
239+
commentHotData.value = null;
240+
commentPage.value = 1;
241+
commentHasMore.value = true;
242+
commentLoading.value = true;
243+
statusStore.songCommentCount = 0;
244+
return;
245+
}
246+
resetAndFetch(newId);
211247
},
212248
);
213249
@@ -218,16 +254,14 @@ watch(
218254
if (!newVal) return;
219255
// 若不存在数据,重新获取
220256
if (!commentData.value?.length) {
221-
getHotCommentData();
222-
getAllComment();
257+
resetAndFetch();
223258
}
224259
},
225260
);
226261
227262
onMounted(() => {
228263
if (!isShowComment.value) return;
229-
getHotCommentData();
230-
getAllComment();
264+
resetAndFetch();
231265
});
232266
</script>
233267

src/views/Home/index.vue

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,21 @@
1212
</template>
1313

1414
<script setup lang="ts">
15-
import { useSettingStore } from "@/stores";
15+
import { useSettingStore, useDataStore } from "@/stores";
1616
import { getGreeting } from "@/utils/time";
17+
import { isLogin } from "@/utils/auth";
1718
import HomeOnline from "./HomeOnline.vue";
1819
import HomeLocal from "./HomeLocal.vue";
1920
2021
const settingStore = useSettingStore();
22+
const dataStore = useDataStore();
2123
2224
// 问候语
23-
const greetings = computed(getGreeting);
25+
const greetings = computed(() => {
26+
const greeting = getGreeting();
27+
const name = isLogin() ? dataStore.userData.name : "";
28+
return name ? `${greeting},${name}` : greeting;
29+
});
2430
</script>
2531

2632
<style lang="scss" scoped>

0 commit comments

Comments
 (0)