refactor(mobile): reorganize timeline selector components and imports

Signed-off-by: Innei <tukon479@gmail.com>
This commit is contained in:
Innei 2025-02-13 22:41:14 +08:00
parent 8703a0d503
commit 710ae5da7a
No known key found for this signature in database
GPG Key ID: 0F62D33977F021F7
7 changed files with 43 additions and 20 deletions

View File

@ -0,0 +1,7 @@
import type { SpringConfig } from "react-native-reanimated/lib/typescript/animation/springUtils"
export const gentleSpringPreset: SpringConfig = {
damping: 15,
stiffness: 100,
mass: 1,
}

View File

@ -8,6 +8,7 @@ import Animated, { useAnimatedStyle, useSharedValue, withSpring } from "react-na
import { setWebViewEntry } from "@/src/components/native/webview/EntryContentWebView"
import { ItemPressable } from "@/src/components/ui/pressable/item-pressable"
import { gentleSpringPreset } from "@/src/constants/spring"
import { EntryItemContextMenu } from "@/src/modules/context-menu/entry"
import { LoadArchiveButton } from "@/src/modules/entry-list/action"
import { EntryListContentGrid } from "@/src/modules/entry-list/entry-list-gird"
@ -16,8 +17,8 @@ import {
useFetchEntriesControls,
useSelectedView,
} from "@/src/modules/screen/atoms"
import { TimelineSelectorHeader } from "@/src/modules/screen/timeline-selector-header"
import { TimelineSelectorList } from "@/src/modules/screen/timeline-selector-list"
import { TimelineSelectorHeader } from "@/src/modules/screen/TimelineSelectorHeader"
import { TimelineSelectorList } from "@/src/modules/screen/TimelineSelectorList"
import { useEntry } from "@/src/store/entry/hooks"
import { debouncedFetchEntryContentByStream } from "@/src/store/entry/store"
@ -104,15 +105,10 @@ function EntryItem({ entryId }: { entryId: string }) {
useEffect(() => {
if (!entry) return
const springConfig = {
damping: 15,
stiffness: 100,
mass: 1,
}
if (entry.read) {
unreadZoomSharedValue.value = withSpring(0, springConfig)
unreadZoomSharedValue.value = withSpring(0, gentleSpringPreset)
} else {
unreadZoomSharedValue.value = withSpring(1, springConfig)
unreadZoomSharedValue.value = withSpring(1, gentleSpringPreset)
}
}, [entry?.read, unreadZoomSharedValue])
if (!entry) return <EntryItemSkeleton />
@ -122,7 +118,7 @@ function EntryItem({ entryId }: { entryId: string }) {
return (
<EntryItemContextMenu id={entryId}>
<ItemPressable className="flex flex-row items-center p-4 px-6" onPress={handlePress}>
<ItemPressable className="flex flex-row items-center p-4 pl-6" onPress={handlePress}>
<Animated.View
className="bg-red absolute left-2 top-[22] size-2.5 rounded-full"
style={unreadIndicatorStyle}

View File

@ -8,7 +8,7 @@ import {
import { HomeLeftAction, HomeRightAction } from "@/src/modules/screen/action"
import { useEntryListContext, useSelectedFeedTitle } from "@/src/modules/screen/atoms"
import { headerHideableBottomHeight } from "@/src/modules/screen/hooks/useHeaderHeight"
import { ViewSelector } from "@/src/modules/screen/view-selector"
import { TimelineViewSelector } from "@/src/modules/screen/TimelineViewSelector"
export function TimelineSelectorHeader({ children }: { children: React.ReactNode }) {
const scrollY = useAnimatedValue(0)
@ -32,7 +32,7 @@ export function TimelineSelectorHeader({ children }: { children: React.ReactNode
[isTimeline],
)}
headerHideableBottomHeight={isTimeline ? headerHideableBottomHeight : undefined}
headerHideableBottom={isTimeline ? ViewSelector : undefined}
headerHideableBottom={isTimeline ? TimelineViewSelector : undefined}
/>
{children}
</NavigationContext.Provider>

View File

@ -7,6 +7,7 @@ import { useAnimatedStyle, useSharedValue, withSpring } from "react-native-reani
import { ReAnimatedTouchableOpacity } from "@/src/components/common/AnimatedComponents"
import { FallbackIcon } from "@/src/components/ui/icon/fallback-icon"
import { gentleSpringPreset } from "@/src/constants/spring"
import type { ViewDefinition } from "@/src/constants/views"
import { views } from "@/src/constants/views"
import { selectTimeline, useSelectedFeed } from "@/src/modules/screen/atoms"
@ -15,7 +16,7 @@ import { useAllListSubscription } from "@/src/store/subscription/hooks"
import { useUnreadCountByView } from "@/src/store/unread/hooks"
import { accentColor, useColor } from "@/src/theme/colors"
export function ViewSelector() {
export function TimelineViewSelector() {
const lists = useAllListSubscription()
return (
@ -48,12 +49,16 @@ function ItemWrapper({
onPress: () => void
style?: Exclude<StyleProp<ViewStyle>, number>
}) {
const width = useSharedValue(isActive ? 130 : 48)
const textWidth = useSharedValue(130)
const width = useSharedValue(isActive ? Math.max(130, textWidth.value + 48) : 48)
const bgColor = useColor("gray5")
useEffect(() => {
width.value = withSpring(isActive ? 130 : 48)
}, [isActive, width])
width.value = withSpring(
isActive ? Math.max(130, textWidth.value + 48) : 48,
gentleSpringPreset,
)
}, [isActive, width, textWidth])
return (
<ReAnimatedTouchableOpacity
@ -65,7 +70,16 @@ function ItemWrapper({
...style,
}))}
>
{children}
<View
className="flex-row items-center gap-2"
onLayout={({ nativeEvent }) => {
if (isActive) {
textWidth.value = nativeEvent.layout.width
}
}}
>
{children}
</View>
</ReAnimatedTouchableOpacity>
)
}
@ -89,7 +103,13 @@ function ViewItem({ view }: { view: ViewDefinition }) {
{view.name + (unreadCount ? ` (${unreadCount})` : "")}
</Text>
) : (
!!unreadCount && <View className="bg-gray absolute right-2 top-2 size-2 rounded-full" />
!!unreadCount &&
!isActive && (
<View
className="border-gray-2 absolute -right-0.5 -top-0.5 size-2.5 rounded-full"
style={{ backgroundColor: view.activeColor }}
/>
)
)}
</ItemWrapper>
)

View File

@ -6,7 +6,7 @@ import { useEventCallback } from "usehooks-ts"
import { ItemPressable } from "@/src/components/ui/pressable/item-pressable"
import { StarCuteFiIcon } from "@/src/icons/star_cute_fi"
import { closeDrawer, selectFeed } from "@/src/modules/screen/atoms"
import { TimelineSelectorList } from "@/src/modules/screen/timeline-selector-list"
import { TimelineSelectorList } from "@/src/modules/screen/TimelineSelectorList"
import { FEED_COLLECTION_LIST } from "@/src/store/entry/utils"
import {
useGroupedSubscription,

View File

@ -1,5 +1,5 @@
import { useSelectedFeed } from "@/src/modules/screen/atoms"
import { TimelineSelectorHeader } from "@/src/modules/screen/timeline-selector-header"
import { TimelineSelectorHeader } from "@/src/modules/screen/TimelineSelectorHeader"
import { SubscriptionList } from "@/src/modules/subscription/SubscriptionLists"
export default function Subscriptions() {