Skip to content

Commit

Permalink
fix: fixes from review
Browse files Browse the repository at this point in the history
  • Loading branch information
mmeissonnier-pass committed Jan 24, 2025
1 parent e49078e commit e702db2
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 79 deletions.
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import React, { FunctionComponent, useState } from 'react'
import {
LayoutChangeEvent,
LayoutRectangle,
NativeScrollEvent,
NativeSyntheticEvent,
} from 'react-native'
import React, { FunctionComponent, useRef } from 'react'
import { useWindowDimensions } from 'react-native'
import { FlatList } from 'react-native-gesture-handler'
import { useTheme } from 'styled-components'
import styled from 'styled-components/native'

import { CHRONICLE_CARD_WIDTH } from 'features/chronicle/constant'
import { useHorizontalFlatListScroll } from 'ui/hooks/useHorizontalFlatListScroll'
import { PlaylistArrowButton } from 'ui/Playlist/PlaylistArrowButton'

import {
Expand All @@ -25,70 +22,52 @@ export const ChronicleCardList: FunctionComponent<ChronicleCardListProps> = ({
headerComponent,
separatorSize = SEPARATOR_DEFAULT_VALUE,
}) => {
const [userOffset, setUserOffset] = useState(0)
const [scrollOffset, setScrollOffset] = useState(0)
const [layout, setLayout] = useState<LayoutRectangle>()
const [leftArrowVisible, setLeftArrowVisible] = useState(false)
const [rightArrowVisible, setRightArrowVisible] = useState(true)

const { isDesktopViewport } = useTheme()
const { width: windowWidth } = useWindowDimensions()

const pageWidth = isDesktopViewport ? layout?.width ?? 0 : CHRONICLE_CARD_WIDTH
const goToPreviousPage = () => setUserOffset(Math.max(scrollOffset - pageWidth, 0))
const goToNextPage = () => setUserOffset(scrollOffset + pageWidth)

const handleLayout = (event: LayoutChangeEvent) => {
setLayout(event.nativeEvent.layout)
}

const handleScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {
const { contentSize, layoutMeasurement, contentOffset } = event.nativeEvent
const progress = contentOffset.x / (contentSize.width - layoutMeasurement.width)

setScrollOffset(contentOffset.x)
const listRef = useRef<FlatList>(null)

switch (progress) {
case 0:
setLeftArrowVisible(false)
setRightArrowVisible(true)
break
case 1:
setLeftArrowVisible(true)
setRightArrowVisible(false)
break
default:
setLeftArrowVisible(true)
setRightArrowVisible(true)
}
}
const {
onScroll,
handleScrollNext,
handleScrollPrevious,
onContainerLayout,
isEnd,
isStart,
onContentSizeChange,
} = useHorizontalFlatListScroll({
ref: listRef,
scrollRatio: isDesktopViewport ? 1 : (cardWidth ?? CHRONICLE_CARD_WIDTH) / windowWidth,
})

return (
<FlatListContainer onLayout={handleLayout}>
<FlatListContainer onLayout={onContainerLayout}>
{horizontal ? (
<React.Fragment>
{leftArrowVisible ? (
{isStart ? null : (
<PlaylistArrowButton
direction="left"
onPress={goToPreviousPage}
onPress={handleScrollPrevious}
testID="chronicle-list-left-arrow"
/>
) : null}
)}

{rightArrowVisible ? (
{isEnd ? null : (
<PlaylistArrowButton
direction="right"
onPress={goToNextPage}
onPress={handleScrollNext}
testID="chronicle-list-right-arrow"
/>
) : null}
)}
</React.Fragment>
) : null}
<ChronicleCardListBase
data={data}
offset={userOffset}
ref={listRef}
horizontal={horizontal}
cardWidth={cardWidth}
onScroll={handleScroll}
onScroll={onScroll}
onContentSizeChange={onContentSizeChange}
headerComponent={headerComponent}
separatorSize={separatorSize}
contentContainerStyle={contentContainerStyle}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React, { FunctionComponent, ReactElement, useEffect, useMemo, useRef } from 'react'
import {
FlatList,
NativeScrollEvent,
NativeSyntheticEvent,
StyleProp,
ViewStyle,
} from 'react-native'
import React, {
ReactElement,
forwardRef,
useEffect,
useImperativeHandle,
useMemo,
useRef,
} from 'react'
import { FlatList, FlatListProps } from 'react-native'
import styled from 'styled-components/native'

import { ChronicleCardData } from 'features/chronicle/type'
Expand All @@ -17,17 +18,20 @@ export const SEPARATOR_DEFAULT_VALUE = 2

const keyExtractor = (item: ChronicleCardData) => item.id.toString()

export type ChronicleCardListProps = {
data: ChronicleCardData[]
export type ChronicleCardListProps = Pick<
FlatListProps<ChronicleCardData>,
| 'data'
| 'contentContainerStyle'
| 'horizontal'
| 'snapToInterval'
| 'onScroll'
| 'onContentSizeChange'
> & {
offset?: number
horizontal?: boolean
cardWidth?: number
contentContainerStyle?: StyleProp<ViewStyle>
snapToInterval?: number
scrollEnabled?: boolean
separatorSize?: number
headerComponent?: ReactElement
onScroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void
}

const renderItem = ({ item, cardWidth }: { item: ChronicleCardData; cardWidth?: number }) => {
Expand All @@ -43,20 +47,30 @@ const renderItem = ({ item, cardWidth }: { item: ChronicleCardData; cardWidth?:
)
}

export const ChronicleCardListBase: FunctionComponent<ChronicleCardListProps> = ({
data,
offset,
horizontal = true,
cardWidth,
contentContainerStyle,
onScroll,
snapToInterval,
scrollEnabled,
headerComponent,
separatorSize = SEPARATOR_DEFAULT_VALUE,
}) => {
export const ChronicleCardListBase = forwardRef<
Partial<FlatList<ChronicleCardData>>,
ChronicleCardListProps
>(function ChronicleCardListBase(
{
data,
offset,
horizontal = true,
cardWidth,
contentContainerStyle,
onScroll,
snapToInterval,
headerComponent,
onContentSizeChange,
separatorSize = SEPARATOR_DEFAULT_VALUE,
},
ref
) {
const listRef = useRef<FlatList>(null)

useImperativeHandle(ref, () => ({
scrollToOffset: (params) => listRef.current?.scrollToOffset(params),
}))

useEffect(() => {
if (listRef.current && offset !== undefined) {
listRef.current.scrollToOffset({ offset, animated: true })
Expand All @@ -81,14 +95,14 @@ export const ChronicleCardListBase: FunctionComponent<ChronicleCardListProps> =
keyExtractor={keyExtractor}
ItemSeparatorComponent={Separator}
contentContainerStyle={contentContainerStyle}
onContentSizeChange={onContentSizeChange}
showsHorizontalScrollIndicator={false}
onScroll={onScroll}
scrollEventThrottle={100}
scrollEnabled={scrollEnabled}
horizontal={horizontal}
decelerationRate="fast"
snapToInterval={snapToInterval}
testID="chronicle-list"
/>
)
}
})
4 changes: 2 additions & 2 deletions src/ui/components/SectionWithDivider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const SectionWithDivider = ({
return (
<ViewGap onLayout={onLayout} testID={testID} gap={gap} style={style}>
<Divider />
{margin ? <MarginContainer>{children}</MarginContainer> : children}
{margin ? <Wrapper>{children}</Wrapper> : children}
</ViewGap>
)
}
Expand All @@ -38,6 +38,6 @@ const Divider = styled.View(({ theme }) => ({
backgroundColor: theme.colors.greyLight,
}))

const MarginContainer = styled.View({
const Wrapper = styled.View({
paddingHorizontal: getSpacing(6),
})

0 comments on commit e702db2

Please sign in to comment.