Skip to content

Commit

Permalink
feat: add auto-expand setting for long social media entries and remov…
Browse files Browse the repository at this point in the history
…e placeholder component, fixed #2064

- Introduced a new setting to automatically expand long social media entries.
- Removed the ReactVirtuosoItemPlaceholder component, replacing it with null returns for better handling of empty entries.
- Updated relevant settings files and translations for the new feature.

Signed-off-by: Innei <tukon479@gmail.com>
  • Loading branch information
Innei committed Dec 9, 2024
1 parent cf5eeb6 commit 639b922
Show file tree
Hide file tree
Showing 14 changed files with 38 additions and 21 deletions.
3 changes: 2 additions & 1 deletion apps/renderer/src/atoms/settings/general.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ const createDefaultSettings = (): GeneralSettings => ({
hoverMarkUnread: true,
renderMarkUnread: false,
// UX

groupByDate: true,
autoExpandLongSocialMedia: false,

// Secure
jumpOutLinkWarn: true,
// TTS
Expand Down
4 changes: 0 additions & 4 deletions apps/renderer/src/components/ui/placeholder.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { memo, useContext, useEffect, useMemo, useState } from "react"
import { useTranslation } from "react-i18next"

import { SwipeMedia } from "~/components/ui/media/SwipeMedia"
import { ReactVirtuosoItemPlaceholder } from "~/components/ui/placeholder"
import { useRouteParamsSelector } from "~/hooks/biz/useRouteParams"
import { filterSmallMedia } from "~/lib/utils"
import { EntryContent } from "~/modules/entry-content"
Expand All @@ -33,7 +32,7 @@ export function PictureItem({ entryId, entryPreview, translation }: UniversalIte
const { t } = useTranslation()
const entryContent = useMemo(() => <EntryContent entryId={entryId} noMedia compact />, [entryId])
const previewMedia = usePreviewMedia(entryContent)
if (!entry) return <ReactVirtuosoItemPlaceholder />
if (!entry) return null
return (
<GridItem entryId={entryId} entryPreview={entryPreview} translation={translation}>
<div className="relative flex gap-2 overflow-x-auto">
Expand Down
17 changes: 11 additions & 6 deletions apps/renderer/src/modules/entry-column/Items/social-media-item.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { PassviseFragment } from "@follow/components/common/Fragment.js"
import { useMobile } from "@follow/components/hooks/useMobile.js"
import { AutoResizeHeight } from "@follow/components/ui/auto-resize-height/index.js"
import { ActionButton } from "@follow/components/ui/button/index.js"
Expand All @@ -9,6 +10,7 @@ import { atom } from "jotai"
import { useLayoutEffect, useMemo, useRef, useState } from "react"
import { useTranslation } from "react-i18next"

import { useGeneralSettingKey } from "~/atoms/settings/general"
import { RelativeTime } from "~/components/ui/datetime"
import { Media } from "~/components/ui/media"
import { usePreviewMedia } from "~/components/ui/media/hooks"
Expand All @@ -23,7 +25,6 @@ import { FeedTitle } from "~/modules/feed/feed-title"
import { useEntry } from "~/store/entry/hooks"
import { useFeedById } from "~/store/feed"

import { ReactVirtuosoItemPlaceholder } from "../../../components/ui/placeholder"
import { filterSmallMedia } from "../../../lib/utils"
import { StarIcon } from "../star-icon"
import { EntryTranslation } from "../translation"
Expand Down Expand Up @@ -52,14 +53,17 @@ export const SocialMediaItem: EntryListItemFC = ({ entryId, entryPreview, transl
jotaiStore.set(socialMediaContentWidthAtom, ref.current.offsetWidth)
}
}, [])
// NOTE: prevent 0 height element, react virtuoso will not stop render any more
if (!entry || !feed) return <ReactVirtuosoItemPlaceholder />
const autoExpandLongSocialMedia = useGeneralSettingKey("autoExpandLongSocialMedia")

if (!entry || !feed) return null

const content = entry.entries.content || entry.entries.description

const parsed = parseSocialMedia(entry.entries)

const media = filterSmallMedia(entry.entries.media)
const EntryContentWrapper = autoExpandLongSocialMedia
? PassviseFragment
: CollapsedSocialMediaItem

return (
<div
Expand Down Expand Up @@ -102,14 +106,14 @@ export const SocialMediaItem: EntryListItemFC = ({ entryId, entryPreview, transl
</span>
</div>
<div className={cn("relative mt-1 text-base", !!entry.collections && "pr-5")}>
<CollapsedSocialMediaItem entryId={entryId}>
<EntryContentWrapper entryId={entryId}>
<EntryTranslation
className="cursor-auto select-text text-sm leading-relaxed prose-blockquote:mt-0 [&_br:last-child]:hidden"
source={content}
target={translation?.content}
isHTML
/>
</CollapsedSocialMediaItem>
</EntryContentWrapper>
{!!entry.collections && <StarIcon className="absolute right-0 top-0" />}
</div>
</div>
Expand Down Expand Up @@ -368,6 +372,7 @@ const CollapsedSocialMediaItem: Component<{
const [isOverflow, setIsOverflow] = useState(false)
const [isShowMore, setIsShowMore] = useState(() => collapsedItemCache.get(entryId) ?? false)
const ref = useRef<HTMLDivElement>(null)

useLayoutEffect(() => {
if (ref.current) {
setIsOverflow(ref.current.scrollHeight > collapsedHeight)
Expand Down
3 changes: 1 addition & 2 deletions apps/renderer/src/modules/entry-column/Items/video-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import { FeedIcon } from "~/modules/feed/feed-icon"
import { FeedTitle } from "~/modules/feed/feed-title"
import { useEntry } from "~/store/entry/hooks"

import { ReactVirtuosoItemPlaceholder } from "../../../components/ui/placeholder"
import { GridItem } from "../templates/grid-item-template"
import type { EntryItemStatelessProps, UniversalItemProps } from "../types"

Expand Down Expand Up @@ -62,7 +61,7 @@ export function VideoItem({ entryId, entryPreview, translation }: UniversalItemP
}
}, [hovered])

if (!entry) return <ReactVirtuosoItemPlaceholder />
if (!entry) return null
return (
<GridItem entryId={entryId} entryPreview={entryPreview} translation={translation}>
<div
Expand Down
3 changes: 1 addition & 2 deletions apps/renderer/src/modules/entry-column/item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { Queries } from "~/queries"
import type { FlatEntryModel } from "~/store/entry"
import { useEntry } from "~/store/entry/hooks"

import { ReactVirtuosoItemPlaceholder } from "../../components/ui/placeholder"
import { getItemComponentByView, getSkeletonItemComponentByView } from "./Items"
import { EntryItemWrapper } from "./layouts/EntryItemWrapper"
import { girdClassNames } from "./styles"
Expand Down Expand Up @@ -49,7 +48,7 @@ function EntryItemImpl({ entry, view }: { entry: FlatEntryModel; view?: number }
export const EntryItem: FC<EntryItemProps> = memo(({ entryId, view }) => {
const entry = useEntry(entryId)

if (!entry) return <ReactVirtuosoItemPlaceholder />
if (!entry) return null
return <EntryItemImpl entry={entry} view={view} />
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { TitleMarquee } from "@follow/components/ui/marquee/index.jsx"
import { cn } from "@follow/utils/utils"
import dayjs from "dayjs"

import { ReactVirtuosoItemPlaceholder } from "~/components/ui/placeholder"
import { useAsRead } from "~/hooks/biz/useAsRead"
import { EntryTranslation } from "~/modules/entry-column/translation"
import { FeedIcon } from "~/modules/feed/feed-icon"
Expand All @@ -21,7 +20,7 @@ export function GridItem(props: GridItemProps) {
const { entryId, entryPreview, wrapperClassName, children, translation } = props
const entry = useEntry(entryId) || entryPreview

if (!entry) return <ReactVirtuosoItemPlaceholder />
if (!entry) return null
return (
<div className={cn("p-1.5", wrapperClassName)}>
{children}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { useEntry } from "~/store/entry/hooks"
import { getPreferredTitle, useFeedById } from "~/store/feed"
import { useInboxById } from "~/store/inbox"

import { ReactVirtuosoItemPlaceholder } from "../../../components/ui/placeholder"
import { StarIcon } from "../star-icon"
import type { UniversalItemProps } from "../types"

Expand Down Expand Up @@ -79,7 +78,7 @@ export function ListItem({
}, [translation?.title, translation?.description, settingWideMode])

// NOTE: prevent 0 height element, react virtuoso will not stop render any more
if (!entry || !(feed || inbox)) return <ReactVirtuosoItemPlaceholder />
if (!entry || !(feed || inbox)) return null

const displayTime = inInCollection ? entry.collections?.createdAt : entry.entries.publishedAt

Expand Down
5 changes: 5 additions & 0 deletions apps/renderer/src/modules/settings/tabs/general.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ export const SettingGeneral = () => {
label: t("general.group_by_date.label"),
description: t("general.group_by_date.description"),
}),

defineSettingItem("autoExpandLongSocialMedia", {
label: t("general.auto_expand_long_social_media.label"),
description: t("general.auto_expand_long_social_media.description"),
}),
isMobile &&
defineSettingItem("showQuickTimeline", {
label: t("general.show_quick_timeline.label"),
Expand Down
1 change: 1 addition & 0 deletions changelog/next.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## New Features

- New `Move to Category` operation in feed subscription context menu
- New `Expand long social media` setting to automatically expand social media entries containing long text.

## Improvements

Expand Down
2 changes: 2 additions & 0 deletions locales/settings/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@
"feeds.tableHeaders.subscriptionCount": "Subs",
"feeds.tableHeaders.tipAmount": "Tips",
"general.app": "App",
"general.auto_expand_long_social_media.description": "Automatically expand social media entries containing long text.",
"general.auto_expand_long_social_media.label": "Expand long social media",
"general.auto_group.description": "Automatically group feeds by site domain.",
"general.auto_group.label": "Auto Group",
"general.cache": "Cache",
Expand Down
2 changes: 2 additions & 0 deletions locales/settings/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@
"feeds.tableHeaders.subscriptionCount": "订阅数",
"feeds.tableHeaders.tipAmount": "收到的打赏",
"general.app": "应用程序",
"general.auto_expand_long_social_media.description": "自动展开包含长文本的社交媒体条目。",
"general.auto_expand_long_social_media.label": "展开长社交媒体",
"general.auto_group.description": "自动按网站域名分组订阅源。",
"general.auto_group.label": "自动分组",
"general.cache": "缓存",
Expand Down
6 changes: 6 additions & 0 deletions packages/components/src/common/Fragment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import * as React from "react"
import { createElement } from "react"

export const PassviseFragment = ({ children }: { children: React.ReactNode }) => {
return createElement(React.Fragment, null, children)
}
4 changes: 4 additions & 0 deletions packages/shared/src/interface/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ export interface GeneralSettings {
* Top timeline for mobile
*/
showQuickTimeline: boolean
/**
* Auto expand long social media
*/
autoExpandLongSocialMedia: boolean
}

export interface UISettings {
Expand Down

0 comments on commit 639b922

Please sign in to comment.