fix feed empty list rendering

This commit is contained in:
leonincs
2026-04-23 19:00:02 +08:00
parent 89c281c8f0
commit d7a0e2a6b7
10 changed files with 112 additions and 16 deletions

View File

@@ -1,8 +1,10 @@
import { postJson } from './client'
import { normalizeCommentList } from './normalize'
import type { Comment, MessageResponse } from './types'
export function listAll(videoId: number) {
return postJson<Comment[]>('/comment/listAll', { video_id: videoId })
export async function listAll(videoId: number) {
const comments = await postJson<Comment[] | null>('/comment/listAll', { video_id: videoId })
return normalizeCommentList(comments)
}
export function publish(videoId: number, content: string) {

View File

@@ -1,23 +1,28 @@
import { postJson } from './client'
import { normalizeFeedVideoList } from './normalize'
import type { ListByFollowingResponse, ListByPopularityResponse, ListLatestResponse, ListLikesCountResponse } from './types'
export function listLatest(input: { limit: number; latest_time: number }) {
return postJson<ListLatestResponse>('/feed/listLatest', input)
export async function listLatest(input: { limit: number; latest_time: number }) {
const res = await postJson<ListLatestResponse>('/feed/listLatest', input)
return { ...res, video_list: normalizeFeedVideoList(res.video_list) }
}
export function listLikesCount(input: { limit: number; likes_count_before?: number; id_before?: number }) {
export async function listLikesCount(input: { limit: number; likes_count_before?: number; id_before?: number }) {
const body: Record<string, unknown> = { limit: input.limit }
if (typeof input.likes_count_before === 'number' || typeof input.id_before === 'number') {
body.likes_count_before = input.likes_count_before ?? 0
body.id_before = input.id_before ?? 0
}
return postJson<ListLikesCountResponse>('/feed/listLikesCount', body)
const res = await postJson<ListLikesCountResponse>('/feed/listLikesCount', body)
return { ...res, video_list: normalizeFeedVideoList(res.video_list) }
}
export function listByPopularity(input: { limit: number; as_of: number; offset: number }) {
return postJson<ListByPopularityResponse>('/feed/listByPopularity', input)
export async function listByPopularity(input: { limit: number; as_of: number; offset: number }) {
const res = await postJson<ListByPopularityResponse>('/feed/listByPopularity', input)
return { ...res, video_list: normalizeFeedVideoList(res.video_list) }
}
export function listByFollowing(input: { limit: number; latest_time: number }) {
return postJson<ListByFollowingResponse>('/feed/listByFollowing', input, { authRequired: true })
export async function listByFollowing(input: { limit: number; latest_time: number }) {
const res = await postJson<ListByFollowingResponse>('/feed/listByFollowing', input, { authRequired: true })
return { ...res, video_list: normalizeFeedVideoList(res.video_list) }
}

View File

@@ -0,0 +1,57 @@
import type { Account, Comment, FeedAuthor, FeedVideoItem, Video } from './types'
export function listOrEmpty<T>(value: T[] | null | undefined): T[] {
return Array.isArray(value) ? value : []
}
export function normalizeAccount(value: Account | null | undefined): Account {
return {
id: Number(value?.id ?? 0),
username: value?.username || '匿名用户',
}
}
function normalizeAuthor(value: FeedAuthor | null | undefined): FeedAuthor {
return {
id: Number(value?.id ?? 0),
username: value?.username || '匿名用户',
}
}
export function normalizeFeedVideoItem(value: FeedVideoItem): FeedVideoItem {
return {
...value,
author: normalizeAuthor(value.author),
title: value.title || '未命名视频',
description: value.description || '',
play_url: value.play_url || '',
cover_url: value.cover_url || '',
create_time: Number(value.create_time ?? 0),
likes_count: Number(value.likes_count ?? 0),
is_liked: Boolean(value.is_liked),
}
}
export function normalizeFeedVideoList(value: FeedVideoItem[] | null | undefined): FeedVideoItem[] {
return listOrEmpty(value).map(normalizeFeedVideoItem)
}
export function normalizeVideoList(value: Video[] | null | undefined): Video[] {
return listOrEmpty(value).map((video) => ({
...video,
username: video.username || '匿名用户',
title: video.title || '未命名视频',
description: video.description || '',
play_url: video.play_url || '',
cover_url: video.cover_url || '',
likes_count: Number(video.likes_count ?? 0),
}))
}
export function normalizeCommentList(value: Comment[] | null | undefined): Comment[] {
return listOrEmpty(value).map((comment) => ({
...comment,
username: comment.username || '匿名用户',
content: comment.content || '',
}))
}

View File

@@ -1,4 +1,5 @@
import { postJson } from './client'
import { listOrEmpty, normalizeAccount } from './normalize'
import type { GetAllFollowersResponse, GetAllVloggersResponse, MessageResponse } from './types'
export function follow(vloggerId: number) {
@@ -9,18 +10,20 @@ export function unfollow(vloggerId: number) {
return postJson<MessageResponse>('/social/unfollow', { vlogger_id: vloggerId }, { authRequired: true })
}
export function getAllFollowers(vloggerId?: number) {
return postJson<GetAllFollowersResponse>(
export async function getAllFollowers(vloggerId?: number) {
const res = await postJson<GetAllFollowersResponse>(
'/social/getAllFollowers',
vloggerId ? { vlogger_id: vloggerId } : {},
{ authRequired: true },
)
return { ...res, followers: listOrEmpty(res.followers).map(normalizeAccount) }
}
export function getAllVloggers(followerId?: number) {
return postJson<GetAllVloggersResponse>(
export async function getAllVloggers(followerId?: number) {
const res = await postJson<GetAllVloggersResponse>(
'/social/getAllVloggers',
followerId ? { follower_id: followerId } : {},
{ authRequired: true },
)
return { ...res, vloggers: listOrEmpty(res.vloggers).map(normalizeAccount) }
}

View File

@@ -1,4 +1,5 @@
import { postForm, postJson } from './client'
import { normalizeVideoList } from './normalize'
import type { Video } from './types'
export function publishVideo(input: { title: string; description: string; play_url: string; cover_url: string }) {
@@ -19,8 +20,9 @@ export function uploadCover(file: File) {
return postForm<UploadResponse>('/video/uploadCover', fd, { authRequired: true })
}
export function listByAuthorId(authorId: number) {
return postJson<Video[]>('/video/listByAuthorID', { author_id: authorId })
export async function listByAuthorId(authorId: number) {
const videos = await postJson<Video[] | null>('/video/listByAuthorID', { author_id: authorId })
return normalizeVideoList(videos)
}
export function getDetail(id: number) {