diff --git a/apps/mobile/src/lib/platform.ts b/apps/mobile/src/lib/platform.ts
new file mode 100644
index 000000000..b0b492f46
--- /dev/null
+++ b/apps/mobile/src/lib/platform.ts
@@ -0,0 +1,3 @@
+import { Platform } from "react-native"
+
+export const isIOS = Platform.OS === "ios"
diff --git a/apps/mobile/src/modules/discover/constants.ts b/apps/mobile/src/modules/discover/constants.ts
index 96e009248..39dcfb891 100644
--- a/apps/mobile/src/modules/discover/constants.ts
+++ b/apps/mobile/src/modules/discover/constants.ts
@@ -1,11 +1,11 @@
export enum SearchType {
Feed = "feed",
List = "list",
- User = "user",
+ // User = "user",
}
export const SearchTabs = [
{ name: "Feed", value: SearchType.Feed },
{ name: "List", value: SearchType.List },
- { name: "User", value: SearchType.User },
+ // { name: "User", value: SearchType.User },
]
diff --git a/apps/mobile/src/modules/feed-drawer/collection-panel.tsx b/apps/mobile/src/modules/feed-drawer/collection-panel.tsx
index 78fdfd115..1b59baf8d 100644
--- a/apps/mobile/src/modules/feed-drawer/collection-panel.tsx
+++ b/apps/mobile/src/modules/feed-drawer/collection-panel.tsx
@@ -1,12 +1,13 @@
import { cn } from "@follow/utils"
import {
Image,
- SafeAreaView,
ScrollView,
+ StyleSheet,
TouchableOpacity,
useWindowDimensions,
View,
} from "react-native"
+import { useSafeAreaInsets } from "react-native-safe-area-context"
import { FallbackIcon } from "@/src/components/ui/icon/fallback-icon"
import type { ViewDefinition } from "@/src/constants/views"
@@ -20,23 +21,34 @@ export const CollectionPanel = () => {
const winDim = useWindowDimensions()
const lists = useAllListSubscription()
+ const insets = useSafeAreaInsets()
return (
-
-
+
{views.map((viewDef) => (
))}
+
{lists.map((listId) => (
))}
-
+
)
}
+const styles = StyleSheet.create({
+ hairline: {
+ height: StyleSheet.hairlineWidth,
+ },
+})
+
const ViewButton = ({ viewDef }: { viewDef: ViewDefinition }) => {
const selectedCollection = useSelectedCollection()
const isActive = selectedCollection.type === "view" && selectedCollection.viewId === viewDef.view
@@ -45,7 +57,7 @@ const ViewButton = ({ viewDef }: { viewDef: ViewDefinition }) => {
selectCollection({
diff --git a/apps/mobile/src/modules/feed-drawer/drawer.tsx b/apps/mobile/src/modules/feed-drawer/drawer.tsx
index 9ae8ae732..7ecb4ef22 100644
--- a/apps/mobile/src/modules/feed-drawer/drawer.tsx
+++ b/apps/mobile/src/modules/feed-drawer/drawer.tsx
@@ -63,7 +63,7 @@ export const FeedDrawer = ({ children }: PropsWithChildren) => {
const DrawerContent = () => {
return (
-
+
diff --git a/apps/mobile/src/modules/feed-drawer/feed-panel.tsx b/apps/mobile/src/modules/feed-drawer/feed-panel.tsx
index b2896fff9..e58a9c61e 100644
--- a/apps/mobile/src/modules/feed-drawer/feed-panel.tsx
+++ b/apps/mobile/src/modules/feed-drawer/feed-panel.tsx
@@ -1,12 +1,12 @@
-import type { FeedViewType } from "@follow/constants"
import { cn } from "@follow/utils"
+import { BottomTabBarHeightContext } from "@react-navigation/bottom-tabs"
+import { HeaderHeightContext } from "@react-navigation/elements"
import { router } from "expo-router"
import type { FC } from "react"
-import { createContext, memo, useContext, useMemo } from "react"
+import { createContext, memo, useContext, useState } from "react"
import {
Animated,
Easing,
- SafeAreaView,
ScrollView,
StyleSheet,
Text,
@@ -23,13 +23,7 @@ import { ItemPressable } from "@/src/components/ui/pressable/item-pressable"
import { MingcuteRightLine } from "@/src/icons/mingcute_right_line"
import { useFeed, usePrefetchFeed } from "@/src/store/feed/hooks"
import { useList } from "@/src/store/list/hooks"
-import {
- useGroupedSubscription,
- usePrefetchSubscription,
- useSortedGroupedSubscription,
- useSortedUngroupedSubscription,
- useSubscription,
-} from "@/src/store/subscription/hooks"
+import { useSortedUngroupedSubscription, useSubscription } from "@/src/store/subscription/hooks"
import { useUnreadCount, useUnreadCounts } from "@/src/store/unread/hooks"
import {
@@ -37,40 +31,44 @@ import {
SubscriptionFeedItemContextMenu,
} from "../context-menu/feeds"
import { useCurrentView, useFeedListSortMethod, useFeedListSortOrder } from "../subscription/atoms"
+import { ViewPageCurrentViewProvider } from "../subscription/ctx"
+import { SubscriptionList } from "../subscription/SubscriptionLists"
import { useSelectedCollection } from "./atoms"
import { ListHeaderComponent, ViewHeaderComponent } from "./header"
-const useSortedSubscription = (view: FeedViewType) => {
- usePrefetchSubscription(view)
- const { grouped, unGrouped } = useGroupedSubscription(view)
-
- const sortBy = useFeedListSortMethod()
- const sortOrder = useFeedListSortOrder()
- const sortedGrouped = useSortedGroupedSubscription(grouped, sortBy, sortOrder)
- const sortedUnGrouped = useSortedUngroupedSubscription(unGrouped, sortBy, sortOrder)
- const data = useMemo(
- () => [...sortedGrouped, ...sortedUnGrouped],
- [sortedGrouped, sortedUnGrouped],
- )
- return data
-}
-
export const FeedPanel = () => {
const selectedCollection = useSelectedCollection()
+ const [headerHeight, setHeaderHeight] = useState(0)
+
if (selectedCollection.type === "view") {
return (
-
-
-
-
+
+ {
+ setHeaderHeight(e.nativeEvent.layout.height)
+ }}
+ />
+
+
+
+
+
+
+
+
+
)
}
return (
-
+
-
+
)
}
@@ -93,23 +91,6 @@ const ListView = ({ listId }: { listId: string }) => {
)
}
-const FeedListView = ({ view }: { view: FeedViewType }) => {
- const data = useSortedSubscription(view)
- return (
-
- {data.map((item, index) => (
-
- ))}
- {/* Just a placeholder */}
-
-
- )
-}
-
const ItemRender = ({
item,
}: {
diff --git a/apps/mobile/src/modules/feed-drawer/header.tsx b/apps/mobile/src/modules/feed-drawer/header.tsx
index 2afabd0e5..67471adc9 100644
--- a/apps/mobile/src/modules/feed-drawer/header.tsx
+++ b/apps/mobile/src/modules/feed-drawer/header.tsx
@@ -1,16 +1,32 @@
import type { FeedViewType } from "@follow/constants"
+import type { LayoutChangeEvent } from "react-native"
import { Text, View } from "react-native"
+import { useSafeAreaInsets } from "react-native-safe-area-context"
+import { BlurEffect } from "@/src/components/common/HeaderBlur"
import { useList } from "@/src/store/list/hooks"
import { SortActionButton } from "../subscription/header-actions"
import { useViewDefinition } from "./atoms"
-export const ViewHeaderComponent = ({ view }: { view: FeedViewType }) => {
+export const ViewHeaderComponent = ({
+ view,
+ onLayout,
+}: {
+ view: FeedViewType
+ onLayout?: (event: LayoutChangeEvent) => void
+}) => {
const viewDef = useViewDefinition(view)
+ const insets = useSafeAreaInsets()
+
return (
-
- {viewDef.name}
+
+
+ {viewDef.name}
)
@@ -18,17 +34,21 @@ export const ViewHeaderComponent = ({ view }: { view: FeedViewType }) => {
export const ListHeaderComponent = ({ listId }: { listId: string }) => {
const list = useList(listId)
+ const insets = useSafeAreaInsets()
if (!list) {
console.warn("list not found:", listId)
return null
}
return (
-
+
{list.title}
{list.description && (
- {list.description}
+ {list.description}
)}
)
diff --git a/apps/mobile/src/modules/subscription/ItemSeparator.tsx b/apps/mobile/src/modules/subscription/ItemSeparator.tsx
index d96b44a8c..b96f3061c 100644
--- a/apps/mobile/src/modules/subscription/ItemSeparator.tsx
+++ b/apps/mobile/src/modules/subscription/ItemSeparator.tsx
@@ -1,7 +1,7 @@
import { StyleSheet, View } from "react-native"
const el = (
-
+
)
export const ItemSeparator = () => {
return el
diff --git a/apps/mobile/src/modules/subscription/SubscriptionLists.tsx b/apps/mobile/src/modules/subscription/SubscriptionLists.tsx
index 467f82bfa..8d886f019 100644
--- a/apps/mobile/src/modules/subscription/SubscriptionLists.tsx
+++ b/apps/mobile/src/modules/subscription/SubscriptionLists.tsx
@@ -62,7 +62,7 @@ export const SubscriptionLists = memo(() => {
].map((view) => {
return (
-
+
)
})}
@@ -75,7 +75,13 @@ const keyExtractor = (item: string | { category: string; subscriptionIds: string
}
return item.category
}
-const SubscriptionList = ({ view }: { view: FeedViewType }) => {
+export const SubscriptionList = ({
+ view,
+ additionalOffsetTop,
+}: {
+ view: FeedViewType
+ additionalOffsetTop?: number
+}) => {
const headerHeight = useHeaderHeight()
const insets = useSafeAreaInsets()
const tabHeight = useBottomTabBarHeight()
@@ -97,13 +103,13 @@ const SubscriptionList = ({ view }: { view: FeedViewType }) => {
return subscriptionSyncService.fetch(view)
})
- const offsetTop = headerHeight - insets.top + ViewTabHeight * 2 + 23
+ const offsetTop = headerHeight - insets.top + (additionalOffsetTop || 0)
return (
{
setRefreshing(true)
onRefresh().finally(() => {
diff --git a/apps/mobile/src/screens/(headless)/search.tsx b/apps/mobile/src/screens/(headless)/search.tsx
index fc8a46dbd..a3b11185d 100644
--- a/apps/mobile/src/screens/(headless)/search.tsx
+++ b/apps/mobile/src/screens/(headless)/search.tsx
@@ -19,7 +19,6 @@ import {
import { SearchHeader } from "@/src/modules/discover/search"
import { SearchFeed } from "@/src/modules/discover/search-tabs/SearchFeed"
import { SearchList } from "@/src/modules/discover/search-tabs/SearchList"
-import { SearchUser } from "@/src/modules/discover/search-tabs/SearchUser"
const Search = () => {
return (
@@ -39,7 +38,7 @@ const Search = () => {
const SearchType2RenderContent: Record = {
[SearchType.Feed]: SearchFeed,
[SearchType.List]: SearchList,
- [SearchType.User]: SearchUser,
+ // [SearchType.User]: SearchUser,
}
const PlaceholderLazyView = () => {
const windowWidth = Dimensions.get("window").width