@fountain-ui/lab 2.0.0-beta.44 → 2.0.0-beta.46
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 +45 -8
- package/build/commonjs/ComicViewer/ComicViewer.js.map +1 -1
- package/build/commonjs/ComicViewer/ComicViewerProps.js.map +1 -1
- package/build/commonjs/ComicViewer/FastScroll.js +162 -0
- package/build/commonjs/ComicViewer/FastScroll.js.map +1 -0
- package/build/commonjs/ComicViewer/FastScrollProps.js +6 -0
- package/build/commonjs/ComicViewer/FastScrollProps.js.map +1 -0
- package/build/commonjs/ComicViewer/ViewerItem.js +4 -2
- package/build/commonjs/ComicViewer/ViewerItem.js.map +1 -1
- package/build/commonjs/ComicViewer/index.js.map +1 -1
- package/build/commonjs/ComicViewer/util.js +27 -0
- package/build/commonjs/ComicViewer/util.js.map +1 -0
- package/build/module/ComicViewer/ComicViewer.js +44 -8
- package/build/module/ComicViewer/ComicViewer.js.map +1 -1
- package/build/module/ComicViewer/ComicViewerProps.js.map +1 -1
- package/build/module/ComicViewer/FastScroll.js +141 -0
- package/build/module/ComicViewer/FastScroll.js.map +1 -0
- package/build/module/ComicViewer/FastScrollProps.js +2 -0
- package/build/module/ComicViewer/FastScrollProps.js.map +1 -0
- package/build/module/ComicViewer/ViewerItem.js +4 -2
- package/build/module/ComicViewer/ViewerItem.js.map +1 -1
- package/build/module/ComicViewer/index.js.map +1 -1
- package/build/module/ComicViewer/util.js +15 -0
- package/build/module/ComicViewer/util.js.map +1 -0
- package/build/typescript/AnimatedY/AnimatedY.d.ts +1 -0
- package/build/typescript/BottomSheet/BottomSheetNative.d.ts +1 -0
- package/build/typescript/BottomSheet/BottomSheetWeb.d.ts +1 -0
- package/build/typescript/BottomSheet/TransparentBackdrop.d.ts +1 -0
- package/build/typescript/ComicViewer/ComicViewer.d.ts +1 -0
- package/build/typescript/ComicViewer/ComicViewerProps.d.ts +10 -0
- package/build/typescript/ComicViewer/FastScroll.d.ts +4 -0
- package/build/typescript/ComicViewer/FastScrollProps.d.ts +70 -0
- package/build/typescript/ComicViewer/ReloadButton.d.ts +1 -0
- package/build/typescript/ComicViewer/ViewerItem.d.ts +5 -0
- package/build/typescript/ComicViewer/index.d.ts +1 -0
- package/build/typescript/ComicViewer/util.d.ts +2 -0
- package/build/typescript/DateTimePicker/DateTimePicker.d.ts +1 -0
- package/build/typescript/DateTimePicker/YearPicker.d.ts +1 -0
- package/build/typescript/FlipCard/FlipCard.d.ts +1 -0
- package/build/typescript/StatusBarProvider/StatusBarProvider.d.ts +1 -0
- package/build/typescript/ViewabilityTrackerView/ViewabilityTrackerView.d.ts +1 -0
- package/package.json +3 -3
- package/src/ComicViewer/ComicViewer.tsx +60 -19
- package/src/ComicViewer/ComicViewerProps.ts +12 -0
- package/src/ComicViewer/FastScroll.tsx +158 -0
- package/src/ComicViewer/FastScrollProps.ts +83 -0
- package/src/ComicViewer/ViewerItem.tsx +8 -1
- package/src/ComicViewer/index.ts +6 -0
- package/src/ComicViewer/util.ts +15 -0
- package/yarn-error.log +103 -0
|
@@ -5,6 +5,7 @@ import { FlatList } from 'react-native';
|
|
|
5
5
|
import * as R from 'ramda';
|
|
6
6
|
import { useDebounce } from '@fountain-ui/core';
|
|
7
7
|
import ViewerItem from './ViewerItem';
|
|
8
|
+
import FastScroll from './FastScroll';
|
|
8
9
|
|
|
9
10
|
const appender = (left, right) => [left + right, left + right];
|
|
10
11
|
|
|
@@ -29,12 +30,14 @@ const mapImageStateToItemState = (index, imageState, autoHandleErrorCount) => {
|
|
|
29
30
|
};
|
|
30
31
|
};
|
|
31
32
|
|
|
33
|
+
const mapIndexed = R.addIndex(R.map);
|
|
32
34
|
const MAXIMUM_WIDTH = 720;
|
|
33
35
|
const NUMBER_OF_ADJACENT_ITEM = 5;
|
|
34
36
|
export default function ComicViewer(props) {
|
|
35
37
|
const {
|
|
36
38
|
debounceMillis = 100,
|
|
37
39
|
autoHandleErrorCount = 3,
|
|
40
|
+
fastScrollOptions,
|
|
38
41
|
getUrlByIndex,
|
|
39
42
|
initialNumToRender = 1,
|
|
40
43
|
initialScrollPercentage = 0,
|
|
@@ -42,10 +45,13 @@ export default function ComicViewer(props) {
|
|
|
42
45
|
intrinsicDimensions,
|
|
43
46
|
maxContentWidth = MAXIMUM_WIDTH,
|
|
44
47
|
onItemPress,
|
|
48
|
+
onScroll,
|
|
45
49
|
viewportWidth,
|
|
50
|
+
invisiblePaddingTop = 0,
|
|
46
51
|
windowSize = 3,
|
|
47
52
|
...otherProps
|
|
48
53
|
} = props;
|
|
54
|
+
const fastScrollRef = fastScrollOptions === null || fastScrollOptions === void 0 ? void 0 : fastScrollOptions.ref;
|
|
49
55
|
const flatListRef = useRef(null);
|
|
50
56
|
const maybeLoadableItemsIndexRange = useRef([-1, 0]);
|
|
51
57
|
const actualImageWidth = Math.min(viewportWidth, maxContentWidth);
|
|
@@ -60,9 +66,9 @@ export default function ComicViewer(props) {
|
|
|
60
66
|
return mapImageStatesToItemStates(imageStatesRef.current);
|
|
61
67
|
});
|
|
62
68
|
const renderedDimensions = useMemo(() => {
|
|
63
|
-
return
|
|
69
|
+
return mapIndexed((intrinsicDimension, index) => ({
|
|
64
70
|
width: actualImageWidth,
|
|
65
|
-
height: intrinsicDimension.height * actualImageWidth / intrinsicDimension.width
|
|
71
|
+
height: intrinsicDimension.height * actualImageWidth / intrinsicDimension.width + (index === 0 ? invisiblePaddingTop : 0)
|
|
66
72
|
}), intrinsicDimensions);
|
|
67
73
|
}, [actualImageWidth]);
|
|
68
74
|
const layoutFromDimensions = useCallback(() => {
|
|
@@ -104,7 +110,7 @@ export default function ComicViewer(props) {
|
|
|
104
110
|
var _state$urlState;
|
|
105
111
|
|
|
106
112
|
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'
|
|
113
|
+
return !state.isNewUrlIncoming && (R.isNil(state.urlState) || ((_state$urlState = state.urlState) === null || _state$urlState === void 0 ? void 0 : _state$urlState.validity) === 'invalid');
|
|
108
114
|
}, indexes);
|
|
109
115
|
updateImageState((imageState, i) => {
|
|
110
116
|
return R.includes(i, filteredIndexes) ? { ...imageState,
|
|
@@ -129,6 +135,7 @@ export default function ComicViewer(props) {
|
|
|
129
135
|
|
|
130
136
|
return imageState;
|
|
131
137
|
});
|
|
138
|
+
} catch (e) {// ignore
|
|
132
139
|
} finally {
|
|
133
140
|
updateImageState((imageState, i) => {
|
|
134
141
|
return R.includes(i, filteredIndexes) ? { ...imageState,
|
|
@@ -138,12 +145,13 @@ export default function ComicViewer(props) {
|
|
|
138
145
|
}
|
|
139
146
|
};
|
|
140
147
|
|
|
141
|
-
const loadMaybeLoadableItems =
|
|
148
|
+
const loadMaybeLoadableItems = () => {
|
|
142
149
|
const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;
|
|
143
150
|
const affectedIndexes = R.range(startIndex, endIndex);
|
|
144
|
-
|
|
151
|
+
loadUrlByIndex(affectedIndexes);
|
|
145
152
|
};
|
|
146
153
|
|
|
154
|
+
const ignoreDebounce = useRef(true);
|
|
147
155
|
const loadItemsDebounce = useDebounce(loadMaybeLoadableItems, debounceMillis);
|
|
148
156
|
const onViewableItemsChanged = useRef(_ref => {
|
|
149
157
|
var _R$head, _R$last;
|
|
@@ -162,8 +170,31 @@ export default function ComicViewer(props) {
|
|
|
162
170
|
const startIndex = R.max(firstViewableIndex - NUMBER_OF_ADJACENT_ITEM, 0);
|
|
163
171
|
const endIndex = R.min(lastViewableItemIndex + NUMBER_OF_ADJACENT_ITEM, itemStates.length - 1);
|
|
164
172
|
maybeLoadableItemsIndexRange.current = [startIndex, endIndex + 1];
|
|
173
|
+
|
|
174
|
+
if (ignoreDebounce.current) {
|
|
175
|
+
loadMaybeLoadableItems();
|
|
176
|
+
ignoreDebounce.current = false;
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
|
|
165
180
|
loadItemsDebounce();
|
|
166
181
|
});
|
|
182
|
+
const handleScroll = useCallback(event => {
|
|
183
|
+
var _fastScrollRef$curren;
|
|
184
|
+
|
|
185
|
+
fastScrollRef === null || fastScrollRef === void 0 ? void 0 : (_fastScrollRef$curren = fastScrollRef.current) === null || _fastScrollRef$curren === void 0 ? void 0 : _fastScrollRef$curren.onContentScroll(event);
|
|
186
|
+
onScroll === null || onScroll === void 0 ? void 0 : onScroll(event);
|
|
187
|
+
}, [onScroll]);
|
|
188
|
+
|
|
189
|
+
const scrollContentToOffset = offset => {
|
|
190
|
+
var _flatListRef$current;
|
|
191
|
+
|
|
192
|
+
(_flatListRef$current = flatListRef.current) === null || _flatListRef$current === void 0 ? void 0 : _flatListRef$current.scrollToOffset({
|
|
193
|
+
offset,
|
|
194
|
+
animated: false
|
|
195
|
+
});
|
|
196
|
+
};
|
|
197
|
+
|
|
167
198
|
const renderItem = useCallback(_ref2 => {
|
|
168
199
|
var _renderedDimensions$i, _renderedDimensions$i2;
|
|
169
200
|
|
|
@@ -229,6 +260,7 @@ export default function ComicViewer(props) {
|
|
|
229
260
|
onPress: onItemPress,
|
|
230
261
|
onReloadPress: onReloadPress,
|
|
231
262
|
url: item.url,
|
|
263
|
+
invisiblePaddingTop: index === 0 ? invisiblePaddingTop : 0,
|
|
232
264
|
width: ((_renderedDimensions$i = renderedDimensions[index]) === null || _renderedDimensions$i === void 0 ? void 0 : _renderedDimensions$i.width) ?? 0,
|
|
233
265
|
height: ((_renderedDimensions$i2 = renderedDimensions[index]) === null || _renderedDimensions$i2 === void 0 ? void 0 : _renderedDimensions$i2.height) ?? 0,
|
|
234
266
|
reloadButtonVisible: item.reloadButtonVisible
|
|
@@ -244,7 +276,7 @@ export default function ComicViewer(props) {
|
|
|
244
276
|
});
|
|
245
277
|
}
|
|
246
278
|
}, []);
|
|
247
|
-
return /*#__PURE__*/React.createElement(FlatList, _extends({
|
|
279
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(FlatList, _extends({
|
|
248
280
|
data: itemStates,
|
|
249
281
|
getItemLayout: getItemLayout,
|
|
250
282
|
initialNumToRender: initialNumToRender,
|
|
@@ -253,8 +285,12 @@ export default function ComicViewer(props) {
|
|
|
253
285
|
ref: flatListRef,
|
|
254
286
|
renderItem: renderItem,
|
|
255
287
|
viewabilityConfig: viewabilityConfig,
|
|
256
|
-
windowSize: windowSize
|
|
257
|
-
|
|
288
|
+
windowSize: windowSize,
|
|
289
|
+
onScroll: handleScroll
|
|
290
|
+
}, otherProps)), /*#__PURE__*/React.createElement(FastScroll, _extends({}, fastScrollOptions, {
|
|
291
|
+
contentLength: totalHeight,
|
|
292
|
+
scrollContentToOffset: scrollContentToOffset
|
|
293
|
+
})));
|
|
258
294
|
}
|
|
259
295
|
;
|
|
260
296
|
//# sourceMappingURL=ComicViewer.js.map
|
|
@@ -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","FastScroll","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","fastScrollOptions","getUrlByIndex","initialNumToRender","initialScrollPercentage","itemVisiblePercentThreshold","intrinsicDimensions","maxContentWidth","onItemPress","onScroll","viewportWidth","invisiblePaddingTop","windowSize","otherProps","fastScrollRef","ref","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","handleScroll","event","onContentScroll","scrollContentToOffset","scrollToOffset","animated","renderItem","onError","onReloadPress","onLoad","floor"],"sources":["ComicViewer.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { FlatList, ListRenderItem, NativeScrollEvent, NativeSyntheticEvent, ViewToken } from 'react-native';\nimport * as R from 'ramda';\nimport { useDebounce } from '@fountain-ui/core';\nimport { default as ComicViewerProps, Dimension } from './ComicViewerProps';\nimport ViewerItem from './ViewerItem';\nimport FastScroll from './FastScroll';\n\nconst appender = (left: number, right: number): [number, number] => [left + right, left + right];\nconst getHeightAccum = (heights: number[]): [number, number[]] => R.mapAccum(appender, 0, heights);\n\nconst keyExtractor = <T, >(item: ItemState) => String(item.index);\n\ninterface UrlState {\n url: string;\n validity: 'valid' | 'invalid' | 'unknown';\n}\n\ninterface ImageState {\n urlState?: UrlState;\n 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 fastScrollOptions,\n getUrlByIndex,\n initialNumToRender = 1,\n initialScrollPercentage = 0,\n itemVisiblePercentThreshold = 0,\n intrinsicDimensions,\n maxContentWidth = MAXIMUM_WIDTH,\n onItemPress,\n onScroll,\n viewportWidth,\n invisiblePaddingTop = 0,\n windowSize = 3,\n ...otherProps\n } = props;\n\n const fastScrollRef = fastScrollOptions?.ref;\n\n const flatListRef = useRef<FlatList>(null);\n\n const 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 handleScroll = useCallback((event: NativeSyntheticEvent<NativeScrollEvent>) => {\n fastScrollRef?.current?.onContentScroll(event);\n\n onScroll?.(event);\n }, [onScroll]);\n\n const scrollContentToOffset = (offset: number) => {\n flatListRef.current?.scrollToOffset({\n offset,\n animated: false,\n });\n };\n\n const renderItem: ListRenderItem<ItemState> = useCallback(({ item, index }) => {\n const 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 <React.Fragment>\n <FlatList\n data={itemStates}\n getItemLayout={getItemLayout}\n initialNumToRender={initialNumToRender}\n keyExtractor={keyExtractor}\n onViewableItemsChanged={onViewableItemsChanged.current}\n ref={flatListRef}\n renderItem={renderItem}\n viewabilityConfig={viewabilityConfig}\n windowSize={windowSize}\n onScroll={handleScroll}\n {...otherProps}\n />\n\n <FastScroll\n {...fastScrollOptions}\n contentLength={totalHeight}\n scrollContentToOffset={scrollContentToOffset}\n />\n </React.Fragment>\n );\n};\n"],"mappings":"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"}
|
|
@@ -1 +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';\nimport { FastScrollOptions } from './FastScrollProps';\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 * Options for fastscroll component.\n */\n fastScrollOptions: FastScrollOptions;\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":""}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import React, { useEffect, useImperativeHandle, useRef, useState } from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
|
|
4
|
+
import Animated, { runOnJS, useAnimatedStyle, useSharedValue, withDelay, withTiming } from 'react-native-reanimated';
|
|
5
|
+
import { ChevronDown, ChevronUp } from '@fountain-ui/icons';
|
|
6
|
+
import { StyleSheet } from '@fountain-ui/core';
|
|
7
|
+
import { offsetToPercentage, percentageToOffset } from './util';
|
|
8
|
+
const styles = StyleSheet.create({
|
|
9
|
+
indicator: {
|
|
10
|
+
width: 24,
|
|
11
|
+
height: 40,
|
|
12
|
+
backgroundColor: '#767676',
|
|
13
|
+
flexDirection: 'column',
|
|
14
|
+
alignItems: 'center',
|
|
15
|
+
borderRadius: 4
|
|
16
|
+
},
|
|
17
|
+
view: {
|
|
18
|
+
position: 'absolute'
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
const FastScroll = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
22
|
+
const {
|
|
23
|
+
absolutePosition,
|
|
24
|
+
additionalLength = 0,
|
|
25
|
+
contentLength,
|
|
26
|
+
movementRange,
|
|
27
|
+
scrollContentToOffset,
|
|
28
|
+
visibleDurations = {
|
|
29
|
+
hideMillis: 200,
|
|
30
|
+
showMillis: 350
|
|
31
|
+
}
|
|
32
|
+
} = props;
|
|
33
|
+
const lastIndicatorOffset = useSharedValue(0);
|
|
34
|
+
const indicatorOffset = useSharedValue(lastIndicatorOffset.value);
|
|
35
|
+
const isIndicatorDragging = useRef(false);
|
|
36
|
+
const indicatorOpacity = useSharedValue(1);
|
|
37
|
+
const [visible, setVisible] = useState(true);
|
|
38
|
+
const animatedStyle = useAnimatedStyle(() => ({
|
|
39
|
+
transform: [{
|
|
40
|
+
translateY: indicatorOffset.value
|
|
41
|
+
}],
|
|
42
|
+
opacity: indicatorOpacity.value
|
|
43
|
+
}));
|
|
44
|
+
const totalContentLength = contentLength + additionalLength;
|
|
45
|
+
|
|
46
|
+
const onContentScroll = event => {
|
|
47
|
+
if (isIndicatorDragging.current === false) {
|
|
48
|
+
const contentPercentage = offsetToPercentage(event.nativeEvent.contentOffset.y, totalContentLength);
|
|
49
|
+
const offset = percentageToOffset(contentPercentage, movementRange);
|
|
50
|
+
|
|
51
|
+
if (offset < 0 || indicatorOffset.value < 0) {
|
|
52
|
+
lastIndicatorOffset.value = 0;
|
|
53
|
+
indicatorOffset.value = 0;
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (offset > movementRange || indicatorOffset.value > movementRange) {
|
|
58
|
+
lastIndicatorOffset.value = movementRange;
|
|
59
|
+
indicatorOffset.value = movementRange;
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
lastIndicatorOffset.value = offset;
|
|
64
|
+
} else {
|
|
65
|
+
setVisible(true);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const getIsIndicatorDragging = () => isIndicatorDragging.current;
|
|
70
|
+
|
|
71
|
+
useImperativeHandle(ref, () => ({
|
|
72
|
+
getIsIndicatorDragging,
|
|
73
|
+
onContentScroll,
|
|
74
|
+
setVisible
|
|
75
|
+
}), []);
|
|
76
|
+
|
|
77
|
+
const handleUpdate = () => {
|
|
78
|
+
const contentPercentage = offsetToPercentage(indicatorOffset.value, movementRange);
|
|
79
|
+
const offset = percentageToOffset(contentPercentage, totalContentLength);
|
|
80
|
+
scrollContentToOffset(offset);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const setIsIndicatorDragging = value => isIndicatorDragging.current = value;
|
|
84
|
+
|
|
85
|
+
const pan = Gesture.Pan().onBegin(e => {
|
|
86
|
+
indicatorOffset.value = lastIndicatorOffset.value;
|
|
87
|
+
runOnJS(setIsIndicatorDragging)(true);
|
|
88
|
+
}).onUpdate(e => {
|
|
89
|
+
if (indicatorOffset.value <= 0 && e.translationY < 0) {
|
|
90
|
+
indicatorOffset.value = 0;
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (indicatorOffset.value >= movementRange && e.translationY > 0) {
|
|
95
|
+
indicatorOffset.value = movementRange;
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
indicatorOffset.value = lastIndicatorOffset.value + e.translationY;
|
|
100
|
+
runOnJS(handleUpdate)();
|
|
101
|
+
}).onFinalize(e => {
|
|
102
|
+
lastIndicatorOffset.value = indicatorOffset.value;
|
|
103
|
+
runOnJS(setIsIndicatorDragging)(false);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const hide = () => indicatorOpacity.value = withDelay(0, withTiming(0, {
|
|
107
|
+
duration: visibleDurations.hideMillis
|
|
108
|
+
}));
|
|
109
|
+
|
|
110
|
+
const show = () => indicatorOpacity.value = withDelay(0, withTiming(1, {
|
|
111
|
+
duration: visibleDurations.showMillis
|
|
112
|
+
}));
|
|
113
|
+
|
|
114
|
+
useEffect(() => {
|
|
115
|
+
if (visible) {
|
|
116
|
+
indicatorOffset.value = lastIndicatorOffset.value;
|
|
117
|
+
show();
|
|
118
|
+
} else {
|
|
119
|
+
hide();
|
|
120
|
+
}
|
|
121
|
+
}, [visible]);
|
|
122
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
123
|
+
style: [{
|
|
124
|
+
height: movementRange
|
|
125
|
+
}, styles.view, absolutePosition]
|
|
126
|
+
}, /*#__PURE__*/React.createElement(GestureDetector, {
|
|
127
|
+
gesture: pan
|
|
128
|
+
}, /*#__PURE__*/React.createElement(Animated.View, {
|
|
129
|
+
style: [animatedStyle, styles.indicator]
|
|
130
|
+
}, /*#__PURE__*/React.createElement(ChevronUp, {
|
|
131
|
+
fill: '#ededed',
|
|
132
|
+
height: 20,
|
|
133
|
+
width: 20
|
|
134
|
+
}), /*#__PURE__*/React.createElement(ChevronDown, {
|
|
135
|
+
fill: '#ededed',
|
|
136
|
+
height: 20,
|
|
137
|
+
width: 20
|
|
138
|
+
}))));
|
|
139
|
+
});
|
|
140
|
+
export default FastScroll;
|
|
141
|
+
//# sourceMappingURL=FastScroll.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["React","useEffect","useImperativeHandle","useRef","useState","View","Gesture","GestureDetector","Animated","runOnJS","useAnimatedStyle","useSharedValue","withDelay","withTiming","ChevronDown","ChevronUp","StyleSheet","offsetToPercentage","percentageToOffset","styles","create","indicator","width","height","backgroundColor","flexDirection","alignItems","borderRadius","view","position","FastScroll","forwardRef","props","ref","absolutePosition","additionalLength","contentLength","movementRange","scrollContentToOffset","visibleDurations","hideMillis","showMillis","lastIndicatorOffset","indicatorOffset","value","isIndicatorDragging","indicatorOpacity","visible","setVisible","animatedStyle","transform","translateY","opacity","totalContentLength","onContentScroll","event","current","contentPercentage","nativeEvent","contentOffset","y","offset","getIsIndicatorDragging","handleUpdate","setIsIndicatorDragging","pan","Pan","onBegin","e","onUpdate","translationY","onFinalize","hide","duration","show"],"sources":["FastScroll.tsx"],"sourcesContent":["import React, { useEffect, useImperativeHandle, useRef, useState } from 'react';\nimport { NativeScrollEvent, NativeSyntheticEvent, View } from 'react-native';\nimport { Gesture, GestureDetector } from 'react-native-gesture-handler';\nimport Animated, { runOnJS, useAnimatedStyle, useSharedValue, withDelay, withTiming } from 'react-native-reanimated';\nimport { ChevronDown, ChevronUp } from '@fountain-ui/icons';\nimport { StyleSheet } from '@fountain-ui/core';\nimport FastScrollProps from './FastScrollProps';\nimport { offsetToPercentage, percentageToOffset } from './util';\n\nconst styles = StyleSheet.create({\n indicator: {\n width: 24,\n height: 40,\n backgroundColor: '#767676',\n flexDirection: 'column',\n alignItems: 'center',\n borderRadius: 4,\n },\n view: { position: 'absolute' },\n});\n\nconst FastScroll = React.forwardRef((props: FastScrollProps, ref) => {\n const {\n absolutePosition,\n additionalLength = 0,\n contentLength,\n movementRange,\n scrollContentToOffset,\n visibleDurations = { hideMillis: 200, showMillis: 350 },\n } = props;\n\n const lastIndicatorOffset = useSharedValue(0);\n const indicatorOffset = useSharedValue(lastIndicatorOffset.value);\n\n const isIndicatorDragging = useRef(false);\n\n const indicatorOpacity = useSharedValue(1);\n const [visible, setVisible] = useState(true);\n\n const animatedStyle = useAnimatedStyle(() => ({\n transform: [{ translateY: indicatorOffset.value }],\n opacity: indicatorOpacity.value,\n }));\n\n const totalContentLength = contentLength + additionalLength;\n\n const onContentScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {\n if (isIndicatorDragging.current === false) {\n const contentPercentage = offsetToPercentage(event.nativeEvent.contentOffset.y, totalContentLength);\n const offset = percentageToOffset(contentPercentage, movementRange);\n\n if (offset < 0 || indicatorOffset.value < 0) {\n lastIndicatorOffset.value = 0;\n indicatorOffset.value = 0;\n return;\n }\n\n if (offset > movementRange || indicatorOffset.value > movementRange) {\n lastIndicatorOffset.value = movementRange;\n indicatorOffset.value = movementRange;\n return;\n }\n\n lastIndicatorOffset.value = offset;\n } else {\n setVisible(true);\n }\n };\n\n const getIsIndicatorDragging = () => isIndicatorDragging.current;\n\n useImperativeHandle(\n ref,\n () => ({\n getIsIndicatorDragging,\n onContentScroll,\n setVisible,\n }),\n [],\n );\n\n const handleUpdate = () => {\n const contentPercentage = offsetToPercentage(indicatorOffset.value, movementRange);\n const offset = percentageToOffset(contentPercentage, totalContentLength);\n\n scrollContentToOffset(offset);\n };\n\n const setIsIndicatorDragging = (value: boolean) => isIndicatorDragging.current = value;\n\n const pan = Gesture.Pan()\n .onBegin((e) => {\n indicatorOffset.value = lastIndicatorOffset.value;\n runOnJS(setIsIndicatorDragging)(true);\n })\n .onUpdate((e) => {\n if (indicatorOffset.value <= 0 && e.translationY < 0) {\n indicatorOffset.value = 0;\n return;\n }\n\n if (indicatorOffset.value >= movementRange && e.translationY > 0) {\n indicatorOffset.value = movementRange;\n return;\n }\n\n indicatorOffset.value = lastIndicatorOffset.value + e.translationY;\n\n runOnJS(handleUpdate)();\n })\n .onFinalize((e) => {\n lastIndicatorOffset.value = indicatorOffset.value;\n runOnJS(setIsIndicatorDragging)(false);\n });\n\n const hide = () => indicatorOpacity.value = withDelay(0, withTiming(0, { duration: visibleDurations.hideMillis }));\n\n const show = () => indicatorOpacity.value = withDelay(0, withTiming(1, { duration: visibleDurations.showMillis }));\n\n useEffect(() => {\n if (visible) {\n indicatorOffset.value = lastIndicatorOffset.value;\n show();\n } else {\n hide();\n }\n }, [visible]);\n\n return (\n <View\n style={[\n { height: movementRange },\n styles.view,\n absolutePosition,\n ]}\n >\n <GestureDetector gesture={pan}>\n <Animated.View style={[\n animatedStyle,\n styles.indicator,\n ]}>\n <ChevronUp\n fill={'#ededed'}\n height={20}\n width={20}\n />\n <ChevronDown\n fill={'#ededed'}\n height={20}\n width={20}\n />\n </Animated.View>\n </GestureDetector>\n </View>\n );\n});\n\nexport default FastScroll;"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["FastScrollProps.ts"],"sourcesContent":["import React from 'react';\nimport { NativeScrollEvent, NativeSyntheticEvent } from 'react-native';\nimport type { RefObject } from 'react';\n\n/**\n * Position infos with display: 'position'.\n */\nexport type AbsolutePosition = {\n top: number;\n bottom: number;\n right: number;\n left: number;\n};\n\n/**\n * Durations(millis) for show, hide animation.\n */\nexport type VisibleDurations = {\n hideMillis: number;\n showMillis: number;\n}\n\nexport interface FastScrollInstance {\n /**\n * Handle content scroll event, not using fast scroll indicator.\n * @param event Function onScroll event params.\n */\n onContentScroll: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;\n\n /**\n * Set indicator visible state.\n */\n setVisible: React.Dispatch<React.SetStateAction<boolean>>;\n\n /**\n * Return true, if pan gesture state is begin to finalize.\n */\n getIsIndicatorDragging: () => boolean,\n}\n\nexport interface FastScrollOptions {\n /**\n * Ref for React.forwardRef.\n */\n ref: RefObject<FastScrollInstance>;\n\n /**\n * Range within which the indicator can move.\n */\n movementRange: number;\n\n /**\n * Scrollbar positions for 'display: position'.\n */\n absolutePosition?: Partial<AbsolutePosition>;\n\n /**\n * Durations(millis) for show, hide animation.\n * @default { hide: 200, show: 350 }\n */\n visibleDurations?: VisibleDurations;\n\n /**\n * Additional height except contentLength.\n * @default 0\n */\n additionalLength?: number;\n}\n\ninterface FastScrollProps extends FastScrollOptions {\n /**\n * Total length of scrollable content.\n */\n contentLength: number;\n\n /**\n * Scroll content to offset appropriate for the indicator location.\n * @param offset Content offset.\n */\n scrollContentToOffset: (offset: number) => void;\n}\n\nexport default FastScrollProps;\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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["default"],"sources":["index.ts"],"sourcesContent":["export { default } from './ComicViewer';\nexport type { Dimension, default as ComicViewerProps } from './ComicViewerProps';\nexport type { ViewerItemProps } from './ViewerItem';\n"],"mappings":"AAAA,SAASA,OAAT,QAAwB,eAAxB"}
|
|
1
|
+
{"version":3,"names":["default"],"sources":["index.ts"],"sourcesContent":["export { default } from './ComicViewer';\nexport type { Dimension, default as ComicViewerProps } from './ComicViewerProps';\nexport type { ViewerItemProps } from './ViewerItem';\nexport type {\n AbsolutePosition,\n FastScrollInstance,\n FastScrollOptions,\n VisibleDurations,\n} from './FastScrollProps';\n"],"mappings":"AAAA,SAASA,OAAT,QAAwB,eAAxB"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const offsetToPercentage = (offset, total) => {
|
|
2
|
+
if (offset === 0 || total === 0) {
|
|
3
|
+
return 0;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
return offset / total * 100;
|
|
7
|
+
};
|
|
8
|
+
export const percentageToOffset = (percentage, total) => {
|
|
9
|
+
if (percentage === 0 || total === 0) {
|
|
10
|
+
return 0;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return percentage / 100 * total;
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["offsetToPercentage","offset","total","percentageToOffset","percentage"],"sources":["util.ts"],"sourcesContent":["export const offsetToPercentage = (offset: number, total: number) => {\n if (offset === 0 || total === 0) {\n return 0;\n }\n\n return offset / total * 100;\n};\n\nexport const percentageToOffset = (percentage: number, total: number) => {\n if (percentage === 0 || total === 0) {\n return 0;\n }\n\n return percentage / 100 * total;\n};\n"],"mappings":"AAAA,OAAO,MAAMA,kBAAkB,GAAG,CAACC,MAAD,EAAiBC,KAAjB,KAAmC;EACjE,IAAID,MAAM,KAAK,CAAX,IAAgBC,KAAK,KAAK,CAA9B,EAAiC;IAC7B,OAAO,CAAP;EACH;;EAED,OAAOD,MAAM,GAAGC,KAAT,GAAiB,GAAxB;AACH,CANM;AAQP,OAAO,MAAMC,kBAAkB,GAAG,CAACC,UAAD,EAAqBF,KAArB,KAAuC;EACrE,IAAIE,UAAU,KAAK,CAAf,IAAoBF,KAAK,KAAK,CAAlC,EAAqC;IACjC,OAAO,CAAP;EACH;;EAED,OAAOE,UAAU,GAAG,GAAb,GAAmBF,KAA1B;AACH,CANM"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ComponentProps } from '@fountain-ui/core';
|
|
3
3
|
import { NativeScrollEvent, NativeSyntheticEvent } from 'react-native';
|
|
4
|
+
import { FastScrollOptions } from './FastScrollProps';
|
|
4
5
|
export interface Dimension {
|
|
5
6
|
width: number;
|
|
6
7
|
height: number;
|
|
@@ -36,6 +37,11 @@ export default interface ComicViewerProps extends ComponentProps<{
|
|
|
36
37
|
* Dimensions of each Image considering viewport.
|
|
37
38
|
*/
|
|
38
39
|
intrinsicDimensions: Array<Dimension>;
|
|
40
|
+
/**
|
|
41
|
+
* Need invisible paddingTop viewer vertically expanded.
|
|
42
|
+
* @default 0
|
|
43
|
+
*/
|
|
44
|
+
invisiblePaddingTop?: number;
|
|
39
45
|
/**
|
|
40
46
|
* Max value of contents image width size.
|
|
41
47
|
* @default 720
|
|
@@ -50,6 +56,10 @@ export default interface ComicViewerProps extends ComponentProps<{
|
|
|
50
56
|
* @default 3
|
|
51
57
|
*/
|
|
52
58
|
windowSize?: number;
|
|
59
|
+
/**
|
|
60
|
+
* Options for fastscroll component.
|
|
61
|
+
*/
|
|
62
|
+
fastScrollOptions: FastScrollOptions;
|
|
53
63
|
/**
|
|
54
64
|
* Get contents urls by indexes.
|
|
55
65
|
*/
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import FastScrollProps from './FastScrollProps';
|
|
3
|
+
declare const FastScroll: React.ForwardRefExoticComponent<Pick<FastScrollProps, "contentLength" | "scrollContentToOffset" | "movementRange" | "absolutePosition" | "visibleDurations" | "additionalLength"> & React.RefAttributes<unknown>>;
|
|
4
|
+
export default FastScroll;
|