Skip to content

Commit 15af65a

Browse files
ice201508jiuling
andauthored
fix-add-loading-in-likes (#1256)
* Draft MR * fix-add-loading-in-likes --------- Co-authored-by: jiuling <[email protected]>
1 parent a19f66d commit 15af65a

File tree

2 files changed

+77
-35
lines changed

2 files changed

+77
-35
lines changed

frontend/src/components/__tests__/shared/RepoHeader.spec.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,16 @@ vi.mock('@/packs/clipboard', () => ({
1212
vi.mock('@/packs/useFetchApi', () => ({
1313
default: vi.fn((url) => ({
1414
put: () => ({
15-
json: () => Promise.resolve({ error: { value: null } })
15+
json: () => Promise.resolve({
16+
error: { value: null },
17+
response: { value: { status: 200 } }
18+
})
1619
}),
1720
delete: () => ({
18-
json: () => Promise.resolve({ error: { value: null } })
21+
json: () => Promise.resolve({
22+
error: { value: null },
23+
response: { value: { status: 200 } }
24+
})
1925
})
2026
}))
2127
}))
@@ -25,7 +31,15 @@ const mockRepoDetailStore = {
2531
likes: 10,
2632
userLikes: false,
2733
updateLikes: vi.fn(),
28-
updateUserLikes: vi.fn()
34+
updateUserLikes: vi.fn(),
35+
// 添加其他可能需要的属性
36+
hfPath: null,
37+
msPath: null,
38+
csgPath: null,
39+
path: null,
40+
githubPath: null,
41+
githubStarNum: 0,
42+
failedReason: ''
2943
}
3044

3145
vi.mock('@/stores/RepoDetailStore', () => ({

frontend/src/components/shared/RepoHeader.vue

Lines changed: 60 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,11 @@
2525
{{ $t('all.private') }}
2626
</div>
2727
<div
28-
class="flex cursor-pointer gap-1 border border-gray-300 bg-white px-2 pr-1 py-[3px] text-center text-xs text-gray-700 font-normal rounded-sm hover:bg-gray-50 active:ring-4 active:ring-gray-400 active:ring-opacity-25 active:bg-white"
29-
:class="
30-
repoDetailStore.userLikes === true
31-
? 'text-gray-400 border-gray-200'
32-
: ''
33-
"
28+
class="flex gap-1 border border-gray-300 bg-white px-2 pr-1 py-[3px] text-center text-xs text-gray-700 font-normal rounded-sm hover:bg-gray-50 active:ring-4 active:ring-gray-400 active:ring-opacity-25 active:bg-white"
29+
:class="[
30+
repoDetailStore.userLikes === true ? 'text-gray-400 border-gray-200' : '',
31+
isLikeLoading ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'
32+
]"
3433
@click="clickLike">
3534
{{
3635
repoDetailStore.userLikes === false
@@ -136,12 +135,11 @@
136135
{{ $t('all.private') }}
137136
</div>
138137
<div
139-
class="flex cursor-pointer gap-1 border border-gray-300 bg-white px-2 pr-1 py-[3px] text-center text-xs text-gray-700 font-normal rounded-sm hover:bg-gray-50 active:ring-4 active:ring-gray-400 active:ring-opacity-25 active:bg-white"
140-
:class="
141-
repoDetailStore.userLikes === true
142-
? 'text-gray-400 border-gray-200'
143-
: ''
144-
"
138+
class="flex gap-1 border border-gray-300 bg-white px-2 pr-1 py-[3px] text-center text-xs text-gray-700 font-normal rounded-sm hover:bg-gray-50 active:ring-4 active:ring-gray-400 active:ring-opacity-25 active:bg-white"
139+
:class="[
140+
repoDetailStore.userLikes === true ? 'text-gray-400 border-gray-200' : '',
141+
isLikeLoading ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'
142+
]"
145143
@click="clickLike">
146144
{{
147145
repoDetailStore.userLikes === false
@@ -294,6 +292,8 @@
294292
295293
const emit = defineEmits(['toggleSpaceLogsDrawer'])
296294
295+
const isLikeLoading = ref(false)
296+
297297
const props = defineProps({
298298
avatar: String,
299299
name: String,
@@ -358,34 +358,62 @@
358358
}
359359
})
360360
361-
const clickLike = () => {
362-
repoDetailStore.userLikes === true ? removeLike() : addLike()
361+
const clickLike = async () => {
362+
// 如果正在加载中,直接返回,防止重复点击
363+
if (isLikeLoading.value) {
364+
return
365+
}
366+
367+
isLikeLoading.value = true
368+
369+
try {
370+
if (repoDetailStore.userLikes === true) {
371+
await removeLike()
372+
} else {
373+
await addLike()
374+
}
375+
} finally {
376+
// 确保无论成功还是失败都要重置加载状态
377+
isLikeLoading.value = false
378+
}
363379
}
364380
365381
const addLike = async () => {
366-
const { error } = await useFetchApi(likeUrl.value).put().json()
367-
if (error.value) {
368-
ElMessage({
369-
type: 'warning',
370-
message: error.value.msg
371-
})
372-
} else {
373-
repoDetailStore.updateLikes(repoDetailStore.likes + 1)
374-
repoDetailStore.updateUserLikes(true)
382+
const { error, response } = await useFetchApi(likeUrl.value).put().json()
383+
384+
// 检查是否有错误或者响应状态码不是2xx
385+
if (error.value || (response.value && response.value?.status >= 400)) {
386+
// 如果是401状态码,不需要显示错误消息,因为会自动弹出登录对话框
387+
if (response.value && response.value?.status !== 401) {
388+
ElMessage({
389+
type: 'warning',
390+
message: error.value?.msg || '请求失败'
391+
})
392+
}
393+
return
375394
}
395+
396+
repoDetailStore.updateLikes(repoDetailStore.likes + 1)
397+
repoDetailStore.updateUserLikes(true)
376398
}
377399
378400
const removeLike = async () => {
379-
const { error } = await useFetchApi(likeUrl.value).delete().json()
380-
if (error.value) {
381-
ElMessage({
382-
type: 'warning',
383-
message: error.value.msg
384-
})
385-
} else {
386-
repoDetailStore.updateLikes(repoDetailStore.likes - 1)
387-
repoDetailStore.updateUserLikes(false)
401+
const { error, response } = await useFetchApi(likeUrl.value).delete().json()
402+
403+
// 检查是否有错误或者响应状态码不是2xx
404+
if (error.value || (response.value && response.value?.status >= 400)) {
405+
// 如果是401状态码,不需要显示错误消息,因为会自动弹出登录对话框
406+
if (response.value && response.value?.status !== 401) {
407+
ElMessage({
408+
type: 'warning',
409+
message: error.value?.msg || '请求失败'
410+
})
411+
}
412+
return
388413
}
414+
415+
repoDetailStore.updateLikes(repoDetailStore.likes - 1)
416+
repoDetailStore.updateUserLikes(false)
389417
}
390418
391419
const repoUrl = computed(() => {

0 commit comments

Comments
 (0)