mirror of
https://github.com/KuekHaoYang/KVideo.git
synced 2026-08-12 23:33:43 +08:00
Merge remote-tracking branch 'origin/pr-229' into agent/release-4.9.19
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
import type { FavoriteItem } from '@/lib/types';
|
||||
import { FavoritesItem } from './FavoritesItem';
|
||||
import { FavoritesEmptyState } from './FavoritesEmptyState';
|
||||
import { keepRenderableFavorites } from '@/lib/utils/sync-records';
|
||||
|
||||
interface FavoritesListProps {
|
||||
favorites: FavoriteItem[];
|
||||
@@ -19,7 +20,7 @@ export function FavoritesList({ favorites, onRemove, isPremium = false }: Favori
|
||||
|
||||
return (
|
||||
<div className="flex-1 overflow-y-auto -mx-2 px-2 space-y-2 scroll-smooth">
|
||||
{favorites.map((item) => (
|
||||
{keepRenderableFavorites(favorites).map((item) => (
|
||||
<FavoritesItem
|
||||
key={`${item.source}:${item.videoId}`}
|
||||
item={item}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { HistoryItem } from './HistoryItem';
|
||||
import { HistoryEmptyState } from './HistoryEmptyState';
|
||||
import type { VideoHistoryItem } from '@/lib/types';
|
||||
import { keepRenderableHistory } from '@/lib/utils/sync-records';
|
||||
|
||||
interface HistoryListProps {
|
||||
history: VideoHistoryItem[];
|
||||
@@ -18,7 +19,7 @@ export function HistoryList({ history, onRemove, isPremium = false }: HistoryLis
|
||||
<HistoryEmptyState />
|
||||
) : (
|
||||
<div className="space-y-3">
|
||||
{history.map((item) => (
|
||||
{keepRenderableHistory(history).map((item) => (
|
||||
<HistoryItem
|
||||
key={item.showIdentifier}
|
||||
item={item}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useState, useCallback } from 'react';
|
||||
import { useHistoryStore, usePremiumHistoryStore } from '@/lib/store/history-store';
|
||||
import { useFavoritesStore, usePremiumFavoritesStore } from '@/lib/store/favorites-store';
|
||||
import { keepRenderableFavorites, keepRenderableHistory } from '@/lib/utils/sync-records';
|
||||
import { getProfileId } from '@/lib/store/auth-store';
|
||||
|
||||
export function useCloudSync(isPremium = false) {
|
||||
@@ -19,11 +20,14 @@ export function useCloudSync(isPremium = false) {
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success && result.data) {
|
||||
if (result.data.history?.length > 0) {
|
||||
historyStore.getState().importHistory(result.data.history);
|
||||
const history = keepRenderableHistory(result.data.history);
|
||||
const favorites = keepRenderableFavorites(result.data.favorites);
|
||||
|
||||
if (history.length > 0) {
|
||||
historyStore.getState().importHistory(history);
|
||||
}
|
||||
if (result.data.favorites?.length > 0) {
|
||||
favoritesStore.getState().importFavorites(result.data.favorites);
|
||||
if (favorites.length > 0) {
|
||||
favoritesStore.getState().importFavorites(favorites);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import type { FavoriteItem, VideoHistoryItem } from '@/lib/types';
|
||||
|
||||
function hasIdentity(value: unknown): boolean {
|
||||
if (!value || typeof value !== 'object') return false;
|
||||
const record = value as { videoId?: unknown; source?: unknown; title?: unknown };
|
||||
const videoId = record.videoId;
|
||||
const hasVideoId = typeof videoId === 'string' ? videoId.length > 0 : typeof videoId === 'number';
|
||||
|
||||
return hasVideoId && typeof record.source === 'string' && typeof record.title === 'string';
|
||||
}
|
||||
|
||||
/**
|
||||
* Records restored from server-side sync are not guaranteed to be well formed —
|
||||
* they may come from an older schema or a partial write. Rendering one without
|
||||
* `videoId` throws while building the player URL, which takes down the whole
|
||||
* page, so anything lacking a usable identity is dropped on the way in.
|
||||
*/
|
||||
export function isRenderableHistoryItem(value: unknown): value is VideoHistoryItem {
|
||||
return hasIdentity(value);
|
||||
}
|
||||
|
||||
export function isRenderableFavoriteItem(value: unknown): value is FavoriteItem {
|
||||
return hasIdentity(value);
|
||||
}
|
||||
|
||||
export function keepRenderableHistory(items: unknown): VideoHistoryItem[] {
|
||||
return Array.isArray(items) ? items.filter(isRenderableHistoryItem) : [];
|
||||
}
|
||||
|
||||
export function keepRenderableFavorites(items: unknown): FavoriteItem[] {
|
||||
return Array.isArray(items) ? items.filter(isRenderableFavoriteItem) : [];
|
||||
}
|
||||
Reference in New Issue
Block a user