From a1a95216e7aa1fbd7396de7ee878755d582fb88a Mon Sep 17 00:00:00 2001
From: Stephen Zhou <38493346+hyoban@users.noreply.github.com>
Date: Wed, 7 May 2025 09:57:06 +0800
Subject: [PATCH] feat(mobile): auto toggle readability for empty content
---
apps/mobile/src/modules/ai/summary.tsx | 8 ++--
.../modules/entry-content/EntryAISummary.tsx | 9 ++---
.../entries/[entryId]/EntryDetailScreen.tsx | 38 ++++++++++++-------
apps/mobile/src/store/summary/store.ts | 9 +----
4 files changed, 34 insertions(+), 30 deletions(-)
diff --git a/apps/mobile/src/modules/ai/summary.tsx b/apps/mobile/src/modules/ai/summary.tsx
index b33161b94..4efd21221 100644
--- a/apps/mobile/src/modules/ai/summary.tsx
+++ b/apps/mobile/src/modules/ai/summary.tsx
@@ -20,7 +20,7 @@ import { isAndroid } from "@/src/lib/platform"
export const AISummary: FC<{
className?: string
- summary: string
+ summary?: string
pending?: boolean
error?: string
onRetry?: () => void
@@ -59,7 +59,7 @@ export const AISummary: FC<{
const purpleColor = useColor("purple")
- if (pending) return null
+ if (pending || (!summary && !error)) return null
return (
)}
@@ -126,7 +126,7 @@ export const AISummary: FC<{
) : (
- {summary.trim()}
+ {summary?.trim()}
)}
diff --git a/apps/mobile/src/modules/entry-content/EntryAISummary.tsx b/apps/mobile/src/modules/entry-content/EntryAISummary.tsx
index 3674daf13..023948d40 100644
--- a/apps/mobile/src/modules/entry-content/EntryAISummary.tsx
+++ b/apps/mobile/src/modules/entry-content/EntryAISummary.tsx
@@ -26,6 +26,9 @@ export const EntryAISummary: FC<{
enabled: showAISummary,
},
)
+ const summaryToShow = showReadability
+ ? summary?.readabilitySummary || summary?.summary
+ : summary?.summary
const status = useSummaryStore((state) => state.generatingStatus[entryId])
if (!showAISummary) return null
@@ -33,11 +36,7 @@ export const EntryAISummary: FC<{
return (
diff --git a/apps/mobile/src/screens/(stack)/entries/[entryId]/EntryDetailScreen.tsx b/apps/mobile/src/screens/(stack)/entries/[entryId]/EntryDetailScreen.tsx
index 44b57daaf..154dafc9a 100644
--- a/apps/mobile/src/screens/(stack)/entries/[entryId]/EntryDetailScreen.tsx
+++ b/apps/mobile/src/screens/(stack)/entries/[entryId]/EntryDetailScreen.tsx
@@ -1,6 +1,6 @@
import { FeedViewType } from "@follow/constants"
import { PortalProvider } from "@gorhom/portal"
-import { atom, useAtomValue } from "jotai"
+import { atom, useAtomValue, useSetAtom } from "jotai"
import { useEffect, useMemo } from "react"
import { Text, View } from "react-native"
import { useSafeAreaInsets } from "react-native-safe-area-context"
@@ -33,7 +33,6 @@ export const EntryDetailScreen: NavigationControllerView<{
entryId: string
view: FeedViewType
}> = ({ entryId, view: viewType }) => {
- usePrefetchEntryDetail(entryId)
useAutoMarkAsRead(entryId)
const entry = useEntry(entryId)
const translation = useEntryTranslation(entryId)
@@ -57,12 +56,6 @@ export const EntryDetailScreen: NavigationControllerView<{
[entry?.settings?.readability, entry?.settings?.summary, entry?.settings?.translation],
)
- useEffect(() => {
- if (entry?.settings?.readability) {
- entrySyncServices.fetchEntryReadabilityContent(entryId)
- }
- }, [entry?.settings?.readability, entryId])
-
return (
@@ -78,15 +71,15 @@ export const EntryDetailScreen: NavigationControllerView<{
className="relative rounded-xl py-4"
>
{viewType === FeedViewType.SocialMedia ? (
-
+
) : (
<>
-
-
+
+
>
)}
-
+
{entryWithTranslation && (
@@ -94,7 +87,7 @@ export const EntryDetailScreen: NavigationControllerView<{
)}
{viewType === FeedViewType.SocialMedia && (
-
+
)}
@@ -109,11 +102,28 @@ const EntryContentWebViewWithContext = ({ entry }: { entry: EntryWithTranslation
const showReadability = useAtomValue(showReadabilityAtom)
const translationSetting = useGeneralSettingKey("translation")
const showTranslation = useAtomValue(showAITranslationAtom)
+ const entryId = entry.id
usePrefetchEntryTranslation({
- entryIds: [entry.id],
+ entryIds: [entryId],
withContent: true,
target: showReadability && entry.readabilityContent ? "readabilityContent" : "content",
})
+
+ // Auto toggle readability when content is empty
+ const setShowReadability = useSetAtom(showReadabilityAtom)
+ const { isPending } = usePrefetchEntryDetail(entryId)
+ useEffect(() => {
+ if (!isPending && !entry.content) {
+ setShowReadability(true)
+ }
+ }, [isPending, entry.content, setShowReadability])
+
+ useEffect(() => {
+ if (showReadability) {
+ entrySyncServices.fetchEntryReadabilityContent(entryId)
+ }
+ }, [showReadability, entryId])
+
return (
{
immerSet((state) => {
- if (!summary.data) {
- state.generatingStatus[entryId] = SummaryGeneratingStatus.Error
- return ""
- }
-
state.data[entryId] = {
lang: actionLanguage,
- summary: target === "content" ? summary.data : state.data[entryId]?.summary || "",
+ summary: target === "content" ? summary.data || "" : state.data[entryId]?.summary || "",
readabilitySummary:
target === "readabilityContent"
- ? summary.data
+ ? summary.data || ""
: state.data[entryId]?.readabilitySummary || null,
lastAccessed: Date.now(),
}