@fountain-ui/lab 2.0.0-beta.34 → 2.0.0-beta.36

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.
Files changed (41) hide show
  1. package/build/commonjs/ComicViewer/ComicViewer.js +196 -143
  2. package/build/commonjs/ComicViewer/ComicViewer.js.map +1 -1
  3. package/build/commonjs/ComicViewer/ComicViewerProps.js +0 -12
  4. package/build/commonjs/ComicViewer/ComicViewerProps.js.map +1 -1
  5. package/build/commonjs/ComicViewer/EncodedTile.js +10 -0
  6. package/build/commonjs/ComicViewer/EncodedTile.js.map +1 -0
  7. package/build/commonjs/ComicViewer/ReloadButton.js +48 -0
  8. package/build/commonjs/ComicViewer/ReloadButton.js.map +1 -0
  9. package/build/commonjs/ComicViewer/ViewerItem.js +41 -173
  10. package/build/commonjs/ComicViewer/ViewerItem.js.map +1 -1
  11. package/build/commonjs/ComicViewer/index.js.map +1 -1
  12. package/build/module/ComicViewer/ComicViewer.js +195 -143
  13. package/build/module/ComicViewer/ComicViewer.js.map +1 -1
  14. package/build/module/ComicViewer/ComicViewerProps.js +1 -6
  15. package/build/module/ComicViewer/ComicViewerProps.js.map +1 -1
  16. package/build/module/ComicViewer/EncodedTile.js +3 -0
  17. package/build/module/ComicViewer/EncodedTile.js.map +1 -0
  18. package/build/module/ComicViewer/ReloadButton.js +33 -0
  19. package/build/module/ComicViewer/ReloadButton.js.map +1 -0
  20. package/build/module/ComicViewer/ViewerItem.js +42 -173
  21. package/build/module/ComicViewer/ViewerItem.js.map +1 -1
  22. package/build/module/ComicViewer/index.js.map +1 -1
  23. package/build/typescript/ComicViewer/ComicViewer.d.ts +1 -1
  24. package/build/typescript/ComicViewer/ComicViewerProps.d.ts +15 -90
  25. package/build/typescript/ComicViewer/EncodedTile.d.ts +2 -0
  26. package/build/typescript/ComicViewer/ReloadButton.d.ts +6 -0
  27. package/build/typescript/ComicViewer/ViewerItem.d.ts +37 -7
  28. package/build/typescript/ComicViewer/index.d.ts +2 -2
  29. package/package.json +2 -2
  30. package/src/ComicViewer/ComicViewer.tsx +210 -157
  31. package/src/ComicViewer/ComicViewerProps.ts +15 -107
  32. package/src/ComicViewer/EncodedTile.ts +3 -0
  33. package/src/ComicViewer/ReloadButton.tsx +36 -0
  34. package/src/ComicViewer/ViewerItem.tsx +82 -184
  35. package/src/ComicViewer/index.ts +2 -2
  36. package/build/commonjs/ComicViewer/ComicViewerItemProps.js +0 -6
  37. package/build/commonjs/ComicViewer/ComicViewerItemProps.js.map +0 -1
  38. package/build/module/ComicViewer/ComicViewerItemProps.js +0 -2
  39. package/build/module/ComicViewer/ComicViewerItemProps.js.map +0 -1
  40. package/build/typescript/ComicViewer/ComicViewerItemProps.d.ts +0 -34
  41. package/src/ComicViewer/ComicViewerItemProps.ts +0 -42
@@ -3,184 +3,237 @@ function _extends() { _extends = Object.assign ? Object.assign.bind() : function
3
3
  import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
4
  import { FlatList } from 'react-native';
5
5
  import * as R from 'ramda';
6
- import { STATE } from './ComicViewerProps';
6
+ import { useDebounce } from '@fountain-ui/core';
7
7
  import ViewerItem from './ViewerItem';
8
8
 
9
- const getItemHeights = items => R.map(content => content.height)(items);
10
-
11
9
  const appender = (left, right) => [left + right, left + right];
12
10
 
13
- const getHeightAccum = itemHeights => R.mapAccum(appender, 0, itemHeights);
11
+ const getHeightAccum = heights => R.mapAccum(appender, 0, heights);
12
+
13
+ const keyExtractor = item => String(item.index);
14
+
15
+ const createInitialImageState = dimension => ({
16
+ isNewUrlIncoming: false,
17
+ totalErrorCount: 0,
18
+ dimension
19
+ });
14
20
 
15
- const keyExtractor = item => `${item.sortKey}`;
21
+ const mapImageStateToItemState = (index, imageState, autoHandleErrorCount) => {
22
+ var _imageState$urlState, _imageState$urlState2;
16
23
 
24
+ return {
25
+ index,
26
+ url: (_imageState$urlState = imageState.urlState) === null || _imageState$urlState === void 0 ? void 0 : _imageState$urlState.url,
27
+ reloadButtonVisible: ((_imageState$urlState2 = imageState.urlState) === null || _imageState$urlState2 === void 0 ? void 0 : _imageState$urlState2.validity) !== 'valid' && imageState.totalErrorCount >= autoHandleErrorCount,
28
+ dimension: imageState.dimension
29
+ };
30
+ };
31
+
32
+ const MAXIMUM_WIDTH = 720;
33
+ const NUMBER_OF_ADJACENT_ITEM = 5;
17
34
  export default function ComicViewer(props) {
18
35
  const {
19
- data,
20
- errorDebounceMillis = 500,
21
- errorRetryCount = 3,
22
- responseTimestamp,
36
+ debounceMillis = 100,
37
+ autoHandleErrorCount = 3,
38
+ getUrlByIndex,
23
39
  initialNumToRender = 1,
24
40
  initialScrollPercentage = 0,
25
41
  itemVisiblePercentThreshold = 0,
26
- onError,
27
- onScroll,
42
+ intrinsicDimensions,
28
43
  onItemPress,
29
- getNextPage,
30
- viewerWidth,
44
+ viewportWidth,
31
45
  windowSize = 3,
32
- pageUnit,
33
- ListFooterComponent,
34
46
  ...otherProps
35
47
  } = props;
36
48
  const flatListRef = useRef(null);
37
- const errors = useRef(new Map());
38
- const debounceTimeOut = useRef(null);
39
- const imageWidth = Math.min(viewerWidth, 720);
40
- const initialItems = R.map(itemData => ({ ...itemData,
41
- isViewable: false,
42
- width: imageWidth,
43
- height: itemData.height * imageWidth / itemData.width
44
- }))(data);
45
- const [items, setItems] = useState(initialItems);
46
- const initialItemState = R.map(itemData => ({
47
- sortKey: itemData.sortKey,
48
- state: R.isNil(itemData.id) ? STATE.INIT : STATE.URL_LOADED
49
- }))(data);
50
- const itemStates = useRef(initialItemState);
51
- const itemHeights = [...getItemHeights(items)];
52
- const itemHeightAccum = getHeightAccum(itemHeights);
49
+ const maybeLoadableItemsIndexRange = useRef([-1, 0]);
50
+ const actualImageWidth = Math.min(viewportWidth, MAXIMUM_WIDTH);
51
+ const initialImageStates = useMemo(() => R.map(createInitialImageState, intrinsicDimensions), []);
52
+ const imageStatesRef = useRef(initialImageStates);
53
+
54
+ const mapImageStatesToItemStates = imageStates => {
55
+ return imageStates.map((image, index) => mapImageStateToItemState(index, image, autoHandleErrorCount));
56
+ };
57
+
58
+ const [itemStates, setItemStates] = useState(() => {
59
+ return mapImageStatesToItemStates(imageStatesRef.current);
60
+ });
61
+ const renderedDimensions = useMemo(() => {
62
+ return R.map(intrinsicDimension => ({
63
+ width: actualImageWidth,
64
+ height: intrinsicDimension.height * actualImageWidth / intrinsicDimension.width
65
+ }), intrinsicDimensions);
66
+ }, [actualImageWidth]);
67
+ const layoutFromDimensions = useCallback(() => {
68
+ const itemHeights = R.map(dimension => dimension.height, renderedDimensions);
69
+ const [totalHeight, heightAccum] = getHeightAccum(itemHeights);
70
+ const itemOffsets = R.prepend(0, heightAccum);
71
+
72
+ const getItemLayout = (data, index) => ({
73
+ index,
74
+ length: itemHeights[index],
75
+ offset: itemOffsets[index]
76
+ });
77
+
78
+ return {
79
+ totalHeight,
80
+ getItemLayout
81
+ };
82
+ }, [renderedDimensions]);
83
+ const {
84
+ totalHeight,
85
+ getItemLayout
86
+ } = layoutFromDimensions();
53
87
  const viewabilityConfig = useMemo(() => ({
54
88
  itemVisiblePercentThreshold
55
89
  }), [itemVisiblePercentThreshold]);
56
- const getItemLayout = useCallback((data, index) => {
57
- const offsets = R.prepend(0, itemHeightAccum[1]);
58
- return {
59
- length: itemHeights[index],
60
- offset: offsets[index],
61
- index
62
- };
63
- }, [itemHeights]);
90
+
91
+ const updateImageState = updateFunction => {
92
+ const prevImageStates = imageStatesRef.current;
93
+ const newImageStates = prevImageStates.map(updateFunction);
94
+ imageStatesRef.current = newImageStates;
95
+ setItemStates(prevItemStates => {
96
+ const newItemStates = mapImageStatesToItemStates(newImageStates);
97
+ return R.equals(prevItemStates, newItemStates) ? prevItemStates : newItemStates;
98
+ });
99
+ };
100
+
101
+ const loadUrlByIndex = async indexes => {
102
+ const filteredIndexes = R.filter(index => {
103
+ var _state$urlState;
104
+
105
+ const state = imageStatesRef.current[index];
106
+ return R.isNil(state.urlState) || ((_state$urlState = state.urlState) === null || _state$urlState === void 0 ? void 0 : _state$urlState.validity) === 'invalid' && !state.isNewUrlIncoming;
107
+ }, indexes);
108
+ updateImageState((imageState, i) => {
109
+ return R.includes(i, filteredIndexes) ? { ...imageState,
110
+ isNewUrlIncoming: true
111
+ } : imageState;
112
+ });
113
+
114
+ try {
115
+ const urls = await getUrlByIndex(filteredIndexes);
116
+ updateImageState((imageState, i) => {
117
+ const newUrl = urls === null || urls === void 0 ? void 0 : urls.get(i);
118
+ const urlState = imageState.urlState;
119
+
120
+ if (newUrl !== undefined && (urlState === null || urlState === void 0 ? void 0 : urlState.validity) !== 'valid') {
121
+ return { ...imageState,
122
+ urlState: {
123
+ url: newUrl,
124
+ validity: 'unknown'
125
+ }
126
+ };
127
+ }
128
+
129
+ return imageState;
130
+ });
131
+ } finally {
132
+ updateImageState((imageState, i) => {
133
+ return R.includes(i, filteredIndexes) ? { ...imageState,
134
+ isNewUrlIncoming: false
135
+ } : imageState;
136
+ });
137
+ }
138
+ };
139
+
140
+ const loadMaybeLoadableItems = async () => {
141
+ const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;
142
+ const affectedIndexes = R.range(startIndex, endIndex);
143
+ await loadUrlByIndex(affectedIndexes);
144
+ };
145
+
146
+ const loadItemsDebounce = useDebounce(loadMaybeLoadableItems, debounceMillis);
64
147
  const onViewableItemsChanged = useRef(_ref => {
148
+ var _R$head, _R$last;
149
+
65
150
  let {
66
151
  viewableItems
67
152
  } = _ref;
68
- setItems(prev => {
69
- const viewableItemSortKeys = R.map(viewableItem => viewableItem.item.sortKey)(viewableItems);
70
- const firstViewableSortKey = R.head(viewableItemSortKeys);
71
- const lastViewableItemSortKey = R.last(viewableItemSortKeys);
72
- const firstItem = R.head(prev);
73
- const lastItem = R.last(prev);
74
-
75
- if (R.isNil(firstViewableSortKey) || R.isNil(lastViewableItemSortKey) || R.isNil(firstItem) || R.isNil(lastItem)) {
76
- return prev;
77
- }
153
+ const orderedViewableItems = R.sort((a, b) => (a.index || 0) - (b.index || 0), viewableItems);
154
+ const firstViewableIndex = (_R$head = R.head(orderedViewableItems)) === null || _R$head === void 0 ? void 0 : _R$head.index;
155
+ const lastViewableItemIndex = (_R$last = R.last(orderedViewableItems)) === null || _R$last === void 0 ? void 0 : _R$last.index;
78
156
 
79
- const frontBoundary = R.max(firstItem.sortKey, firstViewableSortKey - 1);
80
- const backBoundary = R.min(lastItem.sortKey, lastViewableItemSortKey + 1);
81
- const viewableItemBoundary = R.range(frontBoundary, backBoundary + 1);
82
- const newItems = R.map(prevItem => ({ ...prevItem,
83
- isViewable: R.includes(prevItem.sortKey, viewableItemBoundary)
84
- }))([...prev]);
85
- return newItems;
86
- });
87
- });
88
- const itemLoadedHandler = useCallback(sortKey => {
89
- const itemState = R.find(state => state.sortKey === sortKey)(itemStates.current);
90
-
91
- if (R.isNil(itemState)) {
157
+ if (R.isNil(firstViewableIndex) || R.isNil(lastViewableItemIndex)) {
92
158
  return;
93
159
  }
94
160
 
95
- itemState.state = STATE.LOADED;
96
- itemState.error = undefined;
97
- }, [itemStates]);
98
- const itemErrorHandler = useCallback(errorInfo => {
99
- const {
100
- sortKey,
101
- count
102
- } = errorInfo;
161
+ const startIndex = R.max(firstViewableIndex - NUMBER_OF_ADJACENT_ITEM, 0);
162
+ const endIndex = R.min(lastViewableItemIndex + NUMBER_OF_ADJACENT_ITEM, itemStates.length - 1);
163
+ maybeLoadableItemsIndexRange.current = [startIndex, endIndex + 1];
164
+ loadItemsDebounce();
165
+ });
166
+ const renderItem = useCallback(_ref2 => {
167
+ var _renderedDimensions$i, _renderedDimensions$i2;
103
168
 
104
- if (count >= errorRetryCount) {
105
- return;
106
- }
169
+ let {
170
+ item,
171
+ index
172
+ } = _ref2;
107
173
 
108
- errors.current.set(sortKey, errorInfo);
109
- const itemState = R.find(state => state.sortKey === sortKey)(itemStates.current);
174
+ const onError = () => {
175
+ updateImageState((imageState, i) => {
176
+ const urlState = imageState.urlState;
110
177
 
111
- if (R.isNil(itemState)) {
112
- return;
113
- }
178
+ if (i === index && urlState !== undefined) {
179
+ return { ...imageState,
180
+ totalErrorCount: imageState.totalErrorCount + 1,
181
+ urlState: { ...urlState,
182
+ validity: 'invalid'
183
+ }
184
+ };
185
+ }
186
+
187
+ return imageState;
188
+ });
189
+
190
+ if (item.reloadButtonVisible) {
191
+ return;
192
+ }
114
193
 
115
- itemState.state = STATE.FAIL;
116
- itemState.error = errorInfo;
117
-
118
- const handleError = () => {
119
- const errorsArray = Array.from(errors.current.entries());
120
- const errorsInfo = R.map(_ref2 => {
121
- let [key, value] = _ref2;
122
- return value;
123
- })(errorsArray);
124
- onError && onError([...errorsInfo]);
125
- errors.current.clear();
194
+ const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;
195
+
196
+ if (index >= startIndex || index < endIndex) {
197
+ loadItemsDebounce();
198
+ }
126
199
  };
127
200
 
128
- if (debounceTimeOut.current) {
129
- clearTimeout(debounceTimeOut.current);
130
- }
201
+ const onReloadPress = () => {
202
+ const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;
131
203
 
132
- if (errors.current.size === pageUnit) {
133
- handleError();
134
- } else {
135
- debounceTimeOut.current = setTimeout(handleError, errorDebounceMillis);
136
- }
137
- }, [errors.current, itemStates]);
138
- const renderItem = useCallback(_ref3 => {
139
- let {
140
- item
141
- } = _ref3;
142
- const itemState = R.find(state => state.sortKey === item.sortKey)(itemStates.current);
143
- const props = { ...item,
144
- itemState,
145
- responseTimestamp,
146
- errorRetryCount,
147
- onError: itemErrorHandler,
148
- onLoaded: itemLoadedHandler,
149
- onItemPress,
150
- getNextPage
204
+ if (index >= startIndex || index < endIndex) {
205
+ loadUrlByIndex([index]);
206
+ }
151
207
  };
152
- return /*#__PURE__*/React.createElement(ViewerItem, {
153
- props: props
154
- });
155
- }, [responseTimestamp, itemErrorHandler, itemLoadedHandler, onItemPress]);
156
- useEffect(() => {
157
- setItems(prev => {
158
- return R.map(prevItem => {
159
- const currentData = R.find(currentItemData => prevItem.sortKey === currentItemData.sortKey)(data);
160
- const itemState = R.find(state => state.sortKey === (currentData === null || currentData === void 0 ? void 0 : currentData.sortKey))(itemStates.current);
161
-
162
- if (currentData && currentData.id && itemState && itemState.state !== STATE.LOADED) {
163
- itemState.state = STATE.URL_LOADED;
164
- return { ...prevItem,
165
- url: currentData.url,
166
- expiresAt: currentData.expiresAt
208
+
209
+ const onLoad = () => {
210
+ updateImageState((imageState, i) => {
211
+ const urlState = imageState.urlState;
212
+
213
+ if (i === index && urlState !== undefined) {
214
+ return { ...imageState,
215
+ urlState: { ...urlState,
216
+ validity: 'valid'
217
+ }
167
218
  };
168
219
  }
169
220
 
170
- return prevItem;
171
- })([...prev]);
172
- ;
221
+ return imageState;
222
+ });
223
+ };
224
+
225
+ return /*#__PURE__*/React.createElement(ViewerItem, {
226
+ onError: onError,
227
+ onLoad: onLoad,
228
+ onPress: onItemPress,
229
+ onReloadPress: onReloadPress,
230
+ url: item.url,
231
+ width: ((_renderedDimensions$i = renderedDimensions[index]) === null || _renderedDimensions$i === void 0 ? void 0 : _renderedDimensions$i.width) ?? 0,
232
+ height: ((_renderedDimensions$i2 = renderedDimensions[index]) === null || _renderedDimensions$i2 === void 0 ? void 0 : _renderedDimensions$i2.height) ?? 0,
233
+ reloadButtonVisible: item.reloadButtonVisible
173
234
  });
174
- }, [responseTimestamp]);
175
- useEffect(() => {
176
- const newItems = R.map(item => ({ ...item,
177
- width: imageWidth,
178
- height: item.height * imageWidth / item.width
179
- }))(items);
180
- setItems(newItems);
181
- }, [imageWidth]);
235
+ }, [onItemPress, renderedDimensions]);
182
236
  useEffect(() => {
183
- const totalHeight = itemHeightAccum[0];
184
237
  const offset = Math.floor(initialScrollPercentage / 100 * totalHeight);
185
238
 
186
239
  if (flatListRef.current) {
@@ -189,19 +242,18 @@ export default function ComicViewer(props) {
189
242
  animated: false
190
243
  });
191
244
  }
192
- }, [flatListRef.current]);
245
+ }, []);
193
246
  return /*#__PURE__*/React.createElement(FlatList, _extends({
194
- data: items,
247
+ data: itemStates,
195
248
  getItemLayout: getItemLayout,
196
249
  initialNumToRender: initialNumToRender,
197
250
  keyExtractor: keyExtractor,
198
251
  onViewableItemsChanged: onViewableItemsChanged.current,
199
- onScroll: onScroll,
200
252
  ref: flatListRef,
253
+ removeClippedSubviews: false,
201
254
  renderItem: renderItem,
202
255
  viewabilityConfig: viewabilityConfig,
203
- windowSize: windowSize,
204
- ListFooterComponent: ListFooterComponent
256
+ windowSize: windowSize
205
257
  }, otherProps));
206
258
  }
207
259
  ;
@@ -1 +1 @@
1
- {"version":3,"names":["React","useCallback","useEffect","useMemo","useRef","useState","FlatList","R","STATE","ViewerItem","getItemHeights","items","map","content","height","appender","left","right","getHeightAccum","itemHeights","mapAccum","keyExtractor","item","sortKey","ComicViewer","props","data","errorDebounceMillis","errorRetryCount","responseTimestamp","initialNumToRender","initialScrollPercentage","itemVisiblePercentThreshold","onError","onScroll","onItemPress","getNextPage","viewerWidth","windowSize","pageUnit","ListFooterComponent","otherProps","flatListRef","errors","Map","debounceTimeOut","imageWidth","Math","min","initialItems","itemData","isViewable","width","setItems","initialItemState","state","isNil","id","INIT","URL_LOADED","itemStates","itemHeightAccum","viewabilityConfig","getItemLayout","index","offsets","prepend","length","offset","onViewableItemsChanged","viewableItems","prev","viewableItemSortKeys","viewableItem","firstViewableSortKey","head","lastViewableItemSortKey","last","firstItem","lastItem","frontBoundary","max","backBoundary","viewableItemBoundary","range","newItems","prevItem","includes","itemLoadedHandler","itemState","find","current","LOADED","error","undefined","itemErrorHandler","errorInfo","count","set","FAIL","handleError","errorsArray","Array","from","entries","errorsInfo","key","value","clear","clearTimeout","size","setTimeout","renderItem","onLoaded","currentData","currentItemData","url","expiresAt","totalHeight","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 {\n ComicViewerItemData,\n ComicViewerItemState,\n default as ComicViewerProps,\n ErrorInfo,\n STATE,\n} from './ComicViewerProps';\nimport type ComicViewerItemProps from './ComicViewerItemProps';\nimport ViewerItem from './ViewerItem';\n\nconst getItemHeights = <T, >(items: ComicViewerItemProps<T>[]): number[] => R.map((content: ComicViewerItemProps<T>) => content.height)(items);\nconst appender = (left: number, right: number): [number, number] => [left + right, left + right];\nconst getHeightAccum = (itemHeights: number[]): [number, number[]] => R.mapAccum(appender, 0, itemHeights);\n\nconst keyExtractor = <T, >(item: ComicViewerItemProps<T>) => `${item.sortKey}`;\n\nexport default function ComicViewer<T>(props: ComicViewerProps<T>) {\n const {\n data,\n errorDebounceMillis = 500,\n errorRetryCount = 3,\n responseTimestamp,\n initialNumToRender = 1,\n initialScrollPercentage = 0,\n itemVisiblePercentThreshold = 0,\n onError,\n onScroll,\n onItemPress,\n getNextPage,\n viewerWidth,\n windowSize = 3,\n pageUnit,\n ListFooterComponent,\n ...otherProps\n } = props;\n\n const flatListRef = useRef<FlatList>(null);\n\n const errors = useRef<Map<number, ErrorInfo>>(new Map());\n\n const debounceTimeOut = useRef<NodeJS.Timeout | null>(null);\n\n const imageWidth = Math.min(viewerWidth, 720);\n const initialItems = R.map((itemData: ComicViewerItemData<T>) => ({\n ...itemData,\n isViewable: false,\n width: imageWidth,\n height: (itemData.height * imageWidth) / itemData.width,\n }))(data);\n\n const [items, setItems] = useState<ComicViewerItemProps<T>[]>(initialItems);\n\n const initialItemState: ComicViewerItemState[] = R.map((itemData: ComicViewerItemData<T>) => ({\n sortKey: itemData.sortKey,\n state: R.isNil(itemData.id) ? STATE.INIT : STATE.URL_LOADED,\n }))(data);\n\n const itemStates = useRef<Array<ComicViewerItemState>>(initialItemState);\n\n const itemHeights = [...getItemHeights(items)];\n const itemHeightAccum = getHeightAccum(itemHeights);\n\n const viewabilityConfig = useMemo(() => ({\n itemVisiblePercentThreshold,\n }), [itemVisiblePercentThreshold]);\n\n const getItemLayout = useCallback((data: any, index: number) => {\n const offsets = R.prepend(0, itemHeightAccum[1]);\n\n return {\n length: itemHeights[index],\n offset: offsets[index],\n index,\n };\n }, [itemHeights]);\n\n const onViewableItemsChanged = useRef(({ viewableItems }: {\n viewableItems: Array<ViewToken>,\n }) => {\n setItems((prev: ComicViewerItemProps<T>[]) => {\n const viewableItemSortKeys: number[] = R.map((viewableItem: ViewToken) => viewableItem.item.sortKey)(viewableItems);\n const firstViewableSortKey = R.head(viewableItemSortKeys);\n const lastViewableItemSortKey = R.last(viewableItemSortKeys);\n const firstItem = R.head(prev);\n const lastItem = R.last(prev);\n\n if (R.isNil(firstViewableSortKey)\n || R.isNil(lastViewableItemSortKey)\n || R.isNil(firstItem)\n || R.isNil(lastItem)\n ) {\n return prev;\n }\n\n const frontBoundary = R.max(firstItem.sortKey, firstViewableSortKey - 1);\n const backBoundary = R.min(lastItem.sortKey, lastViewableItemSortKey + 1);\n\n const viewableItemBoundary = R.range(frontBoundary, backBoundary + 1);\n const newItems = R.map((prevItem: ComicViewerItemProps<T>) => ({\n ...prevItem,\n isViewable: R.includes(prevItem.sortKey, viewableItemBoundary),\n }))([...prev]);\n\n return newItems;\n });\n });\n\n const itemLoadedHandler = useCallback((sortKey: number) => {\n const itemState: ComicViewerItemState | undefined = R.find((state: ComicViewerItemState) => state.sortKey === sortKey)(itemStates.current);\n\n if (R.isNil(itemState)) {\n return;\n }\n\n itemState.state = STATE.LOADED;\n itemState.error = undefined;\n }, [itemStates]);\n\n const itemErrorHandler = useCallback((errorInfo: ErrorInfo) => {\n const { sortKey, count } = errorInfo;\n\n if (count >= errorRetryCount) {\n return;\n }\n\n errors.current.set(sortKey, errorInfo);\n\n const itemState: ComicViewerItemState | undefined = R.find((state: ComicViewerItemState) => state.sortKey === sortKey)(itemStates.current);\n\n if (R.isNil(itemState)) {\n return;\n }\n\n itemState.state = STATE.FAIL;\n itemState.error = errorInfo;\n\n const handleError = () => {\n const errorsArray = Array.from(errors.current.entries());\n const errorsInfo = R.map(([key, value]: [number, ErrorInfo]) => value)(errorsArray);\n\n onError && onError([...errorsInfo]);\n errors.current.clear();\n };\n\n if (debounceTimeOut.current) {\n clearTimeout(debounceTimeOut.current);\n }\n\n if (errors.current.size === pageUnit) {\n handleError();\n } else {\n debounceTimeOut.current = setTimeout(handleError, errorDebounceMillis);\n }\n }, [errors.current, itemStates]);\n\n const renderItem: ListRenderItem<ComicViewerItemProps<T>> = useCallback(({ item }) => {\n const itemState: ComicViewerItemState | undefined = R.find((state: ComicViewerItemState) => state.sortKey === item.sortKey)(itemStates.current);\n\n const props = {\n ...item,\n itemState,\n responseTimestamp,\n errorRetryCount,\n onError: itemErrorHandler,\n onLoaded: itemLoadedHandler,\n onItemPress,\n getNextPage,\n };\n\n return <ViewerItem props={props}/>;\n }, [responseTimestamp, itemErrorHandler, itemLoadedHandler, onItemPress]);\n\n useEffect(() => {\n setItems((prev: ComicViewerItemProps<T>[]) => {\n return R.map((prevItem: ComicViewerItemProps<T>) => {\n const currentData: ComicViewerItemData | undefined = R.find((currentItemData: ComicViewerItemData<T>) => prevItem.sortKey === currentItemData.sortKey)(data);\n const itemState: ComicViewerItemState | undefined = R.find((state: ComicViewerItemState) => state.sortKey === currentData?.sortKey)(itemStates.current);\n\n if (currentData\n && currentData.id\n && itemState\n && itemState.state !== STATE.LOADED) {\n\n itemState.state = STATE.URL_LOADED;\n\n return {\n ...prevItem,\n url: currentData.url,\n expiresAt: currentData.expiresAt,\n };\n }\n\n return prevItem;\n })([...prev]);\n ;\n });\n }, [responseTimestamp]);\n\n useEffect(() => {\n const newItems = R.map((item: ComicViewerItemProps<T>) => ({\n ...item,\n width: imageWidth,\n height: (item.height * imageWidth) / item.width,\n }))(items);\n\n setItems(newItems);\n }, [imageWidth]);\n\n useEffect(() => {\n const totalHeight = itemHeightAccum[0];\n const offset = Math.floor((initialScrollPercentage / 100) * totalHeight);\n\n if (flatListRef.current) {\n flatListRef.current.scrollToOffset({ offset, animated: false });\n }\n }, [flatListRef.current]);\n\n return (\n <FlatList\n data={items}\n getItemLayout={getItemLayout}\n initialNumToRender={initialNumToRender}\n keyExtractor={keyExtractor}\n onViewableItemsChanged={onViewableItemsChanged.current}\n onScroll={onScroll}\n ref={flatListRef}\n renderItem={renderItem}\n viewabilityConfig={viewabilityConfig}\n windowSize={windowSize}\n ListFooterComponent={ListFooterComponent}\n {...otherProps}\n />\n );\n};"],"mappings":"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"}
1
+ {"version":3,"names":["React","useCallback","useEffect","useMemo","useRef","useState","FlatList","R","useDebounce","ViewerItem","appender","left","right","getHeightAccum","heights","mapAccum","keyExtractor","item","String","index","createInitialImageState","dimension","isNewUrlIncoming","totalErrorCount","mapImageStateToItemState","imageState","autoHandleErrorCount","url","urlState","reloadButtonVisible","validity","MAXIMUM_WIDTH","NUMBER_OF_ADJACENT_ITEM","ComicViewer","props","debounceMillis","getUrlByIndex","initialNumToRender","initialScrollPercentage","itemVisiblePercentThreshold","intrinsicDimensions","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 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, MAXIMUM_WIDTH);\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 removeClippedSubviews={false}\n renderItem={renderItem}\n viewabilityConfig={viewabilityConfig}\n windowSize={windowSize}\n {...otherProps}\n />\n );\n};\n"],"mappings":"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"}
@@ -1,7 +1,2 @@
1
- export const STATE = {
2
- INIT: 'init',
3
- URL_LOADED: 'url_loaded',
4
- LOADED: 'loaded',
5
- FAIL: 'fail'
6
- };
1
+
7
2
  //# sourceMappingURL=ComicViewerProps.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["STATE","INIT","URL_LOADED","LOADED","FAIL"],"sources":["ComicViewerProps.ts"],"sourcesContent":["import React from 'react';\nimport { ComponentProps } from '@fountain-ui/core';\nimport { NativeScrollEvent, NativeSyntheticEvent } from 'react-native';\n\nexport const STATE = {\n INIT: 'init',\n URL_LOADED: 'url_loaded',\n LOADED: 'loaded',\n FAIL: 'fail',\n} as const;\n\nexport type LoadingState = typeof STATE[keyof typeof STATE];\n\nexport interface ComicViewerItemState{\n /**\n * Comic viewer item sortKey.\n */\n sortKey: number;\n\n /**\n * Content's loading state.\n */\n state: LoadingState;\n\n /***\n * Content's error Info.\n */\n error?: ErrorInfo;\n}\n\nexport interface ErrorInfo {\n /**\n * ComicViewerItemData.sortKey.\n */\n sortKey: number;\n\n /**\n * Number of times an error occurred.\n */\n count: number;\n\n /**\n * Content is Expired: true\n */\n expired: boolean;\n}\n\nexport type ComicViewerItemData<T = {}> = T & {\n /**\n * Image height.\n */\n height: number;\n\n /**\n * Unique value for identifying.\n */\n id: number | undefined;\n\n /**\n * Image sourceUrl for displaying.\n */\n url: string;\n\n /**\n * Image width.\n */\n width: number;\n\n /**\n * SortKey\n */\n sortKey: number;\n\n /**\n * Image expire date.\n */\n expiresAt: string;\n\n /***\n * Timestamp when get content response\n */\n responseTimestamp: number;\n}\n\nexport default interface ComicViewerProps<T> extends ComponentProps <{\n /**\n * Data for render.\n */\n data: ComicViewerItemData<T>[];\n\n /**\n * Delay Time to call the error handler.\n * @default 500\n */\n errorDebounceMillis?: number;\n\n /**\n * How many times retry onError when same item error occur\n * @default 3\n */\n errorRetryCount?: 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 * Timestamp when get content response\n */\n responseTimestamp: number;\n\n /**\n * Comic viewer width.\n */\n viewerWidth: number;\n\n /**\n * The value for FlatList windowSize.\n * @default 3\n */\n windowSize?: number;\n\n /**\n * How many images in one page.\n */\n pageUnit: number;\n\n /**\n * Method for getting next page contents.\n * @param sortKey\n */\n getNextPage?: (sortKey: number) => void;\n\n /**\n * Handling all viewerItem errors at once.\n * @param errors Array of ViewerItems errorInfo.\n */\n onError?: (errors: ErrorInfo[]) => void;\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}> {}"],"mappings":"AAIA,OAAO,MAAMA,KAAK,GAAG;EACjBC,IAAI,EAAE,MADW;EAEjBC,UAAU,EAAE,YAFK;EAGjBC,MAAM,EAAE,QAHS;EAIjBC,IAAI,EAAE;AAJW,CAAd"}
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 * 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":""}