fix: 正确处理“我追的合集 / 收藏夹”中的收藏夹条目,以及一些样式、文本调整 (#553)
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
import BotIcon from '@lucide/svelte/icons/bot';
|
||||
import ChartPieIcon from '@lucide/svelte/icons/chart-pie';
|
||||
import HeartIcon from '@lucide/svelte/icons/heart';
|
||||
import FolderIcon from '@lucide/svelte/icons/folder';
|
||||
import FoldersIcon from '@lucide/svelte/icons/folders';
|
||||
import UserIcon from '@lucide/svelte/icons/user';
|
||||
import Settings2Icon from '@lucide/svelte/icons/settings-2';
|
||||
import SquareTerminalIcon from '@lucide/svelte/icons/square-terminal';
|
||||
@@ -62,12 +62,12 @@
|
||||
href: '/me/favorites'
|
||||
},
|
||||
{
|
||||
title: '我关注的合集',
|
||||
icon: FolderIcon,
|
||||
title: '我追的合集 / 收藏夹',
|
||||
icon: FoldersIcon,
|
||||
href: '/me/collections'
|
||||
},
|
||||
{
|
||||
title: '我关注的 up 主',
|
||||
title: '我关注的 UP 主',
|
||||
icon: UserIcon,
|
||||
href: '/me/uppers'
|
||||
}
|
||||
|
||||
@@ -10,28 +10,20 @@
|
||||
import CheckIcon from '@lucide/svelte/icons/check';
|
||||
import PlusIcon from '@lucide/svelte/icons/plus';
|
||||
import XIcon from '@lucide/svelte/icons/x';
|
||||
import type {
|
||||
FavoriteWithSubscriptionStatus,
|
||||
CollectionWithSubscriptionStatus,
|
||||
UpperWithSubscriptionStatus
|
||||
} from '$lib/types';
|
||||
import type { Followed } from '$lib/types';
|
||||
|
||||
export let item:
|
||||
| FavoriteWithSubscriptionStatus
|
||||
| CollectionWithSubscriptionStatus
|
||||
| UpperWithSubscriptionStatus;
|
||||
export let type: 'favorites' | 'collections' | 'submissions' = 'favorites';
|
||||
export let item: Followed;
|
||||
export let onSubscriptionSuccess: (() => void) | null = null;
|
||||
|
||||
let dialogOpen = false;
|
||||
|
||||
function getIcon() {
|
||||
switch (type) {
|
||||
case 'favorites':
|
||||
switch (item.type) {
|
||||
case 'favorite':
|
||||
return HeartIcon;
|
||||
case 'collections':
|
||||
case 'collection':
|
||||
return FolderIcon;
|
||||
case 'submissions':
|
||||
case 'upper':
|
||||
return UserIcon;
|
||||
default:
|
||||
return VideoIcon;
|
||||
@@ -39,12 +31,12 @@
|
||||
}
|
||||
|
||||
function getTypeLabel() {
|
||||
switch (type) {
|
||||
case 'favorites':
|
||||
switch (item.type) {
|
||||
case 'favorite':
|
||||
return '收藏夹';
|
||||
case 'collections':
|
||||
case 'collection':
|
||||
return '合集';
|
||||
case 'submissions':
|
||||
case 'upper':
|
||||
return 'UP 主';
|
||||
default:
|
||||
return '';
|
||||
@@ -52,55 +44,52 @@
|
||||
}
|
||||
|
||||
function getTitle(): string {
|
||||
switch (type) {
|
||||
case 'favorites':
|
||||
return (item as FavoriteWithSubscriptionStatus).title;
|
||||
case 'collections':
|
||||
return (item as CollectionWithSubscriptionStatus).title;
|
||||
case 'submissions':
|
||||
return (item as UpperWithSubscriptionStatus).uname;
|
||||
switch (item.type) {
|
||||
case 'favorite':
|
||||
case 'collection':
|
||||
return item.title;
|
||||
case 'upper':
|
||||
return item.uname;
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function getSubtitle(): string {
|
||||
switch (type) {
|
||||
case 'favorites':
|
||||
return `uid: ${(item as FavoriteWithSubscriptionStatus).mid}`;
|
||||
case 'collections':
|
||||
return `uid: ${(item as CollectionWithSubscriptionStatus).mid}`;
|
||||
switch (item.type) {
|
||||
case 'favorite':
|
||||
case 'collection':
|
||||
return `UID:${item.mid}`;
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function getDescription(): string {
|
||||
switch (type) {
|
||||
case 'submissions':
|
||||
return (item as UpperWithSubscriptionStatus).sign || '';
|
||||
switch (item.type) {
|
||||
case 'upper':
|
||||
return item.sign || '';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function isDisabled(): boolean {
|
||||
switch (type) {
|
||||
case 'collections':
|
||||
return (item as CollectionWithSubscriptionStatus).invalid;
|
||||
case 'submissions': {
|
||||
return (item as UpperWithSubscriptionStatus).invalid;
|
||||
}
|
||||
switch (item.type) {
|
||||
case 'collection':
|
||||
case 'upper':
|
||||
case 'favorite':
|
||||
return item.invalid;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function getDisabledReason(): string {
|
||||
switch (type) {
|
||||
case 'collections':
|
||||
switch (item.type) {
|
||||
case 'collection':
|
||||
return '已失效';
|
||||
case 'submissions':
|
||||
case 'upper':
|
||||
return '账号已注销';
|
||||
default:
|
||||
return '';
|
||||
@@ -108,22 +97,19 @@
|
||||
}
|
||||
|
||||
function getCount(): number | null {
|
||||
switch (type) {
|
||||
case 'favorites':
|
||||
return (item as FavoriteWithSubscriptionStatus).media_count;
|
||||
switch (item.type) {
|
||||
case 'favorite':
|
||||
case 'collection':
|
||||
return item.media_count;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function getCountLabel(): string {
|
||||
return '个视频';
|
||||
}
|
||||
|
||||
function getAvatarUrl(): string {
|
||||
switch (type) {
|
||||
case 'submissions':
|
||||
return (item as UpperWithSubscriptionStatus).face;
|
||||
switch (item.type) {
|
||||
case 'upper':
|
||||
return item.face;
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
@@ -149,7 +135,6 @@
|
||||
const subtitle = getSubtitle();
|
||||
const description = getDescription();
|
||||
const count = getCount();
|
||||
const countLabel = getCountLabel();
|
||||
const avatarUrl = getAvatarUrl();
|
||||
const subscribed = item.subscribed;
|
||||
const disabled = isDisabled();
|
||||
@@ -161,7 +146,7 @@
|
||||
? 'opacity-60'
|
||||
: ''}"
|
||||
>
|
||||
<CardHeader class="flex-shrink-0 pb-4">
|
||||
<CardHeader class="flex-shrink-0">
|
||||
<div class="flex items-start gap-3">
|
||||
<!-- 头像或图标 - 简化设计 -->
|
||||
<div
|
||||
@@ -169,7 +154,7 @@
|
||||
? 'opacity-50'
|
||||
: ''}"
|
||||
>
|
||||
{#if avatarUrl && type === 'submissions'}
|
||||
{#if avatarUrl && item.type === 'upper'}
|
||||
<img
|
||||
src={avatarUrl}
|
||||
alt={title}
|
||||
@@ -197,7 +182,7 @@
|
||||
{#if disabled}
|
||||
<Badge variant="destructive" class="shrink-0 text-xs">不可用</Badge>
|
||||
{:else}
|
||||
<Badge variant={subscribed ? 'outline' : 'secondary'} class="shrink-0 text-xs">
|
||||
<Badge variant="secondary" class="shrink-0 text-xs">
|
||||
{subscribed ? '已订阅' : typeLabel}
|
||||
</Badge>
|
||||
{/if}
|
||||
@@ -211,25 +196,26 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- 计数信息 -->
|
||||
{#if count !== null && !disabled}
|
||||
<div class="text-muted-foreground flex items-center gap-1 text-sm">
|
||||
<VideoIcon class="h-3 w-3 shrink-0" />
|
||||
<span class="truncate">视频数:{count}</span>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- 描述信息 -->
|
||||
{#if description && !disabled}
|
||||
<p class="text-muted-foreground line-clamp-1 text-sm" title={description}>
|
||||
{description}
|
||||
</p>
|
||||
{/if}
|
||||
|
||||
<!-- 计数信息 -->
|
||||
{#if count !== null && !disabled}
|
||||
<div class="text-muted-foreground text-sm">
|
||||
{count}
|
||||
{countLabel}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</CardHeader>
|
||||
|
||||
<!-- 底部按钮区域 -->
|
||||
<CardContent class="flex min-w-0 flex-1 flex-col justify-end pt-0 pb-4">
|
||||
<CardContent class="flex min-w-0 flex-1 flex-col justify-end">
|
||||
<div class="flex justify-end">
|
||||
{#if disabled}
|
||||
<Button
|
||||
@@ -262,4 +248,4 @@
|
||||
</Card>
|
||||
|
||||
<!-- 订阅对话框 -->
|
||||
<SubscriptionDialog bind:open={dialogOpen} {item} {type} onSuccess={handleSubscriptionSuccess} />
|
||||
<SubscriptionDialog bind:open={dialogOpen} {item} onSuccess={handleSubscriptionSuccess} />
|
||||
|
||||
@@ -13,9 +13,7 @@
|
||||
} from '$lib/components/ui/sheet/index.js';
|
||||
import api from '$lib/api';
|
||||
import type {
|
||||
FavoriteWithSubscriptionStatus,
|
||||
CollectionWithSubscriptionStatus,
|
||||
UpperWithSubscriptionStatus,
|
||||
Followed,
|
||||
InsertFavoriteRequest,
|
||||
InsertCollectionRequest,
|
||||
InsertSubmissionRequest,
|
||||
@@ -24,38 +22,37 @@
|
||||
|
||||
interface Props {
|
||||
open: boolean;
|
||||
item:
|
||||
| FavoriteWithSubscriptionStatus
|
||||
| CollectionWithSubscriptionStatus
|
||||
| UpperWithSubscriptionStatus
|
||||
| null;
|
||||
type: 'favorites' | 'collections' | 'submissions';
|
||||
item: Followed | null;
|
||||
onSuccess: (() => void) | null;
|
||||
}
|
||||
|
||||
let {
|
||||
open = $bindable(false),
|
||||
item = null,
|
||||
type = 'favorites',
|
||||
onSuccess = null
|
||||
}: Props = $props();
|
||||
let { open = $bindable(false), item = null, onSuccess = null }: Props = $props();
|
||||
|
||||
let customPath = $state('');
|
||||
let loading = $state(false);
|
||||
|
||||
// 根据类型和 item 生成默认路径
|
||||
async function generateDefaultPath(): Promise<string> {
|
||||
if (!itemTitle) return '';
|
||||
return (await api.getDefaultPath(type, itemTitle)).data;
|
||||
if (!item || !itemTitle) return '';
|
||||
// 根据 item.type 映射到对应的 API 类型
|
||||
const apiType =
|
||||
item.type === 'favorite'
|
||||
? 'favorites'
|
||||
: item.type === 'collection'
|
||||
? 'collections'
|
||||
: 'submissions';
|
||||
return (await api.getDefaultPath(apiType, itemTitle)).data;
|
||||
}
|
||||
|
||||
function getTypeLabel(): string {
|
||||
switch (type) {
|
||||
case 'favorites':
|
||||
if (!item) return '';
|
||||
|
||||
switch (item.type) {
|
||||
case 'favorite':
|
||||
return '收藏夹';
|
||||
case 'collections':
|
||||
case 'collection':
|
||||
return '合集';
|
||||
case 'submissions':
|
||||
case 'upper':
|
||||
return 'UP 主';
|
||||
default:
|
||||
return '';
|
||||
@@ -65,13 +62,12 @@
|
||||
function getItemTitle(): string {
|
||||
if (!item) return '';
|
||||
|
||||
switch (type) {
|
||||
case 'favorites':
|
||||
return (item as FavoriteWithSubscriptionStatus).title;
|
||||
case 'collections':
|
||||
return (item as CollectionWithSubscriptionStatus).title;
|
||||
case 'submissions':
|
||||
return (item as UpperWithSubscriptionStatus).uname;
|
||||
switch (item.type) {
|
||||
case 'favorite':
|
||||
case 'collection':
|
||||
return item.title;
|
||||
case 'upper':
|
||||
return item.uname;
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
@@ -84,30 +80,27 @@
|
||||
try {
|
||||
let response;
|
||||
|
||||
switch (type) {
|
||||
case 'favorites': {
|
||||
const favorite = item as FavoriteWithSubscriptionStatus;
|
||||
switch (item.type) {
|
||||
case 'favorite': {
|
||||
const request: InsertFavoriteRequest = {
|
||||
fid: favorite.fid,
|
||||
fid: item.fid,
|
||||
path: customPath.trim()
|
||||
};
|
||||
response = await api.insertFavorite(request);
|
||||
break;
|
||||
}
|
||||
case 'collections': {
|
||||
const collection = item as CollectionWithSubscriptionStatus;
|
||||
case 'collection': {
|
||||
const request: InsertCollectionRequest = {
|
||||
sid: collection.sid,
|
||||
mid: collection.mid,
|
||||
sid: item.sid,
|
||||
mid: item.mid,
|
||||
path: customPath.trim()
|
||||
};
|
||||
response = await api.insertCollection(request);
|
||||
break;
|
||||
}
|
||||
case 'submissions': {
|
||||
const upper = item as UpperWithSubscriptionStatus;
|
||||
case 'upper': {
|
||||
const request: InsertSubmissionRequest = {
|
||||
upper_id: upper.mid,
|
||||
upper_id: item.mid,
|
||||
path: customPath.trim()
|
||||
};
|
||||
response = await api.insertSubmission(request);
|
||||
@@ -176,21 +169,16 @@
|
||||
<span class="text-muted-foreground text-sm font-medium">{typeLabel}名称:</span>
|
||||
<span class="text-sm">{itemTitle}</span>
|
||||
</div>
|
||||
{#if type === 'favorites'}
|
||||
{@const favorite = item as FavoriteWithSubscriptionStatus}
|
||||
{#if item!.type !== 'upper'}
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-muted-foreground text-sm font-medium">视频数量:</span>
|
||||
<span class="text-sm">{favorite.media_count} 个</span>
|
||||
<span class="text-sm">{item!.media_count} 条</span>
|
||||
</div>
|
||||
{:else if item!.sign}
|
||||
<div class="flex items-start gap-2">
|
||||
<span class="text-muted-foreground text-sm font-medium">个人简介:</span>
|
||||
<span class="text-muted-foreground text-sm">{item!.sign}</span>
|
||||
</div>
|
||||
{/if}
|
||||
{#if type === 'submissions'}
|
||||
{@const upper = item as UpperWithSubscriptionStatus}
|
||||
{#if upper.sign}
|
||||
<div class="flex items-start gap-2">
|
||||
<span class="text-muted-foreground text-sm font-medium">个人简介:</span>
|
||||
<span class="text-muted-foreground text-sm">{upper.sign}</span>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -110,45 +110,46 @@ export interface ResetRequest {
|
||||
force: boolean;
|
||||
}
|
||||
|
||||
// 收藏夹相关类型
|
||||
export interface FavoriteWithSubscriptionStatus {
|
||||
title: string;
|
||||
media_count: number;
|
||||
fid: number;
|
||||
mid: number;
|
||||
subscribed: boolean;
|
||||
}
|
||||
export type Followed =
|
||||
| {
|
||||
type: 'favorite';
|
||||
title: string;
|
||||
media_count: number;
|
||||
fid: number;
|
||||
mid: number;
|
||||
invalid: boolean;
|
||||
subscribed: boolean;
|
||||
}
|
||||
| {
|
||||
type: 'collection';
|
||||
title: string;
|
||||
sid: number;
|
||||
mid: number;
|
||||
media_count: number;
|
||||
invalid: boolean;
|
||||
subscribed: boolean;
|
||||
}
|
||||
| {
|
||||
type: 'upper';
|
||||
mid: number;
|
||||
uname: string;
|
||||
face: string;
|
||||
sign: string;
|
||||
invalid: boolean;
|
||||
subscribed: boolean;
|
||||
};
|
||||
|
||||
export interface FavoritesResponse {
|
||||
favorites: FavoriteWithSubscriptionStatus[];
|
||||
}
|
||||
|
||||
// 合集相关类型
|
||||
export interface CollectionWithSubscriptionStatus {
|
||||
title: string;
|
||||
sid: number;
|
||||
mid: number;
|
||||
invalid: boolean;
|
||||
subscribed: boolean;
|
||||
favorites: Followed[];
|
||||
}
|
||||
|
||||
export interface CollectionsResponse {
|
||||
collections: CollectionWithSubscriptionStatus[];
|
||||
collections: Followed[];
|
||||
total: number;
|
||||
}
|
||||
|
||||
// UP 主相关类型
|
||||
export interface UpperWithSubscriptionStatus {
|
||||
mid: number;
|
||||
uname: string;
|
||||
face: string;
|
||||
sign: string;
|
||||
invalid: boolean;
|
||||
subscribed: boolean;
|
||||
}
|
||||
|
||||
export interface UppersResponse {
|
||||
uppers: UpperWithSubscriptionStatus[];
|
||||
uppers: Followed[];
|
||||
total: number;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
import { clsx, type ClassValue } from 'clsx';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
import type { Followed } from './types';
|
||||
|
||||
export function getFollowedKey(followed: Followed): number {
|
||||
if (followed.type == 'favorite') {
|
||||
return followed.fid;
|
||||
} else if (followed.type == 'collection') {
|
||||
return followed.sid;
|
||||
} else {
|
||||
return followed.mid;
|
||||
}
|
||||
}
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs));
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
import Pagination from '$lib/components/pagination.svelte';
|
||||
import { setBreadcrumb } from '$lib/stores/breadcrumb';
|
||||
import api from '$lib/api';
|
||||
import type { CollectionWithSubscriptionStatus, ApiError } from '$lib/types';
|
||||
import type { Followed, ApiError } from '$lib/types';
|
||||
import { getFollowedKey } from '$lib/utils';
|
||||
|
||||
let collections: CollectionWithSubscriptionStatus[] = [];
|
||||
let collections: Followed[] = [];
|
||||
let totalCount = 0;
|
||||
let currentPage = 0;
|
||||
let loading = false;
|
||||
@@ -21,8 +22,8 @@
|
||||
collections = response.data.collections;
|
||||
totalCount = response.data.total;
|
||||
} catch (error) {
|
||||
console.error('加载合集失败:', error);
|
||||
toast.error('加载合集失败', {
|
||||
console.error('加载合集 / 收藏夹失败:', error);
|
||||
toast.error('加载合集 / 收藏夹失败', {
|
||||
description: (error as ApiError).message
|
||||
});
|
||||
} finally {
|
||||
@@ -43,7 +44,7 @@
|
||||
onMount(async () => {
|
||||
setBreadcrumb([
|
||||
{
|
||||
label: '我关注的合集'
|
||||
label: '我追的合集 / 收藏夹'
|
||||
}
|
||||
]);
|
||||
await loadCollections();
|
||||
@@ -53,14 +54,19 @@
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>关注的合集 - Bili Sync</title>
|
||||
<title>我追的合集 / 收藏夹 - Bili Sync</title>
|
||||
</svelte:head>
|
||||
|
||||
<div>
|
||||
<div class="mb-6 flex items-center justify-between">
|
||||
<div class="text-sm font-medium">
|
||||
<div class="flex items-center gap-6">
|
||||
{#if !loading}
|
||||
共 {totalCount} 个合集
|
||||
<div class=" text-sm font-medium">
|
||||
共 {totalCount} 个合集 / 收藏夹
|
||||
</div>
|
||||
<div class=" text-sm font-medium">
|
||||
当前第 {currentPage + 1} / {totalPages} 页
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
@@ -73,13 +79,9 @@
|
||||
<div
|
||||
style="display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 16px; width: 100%; max-width: none; justify-items: start;"
|
||||
>
|
||||
{#each collections as collection (collection.sid)}
|
||||
{#each collections as collection (getFollowedKey(collection))}
|
||||
<div style="max-width: 450px; width: 100%;">
|
||||
<SubscriptionCard
|
||||
item={collection}
|
||||
type="collections"
|
||||
onSubscriptionSuccess={handleSubscriptionSuccess}
|
||||
/>
|
||||
<SubscriptionCard item={collection} onSubscriptionSuccess={handleSubscriptionSuccess} />
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
@@ -91,8 +93,10 @@
|
||||
{:else}
|
||||
<div class="flex items-center justify-center py-12">
|
||||
<div class="space-y-2 text-center">
|
||||
<p class="text-muted-foreground">暂无合集数据</p>
|
||||
<p class="text-muted-foreground text-sm">请先在 B 站关注一些合集,或检查账号配置</p>
|
||||
<p class="text-muted-foreground">暂无合集 / 收藏夹数据</p>
|
||||
<p class="text-muted-foreground text-sm">
|
||||
请先在 B 站关注一些合集 / 收藏夹,或检查账号配置
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -6,9 +6,10 @@
|
||||
import { setBreadcrumb } from '$lib/stores/breadcrumb';
|
||||
|
||||
import api from '$lib/api';
|
||||
import type { FavoriteWithSubscriptionStatus, ApiError } from '$lib/types';
|
||||
import type { Followed, ApiError } from '$lib/types';
|
||||
import { getFollowedKey } from '$lib/utils';
|
||||
|
||||
let favorites: FavoriteWithSubscriptionStatus[] = [];
|
||||
let favorites: Followed[] = [];
|
||||
let loading = false;
|
||||
|
||||
async function loadFavorites() {
|
||||
@@ -39,7 +40,7 @@
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>我的收藏夹 - Bili Sync</title>
|
||||
<title>我创建的收藏夹 - Bili Sync</title>
|
||||
</svelte:head>
|
||||
|
||||
<div>
|
||||
@@ -59,13 +60,9 @@
|
||||
<div
|
||||
style="display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 16px; width: 100%; max-width: none; justify-items: start;"
|
||||
>
|
||||
{#each favorites as favorite (favorite.fid)}
|
||||
{#each favorites as favorite (getFollowedKey(favorite))}
|
||||
<div style="max-width: 450px; width: 100%;">
|
||||
<SubscriptionCard
|
||||
item={favorite}
|
||||
type="favorites"
|
||||
onSubscriptionSuccess={handleSubscriptionSuccess}
|
||||
/>
|
||||
<SubscriptionCard item={favorite} onSubscriptionSuccess={handleSubscriptionSuccess} />
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
import Pagination from '$lib/components/pagination.svelte';
|
||||
import { setBreadcrumb } from '$lib/stores/breadcrumb';
|
||||
import api from '$lib/api';
|
||||
import type { UpperWithSubscriptionStatus, ApiError } from '$lib/types';
|
||||
import type { Followed, ApiError } from '$lib/types';
|
||||
|
||||
let uppers: UpperWithSubscriptionStatus[] = [];
|
||||
let uppers: Followed[] = [];
|
||||
let totalCount = 0;
|
||||
let currentPage = 0;
|
||||
let loading = false;
|
||||
@@ -49,7 +49,7 @@
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>关注的UP主 - Bili Sync</title>
|
||||
<title>我关注的 UP 主 - Bili Sync</title>
|
||||
</svelte:head>
|
||||
|
||||
<div>
|
||||
@@ -76,11 +76,7 @@
|
||||
>
|
||||
{#each uppers as upper (upper.mid)}
|
||||
<div style="max-width: 450px; width: 100%;">
|
||||
<SubscriptionCard
|
||||
item={upper}
|
||||
type="submissions"
|
||||
onSubscriptionSuccess={handleSubscriptionSuccess}
|
||||
/>
|
||||
<SubscriptionCard item={upper} onSubscriptionSuccess={handleSubscriptionSuccess} />
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user