-
Notifications
You must be signed in to change notification settings - Fork 921
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: basic masonry entry list and entry content view (#2493)
- Loading branch information
Showing
15 changed files
with
424 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,12 @@ | ||
import { Image as ExpoImage } from "expo-image" | ||
import { Animated, FlatList, Pressable, ScrollView, TouchableOpacity } from "react-native" | ||
import Reanimated from "react-native-reanimated" | ||
|
||
export const AnimatedScrollView = Animated.createAnimatedComponent(ScrollView) | ||
export const AnimatedFlatList = Animated.createAnimatedComponent(FlatList) | ||
export const AnimatedTouchableOpacity = Animated.createAnimatedComponent(TouchableOpacity) | ||
|
||
export const ReAnimatedExpoImage = Reanimated.createAnimatedComponent(ExpoImage) | ||
export const ReAnimatedPressable = Reanimated.createAnimatedComponent(Pressable) | ||
export const ReAnimatedScrollView = Reanimated.createAnimatedComponent(ScrollView) | ||
export const ReAnimatedTouchableOpacity = Reanimated.createAnimatedComponent(TouchableOpacity) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import { FeedViewType } from "@follow/constants" | ||
import { useTypeScriptHappyCallback } from "@follow/hooks" | ||
import { useBottomTabBarHeight } from "@react-navigation/bottom-tabs" | ||
import { useHeaderHeight } from "@react-navigation/elements" | ||
import type { MasonryFlashListProps } from "@shopify/flash-list" | ||
import { MasonryFlashList } from "@shopify/flash-list" | ||
import { Link } from "expo-router" | ||
import { useContext } from "react" | ||
import { Pressable, View } from "react-native" | ||
import { useSafeAreaInsets } from "react-native-safe-area-context" | ||
|
||
import { ReAnimatedExpoImage } from "@/src/components/common/AnimatedComponents" | ||
import { NavigationContext } from "@/src/components/common/SafeNavigationScrollView" | ||
import { ThemedText } from "@/src/components/common/ThemedText" | ||
import { ItemPressable } from "@/src/components/ui/pressable/item-pressable" | ||
import { useEntry } from "@/src/store/entry/hooks" | ||
|
||
import { useSelectedFeed } from "../feed-drawer/atoms" | ||
|
||
export function EntryListContentGrid({ | ||
entryIds, | ||
...rest | ||
}: { | ||
entryIds: string[] | ||
} & Omit<MasonryFlashListProps<string>, "data" | "renderItem">) { | ||
const insets = useSafeAreaInsets() | ||
const tabBarHeight = useBottomTabBarHeight() | ||
const headerHeight = useHeaderHeight() | ||
const { scrollY } = useContext(NavigationContext)! | ||
return ( | ||
<MasonryFlashList | ||
data={entryIds} | ||
renderItem={useTypeScriptHappyCallback(({ item }) => { | ||
return <RenderEntryItem id={item} /> | ||
}, [])} | ||
numColumns={2} | ||
onScroll={useTypeScriptHappyCallback( | ||
(e) => { | ||
scrollY.setValue(e.nativeEvent.contentOffset.y) | ||
}, | ||
[scrollY], | ||
)} | ||
scrollIndicatorInsets={{ | ||
top: headerHeight - insets.top, | ||
bottom: tabBarHeight - insets.bottom, | ||
}} | ||
estimatedItemSize={100} | ||
contentContainerStyle={{ | ||
paddingTop: headerHeight, | ||
paddingBottom: tabBarHeight, | ||
}} | ||
{...rest} | ||
/> | ||
) | ||
} | ||
|
||
function RenderEntryItem({ id }: { id: string }) { | ||
const selectedFeed = useSelectedFeed() | ||
const view = selectedFeed.type === "view" ? selectedFeed.viewId : null | ||
const item = useEntry(id) | ||
if (!item) { | ||
return null | ||
} | ||
const photo = item.media?.find((media) => media.type === "photo") | ||
const video = item.media?.find((media) => media.type === "video") | ||
const imageUrl = photo?.url || video?.preview_image_url | ||
const aspectRatio = | ||
view === FeedViewType.Pictures && photo?.height && photo.width | ||
? photo.width / photo.height | ||
: 16 / 9 | ||
|
||
return ( | ||
<ItemPressable className="m-1 overflow-hidden rounded-md"> | ||
<Link href={`/entries/${item.id}`} asChild> | ||
<Pressable> | ||
{imageUrl ? ( | ||
<ReAnimatedExpoImage | ||
source={{ uri: imageUrl }} | ||
style={{ | ||
width: "100%", | ||
aspectRatio, | ||
}} | ||
sharedTransitionTag={`entry-image-${imageUrl}`} | ||
allowDownscaling={false} | ||
recyclingKey={imageUrl} | ||
/> | ||
) : ( | ||
<View className="aspect-video w-full items-center justify-center"> | ||
<ThemedText className="text-center">No media available</ThemedText> | ||
</View> | ||
)} | ||
</Pressable> | ||
</Link> | ||
|
||
<ThemedText className="p-2">{item.title}</ThemedText> | ||
</ItemPressable> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.