Skip to content

Commit 494efa4

Browse files
committed
feat: remove lists in timeline selector
1 parent 924cd70 commit 494efa4

File tree

3 files changed

+57
-77
lines changed

3 files changed

+57
-77
lines changed
Lines changed: 22 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
import { Image } from "expo-image"
21
import { useEffect } from "react"
32
import type { StyleProp, ViewStyle } from "react-native"
4-
import { ScrollView, StyleSheet, Text, View } from "react-native"
5-
import { Grayscale } from "react-native-color-matrix-image-filters"
3+
import { ScrollView, useWindowDimensions, View } from "react-native"
64
import Animated, {
75
FadeOut,
86
useAnimatedStyle,
@@ -11,20 +9,20 @@ import Animated, {
119
} from "react-native-reanimated"
1210

1311
import { ReAnimatedTouchableOpacity } from "@/src/components/common/AnimatedComponents"
14-
import { FallbackIcon } from "@/src/components/ui/icon/fallback-icon"
1512
import { gentleSpringPreset } from "@/src/constants/spring"
1613
import type { ViewDefinition } from "@/src/constants/views"
17-
import { views } from "@/src/constants/views"
1814
import { selectTimeline, useSelectedFeed } from "@/src/modules/screen/atoms"
19-
import { useList } from "@/src/store/list/hooks"
20-
import { useAllListSubscription } from "@/src/store/subscription/hooks"
15+
import { useViewWithSubscription } from "@/src/store/subscription/hooks"
2116
import { useUnreadCountByView } from "@/src/store/unread/hooks"
22-
import { accentColor, useColor } from "@/src/theme/colors"
17+
import { useColor } from "@/src/theme/colors"
2318

2419
import { TimelineViewSelectorContextMenu } from "./TimelineViewSelectorContextMenu"
2520

21+
const ACTIVE_WIDTH = 180
22+
const INACTIVE_WIDTH = 48
23+
2624
export function TimelineViewSelector() {
27-
const lists = useAllListSubscription()
25+
const activeViews = useViewWithSubscription()
2826

2927
return (
3028
<View className="flex items-center justify-between py-2">
@@ -34,13 +32,9 @@ export function TimelineViewSelector() {
3432
contentContainerClassName="flex-row gap-3 items-center px-3"
3533
showsHorizontalScrollIndicator={false}
3634
>
37-
{views.map((view) => (
35+
{activeViews.map((view) => (
3836
<ViewItem key={view.name} view={view} />
3937
))}
40-
{lists.length > 0 && <View className="bg-opaque-separator mx-3 h-8 w-px" />}
41-
{lists.map((listId) => (
42-
<ListItem key={listId} listId={listId} />
43-
))}
4438
</ScrollView>
4539
</View>
4640
)
@@ -57,16 +51,26 @@ function ItemWrapper({
5751
onPress: () => void
5852
style?: Exclude<StyleProp<ViewStyle>, number>
5953
}) {
60-
const textWidth = useSharedValue(130)
61-
const width = useSharedValue(isActive ? Math.max(130, textWidth.value + 48) : 48)
54+
const { width: windowWidth } = useWindowDimensions()
55+
const activeViews = useViewWithSubscription()
56+
57+
const activeWidth = Math.max(
58+
windowWidth - (INACTIVE_WIDTH + 12) * (activeViews.length - 1) - 8 * 2,
59+
ACTIVE_WIDTH,
60+
)
61+
62+
const textWidth = useSharedValue(0)
63+
const width = useSharedValue(
64+
isActive ? Math.max(activeWidth, textWidth.value + INACTIVE_WIDTH) : INACTIVE_WIDTH,
65+
)
6266
const bgColor = useColor("gray5")
6367

6468
useEffect(() => {
6569
width.value = withSpring(
66-
isActive ? Math.max(130, textWidth.value + 48) : 48,
70+
isActive ? Math.max(activeWidth, textWidth.value + INACTIVE_WIDTH) : INACTIVE_WIDTH,
6771
gentleSpringPreset,
6872
)
69-
}, [isActive, width, textWidth])
73+
}, [isActive, width, textWidth, activeWidth])
7074

7175
return (
7276
<ReAnimatedTouchableOpacity
@@ -99,15 +103,6 @@ function ViewItem({ view }: { view: ViewDefinition }) {
99103
const unreadCount = useUnreadCountByView(view.view)
100104
const borderColor = useColor("gray5")
101105

102-
const textWidth = useSharedValue(130)
103-
const width = useSharedValue(isActive ? Math.max(130, textWidth.value + 48) : 48)
104-
105-
useEffect(() => {
106-
if (isActive) {
107-
width.value = withSpring(Math.max(130, textWidth.value + 48), gentleSpringPreset)
108-
}
109-
}, [isActive, unreadCount])
110-
111106
return (
112107
<TimelineViewSelectorContextMenu type="view" viewId={view.view}>
113108
<ItemWrapper
@@ -143,44 +138,3 @@ function ViewItem({ view }: { view: ViewDefinition }) {
143138
</TimelineViewSelectorContextMenu>
144139
)
145140
}
146-
147-
function ListItem({ listId }: { listId: string }) {
148-
const list = useList(listId)
149-
const selectedFeed = useSelectedFeed()
150-
151-
if (!selectedFeed) return null
152-
const isActive = selectedFeed.type === "list" && selectedFeed.listId === listId
153-
154-
if (!list) return null
155-
156-
return (
157-
<ItemWrapper
158-
isActive={isActive}
159-
onPress={() => selectTimeline({ type: "list", listId })}
160-
style={isActive ? { backgroundColor: accentColor } : undefined}
161-
>
162-
{list.image ? (
163-
isActive ? (
164-
<Image source={list.image} contentFit="cover" className="size-7 rounded-lg" />
165-
) : (
166-
<Grayscale>
167-
<Image source={list.image} contentFit="cover" className="size-7 rounded-lg" />
168-
</Grayscale>
169-
)
170-
) : (
171-
<FallbackIcon title={list.title} size={28} gray={!isActive} style={styles.fallbackIcon} />
172-
)}
173-
{isActive && (
174-
<Text className="max-w-24 text-sm font-semibold text-white" numberOfLines={1}>
175-
{list.title}
176-
</Text>
177-
)}
178-
</ItemWrapper>
179-
)
180-
}
181-
182-
const styles = StyleSheet.create({
183-
fallbackIcon: {
184-
borderRadius: 8,
185-
},
186-
})

apps/mobile/src/store/subscription/hooks.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
import type { FeedViewType } from "@follow/constants"
1+
import { FeedViewType } from "@follow/constants"
22
import { sortByAlphabet } from "@follow/utils"
33
import { useQuery } from "@tanstack/react-query"
44
import { useCallback } from "react"
55

6+
import { views } from "@/src/constants/views"
7+
68
import { getFeed } from "../feed/getter"
79
import { getList } from "../list/getters"
810
import { getUnreadCount } from "../unread/getter"
@@ -226,3 +228,21 @@ export const useSubscriptionByFeedId = (feedId: string) =>
226228

227229
export const useSubscriptionByListId = (listId: string) =>
228230
useSubscriptionStore(useCallback((state) => state.data[listId] || null, [listId]))
231+
232+
export const useViewWithSubscription = () =>
233+
useSubscriptionStore(
234+
useCallback((state) => {
235+
return views.filter((view) => {
236+
if (
237+
view.view === FeedViewType.Articles ||
238+
view.view === FeedViewType.SocialMedia ||
239+
view.view === FeedViewType.Pictures ||
240+
view.view === FeedViewType.Videos
241+
) {
242+
return true
243+
} else {
244+
return state.feedIdByView[view.view].size > 0
245+
}
246+
})
247+
}, []),
248+
)

apps/mobile/src/store/subscription/store.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,19 @@ class SubscriptionActions {
9191
}
9292
})
9393
}
94-
async upsertMany(subscriptions: SubscriptionModel[]) {
94+
async upsertMany(
95+
subscriptions: SubscriptionModel[],
96+
options: { resetBeforeUpsert?: boolean | FeedViewType } = {},
97+
) {
9598
const tx = createTransaction()
9699
tx.store(() => {
100+
if (options.resetBeforeUpsert !== undefined) {
101+
if (typeof options.resetBeforeUpsert === "boolean") {
102+
this.reset()
103+
} else {
104+
this.resetByView(options.resetBeforeUpsert)
105+
}
106+
}
97107
this.upsertManyInSession(subscriptions)
98108
})
99109

@@ -131,12 +141,6 @@ class SubscriptionSyncService {
131141
},
132142
})
133143

134-
if (typeof view === "number") {
135-
subscriptionActions.resetByView(view)
136-
} else {
137-
subscriptionActions.reset()
138-
}
139-
140144
const { subscriptions, feeds, lists, inboxes } = honoMorph.toSubscription(res.data)
141145

142146
await SubscriptionService.deleteNotExists(
@@ -145,7 +149,9 @@ class SubscriptionSyncService {
145149
)
146150

147151
feedActions.upsertMany(feeds)
148-
subscriptionActions.upsertMany(subscriptions)
152+
subscriptionActions.upsertMany(subscriptions, {
153+
resetBeforeUpsert: typeof view === "number" ? view : true,
154+
})
149155
listActions.upsertMany(lists)
150156

151157
inboxActions.upsertMany(inboxes)

0 commit comments

Comments
 (0)