refactor(frontend): Rework home and video detail interactions
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
</button>
|
||||
<div>
|
||||
<strong>{{ favoriteTitle }}</strong>
|
||||
<span>{{ total }} 个视频</span>
|
||||
<span>{{ displayTotal }} 个视频</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="head-actions">
|
||||
@@ -101,10 +101,12 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { showConfirmDialog, showSuccessToast, showToast } from 'vant'
|
||||
import { showConfirmDialog } from 'vant'
|
||||
import { showSuccessToast, showToast } from '@/utils/toast'
|
||||
import VideoCard from '@/components/video/VideoCard.vue'
|
||||
import { favoriteApi, type Favorite } from '@/api/favorite.ts'
|
||||
import { videoApi } from '@/api/video.ts'
|
||||
import { userApi } from '@/api/user.ts'
|
||||
import type { VideoInfo } from '@/types'
|
||||
|
||||
const route = useRoute()
|
||||
@@ -113,6 +115,7 @@ const favoriteId = computed(() => Number(route.params.id))
|
||||
const currentFavorite = ref<Favorite | null>(null)
|
||||
const favoriteTitle = computed(() => currentFavorite.value?.name || '收藏夹')
|
||||
const videos = ref<VideoInfo[]>([])
|
||||
const displayTotal = computed(() => Math.max(total.value, videos.value.length))
|
||||
const loading = ref(false)
|
||||
const finished = ref(false)
|
||||
const page = ref(1)
|
||||
@@ -126,6 +129,43 @@ const editForm = ref({
|
||||
isPrivate: 0
|
||||
})
|
||||
|
||||
const hydrateVideoAuthors = async (items: VideoInfo[]) => {
|
||||
const missingUserIds = [...new Set(
|
||||
items
|
||||
.filter((item) => item.userId && (!item.userNickname || !item.userAvatar))
|
||||
.map((item) => item.userId)
|
||||
)]
|
||||
|
||||
if (!missingUserIds.length) {
|
||||
return items
|
||||
}
|
||||
|
||||
const profiles = await Promise.all(
|
||||
missingUserIds.map(async (userId) => {
|
||||
try {
|
||||
const profile = await userApi.getPublicProfile(userId)
|
||||
return [userId, profile] as const
|
||||
} catch {
|
||||
return [userId, null] as const
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
const profileMap = new Map(profiles)
|
||||
return items.map((item) => {
|
||||
const profile = profileMap.get(item.userId)
|
||||
if (!profile) {
|
||||
return item
|
||||
}
|
||||
|
||||
return {
|
||||
...item,
|
||||
userNickname: item.userNickname || profile.nickname,
|
||||
userAvatar: item.userAvatar || profile.avatar
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const loadFavoriteMeta = async () => {
|
||||
try {
|
||||
const favorites = await favoriteApi.getFavoriteList()
|
||||
@@ -151,7 +191,8 @@ const loadMore = async () => {
|
||||
pageNum: page.value,
|
||||
pageSize: 12
|
||||
})
|
||||
videos.value.push(...res.records)
|
||||
const hydratedRecords = await hydrateVideoAuthors(res.records)
|
||||
videos.value.push(...hydratedRecords)
|
||||
total.value = res.total
|
||||
if (videos.value.length >= res.total || res.records.length < 12) finished.value = true
|
||||
page.value += 1
|
||||
|
||||
Reference in New Issue
Block a user