fix feed empty list rendering
This commit is contained in:
@@ -37,6 +37,7 @@ func (f *FeedHandler) ListLatest(c *gin.Context) {
|
||||
c.JSON(500, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
feedItems.VideoList = nonNilFeedVideoItems(feedItems.VideoList)
|
||||
c.JSON(200, feedItems)
|
||||
}
|
||||
|
||||
@@ -85,6 +86,7 @@ func (f *FeedHandler) ListLikesCount(c *gin.Context) {
|
||||
c.JSON(500, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
feedItems.VideoList = nonNilFeedVideoItems(feedItems.VideoList)
|
||||
c.JSON(200, feedItems)
|
||||
}
|
||||
|
||||
@@ -110,6 +112,7 @@ func (f *FeedHandler) ListByFollowing(c *gin.Context) {
|
||||
c.JSON(500, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
feedItems.VideoList = nonNilFeedVideoItems(feedItems.VideoList)
|
||||
c.JSON(200, feedItems)
|
||||
}
|
||||
|
||||
@@ -160,5 +163,13 @@ func (f *FeedHandler) ListByPopularity(c *gin.Context) {
|
||||
c.JSON(500, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
resp.VideoList = nonNilFeedVideoItems(resp.VideoList)
|
||||
c.JSON(200, resp)
|
||||
}
|
||||
|
||||
func nonNilFeedVideoItems(items []FeedVideoItem) []FeedVideoItem {
|
||||
if items == nil {
|
||||
return []FeedVideoItem{}
|
||||
}
|
||||
return items
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package social
|
||||
|
||||
import (
|
||||
"feedsystem_video_go/internal/account"
|
||||
"feedsystem_video_go/internal/middleware/jwt"
|
||||
"net/http"
|
||||
|
||||
@@ -89,6 +90,9 @@ func (h *SocialHandler) GetAllFollowers(c *gin.Context) {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
if followers == nil {
|
||||
followers = []*account.Account{}
|
||||
}
|
||||
c.JSON(http.StatusOK, GetAllFollowersResponse{Followers: followers})
|
||||
}
|
||||
|
||||
@@ -114,5 +118,8 @@ func (h *SocialHandler) GetAllVloggers(c *gin.Context) {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
if vloggers == nil {
|
||||
vloggers = []*account.Account{}
|
||||
}
|
||||
c.JSON(http.StatusOK, GetAllVloggersResponse{Vloggers: vloggers})
|
||||
}
|
||||
|
||||
@@ -90,5 +90,8 @@ func (h *CommentHandler) GetAllComments(c *gin.Context) {
|
||||
c.JSON(400, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
if comments == nil {
|
||||
comments = []Comment{}
|
||||
}
|
||||
c.JSON(200, comments)
|
||||
}
|
||||
|
||||
@@ -106,5 +106,8 @@ func (lh *LikeHandler) ListMyLikedVideos(c *gin.Context) {
|
||||
c.JSON(500, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
if videos == nil {
|
||||
videos = []Video{}
|
||||
}
|
||||
c.JSON(200, videos)
|
||||
}
|
||||
|
||||
@@ -207,6 +207,9 @@ func (vh *VideoHandler) ListByAuthorID(c *gin.Context) {
|
||||
c.JSON(400, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
if videos == nil {
|
||||
videos = []Video{}
|
||||
}
|
||||
c.JSON(200, videos)
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) }
|
||||
}
|
||||
|
||||
57
frontend/src/api/normalize.ts
Normal file
57
frontend/src/api/normalize.ts
Normal 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 || '',
|
||||
}))
|
||||
}
|
||||
@@ -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) }
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user