Skip to content

Commit f21e984

Browse files
authored
Merge pull request #4776 from RSSNext/hotfix/1.2.5
chore(desktop): Release v1.2.5 for hotfix
2 parents ca0795f + 396349c commit f21e984

File tree

27 files changed

+341
-539
lines changed

27 files changed

+341
-539
lines changed

apps/desktop/layer/renderer/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
"@welldone-software/why-did-you-render": "10.0.1",
5252
"@xyflow/react": "12.9.2",
5353
"@yornaath/batshit": "0.11.1",
54-
"ai": "5.0.87",
54+
"ai": "5.0.115",
5555
"camelcase-keys": "10.0.1",
5656
"chrono-node": "2.9.0",
5757
"class-variance-authority": "0.7.1",

apps/desktop/layer/renderer/src/modules/ai-chat/store/transport.ts

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,28 @@ export function createChatTransport({ onValue, titleHandler }: CreateChatTranspo
6262
})
6363
}
6464

65+
const coerceFinishChunk = (chunk: ParseResult<UIMessageChunk>): UIMessageChunk | null => {
66+
const { rawValue } = chunk
67+
if (!rawValue || typeof rawValue !== "object" || Array.isArray(rawValue)) {
68+
return null
69+
}
70+
71+
if ((rawValue as { type?: unknown }).type !== "finish") {
72+
return null
73+
}
74+
75+
const { finishReason, messageMetadata } = rawValue as {
76+
finishReason?: unknown
77+
messageMetadata?: unknown
78+
}
79+
80+
return {
81+
type: "finish",
82+
finishReason: typeof finishReason === "string" ? finishReason : undefined,
83+
messageMetadata,
84+
} as UIMessageChunk
85+
}
86+
6587
class ExtendChatTransport extends HttpChatTransport<BizUIMessage> {
6688
constructor(
6789
private options: HttpChatTransportInitOptions<BizUIMessage> & {
@@ -83,13 +105,14 @@ class ExtendChatTransport extends HttpChatTransport<BizUIMessage> {
83105
}).pipeThrough(
84106
new TransformStream<ParseResult<UIMessageChunk>, UIMessageChunk>({
85107
async transform(chunk, controller) {
86-
if (!chunk.success) {
108+
const parsedChunk = chunk.success ? chunk.value : coerceFinishChunk(chunk)
109+
if (!parsedChunk) {
87110
throw chunk.error
88111
}
89112

90-
await handleGeneratedTitle(chunk.value)
91-
onValue?.(chunk.value)
92-
controller.enqueue(chunk.value)
113+
await handleGeneratedTitle(parsedChunk)
114+
onValue?.(parsedChunk)
115+
controller.enqueue(parsedChunk)
93116
},
94117
}),
95118
)

apps/desktop/layer/renderer/src/modules/auth/LoginModalContent.tsx

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -115,16 +115,6 @@ export const LoginModalContent = (props: LoginModalContentProps) => {
115115
transition={Spring.presets.smooth}
116116
>
117117
<h1 className="text-2xl font-semibold">{t("login.title")}</h1>
118-
<p className="text-balance text-center text-sm text-text-secondary">
119-
{t("login.subtitle")}
120-
</p>
121-
{/* Benefits - single line */}
122-
<div className="mt-1 flex items-center gap-3 text-xs text-text-tertiary">
123-
<span className="text-accent"></span>
124-
<span>{t("login.benefit_1")}</span>
125-
<span className="text-text-quaternary">·</span>
126-
<span>{t("login.benefit_2")}</span>
127-
</div>
128118
</m.div>
129119
) : (
130120
<m.div
@@ -215,17 +205,6 @@ export const LoginModalContent = (props: LoginModalContentProps) => {
215205
</button>
216206
</m.div>
217207
))}
218-
{/* Quick start hint */}
219-
{isRegister && providers.length > 0 && !isLoading && (
220-
<m.p
221-
className="mt-1 text-center text-xs text-text-tertiary"
222-
initial={{ opacity: 0 }}
223-
animate={{ opacity: 1 }}
224-
transition={{ ...Spring.presets.smooth, delay: 0.15 }}
225-
>
226-
{t("login.quick_start")}
227-
</m.p>
228-
)}
229208
</div>
230209

231210
{/* Referral Form */}
@@ -284,18 +263,6 @@ export const LoginModalContent = (props: LoginModalContentProps) => {
284263
}}
285264
/>
286265

287-
{/* View Demo Button */}
288-
{isRegister && (
289-
<m.button
290-
className="mb-2 w-full cursor-pointer text-center text-xs text-text-tertiary transition-colors hover:text-text-secondary"
291-
onClick={() => modal.dismiss()}
292-
whileHover={{ scale: 1.02 }}
293-
whileTap={{ scale: 0.98 }}
294-
>
295-
{t("login.view_demo")}
296-
</m.button>
297-
)}
298-
299266
{/* Switch Account Type */}
300267
<m.button
301268
className="group w-full cursor-pointer pb-2 text-center text-sm font-medium transition-colors"

apps/desktop/layer/renderer/src/modules/discover/DiscoverForm.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import { useTranslation } from "react-i18next"
2424
import { useSearchParams } from "react-router"
2525
import { z } from "zod"
2626

27-
import { useIsInMASReview } from "~/atoms/server-configs"
2827
import { useModalStack } from "~/components/ui/modal/stacked/hooks"
2928
import { useRequireLogin } from "~/hooks/common/useRequireLogin"
3029
import { followClient } from "~/lib/api-client"
@@ -127,19 +126,15 @@ export function DiscoverForm({ type = "search" }: { type?: string }) {
127126
const target = watch("target")
128127
const atomKey = keywordFromSearch + target
129128
const { t } = useTranslation()
130-
const isInMASReview = useIsInMASReview()
131129
const { ensureLogin } = useRequireLogin()
132130

133131
const jotaiStore = useStore()
134132
const mutation = useMutation({
135133
mutationFn: async ({ keyword, target }: { keyword: string; target: "feeds" | "lists" }) => {
136-
let { data } = await followClient.api.discover.discover({
134+
const { data } = await followClient.api.discover.discover({
137135
keyword: keyword.trim(),
138136
target,
139137
})
140-
if (isInMASReview) {
141-
data = data.filter((item) => !item.list?.fee)
142-
}
143138

144139
jotaiStore.set(discoverSearchDataAtom, (prev) => ({
145140
...prev,

apps/desktop/layer/renderer/src/modules/discover/ListForm.tsx

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -256,15 +256,7 @@ const ListInnerForm = ({
256256

257257
return (
258258
<div className="flex flex-1 flex-col gap-y-4">
259-
<FeedSummary
260-
isLoading={isLoading}
261-
feed={{
262-
...list,
263-
fee: list.fee || 0,
264-
}}
265-
analytics={analytics}
266-
showAnalytics
267-
/>
259+
<FeedSummary isLoading={isLoading} feed={list} analytics={analytics} showAnalytics />
268260
<Form {...form}>
269261
<form onSubmit={form.handleSubmit(onSubmit)} className="flex flex-1 flex-col gap-y-4">
270262
<FormField
@@ -343,18 +335,6 @@ const ListInnerForm = ({
343335
</FormItem>
344336
)}
345337
/>
346-
{!!list.fee && !isSubscribed && (
347-
<div>
348-
<FormLabel className="flex items-center gap-1">
349-
{t("feed_form.fee")}{" "}
350-
<div className="ml-2 flex scale-[0.85] items-center gap-1">
351-
{list.fee}
352-
<i className="i-mgc-power size-4 text-folo" />
353-
</div>
354-
</FormLabel>
355-
<FormDescription className="mt-0.5">{t("feed_form.fee_description")}</FormDescription>
356-
</div>
357-
)}
358338
<div className="flex flex-1 items-center justify-end gap-4">
359339
{isSubscribed && (
360340
<Button
@@ -369,13 +349,7 @@ const ListInnerForm = ({
369349
</Button>
370350
)}
371351
<Button ref={buttonRef} type="submit" isLoading={followMutation.isPending}>
372-
{isSubscribed
373-
? t("feed_form.update")
374-
: list.fee
375-
? t("feed_form.follow_with_fee", {
376-
fee: list.fee,
377-
})
378-
: t("feed_form.follow")}
352+
{isSubscribed ? t("feed_form.update") : t("feed_form.follow")}
379353
</Button>
380354
</div>
381355
</form>

apps/desktop/layer/renderer/src/modules/discover/UnifiedDiscoverForm.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import { useTranslation } from "react-i18next"
2424
import { useSearchParams } from "react-router"
2525
import { z } from "zod"
2626

27-
import { useIsInMASReview } from "~/atoms/server-configs"
2827
import { useModalStack } from "~/components/ui/modal/stacked/hooks"
2928
import { useRequireLogin } from "~/hooks/common/useRequireLogin"
3029
import { followClient } from "~/lib/api-client"
@@ -96,7 +95,6 @@ export function UnifiedDiscoverForm() {
9695
const [searchParams, setSearchParams] = useSearchParams()
9796
const keywordFromSearch = searchParams.get("keyword") || ""
9897
const { t } = useTranslation()
99-
const isInMASReview = useIsInMASReview()
10098
const { ensureLogin } = useRequireLogin()
10199
const { present, dismissAll } = useModalStack()
102100
const isMobile = useMobile()
@@ -163,13 +161,10 @@ export function UnifiedDiscoverForm() {
163161
}
164162

165163
// For search, perform discovery
166-
let { data } = await followClient.api.discover.discover({
164+
const { data } = await followClient.api.discover.discover({
167165
keyword: keyword.trim(),
168166
target,
169167
})
170-
if (isInMASReview) {
171-
data = data.filter((item) => !item.list?.fee)
172-
}
173168

174169
setDiscoverSearchData((prev) => ({
175170
...prev,

apps/desktop/layer/renderer/src/modules/entry-content/EntryContent.tsx

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { useFeedById } from "@follow/store/feed/hooks"
88
import type { FeedModel } from "@follow/store/feed/types"
99
import { useIsInbox } from "@follow/store/inbox/hooks"
1010
import { useSubscriptionByFeedId } from "@follow/store/subscription/hooks"
11+
import { useEntryTranslation } from "@follow/store/translation/hooks"
1112
import { thenable } from "@follow/utils"
1213
import { stopPropagation } from "@follow/utils/dom"
1314
import { EventBus } from "@follow/utils/event-bus"
@@ -17,7 +18,9 @@ import { useAnimationControls } from "motion/react"
1718
import * as React from "react"
1819
import { memo, useEffect, useRef, useState } from "react"
1920

21+
import { useShowAITranslation } from "~/atoms/ai-translation"
2022
import { useEntryIsInReadability } from "~/atoms/readability"
23+
import { useActionLanguage } from "~/atoms/settings/general"
2124
import { AppErrorBoundary } from "~/components/common/AppErrorBoundary"
2225
import { Focusable } from "~/components/common/Focusable"
2326
import { m } from "~/components/common/Motion"
@@ -40,6 +43,7 @@ import { EntryScrollingAndNavigationHandler } from "./components/entry-content/E
4043
import { EntryTitleMetaHandler } from "./components/entry-content/EntryTitleMetaHandler"
4144
import type { EntryContentProps } from "./components/entry-content/types"
4245
import { getEntryContentLayout } from "./components/layouts"
46+
import type { EntryLayoutProps } from "./components/layouts/types"
4347
import { SourceContentPanel } from "./components/SourceContentView"
4448
import { useEntryContent } from "./hooks"
4549

@@ -71,6 +75,13 @@ const EntryContentImpl: Component<EntryContentProps> = ({
7175
const isInReadabilityMode = useEntryIsInReadability(entryId)
7276

7377
const { error, content, isPending } = useEntryContent(entryId)
78+
const enableTranslation = useShowAITranslation()
79+
const actionLanguage = useActionLanguage()
80+
const entryTranslation = useEntryTranslation({
81+
entryId,
82+
language: actionLanguage,
83+
enabled: enableTranslation,
84+
})
7485

7586
const routeView = useRouteParamsSelector((route) => route.view)
7687
const subscriptionView = subscription?.view
@@ -133,6 +144,16 @@ const EntryContentImpl: Component<EntryContentProps> = ({
133144
}, [scrollerRef])
134145

135146
const scrollerRefObject = React.useMemo(() => ({ current: scrollerRef }), [scrollerRef])
147+
const layoutTranslation = React.useMemo(
148+
() =>
149+
entryTranslation
150+
? {
151+
content: entryTranslation.content ?? undefined,
152+
title: entryTranslation.title ?? undefined,
153+
}
154+
: undefined,
155+
[entryTranslation?.content, entryTranslation?.title],
156+
)
136157
return (
137158
<div className={cn(className, "flex flex-col @container")}>
138159
<EntryTitleMetaHandler entryId={entryId} />
@@ -219,6 +240,7 @@ const EntryContentImpl: Component<EntryContentProps> = ({
219240
view={view}
220241
compact={compact}
221242
noMedia={noMedia}
243+
translation={layoutTranslation}
222244
/>
223245
)}
224246
</article>
@@ -269,8 +291,16 @@ const AdaptiveContentRenderer: React.FC<{
269291
view: FeedViewType
270292
compact?: boolean
271293
noMedia?: boolean
272-
}> = ({ entryId, view, compact = false, noMedia = false }) => {
294+
translation?: EntryLayoutProps["translation"]
295+
}> = ({ entryId, view, compact = false, noMedia = false, translation }) => {
273296
const LayoutComponent = getEntryContentLayout(view)
274297

275-
return <LayoutComponent entryId={entryId} compact={compact} noMedia={noMedia} />
298+
return (
299+
<LayoutComponent
300+
entryId={entryId}
301+
compact={compact}
302+
noMedia={noMedia}
303+
translation={translation}
304+
/>
305+
)
276306
}

apps/desktop/layer/renderer/src/modules/profile/user-profile-modal/UserProfileModalContent.tsx

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -98,27 +98,18 @@ const ListCard = memo(({ list }: { list: ListWithStats }) => {
9898
</div>
9999

100100
{/* Stats Footer */}
101-
{(typeof list.subscriptionCount === "number" ||
102-
(typeof list.fee === "number" && list.fee > 0)) && (
101+
{typeof list.subscriptionCount === "number" && (
103102
<div className="border-t border-fill-secondary px-4 py-2.5">
104103
<div className="flex items-center justify-between text-xs">
105-
{typeof list.subscriptionCount === "number" && (
106-
<div className="flex items-center gap-1.5 text-text-secondary">
107-
<i className="i-mingcute-group-2-line size-3" />
108-
<span>
109-
{list.subscriptionCount}
110-
<span className="ml-1 hidden sm:inline">
111-
{list.subscriptionCount > 1 ? "subscribers" : "subscriber"}
112-
</span>
104+
<div className="flex items-center gap-1.5 text-text-secondary">
105+
<i className="i-mingcute-group-2-line size-3" />
106+
<span>
107+
{list.subscriptionCount}
108+
<span className="ml-1 hidden sm:inline">
109+
{list.subscriptionCount > 1 ? "subscribers" : "subscriber"}
113110
</span>
114-
</div>
115-
)}
116-
{typeof list.fee === "number" && list.fee > 0 && (
117-
<div className="flex items-center gap-1.5">
118-
<i className="i-mgc-power size-3 text-folo" />
119-
<span className="font-medium">{list.fee}</span>
120-
</div>
121-
)}
111+
</span>
112+
</div>
122113
</div>
123114
</div>
124115
)}

apps/desktop/layer/renderer/src/modules/settings/tabs/lists/index.tsx

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import { toast } from "sonner"
2828
import { useCurrentModal, useModalStack } from "~/components/ui/modal/stacked/hooks"
2929
import { useI18n } from "~/hooks/common"
3030
import { UrlBuilder } from "~/lib/url-builder"
31-
import { Balance } from "~/modules/wallet/balance"
3231

3332
import { ListCreationModalContent, ListFeedsModalContent } from "./modals"
3433

@@ -75,7 +74,6 @@ export const SettingLists = () => {
7574
acc[curr.id] = {
7675
id: curr.id,
7776
subscriptionCount: curr.subscriptionCount,
78-
purchaseAmount: Number(curr.purchaseAmount || 0),
7977
}
8078
return acc
8179
},
@@ -84,7 +82,6 @@ export const SettingLists = () => {
8482
{
8583
id: string
8684
subscriptionCount: number | null | undefined
87-
purchaseAmount: number | null | undefined
8885
}
8986
>,
9087
)
@@ -126,9 +123,7 @@ export const SettingLists = () => {
126123
<TableRow className="[&_*]:!font-semibold">
127124
<TableHead size="sm">{t.settings("lists.title")}</TableHead>
128125
<TableHead size="sm">{t.settings("lists.view")}</TableHead>
129-
<TableHead size="sm">{t.settings("lists.fee.label")}</TableHead>
130126
<TableHead size="sm">{t.settings("lists.subscriptions")}</TableHead>
131-
<TableHead size="sm">{t.settings("lists.earnings")}</TableHead>
132127
<TableHead size="sm" className="center">
133128
{t.common("words.actions")}
134129
</TableHead>
@@ -172,18 +167,9 @@ export const SettingLists = () => {
172167
</TooltipPortal>
173168
</Tooltip>
174169
</TableCell>
175-
<TableCell size="sm">
176-
<div className="flex items-center gap-1 tabular-nums">
177-
{row.fee}
178-
<i className="i-mgc-power shrink-0 text-lg text-folo" />
179-
</div>
180-
</TableCell>
181170
<TableCell size="sm" className="tabular-nums">
182171
{formatNumber(listDataMap[row.id]?.subscriptionCount || 0)}
183172
</TableCell>
184-
<TableCell size="sm" className="tabular-nums">
185-
<Balance>{BigInt(listDataMap[row.id]?.purchaseAmount || 0n)}</Balance>
186-
</TableCell>
187173
<TableCell size="sm" className="center">
188174
<Tooltip>
189175
<TooltipTrigger asChild>

0 commit comments

Comments
 (0)