@fountain-ui/lab 2.0.0-beta.44 → 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.
- package/build/commonjs/ComicViewer/ComicViewer.js +17 -5
- package/build/commonjs/ComicViewer/ComicViewer.js.map +1 -1
- package/build/commonjs/ComicViewer/ComicViewerProps.js.map +1 -1
- package/build/commonjs/ComicViewer/ViewerItem.js +4 -2
- package/build/commonjs/ComicViewer/ViewerItem.js.map +1 -1
- package/build/module/ComicViewer/ComicViewer.js +17 -5
- package/build/module/ComicViewer/ComicViewer.js.map +1 -1
- package/build/module/ComicViewer/ComicViewerProps.js.map +1 -1
- package/build/module/ComicViewer/ViewerItem.js +4 -2
- package/build/module/ComicViewer/ViewerItem.js.map +1 -1
- package/build/typescript/ComicViewer/ComicViewerProps.d.ts +5 -0
- package/build/typescript/ComicViewer/ViewerItem.d.ts +4 -0
- package/package.json +2 -2
- package/src/ComicViewer/ComicViewer.tsx +20 -6
- package/src/ComicViewer/ComicViewerProps.ts +6 -0
- package/src/ComicViewer/ViewerItem.tsx +8 -1
|
@@ -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
|
|
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'
|
|
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 =
|
|
162
|
+
const loadMaybeLoadableItems = () => {
|
|
160
163
|
const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;
|
|
161
164
|
const affectedIndexes = R.range(startIndex, endIndex);
|
|
162
|
-
|
|
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;;;;
|
|
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"}
|
|
@@ -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
|
|
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'
|
|
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 =
|
|
144
|
+
const loadMaybeLoadableItems = () => {
|
|
142
145
|
const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;
|
|
143
146
|
const affectedIndexes = R.range(startIndex, endIndex);
|
|
144
|
-
|
|
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":";;AAAA,OAAOA,KAAP,IAAgBC,WAAhB,EAA6BC,SAA7B,EAAwCC,OAAxC,EAAiDC,MAAjD,EAAyDC,QAAzD,QAAyE,OAAzE;AACA,SAASC,QAAT,QAAoD,cAApD;AACA,OAAO,KAAKC,CAAZ,MAAmB,OAAnB;AACA,SAASC,WAAT,QAA4B,mBAA5B;AAEA,OAAOC,UAAP,MAAuB,cAAvB;;AAEA,MAAMC,QAAQ,GAAG,CAACC,IAAD,EAAeC,KAAf,KAAmD,CAACD,IAAI,GAAGC,KAAR,EAAeD,IAAI,GAAGC,KAAtB,CAApE;;AACA,MAAMC,cAAc,GAAIC,OAAD,IAA2CP,CAAC,CAACQ,QAAF,CAAWL,QAAX,EAAqB,CAArB,EAAwBI,OAAxB,CAAlE;;AAEA,MAAME,YAAY,GAASC,IAAN,IAA0BC,MAAM,CAACD,IAAI,CAACE,KAAN,CAArD;;AAqBA,MAAMC,uBAAuB,GAAIC,SAAD,KAAuC;EACnEC,gBAAgB,EAAE,KADiD;EAEnEC,eAAe,EAAE,CAFkD;EAGnEF;AAHmE,CAAvC,CAAhC;;AAMA,MAAMG,wBAAwB,GAAG,CAC7BL,KAD6B,EAE7BM,UAF6B,EAG7BC,oBAH6B;EAAA;;EAAA,OAIhB;IACbP,KADa;IAEbQ,GAAG,0BAAEF,UAAU,CAACG,QAAb,yDAAE,qBAAqBD,GAFb;IAGbE,mBAAmB,EAAG,0BAAAJ,UAAU,CAACG,QAAX,gFAAqBE,QAArB,MAAkC,OAAnC,IAA+CL,UAAU,CAACF,eAAX,IAA8BG,oBAHrF;IAIbL,SAAS,EAAEI,UAAU,CAACJ;EAJT,CAJgB;AAAA,CAAjC;;AAWA,MAAMU,aAAa,GAAG,GAAtB;AAEA,MAAMC,uBAAuB,GAAG,CAAhC;AAEA,eAAe,SAASC,WAAT,CAAqBC,KAArB,EAA8C;EACzD,MAAM;IACFC,cAAc,GAAG,GADf;IAEFT,oBAAoB,GAAG,CAFrB;IAGFU,aAHE;IAIFC,kBAAkB,GAAG,CAJnB;IAKFC,uBAAuB,GAAG,CALxB;IAMFC,2BAA2B,GAAG,CAN5B;IAOFC,mBAPE;IAQFC,eAAe,GAAGV,aARhB;IASFW,WATE;IAUFC,aAVE;IAWFC,UAAU,GAAG,CAXX;IAYF,GAAGC;EAZD,IAaFX,KAbJ;EAeA,MAAMY,WAAW,GAAG1C,MAAM,CAAW,IAAX,CAA1B;EAEA,MAAM2C,4BAA4B,GAAG3C,MAAM,CAAmB,CAAC,CAAC,CAAF,EAAK,CAAL,CAAnB,CAA3C;EAEA,MAAM4C,gBAAgB,GAAGC,IAAI,CAACC,GAAL,CAASP,aAAT,EAAwBF,eAAxB,CAAzB;EAEA,MAAMU,kBAAkB,GAAGhD,OAAO,CAAoB,MAAMI,CAAC,CAAC6C,GAAF,CAAMhC,uBAAN,EAA+BoB,mBAA/B,CAA1B,EAA+E,EAA/E,CAAlC;EACA,MAAMa,cAAc,GAAGjD,MAAM,CAAoB+C,kBAApB,CAA7B;;EAEA,MAAMG,0BAA0B,GAAIC,WAAD,IAAsD;IACrF,OAAOA,WAAW,CAACH,GAAZ,CAAgB,CAACI,KAAD,EAAQrC,KAAR,KAAkBK,wBAAwB,CAC7DL,KAD6D,EACtDqC,KADsD,EAC/C9B,oBAD+C,CAA1D,CAAP;EAGH,CAJD;;EAMA,MAAM,CAAC+B,UAAD,EAAaC,aAAb,IAA8BrD,QAAQ,CAAmB,MAAM;IACjE,OAAOiD,0BAA0B,CAACD,cAAc,CAACM,OAAhB,CAAjC;EACH,CAF2C,CAA5C;EAIA,MAAMC,kBAAkB,GAAGzD,OAAO,CAAmB,MAAM;IACvD,OAAOI,CAAC,CAAC6C,GAAF,CAAMS,kBAAkB,KAAK;MAChCC,KAAK,EAAEd,gBADyB;MAEhCe,MAAM,EAAGF,kBAAkB,CAACE,MAAnB,GAA4Bf,gBAA7B,GAAiDa,kBAAkB,CAACC;IAF5C,CAAL,CAAxB,EAGHtB,mBAHG,CAAP;EAIH,CALiC,EAK/B,CAACQ,gBAAD,CAL+B,CAAlC;EAOA,MAAMgB,oBAAoB,GAAG/D,WAAW,CAAC,MAAM;IAC3C,MAAMgE,WAAW,GAAG1D,CAAC,CAAC6C,GAAF,CAAM/B,SAAS,IAAIA,SAAS,CAAC0C,MAA7B,EAAqCH,kBAArC,CAApB;IACA,MAAM,CAACM,WAAD,EAAcC,WAAd,IAA6BtD,cAAc,CAACoD,WAAD,CAAjD;IACA,MAAMG,WAAW,GAAG7D,CAAC,CAAC8D,OAAF,CAAU,CAAV,EAAaF,WAAb,CAApB;;IAEA,MAAMG,aAAa,GAAG,CAACC,IAAD,EAAYpD,KAAZ,MAA+B;MACjDA,KADiD;MAEjDqD,MAAM,EAAEP,WAAW,CAAC9C,KAAD,CAF8B;MAGjDsD,MAAM,EAAEL,WAAW,CAACjD,KAAD;IAH8B,CAA/B,CAAtB;;IAMA,OAAO;MACH+C,WADG;MAEHI;IAFG,CAAP;EAIH,CAfuC,EAerC,CAACV,kBAAD,CAfqC,CAAxC;EAiBA,MAAM;IAAEM,WAAF;IAAeI;EAAf,IAAiCN,oBAAoB,EAA3D;EAEA,MAAMU,iBAAiB,GAAGvE,OAAO,CAAC,OAAO;IACrCoC;EADqC,CAAP,CAAD,EAE7B,CAACA,2BAAD,CAF6B,CAAjC;;EAIA,MAAMoC,gBAAgB,GAAIC,cAAD,IAAqE;IAC1F,MAAMC,eAAe,GAAGxB,cAAc,CAACM,OAAvC;IACA,MAAMmB,cAAc,GAAGD,eAAe,CAACzB,GAAhB,CAAoBwB,cAApB,CAAvB;IAEAvB,cAAc,CAACM,OAAf,GAAyBmB,cAAzB;IAEApB,aAAa,CAACqB,cAAc,IAAI;MAC5B,MAAMC,aAAa,GAAG1B,0BAA0B,CAACwB,cAAD,CAAhD;MAEA,OAAOvE,CAAC,CAAC0E,MAAF,CAASF,cAAT,EAAyBC,aAAzB,IAA0CD,cAA1C,GAA2DC,aAAlE;IACH,CAJY,CAAb;EAKH,CAXD;;EAaA,MAAME,cAAc,GAAG,MAAOC,OAAP,IAA6B;IAChD,MAAMC,eAAe,GAAG7E,CAAC,CAAC8E,MAAF,CAASlE,KAAK,IAAI;MAAA;;MACtC,MAAMmE,KAAK,GAAGjC,cAAc,CAACM,OAAf,CAAuBxC,KAAvB,CAAd;MAEA,OAAOZ,CAAC,CAACgF,KAAF,CAAQD,KAAK,CAAC1D,QAAd,KACC,oBAAA0D,KAAK,CAAC1D,QAAN,oEAAgBE,QAAhB,MAA6B,SAA7B,IAA0C,CAACwD,KAAK,CAAChE,gBADzD;IAEH,CALuB,EAKrB6D,OALqB,CAAxB;IAOAR,gBAAgB,CAAC,CAAClD,UAAD,EAAa+D,CAAb,KAAmB;MAChC,OAAOjF,CAAC,CAACkF,QAAF,CAAWD,CAAX,EAAcJ,eAAd,IACD,EAAE,GAAG3D,UAAL;QAAiBH,gBAAgB,EAAE;MAAnC,CADC,GAEDG,UAFN;IAGH,CAJe,CAAhB;;IAMA,IAAI;MACA,MAAMiE,IAAI,GAAG,MAAMtD,aAAa,CAACgD,eAAD,CAAhC;MAEAT,gBAAgB,CAAC,CAAClD,UAAD,EAAa+D,CAAb,KAAmB;QAChC,MAAMG,MAAM,GAAGD,IAAH,aAAGA,IAAH,uBAAGA,IAAI,CAAEE,GAAN,CAAUJ,CAAV,CAAf;QACA,MAAM5D,QAAQ,GAAGH,UAAU,CAACG,QAA5B;;QAEA,IAAI+D,MAAM,KAAKE,SAAX,IAAwB,CAAAjE,QAAQ,SAAR,IAAAA,QAAQ,WAAR,YAAAA,QAAQ,CAAEE,QAAV,MAAuB,OAAnD,EAA4D;UACxD,OAAO,EACH,GAAGL,UADA;YAEHG,QAAQ,EAAE;cACND,GAAG,EAAEgE,MADC;cAEN7D,QAAQ,EAAE;YAFJ;UAFP,CAAP;QAOH;;QAED,OAAOL,UAAP;MACH,CAfe,CAAhB;IAgBH,CAnBD,SAmBU;MACNkD,gBAAgB,CAAC,CAAClD,UAAD,EAAa+D,CAAb,KAAmB;QAChC,OAAOjF,CAAC,CAACkF,QAAF,CAAWD,CAAX,EAAcJ,eAAd,IACD,EAAE,GAAG3D,UAAL;UAAiBH,gBAAgB,EAAE;QAAnC,CADC,GAEDG,UAFN;MAGH,CAJe,CAAhB;IAKH;EACJ,CAxCD;;EA0CA,MAAMqE,sBAAsB,GAAG,YAAY;IACvC,MAAM,CAACC,UAAD,EAAaC,QAAb,IAAyBjD,4BAA4B,CAACY,OAA5D;IACA,MAAMsC,eAAe,GAAG1F,CAAC,CAAC2F,KAAF,CAAQH,UAAR,EAAoBC,QAApB,CAAxB;IAEA,MAAMd,cAAc,CAACe,eAAD,CAApB;EACH,CALD;;EAOA,MAAME,iBAAiB,GAAG3F,WAAW,CAACsF,sBAAD,EAAyB3D,cAAzB,CAArC;EAEA,MAAMiE,sBAAsB,GAAGhG,MAAM,CAAC,QAA4D;IAAA;;IAAA,IAA3D;MAAEiG;IAAF,CAA2D;IAC9F,MAAMC,oBAAoB,GAAG/F,CAAC,CAACgG,IAAF,CAAO,CAACC,CAAD,EAAIC,CAAJ,KAAU,CAACD,CAAC,CAACrF,KAAF,IAAW,CAAZ,KAAkBsF,CAAC,CAACtF,KAAF,IAAW,CAA7B,CAAjB,EAAkDkF,aAAlD,CAA7B;IAEA,MAAMK,kBAAkB,cAAGnG,CAAC,CAACoG,IAAF,CAAOL,oBAAP,CAAH,4CAAG,QAA8BnF,KAAzD;IACA,MAAMyF,qBAAqB,cAAGrG,CAAC,CAACsG,IAAF,CAAOP,oBAAP,CAAH,4CAAG,QAA8BnF,KAA5D;;IAEA,IAAIZ,CAAC,CAACgF,KAAF,CAAQmB,kBAAR,KAA+BnG,CAAC,CAACgF,KAAF,CAAQqB,qBAAR,CAAnC,EAAmE;MAC/D;IACH;;IAED,MAAMb,UAAU,GAAGxF,CAAC,CAACuG,GAAF,CAAMJ,kBAAkB,GAAG1E,uBAA3B,EAAoD,CAApD,CAAnB;IACA,MAAMgE,QAAQ,GAAGzF,CAAC,CAAC2C,GAAF,CAAM0D,qBAAqB,GAAG5E,uBAA9B,EAAuDyB,UAAU,CAACe,MAAX,GAAoB,CAA3E,CAAjB;IAEAzB,4BAA4B,CAACY,OAA7B,GAAuC,CAACoC,UAAD,EAAaC,QAAQ,GAAG,CAAxB,CAAvC;IAEAG,iBAAiB;EACpB,CAhBoC,CAArC;EAkBA,MAAMY,UAAqC,GAAG9G,WAAW,CAAC,SAAqB;IAAA;;IAAA,IAApB;MAAEgB,IAAF;MAAQE;IAAR,CAAoB;;IAC3E,MAAM6F,OAAO,GAAG,MAAM;MAClBrC,gBAAgB,CAAC,CAAClD,UAAD,EAAa+D,CAAb,KAAmB;QAChC,MAAM5D,QAAQ,GAAGH,UAAU,CAACG,QAA5B;;QAEA,IAAI4D,CAAC,KAAKrE,KAAN,IAAeS,QAAQ,KAAKiE,SAAhC,EAA2C;UACvC,OAAO,EACH,GAAGpE,UADA;YAEHF,eAAe,EAAEE,UAAU,CAACF,eAAX,GAA6B,CAF3C;YAGHK,QAAQ,EAAE,EACN,GAAGA,QADG;cAENE,QAAQ,EAAE;YAFJ;UAHP,CAAP;QAQH;;QAED,OAAOL,UAAP;MACH,CAfe,CAAhB;;MAiBA,IAAIR,IAAI,CAACY,mBAAT,EAA8B;QAC1B;MACH;;MAED,MAAM,CAACkE,UAAD,EAAaC,QAAb,IAAyBjD,4BAA4B,CAACY,OAA5D;;MACA,IAAIxC,KAAK,IAAI4E,UAAT,IAAuB5E,KAAK,GAAG6E,QAAnC,EAA6C;QACzCG,iBAAiB;MACpB;IACJ,CA1BD;;IA4BA,MAAMc,aAAa,GAAG,MAAM;MACxB,MAAM,CAAClB,UAAD,EAAaC,QAAb,IAAyBjD,4BAA4B,CAACY,OAA5D;;MACA,IAAIxC,KAAK,IAAI4E,UAAT,IAAuB5E,KAAK,GAAG6E,QAAnC,EAA6C;QACzCd,cAAc,CAAC,CAAC/D,KAAD,CAAD,CAAd;MACH;IACJ,CALD;;IAOA,MAAM+F,MAAM,GAAG,MAAM;MACjBvC,gBAAgB,CAAC,CAAClD,UAAD,EAAa+D,CAAb,KAAmB;QAChC,MAAM5D,QAAQ,GAAGH,UAAU,CAACG,QAA5B;;QAEA,IAAI4D,CAAC,KAAKrE,KAAN,IAAeS,QAAQ,KAAKiE,SAAhC,EAA2C;UACvC,OAAO,EACH,GAAGpE,UADA;YAEHG,QAAQ,EAAE,EACN,GAAGA,QADG;cAENE,QAAQ,EAAE;YAFJ;UAFP,CAAP;QAOH;;QAED,OAAOL,UAAP;MACH,CAde,CAAhB;IAeH,CAhBD;;IAkBA,oBACI,oBAAC,UAAD;MACI,OAAO,EAAEuF,OADb;MAEI,MAAM,EAAEE,MAFZ;MAGI,OAAO,EAAExE,WAHb;MAII,aAAa,EAAEuE,aAJnB;MAKI,GAAG,EAAEhG,IAAI,CAACU,GALd;MAMI,KAAK,EAAE,0BAAAiC,kBAAkB,CAACzC,KAAD,CAAlB,gFAA2B2C,KAA3B,KAAoC,CAN/C;MAOI,MAAM,EAAE,2BAAAF,kBAAkB,CAACzC,KAAD,CAAlB,kFAA2B4C,MAA3B,KAAqC,CAPjD;MAQI,mBAAmB,EAAE9C,IAAI,CAACY;IAR9B,EADJ;EAYH,CAlEwD,EAkEtD,CAACa,WAAD,EAAckB,kBAAd,CAlEsD,CAAzD;EAoEA1D,SAAS,CAAC,MAAM;IACZ,MAAMuE,MAAM,GAAGxB,IAAI,CAACkE,KAAL,CAAY7E,uBAAuB,GAAG,GAA3B,GAAkC4B,WAA7C,CAAf;;IAEA,IAAIpB,WAAW,CAACa,OAAhB,EAAyB;MACrBb,WAAW,CAACa,OAAZ,CAAoByD,cAApB,CAAmC;QAAE3C,MAAF;QAAU4C,QAAQ,EAAE;MAApB,CAAnC;IACH;EACJ,CANQ,EAMN,EANM,CAAT;EAQA,oBACI,oBAAC,QAAD;IACI,IAAI,EAAE5D,UADV;IAEI,aAAa,EAAEa,aAFnB;IAGI,kBAAkB,EAAEjC,kBAHxB;IAII,YAAY,EAAErB,YAJlB;IAKI,sBAAsB,EAAEoF,sBAAsB,CAACzC,OALnD;IAMI,GAAG,EAAEb,WANT;IAOI,UAAU,EAAEiE,UAPhB;IAQI,iBAAiB,EAAErC,iBARvB;IASI,UAAU,EAAE9B;EAThB,GAUQC,UAVR,EADJ;AAcH;AAAA"}
|
|
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;
|
|
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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fountain-ui/lab",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
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": "
|
|
73
|
+
"gitHead": "928b060600a7fc8cd8eccd59c573aca76cdcbec6"
|
|
74
74
|
}
|
|
@@ -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
|
|
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
|
|
136
|
-
|
|
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 =
|
|
178
|
+
const loadMaybeLoadableItems = () => {
|
|
174
179
|
const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;
|
|
175
180
|
const affectedIndexes = R.range(startIndex, endIndex);
|
|
176
181
|
|
|
177
|
-
|
|
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
|
};
|