@fountain-ui/lab 2.0.0-beta.53 → 2.0.0-beta.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -233,14 +233,33 @@ function ComicViewer(props) {
233
233
  });
234
234
  }, [onItemPress, renderedDimensions]);
235
235
  (0, _react.useEffect)(() => {
236
- const offset = Math.floor(initialScrollPercentage / 100 * totalHeight);
236
+ const scroll = () => {
237
+ const offset = Math.floor(initialScrollPercentage / 100 * totalHeight);
238
+
239
+ if (flatListRef.current) {
240
+ flatListRef.current.scrollToOffset({
241
+ offset,
242
+ animated: false
243
+ });
244
+ }
245
+ };
237
246
 
238
- if (flatListRef.current) {
239
- flatListRef.current.scrollToOffset({
240
- offset,
241
- animated: false
242
- });
247
+ let timeoutId = undefined;
248
+ /**
249
+ * @FIXME
250
+ * scrollToOffset has issue(no effect) in useEffect hook on iOS.
251
+ * ref: https://github.com/facebook/react-native/issues/35575
252
+ */
253
+
254
+ if (_reactNative.Platform.OS === 'ios') {
255
+ timeoutId = setTimeout(scroll, 0);
256
+ } else {
257
+ scroll();
243
258
  }
259
+
260
+ return () => {
261
+ timeoutId && clearTimeout(timeoutId);
262
+ };
244
263
  }, []);
245
264
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_reactNative.FlatList, _extends({
246
265
  data: itemStates,
@@ -1 +1 @@
1
- {"version":3,"names":["appender","left","right","getHeightAccum","heights","R","mapAccum","keyExtractor","item","String","index","createInitialImageState","image","totalErrorCount","dimension","tryRenderingMillis","urlState","url","validity","mapImageStateToItemState","imageState","autoHandleErrorCount","imageKey","reloadButtonVisible","mapIndexed","addIndex","map","MAXIMUM_WIDTH","ComicViewer","props","debounceMillis","fastScrollOptions","initialNumToRender","initialScrollPercentage","itemVisiblePercentThreshold","intrinsicImages","maxContentWidth","onItemPress","onScroll","onError","onReloadPress","viewportWidth","invisiblePaddingTop","windowSize","otherProps","fastScrollRef","ref","flatListRef","useRef","actualImageWidth","Math","min","initialImageStates","useMemo","imageStatesRef","mapImageStatesToItemStates","imageStates","itemStates","setItemStates","useState","current","renderedDimensions","intrinsicImage","height","width","isNaN","layoutFromDimensions","useCallback","itemHeights","totalHeight","heightAccum","itemOffsets","prepend","getItemLayout","data","length","offset","viewabilityConfig","updateImageState","updateFunction","prevImageStates","newImageStates","prevItemStates","newItemStates","equals","updateTryRenderingMillis","Date","getTime","i","onViewableItemsChanged","viewableItems","handleScroll","event","onContentScroll","scrollContentToOffset","scrollToOffset","animated","renderItem","handleError","handleReloadPress","onLoad","undefined","useEffect","floor"],"sources":["ComicViewer.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { FlatList, ListRenderItem, NativeScrollEvent, NativeSyntheticEvent, ViewToken } from 'react-native';\nimport * as R from 'ramda';\nimport { default as ComicViewerProps, Dimension, IntrinsicImage } from './ComicViewerProps';\nimport ViewerItem from './ViewerItem';\nimport FastScroll from './FastScroll';\n\nconst appender = (left: number, right: number): [number, number] => [left + right, left + right];\nconst getHeightAccum = (heights: number[]): [number, number[]] => R.mapAccum(appender, 0, heights);\n\nconst keyExtractor = <T, >(item: ItemState) => String(item.index);\n\ninterface UrlState {\n url: string;\n validity: 'valid' | 'invalid' | 'unknown';\n}\n\ninterface ImageState {\n urlState: UrlState;\n totalErrorCount: number;\n dimension: Dimension;\n tryRenderingMillis: number;\n}\n\ninterface ItemState {\n index: number;\n url?: string;\n imageKey: string;\n reloadButtonVisible: boolean;\n dimension: Dimension;\n}\n\nconst createInitialImageState = (image: IntrinsicImage): ImageState => ({\n totalErrorCount: 0,\n dimension: image.dimension,\n tryRenderingMillis: 0,\n urlState: {\n url: image.url,\n validity: 'unknown',\n },\n});\n\nconst mapImageStateToItemState = (\n index: number,\n imageState: ImageState,\n autoHandleErrorCount: number,\n): ItemState => ({\n index,\n url: imageState.urlState?.url,\n imageKey: `${imageState.tryRenderingMillis}-${index}`,\n reloadButtonVisible: (imageState.urlState?.validity !== 'valid') && imageState.totalErrorCount >= autoHandleErrorCount,\n dimension: imageState.dimension,\n});\n\nconst mapIndexed = R.addIndex<IntrinsicImage>(R.map);\n\nconst MAXIMUM_WIDTH = 720;\n\nexport default function ComicViewer(props: ComicViewerProps) {\n const {\n debounceMillis = 100,\n autoHandleErrorCount = 3,\n fastScrollOptions,\n initialNumToRender = 1,\n initialScrollPercentage = 0,\n itemVisiblePercentThreshold = 0,\n intrinsicImages,\n maxContentWidth = MAXIMUM_WIDTH,\n onItemPress,\n onScroll,\n onError,\n onReloadPress,\n viewportWidth,\n invisiblePaddingTop = 0,\n windowSize = 3,\n ...otherProps\n } = props;\n\n const fastScrollRef = fastScrollOptions?.ref;\n\n const flatListRef = useRef<FlatList>(null);\n\n const actualImageWidth = Math.min(viewportWidth, maxContentWidth);\n\n const initialImageStates = useMemo<Array<ImageState>>(() => R.map(createInitialImageState, intrinsicImages), []);\n\n const imageStatesRef = useRef<Array<ImageState>>(initialImageStates);\n\n const mapImageStatesToItemStates = (imageStates: Array<ImageState>): Array<ItemState> => {\n return imageStates.map((image, index) => mapImageStateToItemState(\n index, image, autoHandleErrorCount,\n ));\n };\n\n const [itemStates, setItemStates] = useState<Array<ItemState>>(() => {\n return mapImageStatesToItemStates(imageStatesRef.current);\n });\n\n const renderedDimensions = useMemo<Array<Dimension>>(() => {\n return mapIndexed((intrinsicImage, index) => {\n const height = (intrinsicImage.dimension.height * actualImageWidth) / intrinsicImage.dimension.width + (index === 0 ? invisiblePaddingTop : 0);\n\n return {\n width: actualImageWidth,\n height: isNaN(height) ? 0 : height,\n };\n }, intrinsicImages);\n }, [actualImageWidth]);\n\n const layoutFromDimensions = useCallback(() => {\n const itemHeights = R.map(dimension => dimension.height, renderedDimensions);\n const [totalHeight, heightAccum] = getHeightAccum(itemHeights);\n const itemOffsets = R.prepend(0, heightAccum);\n\n const getItemLayout = (data: any, index: number) => ({\n index,\n length: itemHeights[index],\n offset: itemOffsets[index],\n });\n\n return {\n totalHeight,\n getItemLayout,\n };\n }, [renderedDimensions]);\n\n const { totalHeight, getItemLayout } = layoutFromDimensions();\n\n const viewabilityConfig = useMemo(() => ({\n itemVisiblePercentThreshold,\n }), [itemVisiblePercentThreshold]);\n\n const updateImageState = (updateFunction: (prev: ImageState, index: number) => ImageState) => {\n const prevImageStates = imageStatesRef.current;\n const newImageStates = prevImageStates.map(updateFunction);\n\n imageStatesRef.current = newImageStates;\n\n setItemStates(prevItemStates => {\n const newItemStates = mapImageStatesToItemStates(newImageStates);\n\n return R.equals(prevItemStates, newItemStates) ? prevItemStates : newItemStates;\n });\n };\n\n const updateTryRenderingMillis = () => {\n const tryRenderingMillis = new Date().getTime();\n\n updateImageState((imageState, i) => {\n const urlState = imageState.urlState;\n\n if (urlState?.validity === 'invalid') {\n return {\n ...imageState,\n tryRenderingMillis,\n };\n }\n\n return imageState;\n });\n };\n const onViewableItemsChanged = useRef(({ viewableItems }: { viewableItems: Array<ViewToken> }) => {\n updateTryRenderingMillis();\n });\n\n const handleScroll = useCallback((event: NativeSyntheticEvent<NativeScrollEvent>) => {\n fastScrollRef?.current?.onContentScroll(event);\n\n onScroll?.(event);\n }, [onScroll]);\n\n const scrollContentToOffset = (offset: number) => {\n flatListRef.current?.scrollToOffset({\n offset,\n animated: false,\n });\n };\n\n const renderItem: ListRenderItem<ItemState> = useCallback(({ item, index }) => {\n const handleError = () => {\n onError && onError();\n\n updateImageState((imageState, i) => {\n const urlState = imageState.urlState;\n\n if (i === index) {\n return {\n ...imageState,\n totalErrorCount: imageState.totalErrorCount + 1,\n urlState: {\n ...urlState,\n validity: 'invalid',\n },\n };\n }\n\n return imageState;\n });\n\n if (item.reloadButtonVisible) {\n return;\n }\n\n updateTryRenderingMillis();\n };\n\n const handleReloadPress = () => {\n onReloadPress && onReloadPress();\n\n updateTryRenderingMillis();\n };\n\n const onLoad = () => {\n updateImageState((imageState, i) => {\n const urlState = imageState.urlState;\n\n if (i === index && urlState !== undefined) {\n return {\n ...imageState,\n urlState: {\n ...urlState,\n validity: 'valid',\n },\n };\n }\n\n return imageState;\n });\n };\n\n return (\n <ViewerItem\n onError={handleError}\n onLoad={onLoad}\n onPress={onItemPress}\n onReloadPress={handleReloadPress}\n url={item.url}\n imageKey={item.imageKey}\n invisiblePaddingTop={index === 0 ? invisiblePaddingTop : 0}\n width={renderedDimensions[index]?.width ?? 0}\n height={renderedDimensions[index]?.height ?? 0}\n reloadButtonVisible={item.reloadButtonVisible}\n />\n );\n }, [onItemPress, renderedDimensions]);\n\n useEffect(() => {\n const offset = Math.floor((initialScrollPercentage / 100) * totalHeight);\n\n if (flatListRef.current) {\n flatListRef.current.scrollToOffset({ offset, animated: false });\n }\n }, []);\n\n return (\n <React.Fragment>\n <FlatList\n data={itemStates}\n getItemLayout={getItemLayout}\n initialNumToRender={initialNumToRender}\n keyExtractor={keyExtractor}\n onViewableItemsChanged={onViewableItemsChanged.current}\n ref={flatListRef}\n renderItem={renderItem}\n viewabilityConfig={viewabilityConfig}\n windowSize={windowSize}\n onScroll={handleScroll}\n {...otherProps}\n />\n\n <FastScroll\n {...fastScrollOptions}\n contentLength={totalHeight}\n scrollContentToOffset={scrollContentToOffset}\n />\n </React.Fragment>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"names":["appender","left","right","getHeightAccum","heights","R","mapAccum","keyExtractor","item","String","index","createInitialImageState","image","totalErrorCount","dimension","tryRenderingMillis","urlState","url","validity","mapImageStateToItemState","imageState","autoHandleErrorCount","imageKey","reloadButtonVisible","mapIndexed","addIndex","map","MAXIMUM_WIDTH","ComicViewer","props","debounceMillis","fastScrollOptions","initialNumToRender","initialScrollPercentage","itemVisiblePercentThreshold","intrinsicImages","maxContentWidth","onItemPress","onScroll","onError","onReloadPress","viewportWidth","invisiblePaddingTop","windowSize","otherProps","fastScrollRef","ref","flatListRef","useRef","actualImageWidth","Math","min","initialImageStates","useMemo","imageStatesRef","mapImageStatesToItemStates","imageStates","itemStates","setItemStates","useState","current","renderedDimensions","intrinsicImage","height","width","isNaN","layoutFromDimensions","useCallback","itemHeights","totalHeight","heightAccum","itemOffsets","prepend","getItemLayout","data","length","offset","viewabilityConfig","updateImageState","updateFunction","prevImageStates","newImageStates","prevItemStates","newItemStates","equals","updateTryRenderingMillis","Date","getTime","i","onViewableItemsChanged","viewableItems","handleScroll","event","onContentScroll","scrollContentToOffset","scrollToOffset","animated","renderItem","handleError","handleReloadPress","onLoad","undefined","useEffect","scroll","floor","timeoutId","Platform","OS","setTimeout","clearTimeout"],"sources":["ComicViewer.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { FlatList, ListRenderItem, NativeScrollEvent, NativeSyntheticEvent, Platform, ViewToken } from 'react-native';\nimport * as R from 'ramda';\nimport { default as ComicViewerProps, Dimension, IntrinsicImage } from './ComicViewerProps';\nimport ViewerItem from './ViewerItem';\nimport FastScroll from './FastScroll';\n\nconst appender = (left: number, right: number): [number, number] => [left + right, left + right];\nconst getHeightAccum = (heights: number[]): [number, number[]] => R.mapAccum(appender, 0, heights);\n\nconst keyExtractor = <T, >(item: ItemState) => String(item.index);\n\ninterface UrlState {\n url: string;\n validity: 'valid' | 'invalid' | 'unknown';\n}\n\ninterface ImageState {\n urlState: UrlState;\n totalErrorCount: number;\n dimension: Dimension;\n tryRenderingMillis: number;\n}\n\ninterface ItemState {\n index: number;\n url?: string;\n imageKey: string;\n reloadButtonVisible: boolean;\n dimension: Dimension;\n}\n\nconst createInitialImageState = (image: IntrinsicImage): ImageState => ({\n totalErrorCount: 0,\n dimension: image.dimension,\n tryRenderingMillis: 0,\n urlState: {\n url: image.url,\n validity: 'unknown',\n },\n});\n\nconst mapImageStateToItemState = (\n index: number,\n imageState: ImageState,\n autoHandleErrorCount: number,\n): ItemState => ({\n index,\n url: imageState.urlState?.url,\n imageKey: `${imageState.tryRenderingMillis}-${index}`,\n reloadButtonVisible: (imageState.urlState?.validity !== 'valid') && imageState.totalErrorCount >= autoHandleErrorCount,\n dimension: imageState.dimension,\n});\n\nconst mapIndexed = R.addIndex<IntrinsicImage>(R.map);\n\nconst MAXIMUM_WIDTH = 720;\n\nexport default function ComicViewer(props: ComicViewerProps) {\n const {\n debounceMillis = 100,\n autoHandleErrorCount = 3,\n fastScrollOptions,\n initialNumToRender = 1,\n initialScrollPercentage = 0,\n itemVisiblePercentThreshold = 0,\n intrinsicImages,\n maxContentWidth = MAXIMUM_WIDTH,\n onItemPress,\n onScroll,\n onError,\n onReloadPress,\n viewportWidth,\n invisiblePaddingTop = 0,\n windowSize = 3,\n ...otherProps\n } = props;\n\n const fastScrollRef = fastScrollOptions?.ref;\n\n const flatListRef = useRef<FlatList>(null);\n\n const actualImageWidth = Math.min(viewportWidth, maxContentWidth);\n\n const initialImageStates = useMemo<Array<ImageState>>(() => R.map(createInitialImageState, intrinsicImages), []);\n\n const imageStatesRef = useRef<Array<ImageState>>(initialImageStates);\n\n const mapImageStatesToItemStates = (imageStates: Array<ImageState>): Array<ItemState> => {\n return imageStates.map((image, index) => mapImageStateToItemState(\n index, image, autoHandleErrorCount,\n ));\n };\n\n const [itemStates, setItemStates] = useState<Array<ItemState>>(() => {\n return mapImageStatesToItemStates(imageStatesRef.current);\n });\n\n const renderedDimensions = useMemo<Array<Dimension>>(() => {\n return mapIndexed((intrinsicImage, index) => {\n const height = (intrinsicImage.dimension.height * actualImageWidth) / intrinsicImage.dimension.width + (index === 0 ? invisiblePaddingTop : 0);\n\n return {\n width: actualImageWidth,\n height: isNaN(height) ? 0 : height,\n };\n }, intrinsicImages);\n }, [actualImageWidth]);\n\n const layoutFromDimensions = useCallback(() => {\n const itemHeights = R.map(dimension => dimension.height, renderedDimensions);\n const [totalHeight, heightAccum] = getHeightAccum(itemHeights);\n const itemOffsets = R.prepend(0, heightAccum);\n\n const getItemLayout = (data: any, index: number) => ({\n index,\n length: itemHeights[index],\n offset: itemOffsets[index],\n });\n\n return {\n totalHeight,\n getItemLayout,\n };\n }, [renderedDimensions]);\n\n const { totalHeight, getItemLayout } = layoutFromDimensions();\n\n const viewabilityConfig = useMemo(() => ({\n itemVisiblePercentThreshold,\n }), [itemVisiblePercentThreshold]);\n\n const updateImageState = (updateFunction: (prev: ImageState, index: number) => ImageState) => {\n const prevImageStates = imageStatesRef.current;\n const newImageStates = prevImageStates.map(updateFunction);\n\n imageStatesRef.current = newImageStates;\n\n setItemStates(prevItemStates => {\n const newItemStates = mapImageStatesToItemStates(newImageStates);\n\n return R.equals(prevItemStates, newItemStates) ? prevItemStates : newItemStates;\n });\n };\n\n const updateTryRenderingMillis = () => {\n const tryRenderingMillis = new Date().getTime();\n\n updateImageState((imageState, i) => {\n const urlState = imageState.urlState;\n\n if (urlState?.validity === 'invalid') {\n return {\n ...imageState,\n tryRenderingMillis,\n };\n }\n\n return imageState;\n });\n };\n const onViewableItemsChanged = useRef(({ viewableItems }: { viewableItems: Array<ViewToken> }) => {\n updateTryRenderingMillis();\n });\n\n const handleScroll = useCallback((event: NativeSyntheticEvent<NativeScrollEvent>) => {\n fastScrollRef?.current?.onContentScroll(event);\n\n onScroll?.(event);\n }, [onScroll]);\n\n const scrollContentToOffset = (offset: number) => {\n flatListRef.current?.scrollToOffset({\n offset,\n animated: false,\n });\n };\n\n const renderItem: ListRenderItem<ItemState> = useCallback(({ item, index }) => {\n const handleError = () => {\n onError && onError();\n\n updateImageState((imageState, i) => {\n const urlState = imageState.urlState;\n\n if (i === index) {\n return {\n ...imageState,\n totalErrorCount: imageState.totalErrorCount + 1,\n urlState: {\n ...urlState,\n validity: 'invalid',\n },\n };\n }\n\n return imageState;\n });\n\n if (item.reloadButtonVisible) {\n return;\n }\n\n updateTryRenderingMillis();\n };\n\n const handleReloadPress = () => {\n onReloadPress && onReloadPress();\n\n updateTryRenderingMillis();\n };\n\n const onLoad = () => {\n updateImageState((imageState, i) => {\n const urlState = imageState.urlState;\n\n if (i === index && urlState !== undefined) {\n return {\n ...imageState,\n urlState: {\n ...urlState,\n validity: 'valid',\n },\n };\n }\n\n return imageState;\n });\n };\n\n return (\n <ViewerItem\n onError={handleError}\n onLoad={onLoad}\n onPress={onItemPress}\n onReloadPress={handleReloadPress}\n url={item.url}\n imageKey={item.imageKey}\n invisiblePaddingTop={index === 0 ? invisiblePaddingTop : 0}\n width={renderedDimensions[index]?.width ?? 0}\n height={renderedDimensions[index]?.height ?? 0}\n reloadButtonVisible={item.reloadButtonVisible}\n />\n );\n }, [onItemPress, renderedDimensions]);\n\n useEffect(() => {\n const scroll = () => {\n const offset = Math.floor((initialScrollPercentage / 100) * totalHeight);\n\n if (flatListRef.current) {\n flatListRef.current.scrollToOffset({ offset, animated: false });\n }\n };\n\n let timeoutId: NodeJS.Timeout | undefined = undefined;\n\n /**\n * @FIXME\n * scrollToOffset has issue(no effect) in useEffect hook on iOS.\n * ref: https://github.com/facebook/react-native/issues/35575\n */\n if (Platform.OS === 'ios') {\n timeoutId = setTimeout(scroll, 0);\n } else {\n scroll();\n }\n\n return () => {\n timeoutId && clearTimeout(timeoutId);\n }\n }, []);\n\n return (\n <React.Fragment>\n <FlatList\n data={itemStates}\n getItemLayout={getItemLayout}\n initialNumToRender={initialNumToRender}\n keyExtractor={keyExtractor}\n onViewableItemsChanged={onViewableItemsChanged.current}\n ref={flatListRef}\n renderItem={renderItem}\n viewabilityConfig={viewabilityConfig}\n windowSize={windowSize}\n onScroll={handleScroll}\n {...otherProps}\n />\n\n <FastScroll\n {...fastScrollOptions}\n contentLength={totalHeight}\n scrollContentToOffset={scrollContentToOffset}\n />\n </React.Fragment>\n );\n};\n"],"mappings":"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"}
@@ -25,14 +25,16 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
25
25
 
26
26
  const styles = _core.StyleSheet.create({
27
27
  indicator: {
28
- width: 24,
29
- height: 40,
28
+ width: 28,
29
+ height: 48,
30
30
  backgroundColor: '#767676',
31
31
  flexDirection: 'column',
32
32
  alignItems: 'center',
33
- borderRadius: 4
33
+ justifyContent: 'center',
34
+ borderRadius: 16
34
35
  },
35
36
  view: {
37
+ padding: 4,
36
38
  position: 'absolute'
37
39
  }
38
40
  });
@@ -63,7 +65,7 @@ const FastScroll = /*#__PURE__*/_react.default.forwardRef((props, ref) => {
63
65
  const totalContentLength = contentLength + additionalLength;
64
66
 
65
67
  const onContentScroll = event => {
66
- if (isIndicatorDragging.current === false) {
68
+ if (!isIndicatorDragging.current) {
67
69
  const contentPercentage = (0, _util.offsetToPercentage)(event.nativeEvent.contentOffset.y, totalContentLength);
68
70
  const offset = (0, _util.percentageToOffset)(contentPercentage, movementRange);
69
71
 
@@ -1 +1 @@
1
- {"version":3,"names":["styles","StyleSheet","create","indicator","width","height","backgroundColor","flexDirection","alignItems","borderRadius","view","position","FastScroll","React","forwardRef","props","ref","absolutePosition","additionalLength","contentLength","movementRange","scrollContentToOffset","visibleDurations","hideMillis","showMillis","lastIndicatorOffset","useSharedValue","indicatorOffset","value","isIndicatorDragging","useRef","indicatorOpacity","visible","setVisible","useState","animatedStyle","useAnimatedStyle","transform","translateY","opacity","totalContentLength","onContentScroll","event","current","contentPercentage","offsetToPercentage","nativeEvent","contentOffset","y","offset","percentageToOffset","getIsIndicatorDragging","useImperativeHandle","handleUpdate","setIsIndicatorDragging","pan","Gesture","Pan","onBegin","e","runOnJS","onUpdate","translationY","onFinalize","hide","withDelay","withTiming","duration","show","useEffect"],"sources":["FastScroll.tsx"],"sourcesContent":["import React, { useEffect, useImperativeHandle, useRef, useState } from 'react';\nimport { NativeScrollEvent, NativeSyntheticEvent, View } from 'react-native';\nimport { Gesture, GestureDetector } from 'react-native-gesture-handler';\nimport Animated, { runOnJS, useAnimatedStyle, useSharedValue, withDelay, withTiming } from 'react-native-reanimated';\nimport { ChevronDown, ChevronUp } from '@fountain-ui/icons';\nimport { StyleSheet } from '@fountain-ui/core';\nimport FastScrollProps from './FastScrollProps';\nimport { offsetToPercentage, percentageToOffset } from './util';\n\nconst styles = StyleSheet.create({\n indicator: {\n width: 24,\n height: 40,\n backgroundColor: '#767676',\n flexDirection: 'column',\n alignItems: 'center',\n borderRadius: 4,\n },\n view: { position: 'absolute' },\n});\n\nconst FastScroll = React.forwardRef((props: FastScrollProps, ref) => {\n const {\n absolutePosition,\n additionalLength = 0,\n contentLength,\n movementRange,\n scrollContentToOffset,\n visibleDurations = { hideMillis: 200, showMillis: 350 },\n } = props;\n\n const lastIndicatorOffset = useSharedValue(0);\n const indicatorOffset = useSharedValue(lastIndicatorOffset.value);\n\n const isIndicatorDragging = useRef(false);\n\n const indicatorOpacity = useSharedValue(1);\n const [visible, setVisible] = useState(true);\n\n const animatedStyle = useAnimatedStyle(() => ({\n transform: [{ translateY: indicatorOffset.value }],\n opacity: indicatorOpacity.value,\n }));\n\n const totalContentLength = contentLength + additionalLength;\n\n const onContentScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {\n if (isIndicatorDragging.current === false) {\n const contentPercentage = offsetToPercentage(event.nativeEvent.contentOffset.y, totalContentLength);\n const offset = percentageToOffset(contentPercentage, movementRange);\n\n if (offset < 0 || indicatorOffset.value < 0) {\n lastIndicatorOffset.value = 0;\n indicatorOffset.value = 0;\n return;\n }\n\n if (offset > movementRange || indicatorOffset.value > movementRange) {\n lastIndicatorOffset.value = movementRange;\n indicatorOffset.value = movementRange;\n return;\n }\n\n lastIndicatorOffset.value = offset;\n } else {\n setVisible(true);\n }\n };\n\n const getIsIndicatorDragging = () => isIndicatorDragging.current;\n\n useImperativeHandle(\n ref,\n () => ({\n getIsIndicatorDragging,\n onContentScroll,\n setVisible,\n }),\n [],\n );\n\n const handleUpdate = () => {\n const contentPercentage = offsetToPercentage(indicatorOffset.value, movementRange);\n const offset = percentageToOffset(contentPercentage, totalContentLength);\n\n scrollContentToOffset(offset);\n };\n\n const setIsIndicatorDragging = (value: boolean) => isIndicatorDragging.current = value;\n\n const pan = Gesture.Pan()\n .onBegin((e) => {\n indicatorOffset.value = lastIndicatorOffset.value;\n runOnJS(setIsIndicatorDragging)(true);\n })\n .onUpdate((e) => {\n if (indicatorOffset.value <= 0 && e.translationY < 0) {\n indicatorOffset.value = 0;\n return;\n }\n\n if (indicatorOffset.value >= movementRange && e.translationY > 0) {\n indicatorOffset.value = movementRange;\n return;\n }\n\n indicatorOffset.value = lastIndicatorOffset.value + e.translationY;\n\n runOnJS(handleUpdate)();\n })\n .onFinalize((e) => {\n lastIndicatorOffset.value = indicatorOffset.value;\n runOnJS(setIsIndicatorDragging)(false);\n });\n\n const hide = () => indicatorOpacity.value = withDelay(0, withTiming(0, { duration: visibleDurations.hideMillis }));\n\n const show = () => indicatorOpacity.value = withDelay(0, withTiming(1, { duration: visibleDurations.showMillis }));\n\n useEffect(() => {\n if (visible) {\n indicatorOffset.value = lastIndicatorOffset.value;\n show();\n } else {\n hide();\n }\n }, [visible]);\n\n return (\n <View\n style={[\n { height: movementRange },\n styles.view,\n absolutePosition,\n ]}\n >\n <GestureDetector gesture={pan}>\n <Animated.View style={[\n animatedStyle,\n styles.indicator,\n ]}>\n <ChevronUp\n fill={'#ededed'}\n height={20}\n width={20}\n />\n <ChevronDown\n fill={'#ededed'}\n height={20}\n width={20}\n />\n </Animated.View>\n </GestureDetector>\n </View>\n );\n});\n\nexport default FastScroll;"],"mappings":"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"}
1
+ {"version":3,"names":["styles","StyleSheet","create","indicator","width","height","backgroundColor","flexDirection","alignItems","justifyContent","borderRadius","view","padding","position","FastScroll","React","forwardRef","props","ref","absolutePosition","additionalLength","contentLength","movementRange","scrollContentToOffset","visibleDurations","hideMillis","showMillis","lastIndicatorOffset","useSharedValue","indicatorOffset","value","isIndicatorDragging","useRef","indicatorOpacity","visible","setVisible","useState","animatedStyle","useAnimatedStyle","transform","translateY","opacity","totalContentLength","onContentScroll","event","current","contentPercentage","offsetToPercentage","nativeEvent","contentOffset","y","offset","percentageToOffset","getIsIndicatorDragging","useImperativeHandle","handleUpdate","setIsIndicatorDragging","pan","Gesture","Pan","onBegin","e","runOnJS","onUpdate","translationY","onFinalize","hide","withDelay","withTiming","duration","show","useEffect"],"sources":["FastScroll.tsx"],"sourcesContent":["import React, { useEffect, useImperativeHandle, useRef, useState } from 'react';\nimport { NativeScrollEvent, NativeSyntheticEvent, View } from 'react-native';\nimport { Gesture, GestureDetector } from 'react-native-gesture-handler';\nimport Animated, { runOnJS, useAnimatedStyle, useSharedValue, withDelay, withTiming } from 'react-native-reanimated';\nimport { ChevronDown, ChevronUp } from '@fountain-ui/icons';\nimport { StyleSheet } from '@fountain-ui/core';\nimport FastScrollProps from './FastScrollProps';\nimport { offsetToPercentage, percentageToOffset } from './util';\n\nconst styles = StyleSheet.create({\n indicator: {\n width: 28,\n height: 48,\n backgroundColor: '#767676',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: 16,\n },\n view: { padding: 4, position: 'absolute' },\n});\n\nconst FastScroll = React.forwardRef((props: FastScrollProps, ref) => {\n const {\n absolutePosition,\n additionalLength = 0,\n contentLength,\n movementRange,\n scrollContentToOffset,\n visibleDurations = { hideMillis: 200, showMillis: 350 },\n } = props;\n\n const lastIndicatorOffset = useSharedValue(0);\n const indicatorOffset = useSharedValue(lastIndicatorOffset.value);\n\n const isIndicatorDragging = useRef(false);\n\n const indicatorOpacity = useSharedValue(1);\n const [visible, setVisible] = useState(true);\n\n const animatedStyle = useAnimatedStyle(() => ({\n transform: [{ translateY: indicatorOffset.value }],\n opacity: indicatorOpacity.value,\n }));\n\n const totalContentLength = contentLength + additionalLength;\n\n const onContentScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {\n if (!isIndicatorDragging.current) {\n const contentPercentage = offsetToPercentage(event.nativeEvent.contentOffset.y, totalContentLength);\n const offset = percentageToOffset(contentPercentage, movementRange);\n\n if (offset < 0 || indicatorOffset.value < 0) {\n lastIndicatorOffset.value = 0;\n indicatorOffset.value = 0;\n return;\n }\n\n if (offset > movementRange || indicatorOffset.value > movementRange) {\n lastIndicatorOffset.value = movementRange;\n indicatorOffset.value = movementRange;\n return;\n }\n\n lastIndicatorOffset.value = offset;\n } else {\n setVisible(true);\n }\n };\n\n const getIsIndicatorDragging = () => isIndicatorDragging.current;\n\n useImperativeHandle(\n ref,\n () => ({\n getIsIndicatorDragging,\n onContentScroll,\n setVisible,\n }),\n [],\n );\n\n const handleUpdate = () => {\n const contentPercentage = offsetToPercentage(indicatorOffset.value, movementRange);\n const offset = percentageToOffset(contentPercentage, totalContentLength);\n\n scrollContentToOffset(offset);\n };\n\n const setIsIndicatorDragging = (value: boolean) => isIndicatorDragging.current = value;\n\n const pan = Gesture.Pan()\n .onBegin((e) => {\n indicatorOffset.value = lastIndicatorOffset.value;\n runOnJS(setIsIndicatorDragging)(true);\n })\n .onUpdate((e) => {\n if (indicatorOffset.value <= 0 && e.translationY < 0) {\n indicatorOffset.value = 0;\n return;\n }\n\n if (indicatorOffset.value >= movementRange && e.translationY > 0) {\n indicatorOffset.value = movementRange;\n return;\n }\n\n indicatorOffset.value = lastIndicatorOffset.value + e.translationY;\n\n runOnJS(handleUpdate)();\n })\n .onFinalize((e) => {\n lastIndicatorOffset.value = indicatorOffset.value;\n runOnJS(setIsIndicatorDragging)(false);\n });\n\n const hide = () => indicatorOpacity.value = withDelay(0, withTiming(0, { duration: visibleDurations.hideMillis }));\n\n const show = () => indicatorOpacity.value = withDelay(0, withTiming(1, { duration: visibleDurations.showMillis }));\n\n useEffect(() => {\n if (visible) {\n indicatorOffset.value = lastIndicatorOffset.value;\n show();\n } else {\n hide();\n }\n }, [visible]);\n\n return (\n <View\n style={[\n { height: movementRange },\n styles.view,\n absolutePosition,\n ]}\n >\n <GestureDetector gesture={pan}>\n <Animated.View style={[\n animatedStyle,\n styles.indicator,\n ]}>\n <ChevronUp\n fill={'#ededed'}\n height={20}\n width={20}\n />\n <ChevronDown\n fill={'#ededed'}\n height={20}\n width={20}\n />\n </Animated.View>\n </GestureDetector>\n </View>\n );\n});\n\nexport default FastScroll;"],"mappings":";;;;;;;AAAA;;AACA;;AACA;;AACA;;AACA;;AACA;;AAEA;;;;;;AAEA,MAAMA,MAAM,GAAGC,gBAAA,CAAWC,MAAX,CAAkB;EAC7BC,SAAS,EAAE;IACPC,KAAK,EAAE,EADA;IAEPC,MAAM,EAAE,EAFD;IAGPC,eAAe,EAAE,SAHV;IAIPC,aAAa,EAAE,QAJR;IAKPC,UAAU,EAAE,QALL;IAMPC,cAAc,EAAE,QANT;IAOPC,YAAY,EAAE;EAPP,CADkB;EAU7BC,IAAI,EAAE;IAAEC,OAAO,EAAE,CAAX;IAAcC,QAAQ,EAAE;EAAxB;AAVuB,CAAlB,CAAf;;AAaA,MAAMC,UAAU,gBAAGC,cAAA,CAAMC,UAAN,CAAiB,CAACC,KAAD,EAAyBC,GAAzB,KAAiC;EACjE,MAAM;IACFC,gBADE;IAEFC,gBAAgB,GAAG,CAFjB;IAGFC,aAHE;IAIFC,aAJE;IAKFC,qBALE;IAMFC,gBAAgB,GAAG;MAAEC,UAAU,EAAE,GAAd;MAAmBC,UAAU,EAAE;IAA/B;EANjB,IAOFT,KAPJ;EASA,MAAMU,mBAAmB,GAAG,IAAAC,qCAAA,EAAe,CAAf,CAA5B;EACA,MAAMC,eAAe,GAAG,IAAAD,qCAAA,EAAeD,mBAAmB,CAACG,KAAnC,CAAxB;EAEA,MAAMC,mBAAmB,GAAG,IAAAC,aAAA,EAAO,KAAP,CAA5B;EAEA,MAAMC,gBAAgB,GAAG,IAAAL,qCAAA,EAAe,CAAf,CAAzB;EACA,MAAM,CAACM,OAAD,EAAUC,UAAV,IAAwB,IAAAC,eAAA,EAAS,IAAT,CAA9B;EAEA,MAAMC,aAAa,GAAG,IAAAC,uCAAA,EAAiB,OAAO;IAC1CC,SAAS,EAAE,CAAC;MAAEC,UAAU,EAAEX,eAAe,CAACC;IAA9B,CAAD,CAD+B;IAE1CW,OAAO,EAAER,gBAAgB,CAACH;EAFgB,CAAP,CAAjB,CAAtB;EAKA,MAAMY,kBAAkB,GAAGrB,aAAa,GAAGD,gBAA3C;;EAEA,MAAMuB,eAAe,GAAIC,KAAD,IAAoD;IACxE,IAAI,CAACb,mBAAmB,CAACc,OAAzB,EAAkC;MAC9B,MAAMC,iBAAiB,GAAG,IAAAC,wBAAA,EAAmBH,KAAK,CAACI,WAAN,CAAkBC,aAAlB,CAAgCC,CAAnD,EAAsDR,kBAAtD,CAA1B;MACA,MAAMS,MAAM,GAAG,IAAAC,wBAAA,EAAmBN,iBAAnB,EAAsCxB,aAAtC,CAAf;;MAEA,IAAI6B,MAAM,GAAG,CAAT,IAActB,eAAe,CAACC,KAAhB,GAAwB,CAA1C,EAA6C;QACzCH,mBAAmB,CAACG,KAApB,GAA4B,CAA5B;QACAD,eAAe,CAACC,KAAhB,GAAwB,CAAxB;QACA;MACH;;MAED,IAAIqB,MAAM,GAAG7B,aAAT,IAA0BO,eAAe,CAACC,KAAhB,GAAwBR,aAAtD,EAAqE;QACjEK,mBAAmB,CAACG,KAApB,GAA4BR,aAA5B;QACAO,eAAe,CAACC,KAAhB,GAAwBR,aAAxB;QACA;MACH;;MAEDK,mBAAmB,CAACG,KAApB,GAA4BqB,MAA5B;IACH,CAjBD,MAiBO;MACHhB,UAAU,CAAC,IAAD,CAAV;IACH;EACJ,CArBD;;EAuBA,MAAMkB,sBAAsB,GAAG,MAAMtB,mBAAmB,CAACc,OAAzD;;EAEA,IAAAS,0BAAA,EACIpC,GADJ,EAEI,OAAO;IACHmC,sBADG;IAEHV,eAFG;IAGHR;EAHG,CAAP,CAFJ,EAOI,EAPJ;;EAUA,MAAMoB,YAAY,GAAG,MAAM;IACvB,MAAMT,iBAAiB,GAAG,IAAAC,wBAAA,EAAmBlB,eAAe,CAACC,KAAnC,EAA0CR,aAA1C,CAA1B;IACA,MAAM6B,MAAM,GAAG,IAAAC,wBAAA,EAAmBN,iBAAnB,EAAsCJ,kBAAtC,CAAf;IAEAnB,qBAAqB,CAAC4B,MAAD,CAArB;EACH,CALD;;EAOA,MAAMK,sBAAsB,GAAI1B,KAAD,IAAoBC,mBAAmB,CAACc,OAApB,GAA8Bf,KAAjF;;EAEA,MAAM2B,GAAG,GAAGC,kCAAA,CAAQC,GAAR,GACPC,OADO,CACEC,CAAD,IAAO;IACZhC,eAAe,CAACC,KAAhB,GAAwBH,mBAAmB,CAACG,KAA5C;IACA,IAAAgC,8BAAA,EAAQN,sBAAR,EAAgC,IAAhC;EACH,CAJO,EAKPO,QALO,CAKGF,CAAD,IAAO;IACb,IAAIhC,eAAe,CAACC,KAAhB,IAAyB,CAAzB,IAA8B+B,CAAC,CAACG,YAAF,GAAiB,CAAnD,EAAsD;MAClDnC,eAAe,CAACC,KAAhB,GAAwB,CAAxB;MACA;IACH;;IAED,IAAID,eAAe,CAACC,KAAhB,IAAyBR,aAAzB,IAA0CuC,CAAC,CAACG,YAAF,GAAiB,CAA/D,EAAkE;MAC9DnC,eAAe,CAACC,KAAhB,GAAwBR,aAAxB;MACA;IACH;;IAEDO,eAAe,CAACC,KAAhB,GAAwBH,mBAAmB,CAACG,KAApB,GAA4B+B,CAAC,CAACG,YAAtD;IAEA,IAAAF,8BAAA,EAAQP,YAAR;EACH,CAnBO,EAoBPU,UApBO,CAoBKJ,CAAD,IAAO;IACflC,mBAAmB,CAACG,KAApB,GAA4BD,eAAe,CAACC,KAA5C;IACA,IAAAgC,8BAAA,EAAQN,sBAAR,EAAgC,KAAhC;EACH,CAvBO,CAAZ;;EAyBA,MAAMU,IAAI,GAAG,MAAMjC,gBAAgB,CAACH,KAAjB,GAAyB,IAAAqC,gCAAA,EAAU,CAAV,EAAa,IAAAC,iCAAA,EAAW,CAAX,EAAc;IAAEC,QAAQ,EAAE7C,gBAAgB,CAACC;EAA7B,CAAd,CAAb,CAA5C;;EAEA,MAAM6C,IAAI,GAAG,MAAMrC,gBAAgB,CAACH,KAAjB,GAAyB,IAAAqC,gCAAA,EAAU,CAAV,EAAa,IAAAC,iCAAA,EAAW,CAAX,EAAc;IAAEC,QAAQ,EAAE7C,gBAAgB,CAACE;EAA7B,CAAd,CAAb,CAA5C;;EAEA,IAAA6C,gBAAA,EAAU,MAAM;IACZ,IAAIrC,OAAJ,EAAa;MACTL,eAAe,CAACC,KAAhB,GAAwBH,mBAAmB,CAACG,KAA5C;MACAwC,IAAI;IACP,CAHD,MAGO;MACHJ,IAAI;IACP;EACJ,CAPD,EAOG,CAAChC,OAAD,CAPH;EASA,oBACI,6BAAC,iBAAD;IACI,KAAK,EAAE,CACH;MAAE7B,MAAM,EAAEiB;IAAV,CADG,EAEHtB,MAAM,CAACW,IAFJ,EAGHQ,gBAHG;EADX,gBAOI,6BAAC,0CAAD;IAAiB,OAAO,EAAEsC;EAA1B,gBACI,6BAAC,8BAAD,CAAU,IAAV;IAAe,KAAK,EAAE,CAClBpB,aADkB,EAElBrC,MAAM,CAACG,SAFW;EAAtB,gBAII,6BAAC,gBAAD;IACI,IAAI,EAAE,SADV;IAEI,MAAM,EAAE,EAFZ;IAGI,KAAK,EAAE;EAHX,EAJJ,eASI,6BAAC,kBAAD;IACI,IAAI,EAAE,SADV;IAEI,MAAM,EAAE,EAFZ;IAGI,KAAK,EAAE;EAHX,EATJ,CADJ,CAPJ,CADJ;AA2BH,CAtIkB,CAAnB;;eAwIeW,U"}
@@ -1,7 +1,7 @@
1
1
  function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
2
 
3
3
  import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
- import { FlatList } from 'react-native';
4
+ import { FlatList, Platform } from 'react-native';
5
5
  import * as R from 'ramda';
6
6
  import ViewerItem from './ViewerItem';
7
7
  import FastScroll from './FastScroll';
@@ -215,14 +215,33 @@ export default function ComicViewer(props) {
215
215
  });
216
216
  }, [onItemPress, renderedDimensions]);
217
217
  useEffect(() => {
218
- const offset = Math.floor(initialScrollPercentage / 100 * totalHeight);
218
+ const scroll = () => {
219
+ const offset = Math.floor(initialScrollPercentage / 100 * totalHeight);
220
+
221
+ if (flatListRef.current) {
222
+ flatListRef.current.scrollToOffset({
223
+ offset,
224
+ animated: false
225
+ });
226
+ }
227
+ };
219
228
 
220
- if (flatListRef.current) {
221
- flatListRef.current.scrollToOffset({
222
- offset,
223
- animated: false
224
- });
229
+ let timeoutId = undefined;
230
+ /**
231
+ * @FIXME
232
+ * scrollToOffset has issue(no effect) in useEffect hook on iOS.
233
+ * ref: https://github.com/facebook/react-native/issues/35575
234
+ */
235
+
236
+ if (Platform.OS === 'ios') {
237
+ timeoutId = setTimeout(scroll, 0);
238
+ } else {
239
+ scroll();
225
240
  }
241
+
242
+ return () => {
243
+ timeoutId && clearTimeout(timeoutId);
244
+ };
226
245
  }, []);
227
246
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(FlatList, _extends({
228
247
  data: itemStates,
@@ -1 +1 @@
1
- {"version":3,"names":["React","useCallback","useEffect","useMemo","useRef","useState","FlatList","R","ViewerItem","FastScroll","appender","left","right","getHeightAccum","heights","mapAccum","keyExtractor","item","String","index","createInitialImageState","image","totalErrorCount","dimension","tryRenderingMillis","urlState","url","validity","mapImageStateToItemState","imageState","autoHandleErrorCount","imageKey","reloadButtonVisible","mapIndexed","addIndex","map","MAXIMUM_WIDTH","ComicViewer","props","debounceMillis","fastScrollOptions","initialNumToRender","initialScrollPercentage","itemVisiblePercentThreshold","intrinsicImages","maxContentWidth","onItemPress","onScroll","onError","onReloadPress","viewportWidth","invisiblePaddingTop","windowSize","otherProps","fastScrollRef","ref","flatListRef","actualImageWidth","Math","min","initialImageStates","imageStatesRef","mapImageStatesToItemStates","imageStates","itemStates","setItemStates","current","renderedDimensions","intrinsicImage","height","width","isNaN","layoutFromDimensions","itemHeights","totalHeight","heightAccum","itemOffsets","prepend","getItemLayout","data","length","offset","viewabilityConfig","updateImageState","updateFunction","prevImageStates","newImageStates","prevItemStates","newItemStates","equals","updateTryRenderingMillis","Date","getTime","i","onViewableItemsChanged","viewableItems","handleScroll","event","onContentScroll","scrollContentToOffset","scrollToOffset","animated","renderItem","handleError","handleReloadPress","onLoad","undefined","floor"],"sources":["ComicViewer.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { FlatList, ListRenderItem, NativeScrollEvent, NativeSyntheticEvent, ViewToken } from 'react-native';\nimport * as R from 'ramda';\nimport { default as ComicViewerProps, Dimension, IntrinsicImage } from './ComicViewerProps';\nimport ViewerItem from './ViewerItem';\nimport FastScroll from './FastScroll';\n\nconst appender = (left: number, right: number): [number, number] => [left + right, left + right];\nconst getHeightAccum = (heights: number[]): [number, number[]] => R.mapAccum(appender, 0, heights);\n\nconst keyExtractor = <T, >(item: ItemState) => String(item.index);\n\ninterface UrlState {\n url: string;\n validity: 'valid' | 'invalid' | 'unknown';\n}\n\ninterface ImageState {\n urlState: UrlState;\n totalErrorCount: number;\n dimension: Dimension;\n tryRenderingMillis: number;\n}\n\ninterface ItemState {\n index: number;\n url?: string;\n imageKey: string;\n reloadButtonVisible: boolean;\n dimension: Dimension;\n}\n\nconst createInitialImageState = (image: IntrinsicImage): ImageState => ({\n totalErrorCount: 0,\n dimension: image.dimension,\n tryRenderingMillis: 0,\n urlState: {\n url: image.url,\n validity: 'unknown',\n },\n});\n\nconst mapImageStateToItemState = (\n index: number,\n imageState: ImageState,\n autoHandleErrorCount: number,\n): ItemState => ({\n index,\n url: imageState.urlState?.url,\n imageKey: `${imageState.tryRenderingMillis}-${index}`,\n reloadButtonVisible: (imageState.urlState?.validity !== 'valid') && imageState.totalErrorCount >= autoHandleErrorCount,\n dimension: imageState.dimension,\n});\n\nconst mapIndexed = R.addIndex<IntrinsicImage>(R.map);\n\nconst MAXIMUM_WIDTH = 720;\n\nexport default function ComicViewer(props: ComicViewerProps) {\n const {\n debounceMillis = 100,\n autoHandleErrorCount = 3,\n fastScrollOptions,\n initialNumToRender = 1,\n initialScrollPercentage = 0,\n itemVisiblePercentThreshold = 0,\n intrinsicImages,\n maxContentWidth = MAXIMUM_WIDTH,\n onItemPress,\n onScroll,\n onError,\n onReloadPress,\n viewportWidth,\n invisiblePaddingTop = 0,\n windowSize = 3,\n ...otherProps\n } = props;\n\n const fastScrollRef = fastScrollOptions?.ref;\n\n const flatListRef = useRef<FlatList>(null);\n\n const actualImageWidth = Math.min(viewportWidth, maxContentWidth);\n\n const initialImageStates = useMemo<Array<ImageState>>(() => R.map(createInitialImageState, intrinsicImages), []);\n\n const imageStatesRef = useRef<Array<ImageState>>(initialImageStates);\n\n const mapImageStatesToItemStates = (imageStates: Array<ImageState>): Array<ItemState> => {\n return imageStates.map((image, index) => mapImageStateToItemState(\n index, image, autoHandleErrorCount,\n ));\n };\n\n const [itemStates, setItemStates] = useState<Array<ItemState>>(() => {\n return mapImageStatesToItemStates(imageStatesRef.current);\n });\n\n const renderedDimensions = useMemo<Array<Dimension>>(() => {\n return mapIndexed((intrinsicImage, index) => {\n const height = (intrinsicImage.dimension.height * actualImageWidth) / intrinsicImage.dimension.width + (index === 0 ? invisiblePaddingTop : 0);\n\n return {\n width: actualImageWidth,\n height: isNaN(height) ? 0 : height,\n };\n }, intrinsicImages);\n }, [actualImageWidth]);\n\n const layoutFromDimensions = useCallback(() => {\n const itemHeights = R.map(dimension => dimension.height, renderedDimensions);\n const [totalHeight, heightAccum] = getHeightAccum(itemHeights);\n const itemOffsets = R.prepend(0, heightAccum);\n\n const getItemLayout = (data: any, index: number) => ({\n index,\n length: itemHeights[index],\n offset: itemOffsets[index],\n });\n\n return {\n totalHeight,\n getItemLayout,\n };\n }, [renderedDimensions]);\n\n const { totalHeight, getItemLayout } = layoutFromDimensions();\n\n const viewabilityConfig = useMemo(() => ({\n itemVisiblePercentThreshold,\n }), [itemVisiblePercentThreshold]);\n\n const updateImageState = (updateFunction: (prev: ImageState, index: number) => ImageState) => {\n const prevImageStates = imageStatesRef.current;\n const newImageStates = prevImageStates.map(updateFunction);\n\n imageStatesRef.current = newImageStates;\n\n setItemStates(prevItemStates => {\n const newItemStates = mapImageStatesToItemStates(newImageStates);\n\n return R.equals(prevItemStates, newItemStates) ? prevItemStates : newItemStates;\n });\n };\n\n const updateTryRenderingMillis = () => {\n const tryRenderingMillis = new Date().getTime();\n\n updateImageState((imageState, i) => {\n const urlState = imageState.urlState;\n\n if (urlState?.validity === 'invalid') {\n return {\n ...imageState,\n tryRenderingMillis,\n };\n }\n\n return imageState;\n });\n };\n const onViewableItemsChanged = useRef(({ viewableItems }: { viewableItems: Array<ViewToken> }) => {\n updateTryRenderingMillis();\n });\n\n const handleScroll = useCallback((event: NativeSyntheticEvent<NativeScrollEvent>) => {\n fastScrollRef?.current?.onContentScroll(event);\n\n onScroll?.(event);\n }, [onScroll]);\n\n const scrollContentToOffset = (offset: number) => {\n flatListRef.current?.scrollToOffset({\n offset,\n animated: false,\n });\n };\n\n const renderItem: ListRenderItem<ItemState> = useCallback(({ item, index }) => {\n const handleError = () => {\n onError && onError();\n\n updateImageState((imageState, i) => {\n const urlState = imageState.urlState;\n\n if (i === index) {\n return {\n ...imageState,\n totalErrorCount: imageState.totalErrorCount + 1,\n urlState: {\n ...urlState,\n validity: 'invalid',\n },\n };\n }\n\n return imageState;\n });\n\n if (item.reloadButtonVisible) {\n return;\n }\n\n updateTryRenderingMillis();\n };\n\n const handleReloadPress = () => {\n onReloadPress && onReloadPress();\n\n updateTryRenderingMillis();\n };\n\n const onLoad = () => {\n updateImageState((imageState, i) => {\n const urlState = imageState.urlState;\n\n if (i === index && urlState !== undefined) {\n return {\n ...imageState,\n urlState: {\n ...urlState,\n validity: 'valid',\n },\n };\n }\n\n return imageState;\n });\n };\n\n return (\n <ViewerItem\n onError={handleError}\n onLoad={onLoad}\n onPress={onItemPress}\n onReloadPress={handleReloadPress}\n url={item.url}\n imageKey={item.imageKey}\n invisiblePaddingTop={index === 0 ? invisiblePaddingTop : 0}\n width={renderedDimensions[index]?.width ?? 0}\n height={renderedDimensions[index]?.height ?? 0}\n reloadButtonVisible={item.reloadButtonVisible}\n />\n );\n }, [onItemPress, renderedDimensions]);\n\n useEffect(() => {\n const offset = Math.floor((initialScrollPercentage / 100) * totalHeight);\n\n if (flatListRef.current) {\n flatListRef.current.scrollToOffset({ offset, animated: false });\n }\n }, []);\n\n return (\n <React.Fragment>\n <FlatList\n data={itemStates}\n getItemLayout={getItemLayout}\n initialNumToRender={initialNumToRender}\n keyExtractor={keyExtractor}\n onViewableItemsChanged={onViewableItemsChanged.current}\n ref={flatListRef}\n renderItem={renderItem}\n viewabilityConfig={viewabilityConfig}\n windowSize={windowSize}\n onScroll={handleScroll}\n {...otherProps}\n />\n\n <FastScroll\n {...fastScrollOptions}\n contentLength={totalHeight}\n scrollContentToOffset={scrollContentToOffset}\n />\n </React.Fragment>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"names":["React","useCallback","useEffect","useMemo","useRef","useState","FlatList","Platform","R","ViewerItem","FastScroll","appender","left","right","getHeightAccum","heights","mapAccum","keyExtractor","item","String","index","createInitialImageState","image","totalErrorCount","dimension","tryRenderingMillis","urlState","url","validity","mapImageStateToItemState","imageState","autoHandleErrorCount","imageKey","reloadButtonVisible","mapIndexed","addIndex","map","MAXIMUM_WIDTH","ComicViewer","props","debounceMillis","fastScrollOptions","initialNumToRender","initialScrollPercentage","itemVisiblePercentThreshold","intrinsicImages","maxContentWidth","onItemPress","onScroll","onError","onReloadPress","viewportWidth","invisiblePaddingTop","windowSize","otherProps","fastScrollRef","ref","flatListRef","actualImageWidth","Math","min","initialImageStates","imageStatesRef","mapImageStatesToItemStates","imageStates","itemStates","setItemStates","current","renderedDimensions","intrinsicImage","height","width","isNaN","layoutFromDimensions","itemHeights","totalHeight","heightAccum","itemOffsets","prepend","getItemLayout","data","length","offset","viewabilityConfig","updateImageState","updateFunction","prevImageStates","newImageStates","prevItemStates","newItemStates","equals","updateTryRenderingMillis","Date","getTime","i","onViewableItemsChanged","viewableItems","handleScroll","event","onContentScroll","scrollContentToOffset","scrollToOffset","animated","renderItem","handleError","handleReloadPress","onLoad","undefined","scroll","floor","timeoutId","OS","setTimeout","clearTimeout"],"sources":["ComicViewer.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { FlatList, ListRenderItem, NativeScrollEvent, NativeSyntheticEvent, Platform, ViewToken } from 'react-native';\nimport * as R from 'ramda';\nimport { default as ComicViewerProps, Dimension, IntrinsicImage } from './ComicViewerProps';\nimport ViewerItem from './ViewerItem';\nimport FastScroll from './FastScroll';\n\nconst appender = (left: number, right: number): [number, number] => [left + right, left + right];\nconst getHeightAccum = (heights: number[]): [number, number[]] => R.mapAccum(appender, 0, heights);\n\nconst keyExtractor = <T, >(item: ItemState) => String(item.index);\n\ninterface UrlState {\n url: string;\n validity: 'valid' | 'invalid' | 'unknown';\n}\n\ninterface ImageState {\n urlState: UrlState;\n totalErrorCount: number;\n dimension: Dimension;\n tryRenderingMillis: number;\n}\n\ninterface ItemState {\n index: number;\n url?: string;\n imageKey: string;\n reloadButtonVisible: boolean;\n dimension: Dimension;\n}\n\nconst createInitialImageState = (image: IntrinsicImage): ImageState => ({\n totalErrorCount: 0,\n dimension: image.dimension,\n tryRenderingMillis: 0,\n urlState: {\n url: image.url,\n validity: 'unknown',\n },\n});\n\nconst mapImageStateToItemState = (\n index: number,\n imageState: ImageState,\n autoHandleErrorCount: number,\n): ItemState => ({\n index,\n url: imageState.urlState?.url,\n imageKey: `${imageState.tryRenderingMillis}-${index}`,\n reloadButtonVisible: (imageState.urlState?.validity !== 'valid') && imageState.totalErrorCount >= autoHandleErrorCount,\n dimension: imageState.dimension,\n});\n\nconst mapIndexed = R.addIndex<IntrinsicImage>(R.map);\n\nconst MAXIMUM_WIDTH = 720;\n\nexport default function ComicViewer(props: ComicViewerProps) {\n const {\n debounceMillis = 100,\n autoHandleErrorCount = 3,\n fastScrollOptions,\n initialNumToRender = 1,\n initialScrollPercentage = 0,\n itemVisiblePercentThreshold = 0,\n intrinsicImages,\n maxContentWidth = MAXIMUM_WIDTH,\n onItemPress,\n onScroll,\n onError,\n onReloadPress,\n viewportWidth,\n invisiblePaddingTop = 0,\n windowSize = 3,\n ...otherProps\n } = props;\n\n const fastScrollRef = fastScrollOptions?.ref;\n\n const flatListRef = useRef<FlatList>(null);\n\n const actualImageWidth = Math.min(viewportWidth, maxContentWidth);\n\n const initialImageStates = useMemo<Array<ImageState>>(() => R.map(createInitialImageState, intrinsicImages), []);\n\n const imageStatesRef = useRef<Array<ImageState>>(initialImageStates);\n\n const mapImageStatesToItemStates = (imageStates: Array<ImageState>): Array<ItemState> => {\n return imageStates.map((image, index) => mapImageStateToItemState(\n index, image, autoHandleErrorCount,\n ));\n };\n\n const [itemStates, setItemStates] = useState<Array<ItemState>>(() => {\n return mapImageStatesToItemStates(imageStatesRef.current);\n });\n\n const renderedDimensions = useMemo<Array<Dimension>>(() => {\n return mapIndexed((intrinsicImage, index) => {\n const height = (intrinsicImage.dimension.height * actualImageWidth) / intrinsicImage.dimension.width + (index === 0 ? invisiblePaddingTop : 0);\n\n return {\n width: actualImageWidth,\n height: isNaN(height) ? 0 : height,\n };\n }, intrinsicImages);\n }, [actualImageWidth]);\n\n const layoutFromDimensions = useCallback(() => {\n const itemHeights = R.map(dimension => dimension.height, renderedDimensions);\n const [totalHeight, heightAccum] = getHeightAccum(itemHeights);\n const itemOffsets = R.prepend(0, heightAccum);\n\n const getItemLayout = (data: any, index: number) => ({\n index,\n length: itemHeights[index],\n offset: itemOffsets[index],\n });\n\n return {\n totalHeight,\n getItemLayout,\n };\n }, [renderedDimensions]);\n\n const { totalHeight, getItemLayout } = layoutFromDimensions();\n\n const viewabilityConfig = useMemo(() => ({\n itemVisiblePercentThreshold,\n }), [itemVisiblePercentThreshold]);\n\n const updateImageState = (updateFunction: (prev: ImageState, index: number) => ImageState) => {\n const prevImageStates = imageStatesRef.current;\n const newImageStates = prevImageStates.map(updateFunction);\n\n imageStatesRef.current = newImageStates;\n\n setItemStates(prevItemStates => {\n const newItemStates = mapImageStatesToItemStates(newImageStates);\n\n return R.equals(prevItemStates, newItemStates) ? prevItemStates : newItemStates;\n });\n };\n\n const updateTryRenderingMillis = () => {\n const tryRenderingMillis = new Date().getTime();\n\n updateImageState((imageState, i) => {\n const urlState = imageState.urlState;\n\n if (urlState?.validity === 'invalid') {\n return {\n ...imageState,\n tryRenderingMillis,\n };\n }\n\n return imageState;\n });\n };\n const onViewableItemsChanged = useRef(({ viewableItems }: { viewableItems: Array<ViewToken> }) => {\n updateTryRenderingMillis();\n });\n\n const handleScroll = useCallback((event: NativeSyntheticEvent<NativeScrollEvent>) => {\n fastScrollRef?.current?.onContentScroll(event);\n\n onScroll?.(event);\n }, [onScroll]);\n\n const scrollContentToOffset = (offset: number) => {\n flatListRef.current?.scrollToOffset({\n offset,\n animated: false,\n });\n };\n\n const renderItem: ListRenderItem<ItemState> = useCallback(({ item, index }) => {\n const handleError = () => {\n onError && onError();\n\n updateImageState((imageState, i) => {\n const urlState = imageState.urlState;\n\n if (i === index) {\n return {\n ...imageState,\n totalErrorCount: imageState.totalErrorCount + 1,\n urlState: {\n ...urlState,\n validity: 'invalid',\n },\n };\n }\n\n return imageState;\n });\n\n if (item.reloadButtonVisible) {\n return;\n }\n\n updateTryRenderingMillis();\n };\n\n const handleReloadPress = () => {\n onReloadPress && onReloadPress();\n\n updateTryRenderingMillis();\n };\n\n const onLoad = () => {\n updateImageState((imageState, i) => {\n const urlState = imageState.urlState;\n\n if (i === index && urlState !== undefined) {\n return {\n ...imageState,\n urlState: {\n ...urlState,\n validity: 'valid',\n },\n };\n }\n\n return imageState;\n });\n };\n\n return (\n <ViewerItem\n onError={handleError}\n onLoad={onLoad}\n onPress={onItemPress}\n onReloadPress={handleReloadPress}\n url={item.url}\n imageKey={item.imageKey}\n invisiblePaddingTop={index === 0 ? invisiblePaddingTop : 0}\n width={renderedDimensions[index]?.width ?? 0}\n height={renderedDimensions[index]?.height ?? 0}\n reloadButtonVisible={item.reloadButtonVisible}\n />\n );\n }, [onItemPress, renderedDimensions]);\n\n useEffect(() => {\n const scroll = () => {\n const offset = Math.floor((initialScrollPercentage / 100) * totalHeight);\n\n if (flatListRef.current) {\n flatListRef.current.scrollToOffset({ offset, animated: false });\n }\n };\n\n let timeoutId: NodeJS.Timeout | undefined = undefined;\n\n /**\n * @FIXME\n * scrollToOffset has issue(no effect) in useEffect hook on iOS.\n * ref: https://github.com/facebook/react-native/issues/35575\n */\n if (Platform.OS === 'ios') {\n timeoutId = setTimeout(scroll, 0);\n } else {\n scroll();\n }\n\n return () => {\n timeoutId && clearTimeout(timeoutId);\n }\n }, []);\n\n return (\n <React.Fragment>\n <FlatList\n data={itemStates}\n getItemLayout={getItemLayout}\n initialNumToRender={initialNumToRender}\n keyExtractor={keyExtractor}\n onViewableItemsChanged={onViewableItemsChanged.current}\n ref={flatListRef}\n renderItem={renderItem}\n viewabilityConfig={viewabilityConfig}\n windowSize={windowSize}\n onScroll={handleScroll}\n {...otherProps}\n />\n\n <FastScroll\n {...fastScrollOptions}\n contentLength={totalHeight}\n scrollContentToOffset={scrollContentToOffset}\n />\n </React.Fragment>\n );\n};\n"],"mappings":"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"}
@@ -7,14 +7,16 @@ import { StyleSheet } from '@fountain-ui/core';
7
7
  import { offsetToPercentage, percentageToOffset } from './util';
8
8
  const styles = StyleSheet.create({
9
9
  indicator: {
10
- width: 24,
11
- height: 40,
10
+ width: 28,
11
+ height: 48,
12
12
  backgroundColor: '#767676',
13
13
  flexDirection: 'column',
14
14
  alignItems: 'center',
15
- borderRadius: 4
15
+ justifyContent: 'center',
16
+ borderRadius: 16
16
17
  },
17
18
  view: {
19
+ padding: 4,
18
20
  position: 'absolute'
19
21
  }
20
22
  });
@@ -44,7 +46,7 @@ const FastScroll = /*#__PURE__*/React.forwardRef((props, ref) => {
44
46
  const totalContentLength = contentLength + additionalLength;
45
47
 
46
48
  const onContentScroll = event => {
47
- if (isIndicatorDragging.current === false) {
49
+ if (!isIndicatorDragging.current) {
48
50
  const contentPercentage = offsetToPercentage(event.nativeEvent.contentOffset.y, totalContentLength);
49
51
  const offset = percentageToOffset(contentPercentage, movementRange);
50
52
 
@@ -1 +1 @@
1
- {"version":3,"names":["React","useEffect","useImperativeHandle","useRef","useState","View","Gesture","GestureDetector","Animated","runOnJS","useAnimatedStyle","useSharedValue","withDelay","withTiming","ChevronDown","ChevronUp","StyleSheet","offsetToPercentage","percentageToOffset","styles","create","indicator","width","height","backgroundColor","flexDirection","alignItems","borderRadius","view","position","FastScroll","forwardRef","props","ref","absolutePosition","additionalLength","contentLength","movementRange","scrollContentToOffset","visibleDurations","hideMillis","showMillis","lastIndicatorOffset","indicatorOffset","value","isIndicatorDragging","indicatorOpacity","visible","setVisible","animatedStyle","transform","translateY","opacity","totalContentLength","onContentScroll","event","current","contentPercentage","nativeEvent","contentOffset","y","offset","getIsIndicatorDragging","handleUpdate","setIsIndicatorDragging","pan","Pan","onBegin","e","onUpdate","translationY","onFinalize","hide","duration","show"],"sources":["FastScroll.tsx"],"sourcesContent":["import React, { useEffect, useImperativeHandle, useRef, useState } from 'react';\nimport { NativeScrollEvent, NativeSyntheticEvent, View } from 'react-native';\nimport { Gesture, GestureDetector } from 'react-native-gesture-handler';\nimport Animated, { runOnJS, useAnimatedStyle, useSharedValue, withDelay, withTiming } from 'react-native-reanimated';\nimport { ChevronDown, ChevronUp } from '@fountain-ui/icons';\nimport { StyleSheet } from '@fountain-ui/core';\nimport FastScrollProps from './FastScrollProps';\nimport { offsetToPercentage, percentageToOffset } from './util';\n\nconst styles = StyleSheet.create({\n indicator: {\n width: 24,\n height: 40,\n backgroundColor: '#767676',\n flexDirection: 'column',\n alignItems: 'center',\n borderRadius: 4,\n },\n view: { position: 'absolute' },\n});\n\nconst FastScroll = React.forwardRef((props: FastScrollProps, ref) => {\n const {\n absolutePosition,\n additionalLength = 0,\n contentLength,\n movementRange,\n scrollContentToOffset,\n visibleDurations = { hideMillis: 200, showMillis: 350 },\n } = props;\n\n const lastIndicatorOffset = useSharedValue(0);\n const indicatorOffset = useSharedValue(lastIndicatorOffset.value);\n\n const isIndicatorDragging = useRef(false);\n\n const indicatorOpacity = useSharedValue(1);\n const [visible, setVisible] = useState(true);\n\n const animatedStyle = useAnimatedStyle(() => ({\n transform: [{ translateY: indicatorOffset.value }],\n opacity: indicatorOpacity.value,\n }));\n\n const totalContentLength = contentLength + additionalLength;\n\n const onContentScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {\n if (isIndicatorDragging.current === false) {\n const contentPercentage = offsetToPercentage(event.nativeEvent.contentOffset.y, totalContentLength);\n const offset = percentageToOffset(contentPercentage, movementRange);\n\n if (offset < 0 || indicatorOffset.value < 0) {\n lastIndicatorOffset.value = 0;\n indicatorOffset.value = 0;\n return;\n }\n\n if (offset > movementRange || indicatorOffset.value > movementRange) {\n lastIndicatorOffset.value = movementRange;\n indicatorOffset.value = movementRange;\n return;\n }\n\n lastIndicatorOffset.value = offset;\n } else {\n setVisible(true);\n }\n };\n\n const getIsIndicatorDragging = () => isIndicatorDragging.current;\n\n useImperativeHandle(\n ref,\n () => ({\n getIsIndicatorDragging,\n onContentScroll,\n setVisible,\n }),\n [],\n );\n\n const handleUpdate = () => {\n const contentPercentage = offsetToPercentage(indicatorOffset.value, movementRange);\n const offset = percentageToOffset(contentPercentage, totalContentLength);\n\n scrollContentToOffset(offset);\n };\n\n const setIsIndicatorDragging = (value: boolean) => isIndicatorDragging.current = value;\n\n const pan = Gesture.Pan()\n .onBegin((e) => {\n indicatorOffset.value = lastIndicatorOffset.value;\n runOnJS(setIsIndicatorDragging)(true);\n })\n .onUpdate((e) => {\n if (indicatorOffset.value <= 0 && e.translationY < 0) {\n indicatorOffset.value = 0;\n return;\n }\n\n if (indicatorOffset.value >= movementRange && e.translationY > 0) {\n indicatorOffset.value = movementRange;\n return;\n }\n\n indicatorOffset.value = lastIndicatorOffset.value + e.translationY;\n\n runOnJS(handleUpdate)();\n })\n .onFinalize((e) => {\n lastIndicatorOffset.value = indicatorOffset.value;\n runOnJS(setIsIndicatorDragging)(false);\n });\n\n const hide = () => indicatorOpacity.value = withDelay(0, withTiming(0, { duration: visibleDurations.hideMillis }));\n\n const show = () => indicatorOpacity.value = withDelay(0, withTiming(1, { duration: visibleDurations.showMillis }));\n\n useEffect(() => {\n if (visible) {\n indicatorOffset.value = lastIndicatorOffset.value;\n show();\n } else {\n hide();\n }\n }, [visible]);\n\n return (\n <View\n style={[\n { height: movementRange },\n styles.view,\n absolutePosition,\n ]}\n >\n <GestureDetector gesture={pan}>\n <Animated.View style={[\n animatedStyle,\n styles.indicator,\n ]}>\n <ChevronUp\n fill={'#ededed'}\n height={20}\n width={20}\n />\n <ChevronDown\n fill={'#ededed'}\n height={20}\n width={20}\n />\n </Animated.View>\n </GestureDetector>\n </View>\n );\n});\n\nexport default FastScroll;"],"mappings":"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"}
1
+ {"version":3,"names":["React","useEffect","useImperativeHandle","useRef","useState","View","Gesture","GestureDetector","Animated","runOnJS","useAnimatedStyle","useSharedValue","withDelay","withTiming","ChevronDown","ChevronUp","StyleSheet","offsetToPercentage","percentageToOffset","styles","create","indicator","width","height","backgroundColor","flexDirection","alignItems","justifyContent","borderRadius","view","padding","position","FastScroll","forwardRef","props","ref","absolutePosition","additionalLength","contentLength","movementRange","scrollContentToOffset","visibleDurations","hideMillis","showMillis","lastIndicatorOffset","indicatorOffset","value","isIndicatorDragging","indicatorOpacity","visible","setVisible","animatedStyle","transform","translateY","opacity","totalContentLength","onContentScroll","event","current","contentPercentage","nativeEvent","contentOffset","y","offset","getIsIndicatorDragging","handleUpdate","setIsIndicatorDragging","pan","Pan","onBegin","e","onUpdate","translationY","onFinalize","hide","duration","show"],"sources":["FastScroll.tsx"],"sourcesContent":["import React, { useEffect, useImperativeHandle, useRef, useState } from 'react';\nimport { NativeScrollEvent, NativeSyntheticEvent, View } from 'react-native';\nimport { Gesture, GestureDetector } from 'react-native-gesture-handler';\nimport Animated, { runOnJS, useAnimatedStyle, useSharedValue, withDelay, withTiming } from 'react-native-reanimated';\nimport { ChevronDown, ChevronUp } from '@fountain-ui/icons';\nimport { StyleSheet } from '@fountain-ui/core';\nimport FastScrollProps from './FastScrollProps';\nimport { offsetToPercentage, percentageToOffset } from './util';\n\nconst styles = StyleSheet.create({\n indicator: {\n width: 28,\n height: 48,\n backgroundColor: '#767676',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: 16,\n },\n view: { padding: 4, position: 'absolute' },\n});\n\nconst FastScroll = React.forwardRef((props: FastScrollProps, ref) => {\n const {\n absolutePosition,\n additionalLength = 0,\n contentLength,\n movementRange,\n scrollContentToOffset,\n visibleDurations = { hideMillis: 200, showMillis: 350 },\n } = props;\n\n const lastIndicatorOffset = useSharedValue(0);\n const indicatorOffset = useSharedValue(lastIndicatorOffset.value);\n\n const isIndicatorDragging = useRef(false);\n\n const indicatorOpacity = useSharedValue(1);\n const [visible, setVisible] = useState(true);\n\n const animatedStyle = useAnimatedStyle(() => ({\n transform: [{ translateY: indicatorOffset.value }],\n opacity: indicatorOpacity.value,\n }));\n\n const totalContentLength = contentLength + additionalLength;\n\n const onContentScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {\n if (!isIndicatorDragging.current) {\n const contentPercentage = offsetToPercentage(event.nativeEvent.contentOffset.y, totalContentLength);\n const offset = percentageToOffset(contentPercentage, movementRange);\n\n if (offset < 0 || indicatorOffset.value < 0) {\n lastIndicatorOffset.value = 0;\n indicatorOffset.value = 0;\n return;\n }\n\n if (offset > movementRange || indicatorOffset.value > movementRange) {\n lastIndicatorOffset.value = movementRange;\n indicatorOffset.value = movementRange;\n return;\n }\n\n lastIndicatorOffset.value = offset;\n } else {\n setVisible(true);\n }\n };\n\n const getIsIndicatorDragging = () => isIndicatorDragging.current;\n\n useImperativeHandle(\n ref,\n () => ({\n getIsIndicatorDragging,\n onContentScroll,\n setVisible,\n }),\n [],\n );\n\n const handleUpdate = () => {\n const contentPercentage = offsetToPercentage(indicatorOffset.value, movementRange);\n const offset = percentageToOffset(contentPercentage, totalContentLength);\n\n scrollContentToOffset(offset);\n };\n\n const setIsIndicatorDragging = (value: boolean) => isIndicatorDragging.current = value;\n\n const pan = Gesture.Pan()\n .onBegin((e) => {\n indicatorOffset.value = lastIndicatorOffset.value;\n runOnJS(setIsIndicatorDragging)(true);\n })\n .onUpdate((e) => {\n if (indicatorOffset.value <= 0 && e.translationY < 0) {\n indicatorOffset.value = 0;\n return;\n }\n\n if (indicatorOffset.value >= movementRange && e.translationY > 0) {\n indicatorOffset.value = movementRange;\n return;\n }\n\n indicatorOffset.value = lastIndicatorOffset.value + e.translationY;\n\n runOnJS(handleUpdate)();\n })\n .onFinalize((e) => {\n lastIndicatorOffset.value = indicatorOffset.value;\n runOnJS(setIsIndicatorDragging)(false);\n });\n\n const hide = () => indicatorOpacity.value = withDelay(0, withTiming(0, { duration: visibleDurations.hideMillis }));\n\n const show = () => indicatorOpacity.value = withDelay(0, withTiming(1, { duration: visibleDurations.showMillis }));\n\n useEffect(() => {\n if (visible) {\n indicatorOffset.value = lastIndicatorOffset.value;\n show();\n } else {\n hide();\n }\n }, [visible]);\n\n return (\n <View\n style={[\n { height: movementRange },\n styles.view,\n absolutePosition,\n ]}\n >\n <GestureDetector gesture={pan}>\n <Animated.View style={[\n animatedStyle,\n styles.indicator,\n ]}>\n <ChevronUp\n fill={'#ededed'}\n height={20}\n width={20}\n />\n <ChevronDown\n fill={'#ededed'}\n height={20}\n width={20}\n />\n </Animated.View>\n </GestureDetector>\n </View>\n );\n});\n\nexport default FastScroll;"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fountain-ui/lab",
3
- "version": "2.0.0-beta.53",
3
+ "version": "2.0.0-beta.54",
4
4
  "private": false,
5
5
  "author": "Fountain-UI Team",
6
6
  "description": "Incubator for Fountain-UI React components.",
@@ -70,5 +70,5 @@
70
70
  "publishConfig": {
71
71
  "access": "public"
72
72
  },
73
- "gitHead": "7bb792aa428d7723da4cf011b44e328326cd9195"
73
+ "gitHead": "f9c278a3d035ceaf0745d32398b6036369327678"
74
74
  }
@@ -1,5 +1,5 @@
1
1
  import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
- import { FlatList, ListRenderItem, NativeScrollEvent, NativeSyntheticEvent, ViewToken } from 'react-native';
2
+ import { FlatList, ListRenderItem, NativeScrollEvent, NativeSyntheticEvent, Platform, ViewToken } from 'react-native';
3
3
  import * as R from 'ramda';
4
4
  import { default as ComicViewerProps, Dimension, IntrinsicImage } from './ComicViewerProps';
5
5
  import ViewerItem from './ViewerItem';
@@ -245,10 +245,29 @@ export default function ComicViewer(props: ComicViewerProps) {
245
245
  }, [onItemPress, renderedDimensions]);
246
246
 
247
247
  useEffect(() => {
248
- const offset = Math.floor((initialScrollPercentage / 100) * totalHeight);
248
+ const scroll = () => {
249
+ const offset = Math.floor((initialScrollPercentage / 100) * totalHeight);
249
250
 
250
- if (flatListRef.current) {
251
- flatListRef.current.scrollToOffset({ offset, animated: false });
251
+ if (flatListRef.current) {
252
+ flatListRef.current.scrollToOffset({ offset, animated: false });
253
+ }
254
+ };
255
+
256
+ let timeoutId: NodeJS.Timeout | undefined = undefined;
257
+
258
+ /**
259
+ * @FIXME
260
+ * scrollToOffset has issue(no effect) in useEffect hook on iOS.
261
+ * ref: https://github.com/facebook/react-native/issues/35575
262
+ */
263
+ if (Platform.OS === 'ios') {
264
+ timeoutId = setTimeout(scroll, 0);
265
+ } else {
266
+ scroll();
267
+ }
268
+
269
+ return () => {
270
+ timeoutId && clearTimeout(timeoutId);
252
271
  }
253
272
  }, []);
254
273
 
@@ -9,14 +9,15 @@ import { offsetToPercentage, percentageToOffset } from './util';
9
9
 
10
10
  const styles = StyleSheet.create({
11
11
  indicator: {
12
- width: 24,
13
- height: 40,
12
+ width: 28,
13
+ height: 48,
14
14
  backgroundColor: '#767676',
15
15
  flexDirection: 'column',
16
16
  alignItems: 'center',
17
- borderRadius: 4,
17
+ justifyContent: 'center',
18
+ borderRadius: 16,
18
19
  },
19
- view: { position: 'absolute' },
20
+ view: { padding: 4, position: 'absolute' },
20
21
  });
21
22
 
22
23
  const FastScroll = React.forwardRef((props: FastScrollProps, ref) => {
@@ -45,7 +46,7 @@ const FastScroll = React.forwardRef((props: FastScrollProps, ref) => {
45
46
  const totalContentLength = contentLength + additionalLength;
46
47
 
47
48
  const onContentScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {
48
- if (isIndicatorDragging.current === false) {
49
+ if (!isIndicatorDragging.current) {
49
50
  const contentPercentage = offsetToPercentage(event.nativeEvent.contentOffset.y, totalContentLength);
50
51
  const offset = percentageToOffset(contentPercentage, movementRange);
51
52