@fountain-ui/lab 2.0.0-beta.43 → 2.0.0-beta.45

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.
@@ -88,6 +88,12 @@ function BottomSheet(props) {
88
88
  const backgroundStyle = {
89
89
  backgroundColor: theme.palette.paper.default
90
90
  };
91
+ const contentWrapperStyle = {
92
+ flex: 1,
93
+ borderTopLeftRadius: 15,
94
+ borderTopRightRadius: 15,
95
+ overflow: 'hidden'
96
+ };
91
97
  const isBackdropTransparent = backdropOpacity <= 0;
92
98
 
93
99
  const OpacityAwareBackdrop = props => /*#__PURE__*/_react.default.createElement(_bottomSheet.BottomSheetBackdrop, _extends({}, props, {
@@ -111,9 +117,12 @@ function BottomSheet(props) {
111
117
  enablePanDownToClose: Boolean(onChange),
112
118
  enableDynamicSizing: enableDynamicSizing,
113
119
  maxDynamicContentSize: maxDynamicContentSize
120
+ }, /*#__PURE__*/_react.default.createElement(_reactNative.View, {
121
+ style: contentWrapperStyle
114
122
  }, /*#__PURE__*/_react.default.createElement(_bottomSheet.BottomSheetScrollView, {
123
+ bounces: false,
115
124
  stickyHeaderIndices: header ? [0] : undefined
116
- }, header, children)));
125
+ }, header, children))));
117
126
  }
118
127
 
119
128
  ;
@@ -1 +1 @@
1
- {"version":3,"names":["NoHandle","BottomSheet","props","backdropOpacity","children","enableDynamicSizing","header","index","maxHeightNormalizedRatio","onChange","snapPoints","indexRef","React","useRef","bottomSheetRef","height","windowHeight","useWindowDimensions","maxDynamicContentSize","Math","round","handleChange","useCallback","newIndex","current","handleDismiss","useEffect","present","dismiss","snapToIndex","theme","useTheme","shadow","modalStyle","backgroundColor","Platform","select","android","elevation","ios","web","boxShadow","backgroundStyle","palette","paper","default","isBackdropTransparent","OpacityAwareBackdrop","TransparentBackdrop","Boolean","undefined"],"sources":["BottomSheetNative.tsx"],"sourcesContent":["import React from 'react';\nimport { Platform, useWindowDimensions } from 'react-native';\nimport { useTheme } from '@fountain-ui/styles';\nimport {\n BottomSheetBackdrop,\n BottomSheetBackdropProps,\n BottomSheetModal,\n BottomSheetModalProvider,\n BottomSheetScrollView,\n} from '@gorhom/bottom-sheet';\nimport type BottomSheetProps from './BottomSheetProps';\nimport TransparentBackdrop from './TransparentBackdrop';\n\nconst NoHandle = () => null;\n\nexport default function BottomSheet(props: BottomSheetProps) {\n const {\n backdropOpacity = 0.5,\n children,\n enableDynamicSizing = true,\n header,\n index,\n maxHeightNormalizedRatio = 0.9,\n onChange,\n snapPoints = [],\n } = props;\n\n const indexRef = React.useRef<number>(-1);\n const bottomSheetRef = React.useRef<BottomSheetModal | null>(null);\n\n const { height: windowHeight } = useWindowDimensions();\n const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio);\n\n const handleChange = React.useCallback((newIndex: number) => {\n indexRef.current = newIndex;\n\n if (onChange) {\n onChange(newIndex);\n }\n }, [onChange]);\n\n const handleDismiss = React.useCallback(() => {\n handleChange(-1);\n }, [handleChange]);\n\n React.useEffect(() => {\n if (index === indexRef.current) {\n return;\n }\n\n if (indexRef.current < 0 && index >= 0) {\n bottomSheetRef.current?.present();\n } else if (indexRef.current >= 0 && index < 0) {\n bottomSheetRef.current?.dismiss();\n } else {\n // @ts-ignore\n bottomSheetRef.current?.snapToIndex(index);\n }\n }, [index]);\n\n const theme = useTheme();\n const shadow = theme.shadow[12];\n const modalStyle = {\n backgroundColor: '#ffffff00',\n ...Platform.select<object>({\n android: shadow?.elevation,\n ios: shadow?.shadow,\n web: shadow?.boxShadow,\n }),\n };\n const backgroundStyle = {\n backgroundColor: theme.palette.paper.default,\n };\n\n const isBackdropTransparent = backdropOpacity <= 0;\n\n const OpacityAwareBackdrop = (props: BottomSheetBackdropProps) => (\n <BottomSheetBackdrop\n {...props}\n appearsOnIndex={0}\n disappearsOnIndex={-1}\n opacity={backdropOpacity}\n pressBehavior={onChange ? 'close' : 'none'}\n />\n );\n\n return (\n <BottomSheetModalProvider>\n <BottomSheetModal\n backdropComponent={isBackdropTransparent ? TransparentBackdrop : OpacityAwareBackdrop}\n // @ts-ignore\n backgroundStyle={backgroundStyle}\n index={index}\n handleComponent={NoHandle}\n onChange={handleChange}\n onDismiss={handleDismiss}\n ref={bottomSheetRef}\n snapPoints={snapPoints}\n style={modalStyle}\n enablePanDownToClose={Boolean(onChange)}\n enableDynamicSizing={enableDynamicSizing}\n maxDynamicContentSize={maxDynamicContentSize}\n >\n <BottomSheetScrollView stickyHeaderIndices={header ? [0] : undefined}>\n {header}\n\n {children}\n </BottomSheetScrollView>\n </BottomSheetModal>\n </BottomSheetModalProvider>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"names":["NoHandle","BottomSheet","props","backdropOpacity","children","enableDynamicSizing","header","index","maxHeightNormalizedRatio","onChange","snapPoints","indexRef","React","useRef","bottomSheetRef","height","windowHeight","useWindowDimensions","maxDynamicContentSize","Math","round","handleChange","useCallback","newIndex","current","handleDismiss","useEffect","present","dismiss","snapToIndex","theme","useTheme","shadow","modalStyle","backgroundColor","Platform","select","android","elevation","ios","web","boxShadow","backgroundStyle","palette","paper","default","contentWrapperStyle","flex","borderTopLeftRadius","borderTopRightRadius","overflow","isBackdropTransparent","OpacityAwareBackdrop","TransparentBackdrop","Boolean","undefined"],"sources":["BottomSheetNative.tsx"],"sourcesContent":["import React from 'react';\nimport { Platform, useWindowDimensions, View } from 'react-native';\nimport { useTheme } from '@fountain-ui/styles';\nimport {\n BottomSheetBackdrop,\n BottomSheetBackdropProps,\n BottomSheetModal,\n BottomSheetModalProvider,\n BottomSheetScrollView,\n} from '@gorhom/bottom-sheet';\nimport type BottomSheetProps from './BottomSheetProps';\nimport TransparentBackdrop from './TransparentBackdrop';\n\nconst NoHandle = () => null;\n\nexport default function BottomSheet(props: BottomSheetProps) {\n const {\n backdropOpacity = 0.5,\n children,\n enableDynamicSizing = true,\n header,\n index,\n maxHeightNormalizedRatio = 0.9,\n onChange,\n snapPoints = [],\n } = props;\n\n const indexRef = React.useRef<number>(-1);\n const bottomSheetRef = React.useRef<BottomSheetModal | null>(null);\n\n const { height: windowHeight } = useWindowDimensions();\n const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio);\n\n const handleChange = React.useCallback((newIndex: number) => {\n indexRef.current = newIndex;\n\n if (onChange) {\n onChange(newIndex);\n }\n }, [onChange]);\n\n const handleDismiss = React.useCallback(() => {\n handleChange(-1);\n }, [handleChange]);\n\n React.useEffect(() => {\n if (index === indexRef.current) {\n return;\n }\n\n if (indexRef.current < 0 && index >= 0) {\n bottomSheetRef.current?.present();\n } else if (indexRef.current >= 0 && index < 0) {\n bottomSheetRef.current?.dismiss();\n } else {\n // @ts-ignore\n bottomSheetRef.current?.snapToIndex(index);\n }\n }, [index]);\n\n const theme = useTheme();\n const shadow = theme.shadow[12];\n const modalStyle = {\n backgroundColor: '#ffffff00',\n ...Platform.select<object>({\n android: shadow?.elevation,\n ios: shadow?.shadow,\n web: shadow?.boxShadow,\n }),\n };\n const backgroundStyle = {\n backgroundColor: theme.palette.paper.default,\n };\n const contentWrapperStyle = {\n flex: 1,\n borderTopLeftRadius: 15,\n borderTopRightRadius: 15,\n overflow: 'hidden',\n };\n\n const isBackdropTransparent = backdropOpacity <= 0;\n\n const OpacityAwareBackdrop = (props: BottomSheetBackdropProps) => (\n <BottomSheetBackdrop\n {...props}\n appearsOnIndex={0}\n disappearsOnIndex={-1}\n opacity={backdropOpacity}\n pressBehavior={onChange ? 'close' : 'none'}\n />\n );\n\n return (\n <BottomSheetModalProvider>\n <BottomSheetModal\n backdropComponent={isBackdropTransparent ? TransparentBackdrop : OpacityAwareBackdrop}\n // @ts-ignore\n backgroundStyle={backgroundStyle}\n index={index}\n handleComponent={NoHandle}\n onChange={handleChange}\n onDismiss={handleDismiss}\n ref={bottomSheetRef}\n snapPoints={snapPoints}\n style={modalStyle}\n enablePanDownToClose={Boolean(onChange)}\n enableDynamicSizing={enableDynamicSizing}\n maxDynamicContentSize={maxDynamicContentSize}\n >\n {/* @ts-ignore */}\n <View style={contentWrapperStyle}>\n <BottomSheetScrollView\n bounces={false}\n stickyHeaderIndices={header ? [0] : undefined}\n >\n {header}\n\n {children}\n </BottomSheetScrollView>\n </View>\n </BottomSheetModal>\n </BottomSheetModalProvider>\n );\n};\n"],"mappings":"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"}
@@ -46,6 +46,7 @@ const mapImageStateToItemState = (index, imageState, autoHandleErrorCount) => {
46
46
  };
47
47
  };
48
48
 
49
+ const mapIndexed = R.addIndex(R.map);
49
50
  const MAXIMUM_WIDTH = 720;
50
51
  const NUMBER_OF_ADJACENT_ITEM = 5;
51
52
 
@@ -61,6 +62,7 @@ function ComicViewer(props) {
61
62
  maxContentWidth = MAXIMUM_WIDTH,
62
63
  onItemPress,
63
64
  viewportWidth,
65
+ invisiblePaddingTop = 0,
64
66
  windowSize = 3,
65
67
  ...otherProps
66
68
  } = props;
@@ -78,9 +80,9 @@ function ComicViewer(props) {
78
80
  return mapImageStatesToItemStates(imageStatesRef.current);
79
81
  });
80
82
  const renderedDimensions = (0, _react.useMemo)(() => {
81
- return R.map(intrinsicDimension => ({
83
+ return mapIndexed((intrinsicDimension, index) => ({
82
84
  width: actualImageWidth,
83
- height: intrinsicDimension.height * actualImageWidth / intrinsicDimension.width
85
+ height: intrinsicDimension.height * actualImageWidth / intrinsicDimension.width + (index === 0 ? invisiblePaddingTop : 0)
84
86
  }), intrinsicDimensions);
85
87
  }, [actualImageWidth]);
86
88
  const layoutFromDimensions = (0, _react.useCallback)(() => {
@@ -122,7 +124,7 @@ function ComicViewer(props) {
122
124
  var _state$urlState;
123
125
 
124
126
  const state = imageStatesRef.current[index];
125
- return R.isNil(state.urlState) || ((_state$urlState = state.urlState) === null || _state$urlState === void 0 ? void 0 : _state$urlState.validity) === 'invalid' && !state.isNewUrlIncoming;
127
+ return !state.isNewUrlIncoming && (R.isNil(state.urlState) || ((_state$urlState = state.urlState) === null || _state$urlState === void 0 ? void 0 : _state$urlState.validity) === 'invalid');
126
128
  }, indexes);
127
129
  updateImageState((imageState, i) => {
128
130
  return R.includes(i, filteredIndexes) ? { ...imageState,
@@ -147,6 +149,7 @@ function ComicViewer(props) {
147
149
 
148
150
  return imageState;
149
151
  });
152
+ } catch (e) {// ignore
150
153
  } finally {
151
154
  updateImageState((imageState, i) => {
152
155
  return R.includes(i, filteredIndexes) ? { ...imageState,
@@ -156,12 +159,13 @@ function ComicViewer(props) {
156
159
  }
157
160
  };
158
161
 
159
- const loadMaybeLoadableItems = async () => {
162
+ const loadMaybeLoadableItems = () => {
160
163
  const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;
161
164
  const affectedIndexes = R.range(startIndex, endIndex);
162
- await loadUrlByIndex(affectedIndexes);
165
+ loadUrlByIndex(affectedIndexes);
163
166
  };
164
167
 
168
+ const ignoreDebounce = (0, _react.useRef)(true);
165
169
  const loadItemsDebounce = (0, _core.useDebounce)(loadMaybeLoadableItems, debounceMillis);
166
170
  const onViewableItemsChanged = (0, _react.useRef)(_ref => {
167
171
  var _R$head, _R$last;
@@ -180,6 +184,13 @@ function ComicViewer(props) {
180
184
  const startIndex = R.max(firstViewableIndex - NUMBER_OF_ADJACENT_ITEM, 0);
181
185
  const endIndex = R.min(lastViewableItemIndex + NUMBER_OF_ADJACENT_ITEM, itemStates.length - 1);
182
186
  maybeLoadableItemsIndexRange.current = [startIndex, endIndex + 1];
187
+
188
+ if (ignoreDebounce.current) {
189
+ loadMaybeLoadableItems();
190
+ ignoreDebounce.current = false;
191
+ return;
192
+ }
193
+
183
194
  loadItemsDebounce();
184
195
  });
185
196
  const renderItem = (0, _react.useCallback)(_ref2 => {
@@ -247,6 +258,7 @@ function ComicViewer(props) {
247
258
  onPress: onItemPress,
248
259
  onReloadPress: onReloadPress,
249
260
  url: item.url,
261
+ invisiblePaddingTop: index === 0 ? invisiblePaddingTop : 0,
250
262
  width: ((_renderedDimensions$i = renderedDimensions[index]) === null || _renderedDimensions$i === void 0 ? void 0 : _renderedDimensions$i.width) ?? 0,
251
263
  height: ((_renderedDimensions$i2 = renderedDimensions[index]) === null || _renderedDimensions$i2 === void 0 ? void 0 : _renderedDimensions$i2.height) ?? 0,
252
264
  reloadButtonVisible: item.reloadButtonVisible
@@ -1 +1 @@
1
- {"version":3,"names":["appender","left","right","getHeightAccum","heights","R","mapAccum","keyExtractor","item","String","index","createInitialImageState","dimension","isNewUrlIncoming","totalErrorCount","mapImageStateToItemState","imageState","autoHandleErrorCount","url","urlState","reloadButtonVisible","validity","MAXIMUM_WIDTH","NUMBER_OF_ADJACENT_ITEM","ComicViewer","props","debounceMillis","getUrlByIndex","initialNumToRender","initialScrollPercentage","itemVisiblePercentThreshold","intrinsicDimensions","maxContentWidth","onItemPress","viewportWidth","windowSize","otherProps","flatListRef","useRef","maybeLoadableItemsIndexRange","actualImageWidth","Math","min","initialImageStates","useMemo","map","imageStatesRef","mapImageStatesToItemStates","imageStates","image","itemStates","setItemStates","useState","current","renderedDimensions","intrinsicDimension","width","height","layoutFromDimensions","useCallback","itemHeights","totalHeight","heightAccum","itemOffsets","prepend","getItemLayout","data","length","offset","viewabilityConfig","updateImageState","updateFunction","prevImageStates","newImageStates","prevItemStates","newItemStates","equals","loadUrlByIndex","indexes","filteredIndexes","filter","state","isNil","i","includes","urls","newUrl","get","undefined","loadMaybeLoadableItems","startIndex","endIndex","affectedIndexes","range","loadItemsDebounce","useDebounce","onViewableItemsChanged","viewableItems","orderedViewableItems","sort","a","b","firstViewableIndex","head","lastViewableItemIndex","last","max","renderItem","onError","onReloadPress","onLoad","useEffect","floor","scrollToOffset","animated"],"sources":["ComicViewer.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { FlatList, ListRenderItem, ViewToken } from 'react-native';\nimport * as R from 'ramda';\nimport { useDebounce } from '@fountain-ui/core';\nimport { default as ComicViewerProps, Dimension } from './ComicViewerProps';\nimport ViewerItem from './ViewerItem';\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 isNewUrlIncoming: boolean;\n totalErrorCount: number;\n dimension: Dimension;\n}\n\ninterface ItemState {\n index: number;\n url?: string;\n reloadButtonVisible: boolean;\n dimension: Dimension;\n}\n\nconst createInitialImageState = (dimension: Dimension): ImageState => ({\n isNewUrlIncoming: false,\n totalErrorCount: 0,\n dimension,\n});\n\nconst mapImageStateToItemState = (\n index: number,\n imageState: ImageState,\n autoHandleErrorCount: number,\n): ItemState => ({\n index,\n url: imageState.urlState?.url,\n reloadButtonVisible: (imageState.urlState?.validity !== 'valid') && imageState.totalErrorCount >= autoHandleErrorCount,\n dimension: imageState.dimension,\n});\n\nconst MAXIMUM_WIDTH = 720;\n\nconst NUMBER_OF_ADJACENT_ITEM = 5;\n\nexport default function ComicViewer(props: ComicViewerProps) {\n const {\n debounceMillis = 100,\n autoHandleErrorCount = 3,\n getUrlByIndex,\n initialNumToRender = 1,\n initialScrollPercentage = 0,\n itemVisiblePercentThreshold = 0,\n intrinsicDimensions,\n maxContentWidth = MAXIMUM_WIDTH,\n onItemPress,\n viewportWidth,\n windowSize = 3,\n ...otherProps\n } = props;\n\n const flatListRef = useRef<FlatList>(null);\n\n const maybeLoadableItemsIndexRange = useRef<[number, number]>([-1, 0]);\n\n const actualImageWidth = Math.min(viewportWidth, maxContentWidth);\n\n const initialImageStates = useMemo<Array<ImageState>>(() => R.map(createInitialImageState, intrinsicDimensions), []);\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 R.map(intrinsicDimension => ({\n width: actualImageWidth,\n height: (intrinsicDimension.height * actualImageWidth) / intrinsicDimension.width,\n }), intrinsicDimensions);\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 loadUrlByIndex = async (indexes: number[]) => {\n const filteredIndexes = R.filter(index => {\n const state = imageStatesRef.current[index];\n\n return R.isNil(state.urlState)\n || (state.urlState?.validity === 'invalid' && !state.isNewUrlIncoming);\n }, indexes);\n\n updateImageState((imageState, i) => {\n return R.includes(i, filteredIndexes)\n ? { ...imageState, isNewUrlIncoming: true }\n : imageState;\n });\n\n try {\n const urls = await getUrlByIndex(filteredIndexes);\n\n updateImageState((imageState, i) => {\n const newUrl = urls?.get(i);\n const urlState = imageState.urlState;\n\n if (newUrl !== undefined && urlState?.validity !== 'valid') {\n return {\n ...imageState,\n urlState: {\n url: newUrl,\n validity: 'unknown',\n },\n };\n }\n\n return imageState;\n });\n } finally {\n updateImageState((imageState, i) => {\n return R.includes(i, filteredIndexes)\n ? { ...imageState, isNewUrlIncoming: false }\n : imageState;\n });\n }\n };\n\n const loadMaybeLoadableItems = async () => {\n const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n const affectedIndexes = R.range(startIndex, endIndex);\n\n await loadUrlByIndex(affectedIndexes);\n };\n\n const loadItemsDebounce = useDebounce(loadMaybeLoadableItems, debounceMillis);\n\n const onViewableItemsChanged = useRef(({ viewableItems }: { viewableItems: Array<ViewToken> }) => {\n const orderedViewableItems = R.sort((a, b) => (a.index || 0) - (b.index || 0), viewableItems);\n\n const firstViewableIndex = R.head(orderedViewableItems)?.index;\n const lastViewableItemIndex = R.last(orderedViewableItems)?.index;\n\n if (R.isNil(firstViewableIndex) || R.isNil(lastViewableItemIndex)) {\n return;\n }\n\n const startIndex = R.max(firstViewableIndex - NUMBER_OF_ADJACENT_ITEM, 0);\n const endIndex = R.min(lastViewableItemIndex + NUMBER_OF_ADJACENT_ITEM, itemStates.length - 1);\n\n maybeLoadableItemsIndexRange.current = [startIndex, endIndex + 1];\n\n loadItemsDebounce();\n });\n\n const renderItem: ListRenderItem<ItemState> = useCallback(({ item, index }) => {\n const onError = () => {\n updateImageState((imageState, i) => {\n const urlState = imageState.urlState;\n\n if (i === index && urlState !== undefined) {\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 const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n if (index >= startIndex || index < endIndex) {\n loadItemsDebounce();\n }\n };\n\n const onReloadPress = () => {\n const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n if (index >= startIndex || index < endIndex) {\n loadUrlByIndex([index]);\n }\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={onError}\n onLoad={onLoad}\n onPress={onItemPress}\n onReloadPress={onReloadPress}\n url={item.url}\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 <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 {...otherProps}\n />\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"names":["appender","left","right","getHeightAccum","heights","R","mapAccum","keyExtractor","item","String","index","createInitialImageState","dimension","isNewUrlIncoming","totalErrorCount","mapImageStateToItemState","imageState","autoHandleErrorCount","url","urlState","reloadButtonVisible","validity","mapIndexed","addIndex","map","MAXIMUM_WIDTH","NUMBER_OF_ADJACENT_ITEM","ComicViewer","props","debounceMillis","getUrlByIndex","initialNumToRender","initialScrollPercentage","itemVisiblePercentThreshold","intrinsicDimensions","maxContentWidth","onItemPress","viewportWidth","invisiblePaddingTop","windowSize","otherProps","flatListRef","useRef","maybeLoadableItemsIndexRange","actualImageWidth","Math","min","initialImageStates","useMemo","imageStatesRef","mapImageStatesToItemStates","imageStates","image","itemStates","setItemStates","useState","current","renderedDimensions","intrinsicDimension","width","height","layoutFromDimensions","useCallback","itemHeights","totalHeight","heightAccum","itemOffsets","prepend","getItemLayout","data","length","offset","viewabilityConfig","updateImageState","updateFunction","prevImageStates","newImageStates","prevItemStates","newItemStates","equals","loadUrlByIndex","indexes","filteredIndexes","filter","state","isNil","i","includes","urls","newUrl","get","undefined","e","loadMaybeLoadableItems","startIndex","endIndex","affectedIndexes","range","ignoreDebounce","loadItemsDebounce","useDebounce","onViewableItemsChanged","viewableItems","orderedViewableItems","sort","a","b","firstViewableIndex","head","lastViewableItemIndex","last","max","renderItem","onError","onReloadPress","onLoad","useEffect","floor","scrollToOffset","animated"],"sources":["ComicViewer.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { FlatList, ListRenderItem, ViewToken } from 'react-native';\nimport * as R from 'ramda';\nimport { useDebounce } from '@fountain-ui/core';\nimport { default as ComicViewerProps, Dimension } from './ComicViewerProps';\nimport ViewerItem from './ViewerItem';\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 isNewUrlIncoming: boolean;\n totalErrorCount: number;\n dimension: Dimension;\n}\n\ninterface ItemState {\n index: number;\n url?: string;\n reloadButtonVisible: boolean;\n dimension: Dimension;\n}\n\nconst createInitialImageState = (dimension: Dimension): ImageState => ({\n isNewUrlIncoming: false,\n totalErrorCount: 0,\n dimension,\n});\n\nconst mapImageStateToItemState = (\n index: number,\n imageState: ImageState,\n autoHandleErrorCount: number,\n): ItemState => ({\n index,\n url: imageState.urlState?.url,\n reloadButtonVisible: (imageState.urlState?.validity !== 'valid') && imageState.totalErrorCount >= autoHandleErrorCount,\n dimension: imageState.dimension,\n});\n\nconst mapIndexed = R.addIndex<Dimension>(R.map);\n\nconst MAXIMUM_WIDTH = 720;\n\nconst NUMBER_OF_ADJACENT_ITEM = 5;\n\nexport default function ComicViewer(props: ComicViewerProps) {\n const {\n debounceMillis = 100,\n autoHandleErrorCount = 3,\n getUrlByIndex,\n initialNumToRender = 1,\n initialScrollPercentage = 0,\n itemVisiblePercentThreshold = 0,\n intrinsicDimensions,\n maxContentWidth = MAXIMUM_WIDTH,\n onItemPress,\n viewportWidth,\n invisiblePaddingTop = 0,\n windowSize = 3,\n ...otherProps\n } = props;\n\n const flatListRef = useRef<FlatList>(null);\n\n const maybeLoadableItemsIndexRange = useRef<[number, number]>([-1, 0]);\n\n const actualImageWidth = Math.min(viewportWidth, maxContentWidth);\n\n const initialImageStates = useMemo<Array<ImageState>>(() => R.map(createInitialImageState, intrinsicDimensions), []);\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((intrinsicDimension, index) => ({\n width: actualImageWidth,\n height: (intrinsicDimension.height * actualImageWidth) / intrinsicDimension.width + (index === 0 ? invisiblePaddingTop : 0),\n }), intrinsicDimensions);\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 loadUrlByIndex = async (indexes: number[]) => {\n const filteredIndexes = R.filter(index => {\n const state = imageStatesRef.current[index];\n\n return !state.isNewUrlIncoming\n && (R.isNil(state.urlState) || state.urlState?.validity === 'invalid');\n }, indexes);\n\n updateImageState((imageState, i) => {\n return R.includes(i, filteredIndexes)\n ? { ...imageState, isNewUrlIncoming: true }\n : imageState;\n });\n\n try {\n const urls = await getUrlByIndex(filteredIndexes);\n\n updateImageState((imageState, i) => {\n const newUrl = urls?.get(i);\n const urlState = imageState.urlState;\n\n if (newUrl !== undefined && urlState?.validity !== 'valid') {\n return {\n ...imageState,\n urlState: {\n url: newUrl,\n validity: 'unknown',\n },\n };\n }\n\n return imageState;\n });\n } catch (e) {\n // ignore\n } finally {\n updateImageState((imageState, i) => {\n return R.includes(i, filteredIndexes)\n ? { ...imageState, isNewUrlIncoming: false }\n : imageState;\n });\n }\n };\n\n const loadMaybeLoadableItems = () => {\n const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n const affectedIndexes = R.range(startIndex, endIndex);\n\n loadUrlByIndex(affectedIndexes);\n };\n\n const ignoreDebounce = useRef(true);\n const loadItemsDebounce = useDebounce(loadMaybeLoadableItems, debounceMillis);\n\n const onViewableItemsChanged = useRef(({ viewableItems }: { viewableItems: Array<ViewToken> }) => {\n const orderedViewableItems = R.sort((a, b) => (a.index || 0) - (b.index || 0), viewableItems);\n\n const firstViewableIndex = R.head(orderedViewableItems)?.index;\n const lastViewableItemIndex = R.last(orderedViewableItems)?.index;\n\n if (R.isNil(firstViewableIndex) || R.isNil(lastViewableItemIndex)) {\n return;\n }\n\n const startIndex = R.max(firstViewableIndex - NUMBER_OF_ADJACENT_ITEM, 0);\n const endIndex = R.min(lastViewableItemIndex + NUMBER_OF_ADJACENT_ITEM, itemStates.length - 1);\n\n maybeLoadableItemsIndexRange.current = [startIndex, endIndex + 1];\n\n if (ignoreDebounce.current) {\n loadMaybeLoadableItems();\n\n ignoreDebounce.current = false;\n return;\n }\n\n loadItemsDebounce();\n });\n\n const renderItem: ListRenderItem<ItemState> = useCallback(({ item, index }) => {\n const onError = () => {\n updateImageState((imageState, i) => {\n const urlState = imageState.urlState;\n\n if (i === index && urlState !== undefined) {\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 const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n if (index >= startIndex || index < endIndex) {\n loadItemsDebounce();\n }\n };\n\n const onReloadPress = () => {\n const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n if (index >= startIndex || index < endIndex) {\n loadUrlByIndex([index]);\n }\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={onError}\n onLoad={onLoad}\n onPress={onItemPress}\n onReloadPress={onReloadPress}\n url={item.url}\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 <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 {...otherProps}\n />\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["ComicViewerProps.ts"],"sourcesContent":["import React from 'react';\nimport { ComponentProps } from '@fountain-ui/core';\nimport { NativeScrollEvent, NativeSyntheticEvent } from 'react-native';\n\nexport interface Dimension {\n width: number;\n height: number;\n}\n\nexport default interface ComicViewerProps extends ComponentProps <{\n /**\n * Delay Time to call the error handler.\n * @default 100\n */\n debounceMillis?: number;\n\n /**\n * How many times handle onError directly when item error occur\n * @default 3\n */\n autoHandleErrorCount?: number;\n\n /**\n * How many items to render in the initial batch.\n * @default 1\n */\n initialNumToRender?: number;\n\n /**\n * Start at initialScrollPercentage.\n * If over 100, scroll to end.\n * @default 0\n */\n initialScrollPercentage?: number;\n\n /**\n * The value for FlatList viewabilityConfig.itemVisiblePercentThreshold.\n * @default 0\n */\n itemVisiblePercentThreshold?: number;\n\n /**\n * Dimensions of each Image considering viewport.\n */\n intrinsicDimensions: Array<Dimension>;\n\n /**\n * Max value of contents image width size.\n * @default 720\n */\n maxContentWidth?: number;\n\n /**\n * Width of viewport.\n */\n viewportWidth: number;\n\n /**\n * The value for FlatList windowSize.\n * @default 3\n */\n windowSize?: number;\n\n /**\n * Get contents urls by indexes.\n */\n getUrlByIndex: (indexes: Array<number>) => Promise<Map<number, string> | undefined> ;\n\n /**\n * Handle scroll event.\n * @param event Scroll event.\n */\n onScroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;\n\n /**\n * Handle item press event.\n */\n onItemPress?: () => void;\n\n /**\n * Component for comic viewer footer.\n */\n ListFooterComponent?: React.ReactElement;\n}> {}\n"],"mappings":""}
1
+ {"version":3,"names":[],"sources":["ComicViewerProps.ts"],"sourcesContent":["import React from 'react';\nimport { ComponentProps } from '@fountain-ui/core';\nimport { NativeScrollEvent, NativeSyntheticEvent } from 'react-native';\n\nexport interface Dimension {\n width: number;\n height: number;\n}\n\nexport default interface ComicViewerProps extends ComponentProps <{\n /**\n * Delay Time to call the error handler.\n * @default 100\n */\n debounceMillis?: number;\n\n /**\n * How many times handle onError directly when item error occur\n * @default 3\n */\n autoHandleErrorCount?: number;\n\n /**\n * How many items to render in the initial batch.\n * @default 1\n */\n initialNumToRender?: number;\n\n /**\n * Start at initialScrollPercentage.\n * If over 100, scroll to end.\n * @default 0\n */\n initialScrollPercentage?: number;\n\n /**\n * The value for FlatList viewabilityConfig.itemVisiblePercentThreshold.\n * @default 0\n */\n itemVisiblePercentThreshold?: number;\n\n /**\n * Dimensions of each Image considering viewport.\n */\n intrinsicDimensions: Array<Dimension>;\n\n /**\n * Need invisible paddingTop viewer vertically expanded.\n * @default 0\n */\n invisiblePaddingTop?: number;\n\n /**\n * Max value of contents image width size.\n * @default 720\n */\n maxContentWidth?: number;\n\n /**\n * Width of viewport.\n */\n viewportWidth: number;\n\n /**\n * The value for FlatList windowSize.\n * @default 3\n */\n windowSize?: number;\n\n /**\n * Get contents urls by indexes.\n */\n getUrlByIndex: (indexes: Array<number>) => Promise<Map<number, string> | undefined> ;\n\n /**\n * Handle scroll event.\n * @param event Scroll event.\n */\n onScroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;\n\n /**\n * Handle item press event.\n */\n onItemPress?: () => void;\n\n /**\n * Component for comic viewer footer.\n */\n ListFooterComponent?: React.ReactElement;\n}> {}\n"],"mappings":""}
@@ -22,6 +22,7 @@ function ViewerItem(props) {
22
22
  height,
23
23
  url,
24
24
  width,
25
+ invisiblePaddingTop,
25
26
  onError,
26
27
  onLoad,
27
28
  onPress,
@@ -31,10 +32,11 @@ function ViewerItem(props) {
31
32
  const styles = {
32
33
  view: {
33
34
  height,
34
- width: '100%'
35
+ width: '100%',
36
+ paddingTop: invisiblePaddingTop
35
37
  },
36
38
  image: {
37
- height,
39
+ height: height - invisiblePaddingTop,
38
40
  width
39
41
  }
40
42
  };
@@ -1 +1 @@
1
- {"version":3,"names":["ViewerItem","props","height","url","width","onError","onLoad","onPress","onReloadPress","reloadButtonVisible","styles","view","image","error","placeholder","uri","EncodedTile","css","alignSelf"],"sources":["ViewerItem.tsx"],"sourcesContent":["import React from 'react';\nimport { Image, TouchableWithoutFeedback, View } from 'react-native';\nimport { css, Image as FuiImage, ImageProps } from '@fountain-ui/core';\nimport ReloadButton from './ReloadButton';\nimport EncodedTile from './EncodedTile';\n\nexport interface ViewerItemProps {\n /**\n * Image width.\n */\n width: number;\n\n /**\n * Image height.\n */\n height: number;\n\n /**\n * Image sourceUrl for displaying.\n */\n url?: string;\n\n /**\n * Error handler.\n */\n onError?: ImageProps['onError'];\n\n /**\n * Load handler.\n */\n onLoad?: ImageProps['onLoad'];\n\n /**\n * Handle Reload button press event.\n */\n onReloadPress?: ImageProps['onError'];\n\n /**\n * Handle item press event.\n */\n onPress?: () => void;\n\n /**\n * If true, reload button visible.\n * @default false\n */\n reloadButtonVisible?: boolean;\n}\n\nexport default function ViewerItem(props: ViewerItemProps) {\n const {\n height,\n url,\n width,\n onError,\n onLoad,\n onPress,\n onReloadPress,\n reloadButtonVisible = false,\n } = props;\n\n const styles = {\n view: {\n height,\n width: '100%',\n },\n image: {\n height,\n width,\n },\n };\n\n const error = reloadButtonVisible ? <ReloadButton onPress={onReloadPress}/> : null;\n\n const placeholder = <Image\n source={{ uri: EncodedTile }}\n resizeMode={'cover'}\n style={styles.image}\n />;\n\n return (\n <TouchableWithoutFeedback onPress={onPress}>\n <View style={styles.view}>\n <FuiImage\n cache={'web'}\n disableDrag={true}\n disableLongClick={true}\n disableOutline={true}\n error={error}\n onError={onError}\n onLoad={onLoad}\n loading={'eager'}\n placeholder={placeholder}\n source={{ uri: url }}\n square={true}\n style={css([\n { alignSelf: 'center' },\n styles.image,\n ])}\n />\n </View>\n </TouchableWithoutFeedback>\n );\n};\n"],"mappings":";;;;;;;AAAA;;AACA;;AACA;;AACA;;AACA;;;;AA6Ce,SAASA,UAAT,CAAoBC,KAApB,EAA4C;EACvD,MAAM;IACFC,MADE;IAEFC,GAFE;IAGFC,KAHE;IAIFC,OAJE;IAKFC,MALE;IAMFC,OANE;IAOFC,aAPE;IAQFC,mBAAmB,GAAG;EARpB,IASFR,KATJ;EAWA,MAAMS,MAAM,GAAG;IACXC,IAAI,EAAE;MACFT,MADE;MAEFE,KAAK,EAAE;IAFL,CADK;IAKXQ,KAAK,EAAE;MACHV,MADG;MAEHE;IAFG;EALI,CAAf;EAWA,MAAMS,KAAK,GAAGJ,mBAAmB,gBAAG,6BAAC,qBAAD;IAAc,OAAO,EAAED;EAAvB,EAAH,GAA6C,IAA9E;;EAEA,MAAMM,WAAW,gBAAG,6BAAC,kBAAD;IAChB,MAAM,EAAE;MAAEC,GAAG,EAAEC;IAAP,CADQ;IAEhB,UAAU,EAAE,OAFI;IAGhB,KAAK,EAAEN,MAAM,CAACE;EAHE,EAApB;;EAMA,oBACI,6BAAC,qCAAD;IAA0B,OAAO,EAAEL;EAAnC,gBACI,6BAAC,iBAAD;IAAM,KAAK,EAAEG,MAAM,CAACC;EAApB,gBACI,6BAAC,WAAD;IACI,KAAK,EAAE,KADX;IAEI,WAAW,EAAE,IAFjB;IAGI,gBAAgB,EAAE,IAHtB;IAII,cAAc,EAAE,IAJpB;IAKI,KAAK,EAAEE,KALX;IAMI,OAAO,EAAER,OANb;IAOI,MAAM,EAAEC,MAPZ;IAQI,OAAO,EAAE,OARb;IASI,WAAW,EAAEQ,WATjB;IAUI,MAAM,EAAE;MAAEC,GAAG,EAAEZ;IAAP,CAVZ;IAWI,MAAM,EAAE,IAXZ;IAYI,KAAK,EAAE,IAAAc,SAAA,EAAI,CACP;MAAEC,SAAS,EAAE;IAAb,CADO,EAEPR,MAAM,CAACE,KAFA,CAAJ;EAZX,EADJ,CADJ,CADJ;AAuBH;;AAAA"}
1
+ {"version":3,"names":["ViewerItem","props","height","url","width","invisiblePaddingTop","onError","onLoad","onPress","onReloadPress","reloadButtonVisible","styles","view","paddingTop","image","error","placeholder","uri","EncodedTile","css","alignSelf"],"sources":["ViewerItem.tsx"],"sourcesContent":["import React from 'react';\nimport { Image, TouchableWithoutFeedback, View } from 'react-native';\nimport { css, Image as FuiImage, ImageProps } from '@fountain-ui/core';\nimport ReloadButton from './ReloadButton';\nimport EncodedTile from './EncodedTile';\n\nexport interface ViewerItemProps {\n /**\n * Image width.\n */\n width: number;\n\n /**\n * Image height.\n */\n height: number;\n\n /**\n * Need invisible paddingTop viewer vertically expanded.\n */\n invisiblePaddingTop: number;\n\n /**\n * Image sourceUrl for displaying.\n */\n url?: string;\n\n /**\n * Error handler.\n */\n onError?: ImageProps['onError'];\n\n /**\n * Load handler.\n */\n onLoad?: ImageProps['onLoad'];\n\n /**\n * Handle Reload button press event.\n */\n onReloadPress?: ImageProps['onError'];\n\n /**\n * Handle item press event.\n */\n onPress?: () => void;\n\n /**\n * If true, reload button visible.\n * @default false\n */\n reloadButtonVisible?: boolean;\n}\n\nexport default function ViewerItem(props: ViewerItemProps) {\n const {\n height,\n url,\n width,\n invisiblePaddingTop,\n onError,\n onLoad,\n onPress,\n onReloadPress,\n reloadButtonVisible = false,\n } = props;\n\n const styles = {\n view: {\n height,\n width: '100%',\n paddingTop: invisiblePaddingTop,\n },\n image: {\n height: height - invisiblePaddingTop,\n width,\n },\n };\n\n const error = reloadButtonVisible ? <ReloadButton onPress={onReloadPress}/> : null;\n\n const placeholder = <Image\n source={{ uri: EncodedTile }}\n resizeMode={'cover'}\n style={styles.image}\n />;\n\n return (\n <TouchableWithoutFeedback onPress={onPress}>\n <View style={styles.view}>\n <FuiImage\n cache={'web'}\n disableDrag={true}\n disableLongClick={true}\n disableOutline={true}\n error={error}\n onError={onError}\n onLoad={onLoad}\n loading={'eager'}\n placeholder={placeholder}\n source={{ uri: url }}\n square={true}\n style={css([\n { alignSelf: 'center' },\n styles.image,\n ])}\n />\n </View>\n </TouchableWithoutFeedback>\n );\n};\n"],"mappings":";;;;;;;AAAA;;AACA;;AACA;;AACA;;AACA;;;;AAkDe,SAASA,UAAT,CAAoBC,KAApB,EAA4C;EACvD,MAAM;IACFC,MADE;IAEFC,GAFE;IAGFC,KAHE;IAIFC,mBAJE;IAKFC,OALE;IAMFC,MANE;IAOFC,OAPE;IAQFC,aARE;IASFC,mBAAmB,GAAG;EATpB,IAUFT,KAVJ;EAYA,MAAMU,MAAM,GAAG;IACXC,IAAI,EAAE;MACFV,MADE;MAEFE,KAAK,EAAE,MAFL;MAGFS,UAAU,EAAER;IAHV,CADK;IAMXS,KAAK,EAAE;MACHZ,MAAM,EAAEA,MAAM,GAAGG,mBADd;MAEHD;IAFG;EANI,CAAf;EAYA,MAAMW,KAAK,GAAGL,mBAAmB,gBAAG,6BAAC,qBAAD;IAAc,OAAO,EAAED;EAAvB,EAAH,GAA6C,IAA9E;;EAEA,MAAMO,WAAW,gBAAG,6BAAC,kBAAD;IAChB,MAAM,EAAE;MAAEC,GAAG,EAAEC;IAAP,CADQ;IAEhB,UAAU,EAAE,OAFI;IAGhB,KAAK,EAAEP,MAAM,CAACG;EAHE,EAApB;;EAMA,oBACI,6BAAC,qCAAD;IAA0B,OAAO,EAAEN;EAAnC,gBACI,6BAAC,iBAAD;IAAM,KAAK,EAAEG,MAAM,CAACC;EAApB,gBACI,6BAAC,WAAD;IACI,KAAK,EAAE,KADX;IAEI,WAAW,EAAE,IAFjB;IAGI,gBAAgB,EAAE,IAHtB;IAII,cAAc,EAAE,IAJpB;IAKI,KAAK,EAAEG,KALX;IAMI,OAAO,EAAET,OANb;IAOI,MAAM,EAAEC,MAPZ;IAQI,OAAO,EAAE,OARb;IASI,WAAW,EAAES,WATjB;IAUI,MAAM,EAAE;MAAEC,GAAG,EAAEd;IAAP,CAVZ;IAWI,MAAM,EAAE,IAXZ;IAYI,KAAK,EAAE,IAAAgB,SAAA,EAAI,CACP;MAAEC,SAAS,EAAE;IAAb,CADO,EAEPT,MAAM,CAACG,KAFA,CAAJ;EAZX,EADJ,CADJ,CADJ;AAuBH;;AAAA"}
@@ -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 from 'react';
4
- import { Platform, useWindowDimensions } from 'react-native';
4
+ import { Platform, useWindowDimensions, View } from 'react-native';
5
5
  import { useTheme } from '@fountain-ui/styles';
6
6
  import { BottomSheetBackdrop, BottomSheetModal, BottomSheetModalProvider, BottomSheetScrollView } from '@gorhom/bottom-sheet';
7
7
  import TransparentBackdrop from './TransparentBackdrop';
@@ -68,6 +68,12 @@ export default function BottomSheet(props) {
68
68
  const backgroundStyle = {
69
69
  backgroundColor: theme.palette.paper.default
70
70
  };
71
+ const contentWrapperStyle = {
72
+ flex: 1,
73
+ borderTopLeftRadius: 15,
74
+ borderTopRightRadius: 15,
75
+ overflow: 'hidden'
76
+ };
71
77
  const isBackdropTransparent = backdropOpacity <= 0;
72
78
 
73
79
  const OpacityAwareBackdrop = props => /*#__PURE__*/React.createElement(BottomSheetBackdrop, _extends({}, props, {
@@ -91,9 +97,12 @@ export default function BottomSheet(props) {
91
97
  enablePanDownToClose: Boolean(onChange),
92
98
  enableDynamicSizing: enableDynamicSizing,
93
99
  maxDynamicContentSize: maxDynamicContentSize
100
+ }, /*#__PURE__*/React.createElement(View, {
101
+ style: contentWrapperStyle
94
102
  }, /*#__PURE__*/React.createElement(BottomSheetScrollView, {
103
+ bounces: false,
95
104
  stickyHeaderIndices: header ? [0] : undefined
96
- }, header, children)));
105
+ }, header, children))));
97
106
  }
98
107
  ;
99
108
  //# sourceMappingURL=BottomSheetNative.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["React","Platform","useWindowDimensions","useTheme","BottomSheetBackdrop","BottomSheetModal","BottomSheetModalProvider","BottomSheetScrollView","TransparentBackdrop","NoHandle","BottomSheet","props","backdropOpacity","children","enableDynamicSizing","header","index","maxHeightNormalizedRatio","onChange","snapPoints","indexRef","useRef","bottomSheetRef","height","windowHeight","maxDynamicContentSize","Math","round","handleChange","useCallback","newIndex","current","handleDismiss","useEffect","present","dismiss","snapToIndex","theme","shadow","modalStyle","backgroundColor","select","android","elevation","ios","web","boxShadow","backgroundStyle","palette","paper","default","isBackdropTransparent","OpacityAwareBackdrop","Boolean","undefined"],"sources":["BottomSheetNative.tsx"],"sourcesContent":["import React from 'react';\nimport { Platform, useWindowDimensions } from 'react-native';\nimport { useTheme } from '@fountain-ui/styles';\nimport {\n BottomSheetBackdrop,\n BottomSheetBackdropProps,\n BottomSheetModal,\n BottomSheetModalProvider,\n BottomSheetScrollView,\n} from '@gorhom/bottom-sheet';\nimport type BottomSheetProps from './BottomSheetProps';\nimport TransparentBackdrop from './TransparentBackdrop';\n\nconst NoHandle = () => null;\n\nexport default function BottomSheet(props: BottomSheetProps) {\n const {\n backdropOpacity = 0.5,\n children,\n enableDynamicSizing = true,\n header,\n index,\n maxHeightNormalizedRatio = 0.9,\n onChange,\n snapPoints = [],\n } = props;\n\n const indexRef = React.useRef<number>(-1);\n const bottomSheetRef = React.useRef<BottomSheetModal | null>(null);\n\n const { height: windowHeight } = useWindowDimensions();\n const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio);\n\n const handleChange = React.useCallback((newIndex: number) => {\n indexRef.current = newIndex;\n\n if (onChange) {\n onChange(newIndex);\n }\n }, [onChange]);\n\n const handleDismiss = React.useCallback(() => {\n handleChange(-1);\n }, [handleChange]);\n\n React.useEffect(() => {\n if (index === indexRef.current) {\n return;\n }\n\n if (indexRef.current < 0 && index >= 0) {\n bottomSheetRef.current?.present();\n } else if (indexRef.current >= 0 && index < 0) {\n bottomSheetRef.current?.dismiss();\n } else {\n // @ts-ignore\n bottomSheetRef.current?.snapToIndex(index);\n }\n }, [index]);\n\n const theme = useTheme();\n const shadow = theme.shadow[12];\n const modalStyle = {\n backgroundColor: '#ffffff00',\n ...Platform.select<object>({\n android: shadow?.elevation,\n ios: shadow?.shadow,\n web: shadow?.boxShadow,\n }),\n };\n const backgroundStyle = {\n backgroundColor: theme.palette.paper.default,\n };\n\n const isBackdropTransparent = backdropOpacity <= 0;\n\n const OpacityAwareBackdrop = (props: BottomSheetBackdropProps) => (\n <BottomSheetBackdrop\n {...props}\n appearsOnIndex={0}\n disappearsOnIndex={-1}\n opacity={backdropOpacity}\n pressBehavior={onChange ? 'close' : 'none'}\n />\n );\n\n return (\n <BottomSheetModalProvider>\n <BottomSheetModal\n backdropComponent={isBackdropTransparent ? TransparentBackdrop : OpacityAwareBackdrop}\n // @ts-ignore\n backgroundStyle={backgroundStyle}\n index={index}\n handleComponent={NoHandle}\n onChange={handleChange}\n onDismiss={handleDismiss}\n ref={bottomSheetRef}\n snapPoints={snapPoints}\n style={modalStyle}\n enablePanDownToClose={Boolean(onChange)}\n enableDynamicSizing={enableDynamicSizing}\n maxDynamicContentSize={maxDynamicContentSize}\n >\n <BottomSheetScrollView stickyHeaderIndices={header ? [0] : undefined}>\n {header}\n\n {children}\n </BottomSheetScrollView>\n </BottomSheetModal>\n </BottomSheetModalProvider>\n );\n};\n"],"mappings":";;AAAA,OAAOA,KAAP,MAAkB,OAAlB;AACA,SAASC,QAAT,EAAmBC,mBAAnB,QAA8C,cAA9C;AACA,SAASC,QAAT,QAAyB,qBAAzB;AACA,SACIC,mBADJ,EAGIC,gBAHJ,EAIIC,wBAJJ,EAKIC,qBALJ,QAMO,sBANP;AAQA,OAAOC,mBAAP,MAAgC,uBAAhC;;AAEA,MAAMC,QAAQ,GAAG,MAAM,IAAvB;;AAEA,eAAe,SAASC,WAAT,CAAqBC,KAArB,EAA8C;EACzD,MAAM;IACFC,eAAe,GAAG,GADhB;IAEFC,QAFE;IAGFC,mBAAmB,GAAG,IAHpB;IAIFC,MAJE;IAKFC,KALE;IAMFC,wBAAwB,GAAG,GANzB;IAOFC,QAPE;IAQFC,UAAU,GAAG;EARX,IASFR,KATJ;EAWA,MAAMS,QAAQ,GAAGpB,KAAK,CAACqB,MAAN,CAAqB,CAAC,CAAtB,CAAjB;EACA,MAAMC,cAAc,GAAGtB,KAAK,CAACqB,MAAN,CAAsC,IAAtC,CAAvB;EAEA,MAAM;IAAEE,MAAM,EAAEC;EAAV,IAA2BtB,mBAAmB,EAApD;EACA,MAAMuB,qBAAqB,GAAGC,IAAI,CAACC,KAAL,CAAWH,YAAY,GAAGP,wBAA1B,CAA9B;EAEA,MAAMW,YAAY,GAAG5B,KAAK,CAAC6B,WAAN,CAAmBC,QAAD,IAAsB;IACzDV,QAAQ,CAACW,OAAT,GAAmBD,QAAnB;;IAEA,IAAIZ,QAAJ,EAAc;MACVA,QAAQ,CAACY,QAAD,CAAR;IACH;EACJ,CANoB,EAMlB,CAACZ,QAAD,CANkB,CAArB;EAQA,MAAMc,aAAa,GAAGhC,KAAK,CAAC6B,WAAN,CAAkB,MAAM;IAC1CD,YAAY,CAAC,CAAC,CAAF,CAAZ;EACH,CAFqB,EAEnB,CAACA,YAAD,CAFmB,CAAtB;EAIA5B,KAAK,CAACiC,SAAN,CAAgB,MAAM;IAClB,IAAIjB,KAAK,KAAKI,QAAQ,CAACW,OAAvB,EAAgC;MAC5B;IACH;;IAED,IAAIX,QAAQ,CAACW,OAAT,GAAmB,CAAnB,IAAwBf,KAAK,IAAI,CAArC,EAAwC;MAAA;;MACpC,yBAAAM,cAAc,CAACS,OAAf,gFAAwBG,OAAxB;IACH,CAFD,MAEO,IAAId,QAAQ,CAACW,OAAT,IAAoB,CAApB,IAAyBf,KAAK,GAAG,CAArC,EAAwC;MAAA;;MAC3C,0BAAAM,cAAc,CAACS,OAAf,kFAAwBI,OAAxB;IACH,CAFM,MAEA;MAAA;;MACH;MACA,0BAAAb,cAAc,CAACS,OAAf,kFAAwBK,WAAxB,CAAoCpB,KAApC;IACH;EACJ,CAbD,EAaG,CAACA,KAAD,CAbH;EAeA,MAAMqB,KAAK,GAAGlC,QAAQ,EAAtB;EACA,MAAMmC,MAAM,GAAGD,KAAK,CAACC,MAAN,CAAa,EAAb,CAAf;EACA,MAAMC,UAAU,GAAG;IACfC,eAAe,EAAE,WADF;IAEf,GAAGvC,QAAQ,CAACwC,MAAT,CAAwB;MACvBC,OAAO,EAAEJ,MAAF,aAAEA,MAAF,uBAAEA,MAAM,CAAEK,SADM;MAEvBC,GAAG,EAAEN,MAAF,aAAEA,MAAF,uBAAEA,MAAM,CAAEA,MAFU;MAGvBO,GAAG,EAAEP,MAAF,aAAEA,MAAF,uBAAEA,MAAM,CAAEQ;IAHU,CAAxB;EAFY,CAAnB;EAQA,MAAMC,eAAe,GAAG;IACpBP,eAAe,EAAEH,KAAK,CAACW,OAAN,CAAcC,KAAd,CAAoBC;EADjB,CAAxB;EAIA,MAAMC,qBAAqB,GAAGvC,eAAe,IAAI,CAAjD;;EAEA,MAAMwC,oBAAoB,GAAIzC,KAAD,iBACzB,oBAAC,mBAAD,eACQA,KADR;IAEI,cAAc,EAAE,CAFpB;IAGI,iBAAiB,EAAE,CAAC,CAHxB;IAII,OAAO,EAAEC,eAJb;IAKI,aAAa,EAAEM,QAAQ,GAAG,OAAH,GAAa;EALxC,GADJ;;EAUA,oBACI,oBAAC,wBAAD,qBACI,oBAAC,gBAAD;IACI,iBAAiB,EAAEiC,qBAAqB,GAAG3C,mBAAH,GAAyB4C,oBADrE,CAEI;IAFJ;IAGI,eAAe,EAAEL,eAHrB;IAII,KAAK,EAAE/B,KAJX;IAKI,eAAe,EAAEP,QALrB;IAMI,QAAQ,EAAEmB,YANd;IAOI,SAAS,EAAEI,aAPf;IAQI,GAAG,EAAEV,cART;IASI,UAAU,EAAEH,UAThB;IAUI,KAAK,EAAEoB,UAVX;IAWI,oBAAoB,EAAEc,OAAO,CAACnC,QAAD,CAXjC;IAYI,mBAAmB,EAAEJ,mBAZzB;IAaI,qBAAqB,EAAEW;EAb3B,gBAeI,oBAAC,qBAAD;IAAuB,mBAAmB,EAAEV,MAAM,GAAG,CAAC,CAAD,CAAH,GAASuC;EAA3D,GACKvC,MADL,EAGKF,QAHL,CAfJ,CADJ,CADJ;AAyBH;AAAA"}
1
+ {"version":3,"names":["React","Platform","useWindowDimensions","View","useTheme","BottomSheetBackdrop","BottomSheetModal","BottomSheetModalProvider","BottomSheetScrollView","TransparentBackdrop","NoHandle","BottomSheet","props","backdropOpacity","children","enableDynamicSizing","header","index","maxHeightNormalizedRatio","onChange","snapPoints","indexRef","useRef","bottomSheetRef","height","windowHeight","maxDynamicContentSize","Math","round","handleChange","useCallback","newIndex","current","handleDismiss","useEffect","present","dismiss","snapToIndex","theme","shadow","modalStyle","backgroundColor","select","android","elevation","ios","web","boxShadow","backgroundStyle","palette","paper","default","contentWrapperStyle","flex","borderTopLeftRadius","borderTopRightRadius","overflow","isBackdropTransparent","OpacityAwareBackdrop","Boolean","undefined"],"sources":["BottomSheetNative.tsx"],"sourcesContent":["import React from 'react';\nimport { Platform, useWindowDimensions, View } from 'react-native';\nimport { useTheme } from '@fountain-ui/styles';\nimport {\n BottomSheetBackdrop,\n BottomSheetBackdropProps,\n BottomSheetModal,\n BottomSheetModalProvider,\n BottomSheetScrollView,\n} from '@gorhom/bottom-sheet';\nimport type BottomSheetProps from './BottomSheetProps';\nimport TransparentBackdrop from './TransparentBackdrop';\n\nconst NoHandle = () => null;\n\nexport default function BottomSheet(props: BottomSheetProps) {\n const {\n backdropOpacity = 0.5,\n children,\n enableDynamicSizing = true,\n header,\n index,\n maxHeightNormalizedRatio = 0.9,\n onChange,\n snapPoints = [],\n } = props;\n\n const indexRef = React.useRef<number>(-1);\n const bottomSheetRef = React.useRef<BottomSheetModal | null>(null);\n\n const { height: windowHeight } = useWindowDimensions();\n const maxDynamicContentSize = Math.round(windowHeight * maxHeightNormalizedRatio);\n\n const handleChange = React.useCallback((newIndex: number) => {\n indexRef.current = newIndex;\n\n if (onChange) {\n onChange(newIndex);\n }\n }, [onChange]);\n\n const handleDismiss = React.useCallback(() => {\n handleChange(-1);\n }, [handleChange]);\n\n React.useEffect(() => {\n if (index === indexRef.current) {\n return;\n }\n\n if (indexRef.current < 0 && index >= 0) {\n bottomSheetRef.current?.present();\n } else if (indexRef.current >= 0 && index < 0) {\n bottomSheetRef.current?.dismiss();\n } else {\n // @ts-ignore\n bottomSheetRef.current?.snapToIndex(index);\n }\n }, [index]);\n\n const theme = useTheme();\n const shadow = theme.shadow[12];\n const modalStyle = {\n backgroundColor: '#ffffff00',\n ...Platform.select<object>({\n android: shadow?.elevation,\n ios: shadow?.shadow,\n web: shadow?.boxShadow,\n }),\n };\n const backgroundStyle = {\n backgroundColor: theme.palette.paper.default,\n };\n const contentWrapperStyle = {\n flex: 1,\n borderTopLeftRadius: 15,\n borderTopRightRadius: 15,\n overflow: 'hidden',\n };\n\n const isBackdropTransparent = backdropOpacity <= 0;\n\n const OpacityAwareBackdrop = (props: BottomSheetBackdropProps) => (\n <BottomSheetBackdrop\n {...props}\n appearsOnIndex={0}\n disappearsOnIndex={-1}\n opacity={backdropOpacity}\n pressBehavior={onChange ? 'close' : 'none'}\n />\n );\n\n return (\n <BottomSheetModalProvider>\n <BottomSheetModal\n backdropComponent={isBackdropTransparent ? TransparentBackdrop : OpacityAwareBackdrop}\n // @ts-ignore\n backgroundStyle={backgroundStyle}\n index={index}\n handleComponent={NoHandle}\n onChange={handleChange}\n onDismiss={handleDismiss}\n ref={bottomSheetRef}\n snapPoints={snapPoints}\n style={modalStyle}\n enablePanDownToClose={Boolean(onChange)}\n enableDynamicSizing={enableDynamicSizing}\n maxDynamicContentSize={maxDynamicContentSize}\n >\n {/* @ts-ignore */}\n <View style={contentWrapperStyle}>\n <BottomSheetScrollView\n bounces={false}\n stickyHeaderIndices={header ? [0] : undefined}\n >\n {header}\n\n {children}\n </BottomSheetScrollView>\n </View>\n </BottomSheetModal>\n </BottomSheetModalProvider>\n );\n};\n"],"mappings":"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"}
@@ -29,6 +29,7 @@ const mapImageStateToItemState = (index, imageState, autoHandleErrorCount) => {
29
29
  };
30
30
  };
31
31
 
32
+ const mapIndexed = R.addIndex(R.map);
32
33
  const MAXIMUM_WIDTH = 720;
33
34
  const NUMBER_OF_ADJACENT_ITEM = 5;
34
35
  export default function ComicViewer(props) {
@@ -43,6 +44,7 @@ export default function ComicViewer(props) {
43
44
  maxContentWidth = MAXIMUM_WIDTH,
44
45
  onItemPress,
45
46
  viewportWidth,
47
+ invisiblePaddingTop = 0,
46
48
  windowSize = 3,
47
49
  ...otherProps
48
50
  } = props;
@@ -60,9 +62,9 @@ export default function ComicViewer(props) {
60
62
  return mapImageStatesToItemStates(imageStatesRef.current);
61
63
  });
62
64
  const renderedDimensions = useMemo(() => {
63
- return R.map(intrinsicDimension => ({
65
+ return mapIndexed((intrinsicDimension, index) => ({
64
66
  width: actualImageWidth,
65
- height: intrinsicDimension.height * actualImageWidth / intrinsicDimension.width
67
+ height: intrinsicDimension.height * actualImageWidth / intrinsicDimension.width + (index === 0 ? invisiblePaddingTop : 0)
66
68
  }), intrinsicDimensions);
67
69
  }, [actualImageWidth]);
68
70
  const layoutFromDimensions = useCallback(() => {
@@ -104,7 +106,7 @@ export default function ComicViewer(props) {
104
106
  var _state$urlState;
105
107
 
106
108
  const state = imageStatesRef.current[index];
107
- return R.isNil(state.urlState) || ((_state$urlState = state.urlState) === null || _state$urlState === void 0 ? void 0 : _state$urlState.validity) === 'invalid' && !state.isNewUrlIncoming;
109
+ return !state.isNewUrlIncoming && (R.isNil(state.urlState) || ((_state$urlState = state.urlState) === null || _state$urlState === void 0 ? void 0 : _state$urlState.validity) === 'invalid');
108
110
  }, indexes);
109
111
  updateImageState((imageState, i) => {
110
112
  return R.includes(i, filteredIndexes) ? { ...imageState,
@@ -129,6 +131,7 @@ export default function ComicViewer(props) {
129
131
 
130
132
  return imageState;
131
133
  });
134
+ } catch (e) {// ignore
132
135
  } finally {
133
136
  updateImageState((imageState, i) => {
134
137
  return R.includes(i, filteredIndexes) ? { ...imageState,
@@ -138,12 +141,13 @@ export default function ComicViewer(props) {
138
141
  }
139
142
  };
140
143
 
141
- const loadMaybeLoadableItems = async () => {
144
+ const loadMaybeLoadableItems = () => {
142
145
  const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;
143
146
  const affectedIndexes = R.range(startIndex, endIndex);
144
- await loadUrlByIndex(affectedIndexes);
147
+ loadUrlByIndex(affectedIndexes);
145
148
  };
146
149
 
150
+ const ignoreDebounce = useRef(true);
147
151
  const loadItemsDebounce = useDebounce(loadMaybeLoadableItems, debounceMillis);
148
152
  const onViewableItemsChanged = useRef(_ref => {
149
153
  var _R$head, _R$last;
@@ -162,6 +166,13 @@ export default function ComicViewer(props) {
162
166
  const startIndex = R.max(firstViewableIndex - NUMBER_OF_ADJACENT_ITEM, 0);
163
167
  const endIndex = R.min(lastViewableItemIndex + NUMBER_OF_ADJACENT_ITEM, itemStates.length - 1);
164
168
  maybeLoadableItemsIndexRange.current = [startIndex, endIndex + 1];
169
+
170
+ if (ignoreDebounce.current) {
171
+ loadMaybeLoadableItems();
172
+ ignoreDebounce.current = false;
173
+ return;
174
+ }
175
+
165
176
  loadItemsDebounce();
166
177
  });
167
178
  const renderItem = useCallback(_ref2 => {
@@ -229,6 +240,7 @@ export default function ComicViewer(props) {
229
240
  onPress: onItemPress,
230
241
  onReloadPress: onReloadPress,
231
242
  url: item.url,
243
+ invisiblePaddingTop: index === 0 ? invisiblePaddingTop : 0,
232
244
  width: ((_renderedDimensions$i = renderedDimensions[index]) === null || _renderedDimensions$i === void 0 ? void 0 : _renderedDimensions$i.width) ?? 0,
233
245
  height: ((_renderedDimensions$i2 = renderedDimensions[index]) === null || _renderedDimensions$i2 === void 0 ? void 0 : _renderedDimensions$i2.height) ?? 0,
234
246
  reloadButtonVisible: item.reloadButtonVisible
@@ -1 +1 @@
1
- {"version":3,"names":["React","useCallback","useEffect","useMemo","useRef","useState","FlatList","R","useDebounce","ViewerItem","appender","left","right","getHeightAccum","heights","mapAccum","keyExtractor","item","String","index","createInitialImageState","dimension","isNewUrlIncoming","totalErrorCount","mapImageStateToItemState","imageState","autoHandleErrorCount","url","urlState","reloadButtonVisible","validity","MAXIMUM_WIDTH","NUMBER_OF_ADJACENT_ITEM","ComicViewer","props","debounceMillis","getUrlByIndex","initialNumToRender","initialScrollPercentage","itemVisiblePercentThreshold","intrinsicDimensions","maxContentWidth","onItemPress","viewportWidth","windowSize","otherProps","flatListRef","maybeLoadableItemsIndexRange","actualImageWidth","Math","min","initialImageStates","map","imageStatesRef","mapImageStatesToItemStates","imageStates","image","itemStates","setItemStates","current","renderedDimensions","intrinsicDimension","width","height","layoutFromDimensions","itemHeights","totalHeight","heightAccum","itemOffsets","prepend","getItemLayout","data","length","offset","viewabilityConfig","updateImageState","updateFunction","prevImageStates","newImageStates","prevItemStates","newItemStates","equals","loadUrlByIndex","indexes","filteredIndexes","filter","state","isNil","i","includes","urls","newUrl","get","undefined","loadMaybeLoadableItems","startIndex","endIndex","affectedIndexes","range","loadItemsDebounce","onViewableItemsChanged","viewableItems","orderedViewableItems","sort","a","b","firstViewableIndex","head","lastViewableItemIndex","last","max","renderItem","onError","onReloadPress","onLoad","floor","scrollToOffset","animated"],"sources":["ComicViewer.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { FlatList, ListRenderItem, ViewToken } from 'react-native';\nimport * as R from 'ramda';\nimport { useDebounce } from '@fountain-ui/core';\nimport { default as ComicViewerProps, Dimension } from './ComicViewerProps';\nimport ViewerItem from './ViewerItem';\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 isNewUrlIncoming: boolean;\n totalErrorCount: number;\n dimension: Dimension;\n}\n\ninterface ItemState {\n index: number;\n url?: string;\n reloadButtonVisible: boolean;\n dimension: Dimension;\n}\n\nconst createInitialImageState = (dimension: Dimension): ImageState => ({\n isNewUrlIncoming: false,\n totalErrorCount: 0,\n dimension,\n});\n\nconst mapImageStateToItemState = (\n index: number,\n imageState: ImageState,\n autoHandleErrorCount: number,\n): ItemState => ({\n index,\n url: imageState.urlState?.url,\n reloadButtonVisible: (imageState.urlState?.validity !== 'valid') && imageState.totalErrorCount >= autoHandleErrorCount,\n dimension: imageState.dimension,\n});\n\nconst MAXIMUM_WIDTH = 720;\n\nconst NUMBER_OF_ADJACENT_ITEM = 5;\n\nexport default function ComicViewer(props: ComicViewerProps) {\n const {\n debounceMillis = 100,\n autoHandleErrorCount = 3,\n getUrlByIndex,\n initialNumToRender = 1,\n initialScrollPercentage = 0,\n itemVisiblePercentThreshold = 0,\n intrinsicDimensions,\n maxContentWidth = MAXIMUM_WIDTH,\n onItemPress,\n viewportWidth,\n windowSize = 3,\n ...otherProps\n } = props;\n\n const flatListRef = useRef<FlatList>(null);\n\n const maybeLoadableItemsIndexRange = useRef<[number, number]>([-1, 0]);\n\n const actualImageWidth = Math.min(viewportWidth, maxContentWidth);\n\n const initialImageStates = useMemo<Array<ImageState>>(() => R.map(createInitialImageState, intrinsicDimensions), []);\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 R.map(intrinsicDimension => ({\n width: actualImageWidth,\n height: (intrinsicDimension.height * actualImageWidth) / intrinsicDimension.width,\n }), intrinsicDimensions);\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 loadUrlByIndex = async (indexes: number[]) => {\n const filteredIndexes = R.filter(index => {\n const state = imageStatesRef.current[index];\n\n return R.isNil(state.urlState)\n || (state.urlState?.validity === 'invalid' && !state.isNewUrlIncoming);\n }, indexes);\n\n updateImageState((imageState, i) => {\n return R.includes(i, filteredIndexes)\n ? { ...imageState, isNewUrlIncoming: true }\n : imageState;\n });\n\n try {\n const urls = await getUrlByIndex(filteredIndexes);\n\n updateImageState((imageState, i) => {\n const newUrl = urls?.get(i);\n const urlState = imageState.urlState;\n\n if (newUrl !== undefined && urlState?.validity !== 'valid') {\n return {\n ...imageState,\n urlState: {\n url: newUrl,\n validity: 'unknown',\n },\n };\n }\n\n return imageState;\n });\n } finally {\n updateImageState((imageState, i) => {\n return R.includes(i, filteredIndexes)\n ? { ...imageState, isNewUrlIncoming: false }\n : imageState;\n });\n }\n };\n\n const loadMaybeLoadableItems = async () => {\n const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n const affectedIndexes = R.range(startIndex, endIndex);\n\n await loadUrlByIndex(affectedIndexes);\n };\n\n const loadItemsDebounce = useDebounce(loadMaybeLoadableItems, debounceMillis);\n\n const onViewableItemsChanged = useRef(({ viewableItems }: { viewableItems: Array<ViewToken> }) => {\n const orderedViewableItems = R.sort((a, b) => (a.index || 0) - (b.index || 0), viewableItems);\n\n const firstViewableIndex = R.head(orderedViewableItems)?.index;\n const lastViewableItemIndex = R.last(orderedViewableItems)?.index;\n\n if (R.isNil(firstViewableIndex) || R.isNil(lastViewableItemIndex)) {\n return;\n }\n\n const startIndex = R.max(firstViewableIndex - NUMBER_OF_ADJACENT_ITEM, 0);\n const endIndex = R.min(lastViewableItemIndex + NUMBER_OF_ADJACENT_ITEM, itemStates.length - 1);\n\n maybeLoadableItemsIndexRange.current = [startIndex, endIndex + 1];\n\n loadItemsDebounce();\n });\n\n const renderItem: ListRenderItem<ItemState> = useCallback(({ item, index }) => {\n const onError = () => {\n updateImageState((imageState, i) => {\n const urlState = imageState.urlState;\n\n if (i === index && urlState !== undefined) {\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 const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n if (index >= startIndex || index < endIndex) {\n loadItemsDebounce();\n }\n };\n\n const onReloadPress = () => {\n const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n if (index >= startIndex || index < endIndex) {\n loadUrlByIndex([index]);\n }\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={onError}\n onLoad={onLoad}\n onPress={onItemPress}\n onReloadPress={onReloadPress}\n url={item.url}\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 <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 {...otherProps}\n />\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"names":["React","useCallback","useEffect","useMemo","useRef","useState","FlatList","R","useDebounce","ViewerItem","appender","left","right","getHeightAccum","heights","mapAccum","keyExtractor","item","String","index","createInitialImageState","dimension","isNewUrlIncoming","totalErrorCount","mapImageStateToItemState","imageState","autoHandleErrorCount","url","urlState","reloadButtonVisible","validity","mapIndexed","addIndex","map","MAXIMUM_WIDTH","NUMBER_OF_ADJACENT_ITEM","ComicViewer","props","debounceMillis","getUrlByIndex","initialNumToRender","initialScrollPercentage","itemVisiblePercentThreshold","intrinsicDimensions","maxContentWidth","onItemPress","viewportWidth","invisiblePaddingTop","windowSize","otherProps","flatListRef","maybeLoadableItemsIndexRange","actualImageWidth","Math","min","initialImageStates","imageStatesRef","mapImageStatesToItemStates","imageStates","image","itemStates","setItemStates","current","renderedDimensions","intrinsicDimension","width","height","layoutFromDimensions","itemHeights","totalHeight","heightAccum","itemOffsets","prepend","getItemLayout","data","length","offset","viewabilityConfig","updateImageState","updateFunction","prevImageStates","newImageStates","prevItemStates","newItemStates","equals","loadUrlByIndex","indexes","filteredIndexes","filter","state","isNil","i","includes","urls","newUrl","get","undefined","e","loadMaybeLoadableItems","startIndex","endIndex","affectedIndexes","range","ignoreDebounce","loadItemsDebounce","onViewableItemsChanged","viewableItems","orderedViewableItems","sort","a","b","firstViewableIndex","head","lastViewableItemIndex","last","max","renderItem","onError","onReloadPress","onLoad","floor","scrollToOffset","animated"],"sources":["ComicViewer.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { FlatList, ListRenderItem, ViewToken } from 'react-native';\nimport * as R from 'ramda';\nimport { useDebounce } from '@fountain-ui/core';\nimport { default as ComicViewerProps, Dimension } from './ComicViewerProps';\nimport ViewerItem from './ViewerItem';\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 isNewUrlIncoming: boolean;\n totalErrorCount: number;\n dimension: Dimension;\n}\n\ninterface ItemState {\n index: number;\n url?: string;\n reloadButtonVisible: boolean;\n dimension: Dimension;\n}\n\nconst createInitialImageState = (dimension: Dimension): ImageState => ({\n isNewUrlIncoming: false,\n totalErrorCount: 0,\n dimension,\n});\n\nconst mapImageStateToItemState = (\n index: number,\n imageState: ImageState,\n autoHandleErrorCount: number,\n): ItemState => ({\n index,\n url: imageState.urlState?.url,\n reloadButtonVisible: (imageState.urlState?.validity !== 'valid') && imageState.totalErrorCount >= autoHandleErrorCount,\n dimension: imageState.dimension,\n});\n\nconst mapIndexed = R.addIndex<Dimension>(R.map);\n\nconst MAXIMUM_WIDTH = 720;\n\nconst NUMBER_OF_ADJACENT_ITEM = 5;\n\nexport default function ComicViewer(props: ComicViewerProps) {\n const {\n debounceMillis = 100,\n autoHandleErrorCount = 3,\n getUrlByIndex,\n initialNumToRender = 1,\n initialScrollPercentage = 0,\n itemVisiblePercentThreshold = 0,\n intrinsicDimensions,\n maxContentWidth = MAXIMUM_WIDTH,\n onItemPress,\n viewportWidth,\n invisiblePaddingTop = 0,\n windowSize = 3,\n ...otherProps\n } = props;\n\n const flatListRef = useRef<FlatList>(null);\n\n const maybeLoadableItemsIndexRange = useRef<[number, number]>([-1, 0]);\n\n const actualImageWidth = Math.min(viewportWidth, maxContentWidth);\n\n const initialImageStates = useMemo<Array<ImageState>>(() => R.map(createInitialImageState, intrinsicDimensions), []);\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((intrinsicDimension, index) => ({\n width: actualImageWidth,\n height: (intrinsicDimension.height * actualImageWidth) / intrinsicDimension.width + (index === 0 ? invisiblePaddingTop : 0),\n }), intrinsicDimensions);\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 loadUrlByIndex = async (indexes: number[]) => {\n const filteredIndexes = R.filter(index => {\n const state = imageStatesRef.current[index];\n\n return !state.isNewUrlIncoming\n && (R.isNil(state.urlState) || state.urlState?.validity === 'invalid');\n }, indexes);\n\n updateImageState((imageState, i) => {\n return R.includes(i, filteredIndexes)\n ? { ...imageState, isNewUrlIncoming: true }\n : imageState;\n });\n\n try {\n const urls = await getUrlByIndex(filteredIndexes);\n\n updateImageState((imageState, i) => {\n const newUrl = urls?.get(i);\n const urlState = imageState.urlState;\n\n if (newUrl !== undefined && urlState?.validity !== 'valid') {\n return {\n ...imageState,\n urlState: {\n url: newUrl,\n validity: 'unknown',\n },\n };\n }\n\n return imageState;\n });\n } catch (e) {\n // ignore\n } finally {\n updateImageState((imageState, i) => {\n return R.includes(i, filteredIndexes)\n ? { ...imageState, isNewUrlIncoming: false }\n : imageState;\n });\n }\n };\n\n const loadMaybeLoadableItems = () => {\n const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n const affectedIndexes = R.range(startIndex, endIndex);\n\n loadUrlByIndex(affectedIndexes);\n };\n\n const ignoreDebounce = useRef(true);\n const loadItemsDebounce = useDebounce(loadMaybeLoadableItems, debounceMillis);\n\n const onViewableItemsChanged = useRef(({ viewableItems }: { viewableItems: Array<ViewToken> }) => {\n const orderedViewableItems = R.sort((a, b) => (a.index || 0) - (b.index || 0), viewableItems);\n\n const firstViewableIndex = R.head(orderedViewableItems)?.index;\n const lastViewableItemIndex = R.last(orderedViewableItems)?.index;\n\n if (R.isNil(firstViewableIndex) || R.isNil(lastViewableItemIndex)) {\n return;\n }\n\n const startIndex = R.max(firstViewableIndex - NUMBER_OF_ADJACENT_ITEM, 0);\n const endIndex = R.min(lastViewableItemIndex + NUMBER_OF_ADJACENT_ITEM, itemStates.length - 1);\n\n maybeLoadableItemsIndexRange.current = [startIndex, endIndex + 1];\n\n if (ignoreDebounce.current) {\n loadMaybeLoadableItems();\n\n ignoreDebounce.current = false;\n return;\n }\n\n loadItemsDebounce();\n });\n\n const renderItem: ListRenderItem<ItemState> = useCallback(({ item, index }) => {\n const onError = () => {\n updateImageState((imageState, i) => {\n const urlState = imageState.urlState;\n\n if (i === index && urlState !== undefined) {\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 const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n if (index >= startIndex || index < endIndex) {\n loadItemsDebounce();\n }\n };\n\n const onReloadPress = () => {\n const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n if (index >= startIndex || index < endIndex) {\n loadUrlByIndex([index]);\n }\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={onError}\n onLoad={onLoad}\n onPress={onItemPress}\n onReloadPress={onReloadPress}\n url={item.url}\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 <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 {...otherProps}\n />\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["ComicViewerProps.ts"],"sourcesContent":["import React from 'react';\nimport { ComponentProps } from '@fountain-ui/core';\nimport { NativeScrollEvent, NativeSyntheticEvent } from 'react-native';\n\nexport interface Dimension {\n width: number;\n height: number;\n}\n\nexport default interface ComicViewerProps extends ComponentProps <{\n /**\n * Delay Time to call the error handler.\n * @default 100\n */\n debounceMillis?: number;\n\n /**\n * How many times handle onError directly when item error occur\n * @default 3\n */\n autoHandleErrorCount?: number;\n\n /**\n * How many items to render in the initial batch.\n * @default 1\n */\n initialNumToRender?: number;\n\n /**\n * Start at initialScrollPercentage.\n * If over 100, scroll to end.\n * @default 0\n */\n initialScrollPercentage?: number;\n\n /**\n * The value for FlatList viewabilityConfig.itemVisiblePercentThreshold.\n * @default 0\n */\n itemVisiblePercentThreshold?: number;\n\n /**\n * Dimensions of each Image considering viewport.\n */\n intrinsicDimensions: Array<Dimension>;\n\n /**\n * Max value of contents image width size.\n * @default 720\n */\n maxContentWidth?: number;\n\n /**\n * Width of viewport.\n */\n viewportWidth: number;\n\n /**\n * The value for FlatList windowSize.\n * @default 3\n */\n windowSize?: number;\n\n /**\n * Get contents urls by indexes.\n */\n getUrlByIndex: (indexes: Array<number>) => Promise<Map<number, string> | undefined> ;\n\n /**\n * Handle scroll event.\n * @param event Scroll event.\n */\n onScroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;\n\n /**\n * Handle item press event.\n */\n onItemPress?: () => void;\n\n /**\n * Component for comic viewer footer.\n */\n ListFooterComponent?: React.ReactElement;\n}> {}\n"],"mappings":""}
1
+ {"version":3,"names":[],"sources":["ComicViewerProps.ts"],"sourcesContent":["import React from 'react';\nimport { ComponentProps } from '@fountain-ui/core';\nimport { NativeScrollEvent, NativeSyntheticEvent } from 'react-native';\n\nexport interface Dimension {\n width: number;\n height: number;\n}\n\nexport default interface ComicViewerProps extends ComponentProps <{\n /**\n * Delay Time to call the error handler.\n * @default 100\n */\n debounceMillis?: number;\n\n /**\n * How many times handle onError directly when item error occur\n * @default 3\n */\n autoHandleErrorCount?: number;\n\n /**\n * How many items to render in the initial batch.\n * @default 1\n */\n initialNumToRender?: number;\n\n /**\n * Start at initialScrollPercentage.\n * If over 100, scroll to end.\n * @default 0\n */\n initialScrollPercentage?: number;\n\n /**\n * The value for FlatList viewabilityConfig.itemVisiblePercentThreshold.\n * @default 0\n */\n itemVisiblePercentThreshold?: number;\n\n /**\n * Dimensions of each Image considering viewport.\n */\n intrinsicDimensions: Array<Dimension>;\n\n /**\n * Need invisible paddingTop viewer vertically expanded.\n * @default 0\n */\n invisiblePaddingTop?: number;\n\n /**\n * Max value of contents image width size.\n * @default 720\n */\n maxContentWidth?: number;\n\n /**\n * Width of viewport.\n */\n viewportWidth: number;\n\n /**\n * The value for FlatList windowSize.\n * @default 3\n */\n windowSize?: number;\n\n /**\n * Get contents urls by indexes.\n */\n getUrlByIndex: (indexes: Array<number>) => Promise<Map<number, string> | undefined> ;\n\n /**\n * Handle scroll event.\n * @param event Scroll event.\n */\n onScroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;\n\n /**\n * Handle item press event.\n */\n onItemPress?: () => void;\n\n /**\n * Component for comic viewer footer.\n */\n ListFooterComponent?: React.ReactElement;\n}> {}\n"],"mappings":""}
@@ -8,6 +8,7 @@ export default function ViewerItem(props) {
8
8
  height,
9
9
  url,
10
10
  width,
11
+ invisiblePaddingTop,
11
12
  onError,
12
13
  onLoad,
13
14
  onPress,
@@ -17,10 +18,11 @@ export default function ViewerItem(props) {
17
18
  const styles = {
18
19
  view: {
19
20
  height,
20
- width: '100%'
21
+ width: '100%',
22
+ paddingTop: invisiblePaddingTop
21
23
  },
22
24
  image: {
23
- height,
25
+ height: height - invisiblePaddingTop,
24
26
  width
25
27
  }
26
28
  };
@@ -1 +1 @@
1
- {"version":3,"names":["React","Image","TouchableWithoutFeedback","View","css","FuiImage","ReloadButton","EncodedTile","ViewerItem","props","height","url","width","onError","onLoad","onPress","onReloadPress","reloadButtonVisible","styles","view","image","error","placeholder","uri","alignSelf"],"sources":["ViewerItem.tsx"],"sourcesContent":["import React from 'react';\nimport { Image, TouchableWithoutFeedback, View } from 'react-native';\nimport { css, Image as FuiImage, ImageProps } from '@fountain-ui/core';\nimport ReloadButton from './ReloadButton';\nimport EncodedTile from './EncodedTile';\n\nexport interface ViewerItemProps {\n /**\n * Image width.\n */\n width: number;\n\n /**\n * Image height.\n */\n height: number;\n\n /**\n * Image sourceUrl for displaying.\n */\n url?: string;\n\n /**\n * Error handler.\n */\n onError?: ImageProps['onError'];\n\n /**\n * Load handler.\n */\n onLoad?: ImageProps['onLoad'];\n\n /**\n * Handle Reload button press event.\n */\n onReloadPress?: ImageProps['onError'];\n\n /**\n * Handle item press event.\n */\n onPress?: () => void;\n\n /**\n * If true, reload button visible.\n * @default false\n */\n reloadButtonVisible?: boolean;\n}\n\nexport default function ViewerItem(props: ViewerItemProps) {\n const {\n height,\n url,\n width,\n onError,\n onLoad,\n onPress,\n onReloadPress,\n reloadButtonVisible = false,\n } = props;\n\n const styles = {\n view: {\n height,\n width: '100%',\n },\n image: {\n height,\n width,\n },\n };\n\n const error = reloadButtonVisible ? <ReloadButton onPress={onReloadPress}/> : null;\n\n const placeholder = <Image\n source={{ uri: EncodedTile }}\n resizeMode={'cover'}\n style={styles.image}\n />;\n\n return (\n <TouchableWithoutFeedback onPress={onPress}>\n <View style={styles.view}>\n <FuiImage\n cache={'web'}\n disableDrag={true}\n disableLongClick={true}\n disableOutline={true}\n error={error}\n onError={onError}\n onLoad={onLoad}\n loading={'eager'}\n placeholder={placeholder}\n source={{ uri: url }}\n square={true}\n style={css([\n { alignSelf: 'center' },\n styles.image,\n ])}\n />\n </View>\n </TouchableWithoutFeedback>\n );\n};\n"],"mappings":"AAAA,OAAOA,KAAP,MAAkB,OAAlB;AACA,SAASC,KAAT,EAAgBC,wBAAhB,EAA0CC,IAA1C,QAAsD,cAAtD;AACA,SAASC,GAAT,EAAcH,KAAK,IAAII,QAAvB,QAAmD,mBAAnD;AACA,OAAOC,YAAP,MAAyB,gBAAzB;AACA,OAAOC,WAAP,MAAwB,eAAxB;AA6CA,eAAe,SAASC,UAAT,CAAoBC,KAApB,EAA4C;EACvD,MAAM;IACFC,MADE;IAEFC,GAFE;IAGFC,KAHE;IAIFC,OAJE;IAKFC,MALE;IAMFC,OANE;IAOFC,aAPE;IAQFC,mBAAmB,GAAG;EARpB,IASFR,KATJ;EAWA,MAAMS,MAAM,GAAG;IACXC,IAAI,EAAE;MACFT,MADE;MAEFE,KAAK,EAAE;IAFL,CADK;IAKXQ,KAAK,EAAE;MACHV,MADG;MAEHE;IAFG;EALI,CAAf;EAWA,MAAMS,KAAK,GAAGJ,mBAAmB,gBAAG,oBAAC,YAAD;IAAc,OAAO,EAAED;EAAvB,EAAH,GAA6C,IAA9E;EAEA,MAAMM,WAAW,gBAAG,oBAAC,KAAD;IAChB,MAAM,EAAE;MAAEC,GAAG,EAAEhB;IAAP,CADQ;IAEhB,UAAU,EAAE,OAFI;IAGhB,KAAK,EAAEW,MAAM,CAACE;EAHE,EAApB;EAMA,oBACI,oBAAC,wBAAD;IAA0B,OAAO,EAAEL;EAAnC,gBACI,oBAAC,IAAD;IAAM,KAAK,EAAEG,MAAM,CAACC;EAApB,gBACI,oBAAC,QAAD;IACI,KAAK,EAAE,KADX;IAEI,WAAW,EAAE,IAFjB;IAGI,gBAAgB,EAAE,IAHtB;IAII,cAAc,EAAE,IAJpB;IAKI,KAAK,EAAEE,KALX;IAMI,OAAO,EAAER,OANb;IAOI,MAAM,EAAEC,MAPZ;IAQI,OAAO,EAAE,OARb;IASI,WAAW,EAAEQ,WATjB;IAUI,MAAM,EAAE;MAAEC,GAAG,EAAEZ;IAAP,CAVZ;IAWI,MAAM,EAAE,IAXZ;IAYI,KAAK,EAAEP,GAAG,CAAC,CACP;MAAEoB,SAAS,EAAE;IAAb,CADO,EAEPN,MAAM,CAACE,KAFA,CAAD;EAZd,EADJ,CADJ,CADJ;AAuBH;AAAA"}
1
+ {"version":3,"names":["React","Image","TouchableWithoutFeedback","View","css","FuiImage","ReloadButton","EncodedTile","ViewerItem","props","height","url","width","invisiblePaddingTop","onError","onLoad","onPress","onReloadPress","reloadButtonVisible","styles","view","paddingTop","image","error","placeholder","uri","alignSelf"],"sources":["ViewerItem.tsx"],"sourcesContent":["import React from 'react';\nimport { Image, TouchableWithoutFeedback, View } from 'react-native';\nimport { css, Image as FuiImage, ImageProps } from '@fountain-ui/core';\nimport ReloadButton from './ReloadButton';\nimport EncodedTile from './EncodedTile';\n\nexport interface ViewerItemProps {\n /**\n * Image width.\n */\n width: number;\n\n /**\n * Image height.\n */\n height: number;\n\n /**\n * Need invisible paddingTop viewer vertically expanded.\n */\n invisiblePaddingTop: number;\n\n /**\n * Image sourceUrl for displaying.\n */\n url?: string;\n\n /**\n * Error handler.\n */\n onError?: ImageProps['onError'];\n\n /**\n * Load handler.\n */\n onLoad?: ImageProps['onLoad'];\n\n /**\n * Handle Reload button press event.\n */\n onReloadPress?: ImageProps['onError'];\n\n /**\n * Handle item press event.\n */\n onPress?: () => void;\n\n /**\n * If true, reload button visible.\n * @default false\n */\n reloadButtonVisible?: boolean;\n}\n\nexport default function ViewerItem(props: ViewerItemProps) {\n const {\n height,\n url,\n width,\n invisiblePaddingTop,\n onError,\n onLoad,\n onPress,\n onReloadPress,\n reloadButtonVisible = false,\n } = props;\n\n const styles = {\n view: {\n height,\n width: '100%',\n paddingTop: invisiblePaddingTop,\n },\n image: {\n height: height - invisiblePaddingTop,\n width,\n },\n };\n\n const error = reloadButtonVisible ? <ReloadButton onPress={onReloadPress}/> : null;\n\n const placeholder = <Image\n source={{ uri: EncodedTile }}\n resizeMode={'cover'}\n style={styles.image}\n />;\n\n return (\n <TouchableWithoutFeedback onPress={onPress}>\n <View style={styles.view}>\n <FuiImage\n cache={'web'}\n disableDrag={true}\n disableLongClick={true}\n disableOutline={true}\n error={error}\n onError={onError}\n onLoad={onLoad}\n loading={'eager'}\n placeholder={placeholder}\n source={{ uri: url }}\n square={true}\n style={css([\n { alignSelf: 'center' },\n styles.image,\n ])}\n />\n </View>\n </TouchableWithoutFeedback>\n );\n};\n"],"mappings":"AAAA,OAAOA,KAAP,MAAkB,OAAlB;AACA,SAASC,KAAT,EAAgBC,wBAAhB,EAA0CC,IAA1C,QAAsD,cAAtD;AACA,SAASC,GAAT,EAAcH,KAAK,IAAII,QAAvB,QAAmD,mBAAnD;AACA,OAAOC,YAAP,MAAyB,gBAAzB;AACA,OAAOC,WAAP,MAAwB,eAAxB;AAkDA,eAAe,SAASC,UAAT,CAAoBC,KAApB,EAA4C;EACvD,MAAM;IACFC,MADE;IAEFC,GAFE;IAGFC,KAHE;IAIFC,mBAJE;IAKFC,OALE;IAMFC,MANE;IAOFC,OAPE;IAQFC,aARE;IASFC,mBAAmB,GAAG;EATpB,IAUFT,KAVJ;EAYA,MAAMU,MAAM,GAAG;IACXC,IAAI,EAAE;MACFV,MADE;MAEFE,KAAK,EAAE,MAFL;MAGFS,UAAU,EAAER;IAHV,CADK;IAMXS,KAAK,EAAE;MACHZ,MAAM,EAAEA,MAAM,GAAGG,mBADd;MAEHD;IAFG;EANI,CAAf;EAYA,MAAMW,KAAK,GAAGL,mBAAmB,gBAAG,oBAAC,YAAD;IAAc,OAAO,EAAED;EAAvB,EAAH,GAA6C,IAA9E;EAEA,MAAMO,WAAW,gBAAG,oBAAC,KAAD;IAChB,MAAM,EAAE;MAAEC,GAAG,EAAElB;IAAP,CADQ;IAEhB,UAAU,EAAE,OAFI;IAGhB,KAAK,EAAEY,MAAM,CAACG;EAHE,EAApB;EAMA,oBACI,oBAAC,wBAAD;IAA0B,OAAO,EAAEN;EAAnC,gBACI,oBAAC,IAAD;IAAM,KAAK,EAAEG,MAAM,CAACC;EAApB,gBACI,oBAAC,QAAD;IACI,KAAK,EAAE,KADX;IAEI,WAAW,EAAE,IAFjB;IAGI,gBAAgB,EAAE,IAHtB;IAII,cAAc,EAAE,IAJpB;IAKI,KAAK,EAAEG,KALX;IAMI,OAAO,EAAET,OANb;IAOI,MAAM,EAAEC,MAPZ;IAQI,OAAO,EAAE,OARb;IASI,WAAW,EAAES,WATjB;IAUI,MAAM,EAAE;MAAEC,GAAG,EAAEd;IAAP,CAVZ;IAWI,MAAM,EAAE,IAXZ;IAYI,KAAK,EAAEP,GAAG,CAAC,CACP;MAAEsB,SAAS,EAAE;IAAb,CADO,EAEPP,MAAM,CAACG,KAFA,CAAD;EAZd,EADJ,CADJ,CADJ;AAuBH;AAAA"}
@@ -36,6 +36,11 @@ export default interface ComicViewerProps extends ComponentProps<{
36
36
  * Dimensions of each Image considering viewport.
37
37
  */
38
38
  intrinsicDimensions: Array<Dimension>;
39
+ /**
40
+ * Need invisible paddingTop viewer vertically expanded.
41
+ * @default 0
42
+ */
43
+ invisiblePaddingTop?: number;
39
44
  /**
40
45
  * Max value of contents image width size.
41
46
  * @default 720
@@ -8,6 +8,10 @@ export interface ViewerItemProps {
8
8
  * Image height.
9
9
  */
10
10
  height: number;
11
+ /**
12
+ * Need invisible paddingTop viewer vertically expanded.
13
+ */
14
+ invisiblePaddingTop: number;
11
15
  /**
12
16
  * Image sourceUrl for displaying.
13
17
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fountain-ui/lab",
3
- "version": "2.0.0-beta.43",
3
+ "version": "2.0.0-beta.45",
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": "d6fdcaa8a08a999fd1be2f9be76e47230b32545e"
73
+ "gitHead": "928b060600a7fc8cd8eccd59c573aca76cdcbec6"
74
74
  }
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { Platform, useWindowDimensions } from 'react-native';
2
+ import { Platform, useWindowDimensions, View } from 'react-native';
3
3
  import { useTheme } from '@fountain-ui/styles';
4
4
  import {
5
5
  BottomSheetBackdrop,
@@ -71,6 +71,12 @@ export default function BottomSheet(props: BottomSheetProps) {
71
71
  const backgroundStyle = {
72
72
  backgroundColor: theme.palette.paper.default,
73
73
  };
74
+ const contentWrapperStyle = {
75
+ flex: 1,
76
+ borderTopLeftRadius: 15,
77
+ borderTopRightRadius: 15,
78
+ overflow: 'hidden',
79
+ };
74
80
 
75
81
  const isBackdropTransparent = backdropOpacity <= 0;
76
82
 
@@ -101,11 +107,17 @@ export default function BottomSheet(props: BottomSheetProps) {
101
107
  enableDynamicSizing={enableDynamicSizing}
102
108
  maxDynamicContentSize={maxDynamicContentSize}
103
109
  >
104
- <BottomSheetScrollView stickyHeaderIndices={header ? [0] : undefined}>
105
- {header}
110
+ {/* @ts-ignore */}
111
+ <View style={contentWrapperStyle}>
112
+ <BottomSheetScrollView
113
+ bounces={false}
114
+ stickyHeaderIndices={header ? [0] : undefined}
115
+ >
116
+ {header}
106
117
 
107
- {children}
108
- </BottomSheetScrollView>
118
+ {children}
119
+ </BottomSheetScrollView>
120
+ </View>
109
121
  </BottomSheetModal>
110
122
  </BottomSheetModalProvider>
111
123
  );
@@ -46,6 +46,8 @@ const mapImageStateToItemState = (
46
46
  dimension: imageState.dimension,
47
47
  });
48
48
 
49
+ const mapIndexed = R.addIndex<Dimension>(R.map);
50
+
49
51
  const MAXIMUM_WIDTH = 720;
50
52
 
51
53
  const NUMBER_OF_ADJACENT_ITEM = 5;
@@ -62,6 +64,7 @@ export default function ComicViewer(props: ComicViewerProps) {
62
64
  maxContentWidth = MAXIMUM_WIDTH,
63
65
  onItemPress,
64
66
  viewportWidth,
67
+ invisiblePaddingTop = 0,
65
68
  windowSize = 3,
66
69
  ...otherProps
67
70
  } = props;
@@ -86,9 +89,9 @@ export default function ComicViewer(props: ComicViewerProps) {
86
89
  });
87
90
 
88
91
  const renderedDimensions = useMemo<Array<Dimension>>(() => {
89
- return R.map(intrinsicDimension => ({
92
+ return mapIndexed((intrinsicDimension, index) => ({
90
93
  width: actualImageWidth,
91
- height: (intrinsicDimension.height * actualImageWidth) / intrinsicDimension.width,
94
+ height: (intrinsicDimension.height * actualImageWidth) / intrinsicDimension.width + (index === 0 ? invisiblePaddingTop : 0),
92
95
  }), intrinsicDimensions);
93
96
  }, [actualImageWidth]);
94
97
 
@@ -132,8 +135,8 @@ export default function ComicViewer(props: ComicViewerProps) {
132
135
  const filteredIndexes = R.filter(index => {
133
136
  const state = imageStatesRef.current[index];
134
137
 
135
- return R.isNil(state.urlState)
136
- || (state.urlState?.validity === 'invalid' && !state.isNewUrlIncoming);
138
+ return !state.isNewUrlIncoming
139
+ && (R.isNil(state.urlState) || state.urlState?.validity === 'invalid');
137
140
  }, indexes);
138
141
 
139
142
  updateImageState((imageState, i) => {
@@ -161,6 +164,8 @@ export default function ComicViewer(props: ComicViewerProps) {
161
164
 
162
165
  return imageState;
163
166
  });
167
+ } catch (e) {
168
+ // ignore
164
169
  } finally {
165
170
  updateImageState((imageState, i) => {
166
171
  return R.includes(i, filteredIndexes)
@@ -170,13 +175,14 @@ export default function ComicViewer(props: ComicViewerProps) {
170
175
  }
171
176
  };
172
177
 
173
- const loadMaybeLoadableItems = async () => {
178
+ const loadMaybeLoadableItems = () => {
174
179
  const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;
175
180
  const affectedIndexes = R.range(startIndex, endIndex);
176
181
 
177
- await loadUrlByIndex(affectedIndexes);
182
+ loadUrlByIndex(affectedIndexes);
178
183
  };
179
184
 
185
+ const ignoreDebounce = useRef(true);
180
186
  const loadItemsDebounce = useDebounce(loadMaybeLoadableItems, debounceMillis);
181
187
 
182
188
  const onViewableItemsChanged = useRef(({ viewableItems }: { viewableItems: Array<ViewToken> }) => {
@@ -194,6 +200,13 @@ export default function ComicViewer(props: ComicViewerProps) {
194
200
 
195
201
  maybeLoadableItemsIndexRange.current = [startIndex, endIndex + 1];
196
202
 
203
+ if (ignoreDebounce.current) {
204
+ loadMaybeLoadableItems();
205
+
206
+ ignoreDebounce.current = false;
207
+ return;
208
+ }
209
+
197
210
  loadItemsDebounce();
198
211
  });
199
212
 
@@ -258,6 +271,7 @@ export default function ComicViewer(props: ComicViewerProps) {
258
271
  onPress={onItemPress}
259
272
  onReloadPress={onReloadPress}
260
273
  url={item.url}
274
+ invisiblePaddingTop={index === 0 ? invisiblePaddingTop : 0}
261
275
  width={renderedDimensions[index]?.width ?? 0}
262
276
  height={renderedDimensions[index]?.height ?? 0}
263
277
  reloadButtonVisible={item.reloadButtonVisible}
@@ -44,6 +44,12 @@ export default interface ComicViewerProps extends ComponentProps <{
44
44
  */
45
45
  intrinsicDimensions: Array<Dimension>;
46
46
 
47
+ /**
48
+ * Need invisible paddingTop viewer vertically expanded.
49
+ * @default 0
50
+ */
51
+ invisiblePaddingTop?: number;
52
+
47
53
  /**
48
54
  * Max value of contents image width size.
49
55
  * @default 720
@@ -15,6 +15,11 @@ export interface ViewerItemProps {
15
15
  */
16
16
  height: number;
17
17
 
18
+ /**
19
+ * Need invisible paddingTop viewer vertically expanded.
20
+ */
21
+ invisiblePaddingTop: number;
22
+
18
23
  /**
19
24
  * Image sourceUrl for displaying.
20
25
  */
@@ -52,6 +57,7 @@ export default function ViewerItem(props: ViewerItemProps) {
52
57
  height,
53
58
  url,
54
59
  width,
60
+ invisiblePaddingTop,
55
61
  onError,
56
62
  onLoad,
57
63
  onPress,
@@ -63,9 +69,10 @@ export default function ViewerItem(props: ViewerItemProps) {
63
69
  view: {
64
70
  height,
65
71
  width: '100%',
72
+ paddingTop: invisiblePaddingTop,
66
73
  },
67
74
  image: {
68
- height,
75
+ height: height - invisiblePaddingTop,
69
76
  width,
70
77
  },
71
78
  };