diff --git a/apps/renderer/src/atoms/settings/ui.ts b/apps/renderer/src/atoms/settings/ui.ts
index 5133b35f1..9b858efd0 100644
--- a/apps/renderer/src/atoms/settings/ui.ts
+++ b/apps/renderer/src/atoms/settings/ui.ts
@@ -30,6 +30,9 @@ export const createDefaultSettings = (): UISettings => ({
// Font
uiFontFamily: "SN Pro",
readerFontFamily: "inherit",
+ contentFontSize: 16,
+ dateFormat: "default",
+ contentLineHeight: 1.75,
// Content
readerRenderInlineStyle: false,
codeHighlightThemeLight: "github-light",
diff --git a/apps/renderer/src/modules/entry-content/components/EntryTitle.tsx b/apps/renderer/src/modules/entry-content/components/EntryTitle.tsx
index 976e3a7fd..8a5fc8b44 100644
--- a/apps/renderer/src/modules/entry-content/components/EntryTitle.tsx
+++ b/apps/renderer/src/modules/entry-content/components/EntryTitle.tsx
@@ -1,9 +1,11 @@
import type { SupportedLanguages } from "@follow/models/types"
import { cn } from "@follow/utils/utils"
+import dayjs from "dayjs"
import { useMemo } from "react"
import { useShowAITranslation } from "~/atoms/ai-translation"
import { useGeneralSettingSelector } from "~/atoms/settings/general"
+import { useUISettingKey } from "~/atoms/settings/ui"
import { useWhoami } from "~/atoms/user"
import { RelativeTime } from "~/components/ui/datetime"
import { useAuthQuery } from "~/hooks/common"
@@ -65,6 +67,14 @@ export const EntryTitle = ({ entryId, compact }: EntryLinkProps) => {
},
)
+ const dateFormat = useUISettingKey("dateFormat")
+
+ const dateRender = useMemo(() => {
+ if (!entry?.entries.publishedAt) return null
+ if (dateFormat === "default") return new Date(entry.entries.publishedAt).toLocaleString()
+ return dayjs(entry.entries.publishedAt).format(dateFormat)
+ }, [dateFormat, entry?.entries.publishedAt])
+
if (!entry) return null
return compact ? (
@@ -104,7 +114,7 @@ export const EntryTitle = ({ entryId, compact }: EntryLinkProps) => {
{getPreferredTitle(feed || inbox, entry.entries)}
- {entry.entries.publishedAt && new Date(entry.entries.publishedAt).toLocaleString()}
+ {dateRender}
diff --git a/apps/renderer/src/modules/entry-content/index.desktop.tsx b/apps/renderer/src/modules/entry-content/index.desktop.tsx
index 45f14009a..8d8aacf0e 100644
--- a/apps/renderer/src/modules/entry-content/index.desktop.tsx
+++ b/apps/renderer/src/modules/entry-content/index.desktop.tsx
@@ -6,6 +6,7 @@ import { IN_ELECTRON } from "@follow/shared/constants"
import { stopPropagation } from "@follow/utils/dom"
import { cn } from "@follow/utils/utils"
import { ErrorBoundary } from "@sentry/react"
+import * as React from "react"
import { useEffect, useMemo, useRef } from "react"
import { useShowAITranslation } from "~/atoms/ai-translation"
@@ -82,15 +83,23 @@ export const EntryContent: Component
= ({
[entryId, isPeekModal],
)
useFocusEntryContainerSubscriptions(scrollerRef)
- const stableRenderStyle = useMemo(
- () =>
- readerFontFamily
- ? {
- fontFamily: readerFontFamily,
- }
- : undefined,
- [readerFontFamily],
- )
+ const contentLineHeight = useUISettingKey("contentLineHeight")
+ const contentFontSize = useUISettingKey("contentFontSize")
+
+ const stableRenderStyle = useMemo(() => {
+ const css = {} as React.CSSProperties
+ if (readerFontFamily) {
+ css.fontFamily = readerFontFamily
+ }
+ if (contentLineHeight) {
+ css.lineHeight = contentLineHeight
+ }
+ if (contentFontSize) {
+ css.fontSize = contentFontSize
+ }
+
+ return css
+ }, [readerFontFamily, contentLineHeight, contentFontSize])
const mediaInfo = useMemo(
() =>
Object.fromEntries(
diff --git a/apps/renderer/src/modules/entry-content/index.mobile.tsx b/apps/renderer/src/modules/entry-content/index.mobile.tsx
index 47eb6c4bd..ed33f5ef4 100644
--- a/apps/renderer/src/modules/entry-content/index.mobile.tsx
+++ b/apps/renderer/src/modules/entry-content/index.mobile.tsx
@@ -108,6 +108,22 @@ export const EntryContent: Component<{
(s) => s.translationLanguage,
) as SupportedLanguages
+ const contentLineHeight = useUISettingKey("contentLineHeight")
+ const contentFontSize = useUISettingKey("contentFontSize")
+
+ const stableRenderStyle = useMemo(() => {
+ const css = {} as React.CSSProperties
+
+ if (contentLineHeight) {
+ css.lineHeight = contentLineHeight
+ }
+ if (contentFontSize) {
+ css.fontSize = contentFontSize
+ }
+
+ return css
+ }, [contentLineHeight, contentFontSize])
+
if (!entry) return null
const content = entry?.entries.content ?? data?.entries.content
@@ -207,6 +223,7 @@ export const EntryContent: Component<{
as="article"
className="prose !max-w-full hyphens-auto dark:prose-invert prose-h1:text-[1.6em] prose-h1:font-bold"
renderInlineStyle={readerRenderInlineStyle}
+ style={stableRenderStyle}
>
{content}
diff --git a/apps/renderer/src/modules/settings/sections/fonts.tsx b/apps/renderer/src/modules/settings/sections/fonts.tsx
index 2e058ddb3..3c0556375 100644
--- a/apps/renderer/src/modules/settings/sections/fonts.tsx
+++ b/apps/renderer/src/modules/settings/sections/fonts.tsx
@@ -70,7 +70,7 @@ export const ContentFontSelector = () => {
)
return (
-
+
{t("appearance.content_font")}