Skip to content

Commit

Permalink
feat: collection panel active indicator
Browse files Browse the repository at this point in the history
  • Loading branch information
DIYgod committed Jan 22, 2025
1 parent e0d6746 commit c38677b
Showing 1 changed file with 40 additions and 15 deletions.
55 changes: 40 additions & 15 deletions apps/mobile/src/modules/feed-drawer/collection-panel.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { cn } from "@follow/utils"
import { useEffect } from "react"
import { Image, ScrollView, StyleSheet, TouchableOpacity, View } from "react-native"
import Animated, { useAnimatedStyle, useSharedValue, withTiming } from "react-native-reanimated"
import { useSafeAreaInsets } from "react-native-safe-area-context"

import { FallbackIcon } from "@/src/components/ui/icon/fallback-icon"
Expand All @@ -17,12 +19,12 @@ export const CollectionPanel = () => {
const insets = useSafeAreaInsets()
return (
<View
className="bg-quaternary-system-fill dark:bg-tertiary-system-background"
className="bg-secondary-system-fill dark:bg-tertiary-system-background"
style={{ width: 65 }}
>
<ScrollView
contentContainerClassName="flex gap-4 px-3.5"
contentContainerStyle={{ paddingTop: insets.top + 10, paddingBottom: insets.bottom }}
contentContainerStyle={{ marginTop: insets.top + 10, paddingBottom: insets.bottom }}
>
<View className="flex-1 items-center">
<Logo width={37} height={37} color="#222" />
Expand All @@ -46,16 +48,38 @@ const styles = StyleSheet.create({
},
})

const ActiveIndicator = ({ isActive }: { isActive: boolean }) => {
const scaleY = useSharedValue(1)

useEffect(() => {
if (isActive) {
scaleY.value = withTiming(1, { duration: 200 })
} else {
scaleY.value = withTiming(0, { duration: 200 })
}
}, [isActive, scaleY])

const animatedStyle = useAnimatedStyle(() => {
return {
transform: [{ scaleY: scaleY.value }],
}
})

return (
<Animated.View
className="absolute -left-3.5 h-9 w-1 rounded-r-xl bg-black"
style={animatedStyle}
/>
)
}

const ViewButton = ({ viewDef }: { viewDef: ViewDefinition }) => {
const selectedCollection = useSelectedCollection()
const isActive = selectedCollection.type === "view" && selectedCollection.viewId === viewDef.view

return (
<TouchableOpacity
className={cn(
"flex aspect-square items-center justify-center rounded-full p-3",
isActive ? "bg-secondary-system-fill" : "bg-system-background",
)}
className="relative flex aspect-square items-center justify-center rounded-full p-3"
onPress={() =>
selectCollection({
type: "view",
Expand All @@ -64,6 +88,7 @@ const ViewButton = ({ viewDef }: { viewDef: ViewDefinition }) => {
}
style={{ backgroundColor: viewDef.activeColor }}
>
<ActiveIndicator isActive={isActive} />
<viewDef.icon key={viewDef.name} color={"#fff"} />
</TouchableOpacity>
)
Expand All @@ -77,22 +102,22 @@ const ListButton = ({ listId }: { listId: string }) => {

return (
<TouchableOpacity
className={cn(
"flex aspect-square items-center justify-center overflow-hidden rounded-full p-3",
isActive ? "bg-system-fill" : "bg-system-background",
)}
className={cn("relative flex aspect-square items-center justify-center rounded-full p-3")}
onPress={() =>
selectCollection({
type: "list",
listId,
})
}
>
{list.image ? (
<Image source={{ uri: list.image, width: 41, height: 41 }} resizeMode="cover" />
) : (
<FallbackIcon title={list.title} size={41} />
)}
<ActiveIndicator isActive={isActive} />
<View className="overflow-hidden rounded-full">
{list.image ? (
<Image source={{ uri: list.image, width: 41, height: 41 }} resizeMode="cover" />
) : (
<FallbackIcon title={list.title} size={41} />
)}
</View>
</TouchableOpacity>
)
}

0 comments on commit c38677b

Please sign in to comment.