@fountain-ui/lab 2.0.0-beta.33 → 2.0.0-beta.35

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 (38) hide show
  1. package/build/commonjs/ComicViewer/ComicViewer.js +197 -142
  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/ReloadButton.js +43 -0
  6. package/build/commonjs/ComicViewer/ReloadButton.js.map +1 -0
  7. package/build/commonjs/ComicViewer/ViewerItem.js +37 -152
  8. package/build/commonjs/ComicViewer/ViewerItem.js.map +1 -1
  9. package/build/commonjs/ComicViewer/checkered-loading.jpg +0 -0
  10. package/build/commonjs/ComicViewer/index.js.map +1 -1
  11. package/build/module/ComicViewer/ComicViewer.js +196 -142
  12. package/build/module/ComicViewer/ComicViewer.js.map +1 -1
  13. package/build/module/ComicViewer/ComicViewerProps.js +1 -6
  14. package/build/module/ComicViewer/ComicViewerProps.js.map +1 -1
  15. package/build/module/ComicViewer/ReloadButton.js +29 -0
  16. package/build/module/ComicViewer/ReloadButton.js.map +1 -0
  17. package/build/module/ComicViewer/ViewerItem.js +39 -154
  18. package/build/module/ComicViewer/ViewerItem.js.map +1 -1
  19. package/build/module/ComicViewer/checkered-loading.jpg +0 -0
  20. package/build/module/ComicViewer/index.js.map +1 -1
  21. package/build/typescript/ComicViewer/ComicViewer.d.ts +1 -1
  22. package/build/typescript/ComicViewer/ComicViewerProps.d.ts +15 -82
  23. package/build/typescript/ComicViewer/ReloadButton.d.ts +6 -0
  24. package/build/typescript/ComicViewer/ViewerItem.d.ts +37 -7
  25. package/build/typescript/ComicViewer/index.d.ts +2 -2
  26. package/package.json +2 -2
  27. package/src/ComicViewer/ComicViewer.tsx +210 -155
  28. package/src/ComicViewer/ComicViewerProps.ts +16 -98
  29. package/src/ComicViewer/ReloadButton.tsx +33 -0
  30. package/src/ComicViewer/ViewerItem.tsx +81 -169
  31. package/src/ComicViewer/checkered-loading.jpg +0 -0
  32. package/src/ComicViewer/index.ts +2 -2
  33. package/build/commonjs/ComicViewer/ComicViewerItemProps.js +0 -6
  34. package/build/commonjs/ComicViewer/ComicViewerItemProps.js.map +0 -1
  35. package/build/module/ComicViewer/ComicViewerItemProps.js +0 -2
  36. package/build/module/ComicViewer/ComicViewerItemProps.js.map +0 -1
  37. package/build/typescript/ComicViewer/ComicViewerItemProps.d.ts +0 -34
  38. package/src/ComicViewer/ComicViewerItemProps.ts +0 -42
@@ -11,7 +11,7 @@ var _reactNative = require("react-native");
11
11
 
12
12
  var R = _interopRequireWildcard(require("ramda"));
13
13
 
14
- var _ComicViewerProps = require("./ComicViewerProps");
14
+ var _core = require("@fountain-ui/core");
15
15
 
16
16
  var _ViewerItem = _interopRequireDefault(require("./ViewerItem"));
17
17
 
@@ -23,180 +23,236 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
23
23
 
24
24
  function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
25
25
 
26
- const getItemHeights = items => R.map(content => content.height)(items);
27
-
28
26
  const appender = (left, right) => [left + right, left + right];
29
27
 
30
- const getHeightAccum = itemHeights => R.mapAccum(appender, 0, itemHeights);
28
+ const getHeightAccum = heights => R.mapAccum(appender, 0, heights);
29
+
30
+ const keyExtractor = item => String(item.index);
31
+
32
+ const createInitialImageState = dimension => ({
33
+ isNewUrlIncoming: false,
34
+ totalErrorCount: 0,
35
+ dimension
36
+ });
37
+
38
+ const mapImageStateToItemState = (index, imageState, autoHandleErrorCount) => {
39
+ var _imageState$urlState, _imageState$urlState2;
31
40
 
32
- const keyExtractor = item => `${item.sortKey}`;
41
+ return {
42
+ index,
43
+ url: (_imageState$urlState = imageState.urlState) === null || _imageState$urlState === void 0 ? void 0 : _imageState$urlState.url,
44
+ reloadButtonVisible: ((_imageState$urlState2 = imageState.urlState) === null || _imageState$urlState2 === void 0 ? void 0 : _imageState$urlState2.validity) !== 'valid' && imageState.totalErrorCount >= autoHandleErrorCount,
45
+ dimension: imageState.dimension
46
+ };
47
+ };
48
+
49
+ const MAXIMUM_WIDTH = 720;
50
+ const NUMBER_OF_ADJACENT_ITEM = 5;
33
51
 
34
52
  function ComicViewer(props) {
35
53
  const {
36
- data,
37
- errorDebounceMillis = 500,
38
- errorRetryCount = 3,
54
+ debounceMillis = 100,
55
+ autoHandleErrorCount = 3,
56
+ getUrlByIndex,
39
57
  initialNumToRender = 1,
40
58
  initialScrollPercentage = 0,
41
59
  itemVisiblePercentThreshold = 0,
42
- onError,
43
- onScroll,
60
+ intrinsicDimensions,
44
61
  onItemPress,
45
- getNextPage,
46
- viewerWidth,
62
+ viewportWidth,
47
63
  windowSize = 3,
48
- pageUnit,
49
- ListFooterComponent,
50
64
  ...otherProps
51
65
  } = props;
52
66
  const flatListRef = (0, _react.useRef)(null);
53
- const errors = (0, _react.useRef)(new Map());
54
- const debounceTimeOut = (0, _react.useRef)(null);
55
- const resourceString = R.toString(R.map(itemData => itemData.url)(data));
56
- const imageWidth = Math.min(viewerWidth, 720);
57
- const initialItems = R.map(itemData => ({ ...itemData,
58
- isViewable: false,
59
- width: imageWidth,
60
- height: itemData.height * imageWidth / itemData.width
61
- }))(data);
62
- const [items, setItems] = (0, _react.useState)(initialItems);
63
- const initialItemState = R.map(itemData => ({
64
- sortKey: itemData.sortKey,
65
- state: R.isEmpty(itemData.expiresAt) ? _ComicViewerProps.STATE.INIT : _ComicViewerProps.STATE.URL_LOADED
66
- }))(data);
67
- const itemStates = (0, _react.useRef)(initialItemState);
68
- const itemHeights = [...getItemHeights(items)];
69
- const itemHeightAccum = getHeightAccum(itemHeights);
67
+ const debounceTimeout = (0, _react.useRef)(null);
68
+ const maybeLoadableItemsIndexRange = (0, _react.useRef)([-1, 0]);
69
+ const actualImageWidth = Math.min(viewportWidth, MAXIMUM_WIDTH);
70
+ const initialImageStates = (0, _react.useMemo)(() => R.map(createInitialImageState, intrinsicDimensions), []);
71
+ const imageStatesRef = (0, _react.useRef)(initialImageStates);
72
+
73
+ const mapImageStatesToItemStates = imageStates => {
74
+ return imageStates.map((image, index) => mapImageStateToItemState(index, image, autoHandleErrorCount));
75
+ };
76
+
77
+ const [itemStates, setItemStates] = (0, _react.useState)(() => {
78
+ return mapImageStatesToItemStates(imageStatesRef.current);
79
+ });
80
+ const renderedDimensions = (0, _react.useMemo)(() => {
81
+ return R.map(intrinsicDimension => ({
82
+ width: actualImageWidth,
83
+ height: intrinsicDimension.height * actualImageWidth / intrinsicDimension.width
84
+ }), intrinsicDimensions);
85
+ }, [actualImageWidth]);
86
+ const layoutFromDimensions = (0, _react.useCallback)(() => {
87
+ const itemHeights = R.map(dimension => dimension.height, renderedDimensions);
88
+ const [totalHeight, heightAccum] = getHeightAccum(itemHeights);
89
+ const itemOffsets = R.prepend(0, heightAccum);
90
+
91
+ const getItemLayout = (data, index) => ({
92
+ index,
93
+ length: itemHeights[index],
94
+ offset: itemOffsets[index]
95
+ });
96
+
97
+ return {
98
+ totalHeight,
99
+ getItemLayout
100
+ };
101
+ }, [renderedDimensions]);
102
+ const {
103
+ totalHeight,
104
+ getItemLayout
105
+ } = layoutFromDimensions();
70
106
  const viewabilityConfig = (0, _react.useMemo)(() => ({
71
107
  itemVisiblePercentThreshold
72
108
  }), [itemVisiblePercentThreshold]);
73
- const getItemLayout = (0, _react.useCallback)((data, index) => {
74
- const offsets = R.prepend(0, itemHeightAccum[1]);
75
- return {
76
- length: itemHeights[index],
77
- offset: offsets[index],
78
- index
79
- };
80
- }, [itemHeights]);
109
+
110
+ const updateImageState = updateFunction => {
111
+ const prevImageStates = imageStatesRef.current;
112
+ const newImageStates = prevImageStates.map(updateFunction);
113
+ imageStatesRef.current = newImageStates;
114
+ setItemStates(prevItemStates => {
115
+ const newItemStates = mapImageStatesToItemStates(newImageStates);
116
+ return R.equals(prevItemStates, newItemStates) ? prevItemStates : newItemStates;
117
+ });
118
+ };
119
+
120
+ const loadUrlByIndex = async indexes => {
121
+ const filteredIndexes = R.filter(index => {
122
+ var _state$urlState;
123
+
124
+ const state = imageStatesRef.current[index];
125
+ return R.isNil(state.urlState) || ((_state$urlState = state.urlState) === null || _state$urlState === void 0 ? void 0 : _state$urlState.validity) === 'invalid' && !state.isNewUrlIncoming;
126
+ }, indexes);
127
+ updateImageState((imageState, i) => {
128
+ return R.includes(i, filteredIndexes) ? { ...imageState,
129
+ isNewUrlIncoming: true
130
+ } : imageState;
131
+ });
132
+
133
+ try {
134
+ const urls = await getUrlByIndex(filteredIndexes);
135
+ updateImageState((imageState, i) => {
136
+ const newUrl = urls === null || urls === void 0 ? void 0 : urls.get(i);
137
+ const urlState = imageState.urlState;
138
+
139
+ if (newUrl !== undefined && (urlState === null || urlState === void 0 ? void 0 : urlState.validity) !== 'valid') {
140
+ return { ...imageState,
141
+ urlState: {
142
+ url: newUrl,
143
+ validity: 'unknown'
144
+ }
145
+ };
146
+ }
147
+
148
+ return imageState;
149
+ });
150
+ } finally {
151
+ updateImageState((imageState, i) => {
152
+ return R.includes(i, filteredIndexes) ? { ...imageState,
153
+ isNewUrlIncoming: false
154
+ } : imageState;
155
+ });
156
+ }
157
+ };
158
+
159
+ const loadMaybeLoadableItems = async () => {
160
+ const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;
161
+ const affectedIndexes = R.range(startIndex, endIndex);
162
+ await loadUrlByIndex(affectedIndexes);
163
+ };
164
+
165
+ const loadItemsDebounce = (0, _core.useDebounce)(loadMaybeLoadableItems, debounceMillis);
81
166
  const onViewableItemsChanged = (0, _react.useRef)(_ref => {
167
+ var _R$head, _R$last;
168
+
82
169
  let {
83
170
  viewableItems
84
171
  } = _ref;
85
- setItems(prev => {
86
- const viewableItemSortKeys = R.map(viewableItem => viewableItem.item.sortKey)(viewableItems);
87
- const firstViewableSortKey = R.head(viewableItemSortKeys);
88
- const lastViewableItemSortKey = R.last(viewableItemSortKeys);
89
- const firstItem = R.head(prev);
90
- const lastItem = R.last(prev);
91
-
92
- if (R.isNil(firstViewableSortKey) || R.isNil(lastViewableItemSortKey) || R.isNil(firstItem) || R.isNil(lastItem)) {
93
- return prev;
94
- }
95
-
96
- const frontBoundary = R.max(firstItem.sortKey, firstViewableSortKey - 1);
97
- const backBoundary = R.min(lastItem.sortKey, lastViewableItemSortKey + 1);
98
- const viewableItemBoundary = R.range(frontBoundary, backBoundary + 1);
99
- const newItems = R.map(prevItem => ({ ...prevItem,
100
- isViewable: R.includes(prevItem.sortKey, viewableItemBoundary)
101
- }))([...prev]);
102
- return newItems;
103
- });
104
- });
105
- const itemLoadedHandler = (0, _react.useCallback)(sortKey => {
106
- const itemState = R.find(state => state.sortKey === sortKey)(itemStates.current);
172
+ const orderedViewableItems = R.sort((a, b) => (a.index || 0) - (b.index || 0), viewableItems);
173
+ const firstViewableIndex = (_R$head = R.head(orderedViewableItems)) === null || _R$head === void 0 ? void 0 : _R$head.index;
174
+ const lastViewableItemIndex = (_R$last = R.last(orderedViewableItems)) === null || _R$last === void 0 ? void 0 : _R$last.index;
107
175
 
108
- if (R.isNil(itemState)) {
176
+ if (R.isNil(firstViewableIndex) || R.isNil(lastViewableItemIndex)) {
109
177
  return;
110
178
  }
111
179
 
112
- itemState.state = _ComicViewerProps.STATE.LOADED;
113
- itemState.error = undefined;
114
- }, [itemStates]);
115
- const itemErrorHandler = (0, _react.useCallback)(errorInfo => {
116
- const {
117
- sortKey,
118
- count
119
- } = errorInfo;
180
+ const startIndex = R.max(firstViewableIndex - NUMBER_OF_ADJACENT_ITEM, 0);
181
+ const endIndex = R.min(lastViewableItemIndex + NUMBER_OF_ADJACENT_ITEM, itemStates.length - 1);
182
+ maybeLoadableItemsIndexRange.current = [startIndex, endIndex + 1];
183
+ loadItemsDebounce();
184
+ });
185
+ const renderItem = (0, _react.useCallback)(_ref2 => {
186
+ var _renderedDimensions$i, _renderedDimensions$i2;
120
187
 
121
- if (count >= errorRetryCount) {
122
- return;
123
- }
188
+ let {
189
+ item,
190
+ index
191
+ } = _ref2;
124
192
 
125
- errors.current.set(sortKey, errorInfo);
126
- const itemState = R.find(state => state.sortKey === sortKey)(itemStates.current);
193
+ const onError = () => {
194
+ updateImageState((imageState, i) => {
195
+ const urlState = imageState.urlState;
127
196
 
128
- if (R.isNil(itemState)) {
129
- return;
130
- }
197
+ if (i === index && urlState !== undefined) {
198
+ return { ...imageState,
199
+ totalErrorCount: imageState.totalErrorCount + 1,
200
+ urlState: { ...urlState,
201
+ validity: 'invalid'
202
+ }
203
+ };
204
+ }
205
+
206
+ return imageState;
207
+ });
208
+
209
+ if (item.reloadButtonVisible) {
210
+ return;
211
+ }
212
+
213
+ const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;
131
214
 
132
- itemState.state = _ComicViewerProps.STATE.FAIL;
133
- itemState.error = errorInfo;
134
-
135
- const handleError = () => {
136
- const errorsArray = Array.from(errors.current.entries());
137
- const errorsInfo = R.map(_ref2 => {
138
- let [key, value] = _ref2;
139
- return value;
140
- })(errorsArray);
141
- onError && onError([...errorsInfo]);
142
- errors.current.clear();
215
+ if (index >= startIndex || index < endIndex) {
216
+ loadItemsDebounce();
217
+ }
143
218
  };
144
219
 
145
- if (debounceTimeOut.current) {
146
- clearTimeout(debounceTimeOut.current);
147
- }
220
+ const onReloadPress = () => {
221
+ const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;
148
222
 
149
- if (errors.current.size === pageUnit) {
150
- handleError();
151
- } else {
152
- debounceTimeOut.current = setTimeout(handleError, errorDebounceMillis);
153
- }
154
- }, [errors.current, itemStates]);
155
- const renderItem = (0, _react.useCallback)(_ref3 => {
156
- let {
157
- item
158
- } = _ref3;
159
- const itemState = R.find(state => state.sortKey === item.sortKey)(itemStates.current);
160
- const props = { ...item,
161
- itemState,
162
- errorRetryCount,
163
- onError: itemErrorHandler,
164
- onLoaded: itemLoadedHandler,
165
- onItemPress,
166
- getNextPage
223
+ if (index >= startIndex || index < endIndex) {
224
+ loadUrlByIndex([index]);
225
+ }
167
226
  };
168
- return /*#__PURE__*/_react.default.createElement(_ViewerItem.default, {
169
- props: props
170
- });
171
- }, [resourceString, itemErrorHandler, itemLoadedHandler, onItemPress]);
172
- (0, _react.useEffect)(() => {
173
- setItems(prev => {
174
- return R.map(prevItem => {
175
- const currentData = R.find(currentItemData => prevItem.sortKey === currentItemData.sortKey)(data);
176
- const itemState = R.find(state => state.sortKey === (currentData === null || currentData === void 0 ? void 0 : currentData.sortKey))(itemStates.current);
177
-
178
- if (currentData && itemState && itemState.state !== _ComicViewerProps.STATE.LOADED && currentData.url !== prevItem.url) {
179
- itemState.state = _ComicViewerProps.STATE.URL_LOADED;
180
- return { ...prevItem,
181
- url: currentData.url,
182
- expiresAt: currentData.expiresAt
227
+
228
+ const onLoad = () => {
229
+ updateImageState((imageState, i) => {
230
+ const urlState = imageState.urlState;
231
+
232
+ if (i === index && urlState !== undefined) {
233
+ return { ...imageState,
234
+ urlState: { ...urlState,
235
+ validity: 'valid'
236
+ }
183
237
  };
184
238
  }
185
239
 
186
- return prevItem;
187
- })([...prev]);
188
- ;
240
+ return imageState;
241
+ });
242
+ };
243
+
244
+ return /*#__PURE__*/_react.default.createElement(_ViewerItem.default, {
245
+ onError: onError,
246
+ onLoad: onLoad,
247
+ onPress: onItemPress,
248
+ onReloadPress: onReloadPress,
249
+ url: item.url,
250
+ width: ((_renderedDimensions$i = renderedDimensions[index]) === null || _renderedDimensions$i === void 0 ? void 0 : _renderedDimensions$i.width) ?? 0,
251
+ height: ((_renderedDimensions$i2 = renderedDimensions[index]) === null || _renderedDimensions$i2 === void 0 ? void 0 : _renderedDimensions$i2.height) ?? 0,
252
+ reloadButtonVisible: item.reloadButtonVisible
189
253
  });
190
- }, [resourceString]);
191
- (0, _react.useEffect)(() => {
192
- const newItems = R.map(item => ({ ...item,
193
- width: imageWidth,
194
- height: item.height * imageWidth / item.width
195
- }))(items);
196
- setItems(newItems);
197
- }, [imageWidth]);
254
+ }, [onItemPress, renderedDimensions]);
198
255
  (0, _react.useEffect)(() => {
199
- const totalHeight = itemHeightAccum[0];
200
256
  const offset = Math.floor(initialScrollPercentage / 100 * totalHeight);
201
257
 
202
258
  if (flatListRef.current) {
@@ -205,19 +261,18 @@ function ComicViewer(props) {
205
261
  animated: false
206
262
  });
207
263
  }
208
- }, [flatListRef.current]);
264
+ }, []);
209
265
  return /*#__PURE__*/_react.default.createElement(_reactNative.FlatList, _extends({
210
- data: items,
266
+ data: itemStates,
211
267
  getItemLayout: getItemLayout,
212
268
  initialNumToRender: initialNumToRender,
213
269
  keyExtractor: keyExtractor,
214
270
  onViewableItemsChanged: onViewableItemsChanged.current,
215
- onScroll: onScroll,
216
271
  ref: flatListRef,
272
+ removeClippedSubviews: false,
217
273
  renderItem: renderItem,
218
274
  viewabilityConfig: viewabilityConfig,
219
- windowSize: windowSize,
220
- ListFooterComponent: ListFooterComponent
275
+ windowSize: windowSize
221
276
  }, otherProps));
222
277
  }
223
278
 
@@ -1 +1 @@
1
- {"version":3,"names":["getItemHeights","items","R","map","content","height","appender","left","right","getHeightAccum","itemHeights","mapAccum","keyExtractor","item","sortKey","ComicViewer","props","data","errorDebounceMillis","errorRetryCount","initialNumToRender","initialScrollPercentage","itemVisiblePercentThreshold","onError","onScroll","onItemPress","getNextPage","viewerWidth","windowSize","pageUnit","ListFooterComponent","otherProps","flatListRef","useRef","errors","Map","debounceTimeOut","resourceString","toString","itemData","url","imageWidth","Math","min","initialItems","isViewable","width","setItems","useState","initialItemState","state","isEmpty","expiresAt","STATE","INIT","URL_LOADED","itemStates","itemHeightAccum","viewabilityConfig","useMemo","getItemLayout","useCallback","index","offsets","prepend","length","offset","onViewableItemsChanged","viewableItems","prev","viewableItemSortKeys","viewableItem","firstViewableSortKey","head","lastViewableItemSortKey","last","firstItem","lastItem","isNil","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","useEffect","currentData","currentItemData","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 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 resourceString = R.toString(R.map((itemData: ComicViewerItemData) => itemData.url)(data));\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.isEmpty(itemData.expiresAt) ? 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 errorRetryCount,\n onError: itemErrorHandler,\n onLoaded: itemLoadedHandler,\n onItemPress,\n getNextPage,\n };\n\n return <ViewerItem props={props}/>;\n }, [resourceString, 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 && itemState\n && itemState.state !== STATE.LOADED\n && (currentData.url !== prevItem.url)) {\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 }, [resourceString]);\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};\n"],"mappings":"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"}
1
+ {"version":3,"names":["appender","left","right","getHeightAccum","heights","R","mapAccum","keyExtractor","item","String","index","createInitialImageState","dimension","isNewUrlIncoming","totalErrorCount","mapImageStateToItemState","imageState","autoHandleErrorCount","url","urlState","reloadButtonVisible","validity","MAXIMUM_WIDTH","NUMBER_OF_ADJACENT_ITEM","ComicViewer","props","debounceMillis","getUrlByIndex","initialNumToRender","initialScrollPercentage","itemVisiblePercentThreshold","intrinsicDimensions","onItemPress","viewportWidth","windowSize","otherProps","flatListRef","useRef","debounceTimeout","maybeLoadableItemsIndexRange","actualImageWidth","Math","min","initialImageStates","useMemo","map","imageStatesRef","mapImageStatesToItemStates","imageStates","image","itemStates","setItemStates","useState","current","renderedDimensions","intrinsicDimension","width","height","layoutFromDimensions","useCallback","itemHeights","totalHeight","heightAccum","itemOffsets","prepend","getItemLayout","data","length","offset","viewabilityConfig","updateImageState","updateFunction","prevImageStates","newImageStates","prevItemStates","newItemStates","equals","loadUrlByIndex","indexes","filteredIndexes","filter","state","isNil","i","includes","urls","newUrl","get","undefined","loadMaybeLoadableItems","startIndex","endIndex","affectedIndexes","range","loadItemsDebounce","useDebounce","onViewableItemsChanged","viewableItems","orderedViewableItems","sort","a","b","firstViewableIndex","head","lastViewableItemIndex","last","max","renderItem","onError","onReloadPress","onLoad","useEffect","floor","scrollToOffset","animated"],"sources":["ComicViewer.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { FlatList, ListRenderItem, ViewToken } from 'react-native';\nimport * as R from 'ramda';\nimport { useDebounce } from '@fountain-ui/core';\nimport { default as ComicViewerProps, Dimension } from './ComicViewerProps';\nimport ViewerItem from './ViewerItem';\n\nconst appender = (left: number, right: number): [number, number] => [left + right, left + right];\nconst getHeightAccum = (heights: number[]): [number, number[]] => R.mapAccum(appender, 0, heights);\n\nconst keyExtractor = <T, >(item: ItemState) => String(item.index);\n\ninterface UrlState {\n url: string;\n validity: 'valid' | 'invalid' | 'unknown';\n}\n\ninterface ImageState {\n urlState?: UrlState;\n isNewUrlIncoming: boolean;\n totalErrorCount: number;\n dimension: Dimension;\n}\n\ninterface ItemState {\n index: number;\n url?: string;\n reloadButtonVisible: boolean;\n dimension: Dimension;\n}\n\nconst createInitialImageState = (dimension: Dimension): ImageState => ({\n isNewUrlIncoming: false,\n totalErrorCount: 0,\n dimension,\n});\n\nconst mapImageStateToItemState = (\n index: number,\n imageState: ImageState,\n autoHandleErrorCount: number,\n): ItemState => ({\n index,\n url: imageState.urlState?.url,\n reloadButtonVisible: (imageState.urlState?.validity !== 'valid') && imageState.totalErrorCount >= autoHandleErrorCount,\n dimension: imageState.dimension,\n});\n\nconst MAXIMUM_WIDTH = 720;\n\nconst NUMBER_OF_ADJACENT_ITEM = 5;\n\nexport default function ComicViewer(props: ComicViewerProps) {\n const {\n debounceMillis = 100,\n autoHandleErrorCount = 3,\n getUrlByIndex,\n initialNumToRender = 1,\n initialScrollPercentage = 0,\n itemVisiblePercentThreshold = 0,\n intrinsicDimensions,\n onItemPress,\n viewportWidth,\n windowSize = 3,\n ...otherProps\n } = props;\n\n const flatListRef = useRef<FlatList>(null);\n\n const debounceTimeout = useRef<NodeJS.Timeout | null>(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,14 +1,2 @@
1
1
  "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.STATE = void 0;
7
- const STATE = {
8
- INIT: 'init',
9
- URL_LOADED: 'url_loaded',
10
- LOADED: 'loaded',
11
- FAIL: 'fail'
12
- };
13
- exports.STATE = STATE;
14
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\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 * 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":";;;;;;AAIO,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 500\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 * TBD\n */\n viewportWidth: number;\n\n /**\n * The value for FlatList windowSize.\n * @default 3\n */\n windowSize?: number;\n\n /**\n * TBD\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,43 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = ReloadButton;
7
+
8
+ var _react = _interopRequireDefault(require("react"));
9
+
10
+ var _reactNative = require("react-native");
11
+
12
+ var _core = require("@fountain-ui/core");
13
+
14
+ var _icons = require("@fountain-ui/icons");
15
+
16
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
+
18
+ function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
19
+
20
+ function ReloadButton(props) {
21
+ return /*#__PURE__*/_react.default.createElement(_reactNative.View, {
22
+ style: {
23
+ width: '100%',
24
+ height: '100%',
25
+ alignItems: 'center',
26
+ paddingTop: 80
27
+ }
28
+ }, /*#__PURE__*/_react.default.createElement(_core.IconButton, _extends({}, props, {
29
+ children: /*#__PURE__*/_react.default.createElement(_icons.Restart, {
30
+ fill: '#ffffff'
31
+ }),
32
+ style: {
33
+ width: 48,
34
+ height: 48,
35
+ borderRadius: 24,
36
+ color: '#ffffff',
37
+ backgroundColor: '#767676'
38
+ }
39
+ })));
40
+ }
41
+
42
+ ;
43
+ //# sourceMappingURL=ReloadButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["ReloadButton","props","width","height","alignItems","paddingTop","borderRadius","color","backgroundColor"],"sources":["ReloadButton.tsx"],"sourcesContent":["import React from 'react';\nimport { View } from 'react-native';\nimport { IconButton, IconButtonProps } from '@fountain-ui/core';\nimport { Restart } from '@fountain-ui/icons';\n\ninterface ReloadButtonProps {\n onPress: IconButtonProps['onPress'];\n}\n\nexport default function ReloadButton(props: ReloadButtonProps) {\n return (\n <View\n style={{\n width: '100%',\n height: '100%',\n alignItems: 'center',\n paddingTop: 80,\n }}\n >\n <IconButton\n {...props}\n children={<Restart fill={'#ffffff'}/>}\n style={{\n width: 48,\n height: 48,\n borderRadius: 24,\n color: '#ffffff',\n backgroundColor: '#767676',\n }}\n />\n </View>\n );\n};\n"],"mappings":";;;;;;;AAAA;;AACA;;AACA;;AACA;;;;;;AAMe,SAASA,YAAT,CAAsBC,KAAtB,EAAgD;EAC3D,oBACI,6BAAC,iBAAD;IACI,KAAK,EAAE;MACHC,KAAK,EAAE,MADJ;MAEHC,MAAM,EAAE,MAFL;MAGHC,UAAU,EAAE,QAHT;MAIHC,UAAU,EAAE;IAJT;EADX,gBAQI,6BAAC,gBAAD,eACQJ,KADR;IAEI,QAAQ,eAAE,6BAAC,cAAD;MAAS,IAAI,EAAE;IAAf,EAFd;IAGI,KAAK,EAAE;MACHC,KAAK,EAAE,EADJ;MAEHC,MAAM,EAAE,EAFL;MAGHG,YAAY,EAAE,EAHX;MAIHC,KAAK,EAAE,SAJJ;MAKHC,eAAe,EAAE;IALd;EAHX,GARJ,CADJ;AAsBH;;AAAA"}