Skip to content

Commit 6abad19

Browse files
authored
Merge pull request #526 from leeon666/upstream/stability-content-fixes
fix: 增强内容渲染和 AI 摘要的稳定性
2 parents 02674ae + efda4b5 commit 6abad19

13 files changed

Lines changed: 69 additions & 35 deletions

File tree

client/src/components/feed_card.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ function FeedCardImage({ src, variant }: { src: string; variant: FeedCardVariant
1313
const canvasRef = useRef<HTMLCanvasElement>(null);
1414
const { src: cleanSrc, blurhash, width, height } = parseImageUrlMetadata(src);
1515
const { failed, imageRef, loaded, onError, onLoad } = useImageLoadState(cleanSrc);
16-
const aspectRatio = width && height ? `${width} / ${height}` : undefined;
16+
const aspectRatio = width && height ? `${width} / ${height}` : "16 / 9";
1717
const imageFrameClass =
1818
variant === "editorial"
1919
? "relative flex max-h-80 w-full flex-row items-center overflow-hidden rounded-[20px]"
@@ -91,7 +91,7 @@ export type FeedCardProps = {
9191
top?: number;
9292
title: string;
9393
summary: string;
94-
hashtags: { id: number, name: string }[];
94+
hashtags?: { id: number, name: string }[];
9595
createdAt: Date;
9696
updatedAt: Date;
9797
preview?: boolean;
@@ -101,6 +101,7 @@ export type FeedCardProps = {
101101
export function FeedCard({ id, title, avatar, draft, listed, top, summary, hashtags, createdAt, updatedAt, preview = false, variant }: FeedCardProps) {
102102
const { t } = useTranslation();
103103
const siteConfig = useSiteConfig();
104+
const safeHashtags = Array.isArray(hashtags) ? hashtags : [];
104105
const activeVariant = normalizeFeedCardVariant(variant ?? siteConfig.feedCardVariant);
105106
const styles = FEED_CARD_STYLES[activeVariant];
106107
const body = (
@@ -128,9 +129,9 @@ export function FeedCard({ id, title, avatar, draft, listed, top, summary, hasht
128129
{top === 1 && <span className="text-theme">{t('article.top.title')}</span>}
129130
</p>
130131
<p className={`${styles.summary} ${activeVariant === "editorial" ? "mt-4 max-w-3xl" : ""}`}>{summary}</p>
131-
{hashtags.length > 0 &&
132+
{safeHashtags.length > 0 &&
132133
<div className={`flex flex-row flex-wrap justify-start gap-2 ${activeVariant === "editorial" ? "mt-4" : "mt-2 gap-x-2"}`}>
133-
{hashtags.map(({ name }, index) => (
134+
{safeHashtags.map(({ name }, index) => (
134135
<HashTag key={index} name={name} />
135136
))}
136137
</div>

client/src/page/compat-tasks.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export function CompatTasksPage() {
7474
return;
7575
}
7676

77-
const items = data?.items || [];
77+
const items = Array.isArray(data?.items) ? data.items : [];
7878
setBlurhashProgress({ total: items.length, processed: 0, updated: 0, failed: 0 });
7979

8080
let processed = 0;

client/src/page/feed.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export function FeedPage({ id, TOC, clean }: { id: string, TOC: () => JSX.Elemen
4646
const counterEnabled = config.getBoolean('counter.enabled');
4747
const hasAISummary = Boolean(feed?.ai_summary?.trim());
4848
const showAISummaryState = feed?.ai_summary_status === "pending" || feed?.ai_summary_status === "processing" || feed?.ai_summary_status === "failed";
49+
const hashtags = Array.isArray(feed?.hashtags) ? feed.hashtags : [];
4950
function deleteFeed() {
5051
// Confirm
5152
showConfirm(
@@ -151,7 +152,7 @@ export function FeedPage({ id, TOC, clean }: { id: string, TOC: () => JSX.Elemen
151152
<meta name="author" content={feed.user.username} />
152153
<meta
153154
name="keywords"
154-
content={feed.hashtags.map(({ name }) => name).join(", ")}
155+
content={hashtags.map(({ name }) => name).join(", ")}
155156
/>
156157
<meta
157158
name="description"
@@ -282,9 +283,9 @@ export function FeedPage({ id, TOC, clean }: { id: string, TOC: () => JSX.Elemen
282283
)}
283284
<Markdown content={feed.content} />
284285
<div className="mt-6 flex flex-col gap-2">
285-
{feed.hashtags.length > 0 && (
286+
{hashtags.length > 0 && (
286287
<div className="flex flex-row flex-wrap gap-x-2">
287-
{feed.hashtags.map(({ name }, index) => (
288+
{hashtags.map(({ name }, index) => (
288289
<HashTag key={index} name={name} />
289290
))}
290291
</div>

client/src/page/feeds.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ export function FeedsPage() {
3838
const page = tryInt(1, query.get("page"))
3939
const limit = tryInt(siteConfig.pageSize, query.get("limit"))
4040
const feedListClass = siteConfig.feedLayout === "masonry" ? "wauto columns-1 gap-5 ani-show md:columns-2" : "wauto flex flex-col ani-show";
41+
const currentFeeds = feeds[listState] ?? { size: 0, data: [], hasNext: false };
42+
const currentFeedData = Array.isArray(currentFeeds.data) ? currentFeeds.data : [];
4143
const ref = useRef("")
4244
function fetchFeeds(type: FeedType) {
4345
client.feed.list({
@@ -83,7 +85,7 @@ export function FeedsPage() {
8385
</p>
8486
<div className="flex flex-row justify-between">
8587
<p className="text-sm mt-4 text-neutral-500 font-normal">
86-
{t('article.total$count', { count: feeds[listState]?.size })}
88+
{t('article.total$count', { count: currentFeeds.size })}
8789
</p>
8890
{profile?.permission &&
8991
<div className="flex flex-row space-x-4">
@@ -99,7 +101,7 @@ export function FeedsPage() {
99101
</div>
100102
<Waiting for={status === 'idle'}>
101103
<div className={feedListClass}>
102-
{feeds[listState].data.map(({ id, ...feed }: any) => (
104+
{currentFeedData.map(({ id, ...feed }: any) => (
103105
<FeedCard key={id} id={id} {...feed} />
104106
))}
105107
</div>
@@ -111,7 +113,7 @@ export function FeedsPage() {
111113
</Link>
112114
}
113115
<div className="flex-1" />
114-
{feeds[listState]?.hasNext &&
116+
{currentFeeds.hasNext &&
115117
<Link href={`/?type=${listState}&page=${(page + 1)}`}
116118
className={`text-sm font-normal rounded-full px-4 py-2 text-white bg-theme`}>
117119
{t('next')}

client/src/page/hashtag.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export function HashtagPage({ name }: { name: string }) {
3939
const [status, setStatus] = useState<'loading' | 'idle'>('idle')
4040
const [hashtag, setHashtag] = useState<FeedsData>()
4141
const feedListClass = siteConfig.feedLayout === "masonry" ? "wauto columns-1 gap-5 md:columns-2" : "wauto flex flex-col";
42+
const hashtagFeeds = Array.isArray(hashtag?.feeds) ? hashtag.feeds : [];
4243
const ref = useRef("")
4344
function fetchFeeds() {
4445
const nameDecoded = decodeURI(name)
@@ -73,13 +74,13 @@ export function HashtagPage({ name }: { name: string }) {
7374
</p>
7475
<div className="flex flex-row justify-between">
7576
<p className="text-sm mt-4 text-neutral-500 font-normal">
76-
{t('article.total$count', { count: hashtag?.feeds?.length })}
77+
{t('article.total$count', { count: hashtagFeeds.length })}
7778
</p>
7879
</div>
7980
</div>
8081
<Waiting for={status === 'idle'}>
8182
<div className={feedListClass}>
82-
{hashtag?.feeds?.map(({ id, ...feed }: any) => (
83+
{hashtagFeeds.map(({ id, ...feed }: any) => (
8384
<FeedCard key={id} id={id} {...feed} />
8485
))}
8586
</div>

client/src/page/health.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export function HealthPage() {
6767
return;
6868
}
6969
if (data) {
70-
setItems(data.items);
70+
setItems(Array.isArray(data.items) ? data.items : []);
7171
setSummary(data.summary);
7272
setGeneratedAt(data.generatedAt);
7373
}

client/src/page/moments.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,14 @@ export function MomentsPage() {
6262
limit: limit
6363
}).then(({ data }) => {
6464
if (data) {
65-
setLength(data.data.length)
65+
const momentData = Array.isArray(data.data) ? data.data : [];
66+
setLength(momentData.length)
6667
setHasNextPage(data.hasNext)
6768

6869
if (append) {
69-
setMoments(prev => [...prev, ...data.data] as any)
70+
setMoments(prev => [...prev, ...momentData] as any)
7071
} else {
71-
setMoments(data.data as any)
72+
setMoments(momentData as any)
7273
}
7374

7475
setCurrentPage(page)

client/src/page/queue-status.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ export function QueueStatusPage() {
105105
setQueueConfigured(data.queueConfigured);
106106
setGeneratedAt(data.generatedAt);
107107
setSummary(data.summary);
108-
setItems(data.items);
108+
setItems(Array.isArray(data.items) ? data.items : []);
109109
}
110110
})
111111
.finally(() => setLoading(false));

client/src/page/search.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export function SearchPage({ keyword }: { keyword: string }) {
2525
const page = tryInt(1, query.get("page"))
2626
const limit = tryInt(siteConfig.pageSize, query.get("limit"))
2727
const feedListClass = siteConfig.feedLayout === "masonry" ? "wauto columns-1 gap-5 md:columns-2" : "wauto flex flex-col";
28+
const feedData = Array.isArray(feeds?.data) ? feeds.data : [];
2829
const ref = useRef("")
2930
function fetchFeeds() {
3031
if (!keyword) return
@@ -70,7 +71,7 @@ export function SearchPage({ keyword }: { keyword: string }) {
7071
</div>
7172
<Waiting for={status === 'idle'}>
7273
<div className={feedListClass}>
73-
{feeds?.data.map(({ id, ...feed }: any) => (
74+
{feedData.map(({ id, ...feed }: any) => (
7475
<FeedCard key={id} id={id} {...feed} />
7576
))}
7677
</div>

client/src/page/writing.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ export function WritingPage({ id }: { id?: number }) {
189189
.then(({ data }) => {
190190
if (data) {
191191
if (title == "" && data.title) setTitle(data.title);
192-
if (tags == "" && data.hashtags)
192+
if (tags == "" && Array.isArray(data.hashtags))
193193
setTags(data.hashtags.map(({ name }: {name: string}) => `#${name}`).join(" "));
194194
if (alias == "" && (data as any).alias) setAlias((data as any).alias);
195195
if (content == "") setContent(data.content);

0 commit comments

Comments
 (0)