@fountain-ui/lab 2.0.0-beta.29 → 2.0.0-beta.30

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.
@@ -11,6 +11,8 @@ var _reactNative = require("react-native");
11
11
 
12
12
  var R = _interopRequireWildcard(require("ramda"));
13
13
 
14
+ var _ComicViewerProps = require("./ComicViewerProps");
15
+
14
16
  var _ViewerItem = _interopRequireDefault(require("./ViewerItem"));
15
17
 
16
18
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -27,7 +29,7 @@ const appender = (left, right) => [left + right, left + right];
27
29
 
28
30
  const getHeightAccum = itemHeights => R.mapAccum(appender, 0, itemHeights);
29
31
 
30
- const keyExtractor = item => item.id;
32
+ const keyExtractor = item => `${item.sortKey}`;
31
33
 
32
34
  function ComicViewer(props) {
33
35
  const {
@@ -38,21 +40,29 @@ function ComicViewer(props) {
38
40
  initialScrollPercentage = 0,
39
41
  itemVisiblePercentThreshold = 0,
40
42
  onError,
43
+ onScroll,
44
+ getNextPage,
41
45
  viewerWidth,
42
46
  windowSize = 3,
47
+ pageUnit,
48
+ ListFooterComponent,
43
49
  ...otherProps
44
50
  } = props;
45
51
  const flatListRef = (0, _react.useRef)(null);
46
52
  const errors = (0, _react.useRef)(new Map());
47
53
  const debounceTimeOut = (0, _react.useRef)(null);
48
- const resourceString = R.toString(R.map(itemData => itemData.sourceUrl)(data));
54
+ const resourceString = R.toString(R.map(itemData => itemData.url)(data));
49
55
  const initialItems = R.map(itemData => ({ ...itemData,
50
56
  isViewable: false,
51
57
  width: viewerWidth,
52
58
  height: itemData.height * viewerWidth / itemData.width
53
59
  }))(data);
54
60
  const [items, setItems] = (0, _react.useState)(initialItems);
55
- const itemHeights = getItemHeights(items);
61
+ const initialItemState = R.map(() => ({
62
+ state: _ComicViewerProps.STATE.UNLOAD
63
+ }))(data);
64
+ const itemStates = (0, _react.useRef)(initialItemState);
65
+ const itemHeights = [...getItemHeights(items)];
56
66
  const itemHeightAccum = getHeightAccum(itemHeights);
57
67
  const viewabilityConfig = (0, _react.useMemo)(() => ({
58
68
  itemVisiblePercentThreshold
@@ -70,67 +80,84 @@ function ComicViewer(props) {
70
80
  viewableItems
71
81
  } = _ref;
72
82
  setItems(prev => {
73
- const viewableItemIds = R.map(viewableItem => viewableItem.item.id)(viewableItems);
74
- return R.map(prevItem => ({ ...prevItem,
75
- isViewable: R.includes(prevItem.id, viewableItemIds)
83
+ const viewableItemSortKeys = R.map(viewableItem => viewableItem.item.sortKey)(viewableItems);
84
+ const newItems = R.map(prevItem => ({ ...prevItem,
85
+ isViewable: R.includes(prevItem.sortKey, viewableItemSortKeys)
76
86
  }))([...prev]);
87
+ return newItems;
77
88
  });
78
89
  });
90
+ const itemLoadedHandler = (0, _react.useCallback)(sortKey => {
91
+ const itemState = itemStates.current[sortKey - 1];
92
+ itemState.state = _ComicViewerProps.STATE.LOADED;
93
+ itemState.error = undefined;
94
+ }, [itemStates]);
95
+ const itemErrorHandler = (0, _react.useCallback)(errorInfo => {
96
+ const {
97
+ sortKey,
98
+ count
99
+ } = errorInfo;
79
100
 
80
- const onErrorHandler = errors => {
81
- const isRetryLimited = R.any(error => error.count >= errorRetryCount)(errors);
82
-
83
- if (isRetryLimited) {
101
+ if (count >= errorRetryCount) {
84
102
  return;
85
103
  }
86
104
 
87
- onError && onError(errors);
88
- };
105
+ errors.current.set(sortKey, errorInfo);
106
+ const itemState = itemStates.current[sortKey - 1];
107
+ itemState.state = _ComicViewerProps.STATE.FAIL;
108
+ itemState.error = errorInfo;
89
109
 
90
- const itemErrorHandler = (0, _react.useCallback)(errorInfo => {
91
- errors.current.set(errorInfo.id, errorInfo.count);
92
-
93
- if (debounceTimeOut.current) {
94
- clearTimeout(debounceTimeOut.current);
95
- }
96
-
97
- debounceTimeOut.current = setTimeout(function () {
110
+ const handleError = () => {
98
111
  const errorsArray = Array.from(errors.current.entries());
99
112
  const errorsInfo = R.map(_ref2 => {
100
113
  let [key, value] = _ref2;
101
- return {
102
- id: key,
103
- count: value
104
- };
114
+ return value;
105
115
  })(errorsArray);
106
- onErrorHandler([...errorsInfo]);
116
+ onError && onError([...errorsInfo]);
107
117
  errors.current.clear();
108
- }, errorDebounceMillis);
109
- }, [errorDebounceMillis, errors.current]);
118
+ };
119
+
120
+ if (debounceTimeOut.current) {
121
+ clearTimeout(debounceTimeOut.current);
122
+ }
123
+
124
+ if (errors.current.size === pageUnit) {
125
+ handleError();
126
+ } else {
127
+ debounceTimeOut.current = setTimeout(handleError, errorDebounceMillis);
128
+ }
129
+ }, [errors.current, itemStates]);
110
130
  const renderItem = (0, _react.useCallback)(_ref3 => {
111
131
  let {
112
132
  item
113
133
  } = _ref3;
134
+ const itemState = itemStates.current[item.sortKey - 1];
114
135
  const props = { ...item,
115
- onError: itemErrorHandler
136
+ itemState,
137
+ errorRetryCount,
138
+ onError: itemErrorHandler,
139
+ onLoaded: itemLoadedHandler,
140
+ getNextPage
116
141
  };
117
142
  return /*#__PURE__*/_react.default.createElement(_ViewerItem.default, {
118
143
  props: props
119
144
  });
120
- }, []);
145
+ }, [resourceString, itemStates, itemErrorHandler, itemLoadedHandler]);
121
146
  (0, _react.useEffect)(() => {
122
147
  setItems(prev => {
123
148
  return R.map(prevItem => {
124
- const currentData = R.find(currentItemData => prevItem.id === currentItemData.id)(data);
149
+ const currentData = R.find(currentItemData => prevItem.sortKey === currentItemData.sortKey)(data);
125
150
 
126
- if (currentData && currentData.sourceUrl !== prevItem.sourceUrl) {
151
+ if (currentData && itemStates.current[currentData.sortKey - 1].state !== _ComicViewerProps.STATE.LOADED && currentData.url !== prevItem.url) {
127
152
  return { ...prevItem,
128
- sourceUrl: currentData.sourceUrl
153
+ url: currentData.url,
154
+ expiresAt: currentData.expiresAt
129
155
  };
130
156
  }
131
157
 
132
158
  return prevItem;
133
159
  })([...prev]);
160
+ ;
134
161
  });
135
162
  }, [resourceString]);
136
163
  (0, _react.useEffect)(() => {
@@ -157,10 +184,12 @@ function ComicViewer(props) {
157
184
  initialNumToRender: initialNumToRender,
158
185
  keyExtractor: keyExtractor,
159
186
  onViewableItemsChanged: onViewableItemsChanged.current,
187
+ onScroll: onScroll,
160
188
  ref: flatListRef,
161
189
  renderItem: renderItem,
162
190
  viewabilityConfig: viewabilityConfig,
163
- windowSize: windowSize
191
+ windowSize: windowSize,
192
+ ListFooterComponent: ListFooterComponent
164
193
  }, otherProps));
165
194
  }
166
195
 
@@ -1 +1 @@
1
- {"version":3,"names":["getItemHeights","items","R","map","content","height","appender","left","right","getHeightAccum","itemHeights","mapAccum","keyExtractor","item","id","ComicViewer","props","data","errorDebounceMillis","errorRetryCount","initialNumToRender","initialScrollPercentage","itemVisiblePercentThreshold","onError","viewerWidth","windowSize","otherProps","flatListRef","useRef","errors","Map","debounceTimeOut","resourceString","toString","itemData","sourceUrl","initialItems","isViewable","width","setItems","useState","itemHeightAccum","viewabilityConfig","useMemo","getItemLayout","useCallback","index","offsets","prepend","length","offset","onViewableItemsChanged","viewableItems","prev","viewableItemIds","viewableItem","prevItem","includes","onErrorHandler","isRetryLimited","any","error","count","itemErrorHandler","errorInfo","current","set","clearTimeout","setTimeout","errorsArray","Array","from","entries","errorsInfo","key","value","clear","renderItem","useEffect","currentData","find","currentItemData","newItems","totalHeight","Math","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 { ComicViewerItemData, default as ComicViewerProps, ErrorInfo } 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.id;\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 viewerWidth,\n windowSize = 3,\n ...otherProps\n } = props;\n\n const flatListRef = useRef<FlatList>(null);\n\n const errors = useRef<Map<string, number>>(new Map());\n const debounceTimeOut = useRef<NodeJS.Timeout | null>(null);\n\n const resourceString = R.toString(R.map((itemData: ComicViewerItemData) => itemData.sourceUrl)(data));\n\n const initialItems = R.map((itemData: ComicViewerItemData<T>) => ({\n ...itemData,\n isViewable: false,\n width: viewerWidth,\n height: (itemData.height * viewerWidth) / itemData.width,\n }))(data);\n\n const [items, setItems] = useState<ComicViewerItemProps<T>[]>(initialItems);\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 viewableItemIds = R.map((viewableItem: ViewToken) => viewableItem.item.id)(viewableItems);\n\n return R.map((prevItem: ComicViewerItemProps<T>) => ({\n ...prevItem,\n isViewable: R.includes(prevItem.id, viewableItemIds),\n }))([...prev]);\n });\n });\n\n const onErrorHandler = (errors: ErrorInfo[]) => {\n const isRetryLimited = R.any((error: ErrorInfo) => error.count >= errorRetryCount)(errors);\n\n if (isRetryLimited) {\n return;\n }\n\n onError && onError(errors);\n };\n\n const itemErrorHandler = useCallback((errorInfo: ErrorInfo) => {\n errors.current.set(errorInfo.id, errorInfo.count);\n\n if (debounceTimeOut.current) {\n clearTimeout(debounceTimeOut.current);\n }\n\n debounceTimeOut.current = setTimeout(function () {\n const errorsArray = Array.from(errors.current.entries());\n const errorsInfo = R.map(([key, value]: [string, number]) => ({\n id: key,\n count: value,\n }))(errorsArray);\n\n onErrorHandler([...errorsInfo]);\n errors.current.clear();\n }, errorDebounceMillis);\n }, [errorDebounceMillis, errors.current]);\n\n const renderItem: ListRenderItem<ComicViewerItemProps<T>> = useCallback(({ item }) => {\n const props = {\n ...item,\n onError: itemErrorHandler,\n };\n\n return <ViewerItem props={props}/>;\n }, []);\n\n useEffect(() => {\n setItems((prev: ComicViewerItemProps<T>[]) => {\n return R.map((prevItem: ComicViewerItemProps<T>) => {\n const currentData = R.find((currentItemData: ComicViewerItemData<T>) => prevItem.id === currentItemData.id)(data);\n\n if (currentData && (currentData.sourceUrl !== prevItem.sourceUrl)) {\n return {\n ...prevItem,\n sourceUrl: currentData.sourceUrl,\n };\n }\n\n return prevItem;\n })([...prev]);\n });\n }, [resourceString]);\n\n useEffect(() => {\n const newItems = R.map((item: ComicViewerItemProps<T>) => ({\n ...item,\n width: viewerWidth,\n height: (item.height * viewerWidth) / item.width,\n }))(items);\n\n setItems(newItems);\n }, [viewerWidth]);\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 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":["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","getNextPage","viewerWidth","windowSize","pageUnit","ListFooterComponent","otherProps","flatListRef","useRef","errors","Map","debounceTimeOut","resourceString","toString","itemData","url","initialItems","isViewable","width","setItems","useState","initialItemState","state","STATE","UNLOAD","itemStates","itemHeightAccum","viewabilityConfig","useMemo","getItemLayout","useCallback","index","offsets","prepend","length","offset","onViewableItemsChanged","viewableItems","prev","viewableItemSortKeys","viewableItem","newItems","prevItem","includes","itemLoadedHandler","itemState","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","find","currentItemData","expiresAt","totalHeight","Math","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 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 initialItems = R.map((itemData: ComicViewerItemData<T>) => ({\n ...itemData,\n isViewable: false,\n width: viewerWidth,\n height: (itemData.height * viewerWidth) / itemData.width,\n }))(data);\n\n const [items, setItems] = useState<ComicViewerItemProps<T>[]>(initialItems);\n\n const initialItemState: ComicViewerItemState[] = R.map(() => ({\n state: STATE.UNLOAD,\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 = R.map((viewableItem: ViewToken) => viewableItem.item.sortKey)(viewableItems);\n\n const newItems = R.map((prevItem: ComicViewerItemProps<T>) => ({\n ...prevItem,\n isViewable: R.includes(prevItem.sortKey, viewableItemSortKeys),\n }))([...prev]);\n\n return newItems;\n });\n });\n\n const itemLoadedHandler = useCallback((sortKey: number) => {\n const itemState = itemStates.current[sortKey - 1];\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 = itemStates.current[sortKey - 1];\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 = itemStates.current[item.sortKey - 1];\n\n const props = {\n ...item,\n itemState,\n errorRetryCount,\n onError: itemErrorHandler,\n onLoaded: itemLoadedHandler,\n getNextPage,\n };\n\n return <ViewerItem props={props}/>;\n }, [resourceString, itemStates, itemErrorHandler, itemLoadedHandler]);\n\n useEffect(() => {\n setItems((prev: ComicViewerItemProps<T>[]) => {\n return R.map((prevItem: ComicViewerItemProps<T>) => {\n const currentData = R.find((currentItemData: ComicViewerItemData<T>) => prevItem.sortKey === currentItemData.sortKey)(data);\n\n if (currentData\n && itemStates.current[currentData.sortKey - 1].state !== STATE.LOADED\n && (currentData.url !== prevItem.url)) {\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: viewerWidth,\n height: (item.height * viewerWidth) / item.width,\n }))(items);\n\n setItems(newItems);\n }, [viewerWidth]);\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 +1 @@
1
- {"version":3,"names":[],"sources":["ComicViewerItemProps.ts"],"sourcesContent":["import { ComicViewerItemData, ErrorInfo } from './ComicViewerProps';\n\ntype ComicViewerItemProps<T> = ComicViewerItemData<T> & {\n /**\n * FlatListItem is viewable in screen.\n */\n isViewable: boolean;\n\n /**\n * Error handler\n */\n onError?: (errorInfo: ErrorInfo) => void;\n}\n\nexport default ComicViewerItemProps;"],"mappings":""}
1
+ {"version":3,"names":[],"sources":["ComicViewerItemProps.ts"],"sourcesContent":["import { ComicViewerItemData, ErrorInfo, ComicViewerItemState } from './ComicViewerProps';\n\ntype ComicViewerItemProps<T> = ComicViewerItemData<T> & {\n /**\n * FlatListItem is viewable in screen.\n */\n isViewable: boolean;\n\n /**\n * How many times retry onError when same item error occur\n * @default 3\n */\n errorRetryCount?: number;\n\n /**\n * Error handler\n */\n onError?: (errorInfo: ErrorInfo) => void;\n\n /**\n * Load handler\n */\n onLoaded?: (sortKey: number) => void;\n\n getNextPage?: (sortKey: number) => void;\n\n itemState?: ComicViewerItemState;\n}\n\nexport default ComicViewerItemProps;"],"mappings":""}
@@ -1,2 +1,14 @@
1
1
  "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.STATE = void 0;
7
+ const STATE = {
8
+ UNLOAD: 'unload',
9
+ LOADING: 'loading',
10
+ LOADED: 'loaded',
11
+ FAIL: 'fail'
12
+ };
13
+ exports.STATE = STATE;
2
14
  //# sourceMappingURL=ComicViewerProps.js.map
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["ComicViewerProps.ts"],"sourcesContent":["import { ComponentProps } from '@fountain-ui/core';\n\nexport interface ErrorInfo {\n /**\n * ComicViewerItemData.id.\n */\n id: string;\n\n /**\n * Number of times an error occurred.\n */\n count: number;\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: string;\n\n /**\n * Image sourceUrl for displaying.\n */\n sourceUrl: string;\n\n /**\n * Image width.\n */\n width: 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 * Handling all viewerItem errors at once.\n * @param errors Array of ViewerItems errorInfo.\n */\n onError?: (errors: ErrorInfo[]) => void;\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}> {}"],"mappings":""}
1
+ {"version":3,"names":["STATE","UNLOAD","LOADING","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 UNLOAD: 'unload',\n LOADING: 'loading',\n LOADED: 'loaded',\n FAIL: 'fail',\n} as const;\n\nexport type LoadingState = typeof STATE[keyof typeof STATE];\n\nexport interface ComicViewerItemState{\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 * Component for comic viewer footer.\n */\n ListFooterComponent?: React.ReactElement;\n}> {}"],"mappings":";;;;;;AAIO,MAAMA,KAAK,GAAG;EACjBC,MAAM,EAAE,QADS;EAEjBC,OAAO,EAAE,SAFQ;EAGjBC,MAAM,EAAE,QAHS;EAIjBC,IAAI,EAAE;AAJW,CAAd"}
@@ -9,66 +9,137 @@ var _react = _interopRequireWildcard(require("react"));
9
9
 
10
10
  var _reactNative = require("react-native");
11
11
 
12
+ var R = _interopRequireWildcard(require("ramda"));
13
+
12
14
  var _core = require("@fountain-ui/core");
13
15
 
16
+ var _icons = require("@fountain-ui/icons");
17
+
14
18
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
15
19
 
16
20
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
17
21
 
18
- const styles = _core.StyleSheet.create({
19
- placeholder: {
20
- backgroundColor: '#abcabc'
21
- }
22
- });
22
+ const useStyles = function () {
23
+ const theme = (0, _core.useTheme)();
24
+ return {
25
+ init: {
26
+ backgroundColor: theme.palette.paper.grey
27
+ },
28
+ failed: {
29
+ backgroundColor: theme.palette.paper.grey
30
+ },
31
+ reload: {
32
+ backgroundColor: theme.palette.paper.grey,
33
+ display: 'flex',
34
+ alignItems: 'center'
35
+ }
36
+ };
37
+ };
23
38
 
24
39
  function ViewerItem(_ref) {
40
+ var _itemState$error;
41
+
25
42
  let {
26
43
  props
27
44
  } = _ref;
28
45
  const {
46
+ expiresAt,
47
+ errorRetryCount = 3,
29
48
  height,
30
- id,
49
+ itemState,
31
50
  isViewable,
51
+ sortKey,
52
+ url,
53
+ width,
54
+ getNextPage,
32
55
  onError,
33
- sourceUrl,
34
- width
56
+ onLoaded
35
57
  } = props;
36
58
  const [isLoaded, setIsLoaded] = (0, _react.useState)(false);
37
- const errorCount = (0, _react.useRef)(0);
59
+ const styles = useStyles();
60
+ const errorCount = (0, _react.useRef)(R.defaultTo(0)(itemState === null || itemState === void 0 ? void 0 : (_itemState$error = itemState.error) === null || _itemState$error === void 0 ? void 0 : _itemState$error.count));
38
61
  const onLoad = (0, _react.useCallback)(() => {
39
62
  errorCount.current = 0;
40
63
  setIsLoaded(true);
41
- }, []);
64
+ onLoaded && onLoaded(sortKey);
65
+ }, [sortKey]);
42
66
  const handleError = (0, _react.useCallback)(() => {
43
67
  errorCount.current = errorCount.current + 1;
68
+ const expired = expiresAt ? new Date(expiresAt) <= new Date() : false;
69
+ onError && onError({
70
+ sortKey,
71
+ count: errorCount.current,
72
+ expired
73
+ });
74
+ }, [errorCount.current]);
75
+ const onReloadPress = (0, _react.useCallback)(() => {
76
+ errorCount.current = 1;
44
77
  onError && onError({
45
- id,
46
- count: errorCount.current
78
+ sortKey,
79
+ count: errorCount.current,
80
+ expired: false
47
81
  });
48
- }, [id]);
82
+ }, [sortKey]);
49
83
  const viewStyle = {
50
84
  width,
51
85
  height
52
86
  };
87
+ const Placeholder = (0, _react.useCallback)(props => {
88
+ const {
89
+ children,
90
+ failed
91
+ } = props;
53
92
 
54
- const Placeholder = () => /*#__PURE__*/_react.default.createElement(_reactNative.View, {
55
- style: [viewStyle, styles.placeholder]
56
- });
93
+ if (!isViewable && !isLoaded) {
94
+ return /*#__PURE__*/_react.default.createElement(_reactNative.View, {
95
+ style: [viewStyle, styles.init]
96
+ });
97
+ }
57
98
 
58
- if (!isViewable && !isLoaded) {
59
- return /*#__PURE__*/_react.default.createElement(Placeholder, null);
60
- }
99
+ if (errorCount.current >= errorRetryCount) {
100
+ return /*#__PURE__*/_react.default.createElement(_reactNative.View, {
101
+ style: [viewStyle, styles.reload]
102
+ }, /*#__PURE__*/_react.default.createElement(_core.Spacer, {
103
+ size: 20
104
+ }), /*#__PURE__*/_react.default.createElement(_core.IconButton, {
105
+ children: /*#__PURE__*/_react.default.createElement(_icons.Restart, {
106
+ fill: '#ffffff'
107
+ }),
108
+ style: {
109
+ width: 48,
110
+ height: 48,
111
+ borderRadius: 24,
112
+ color: '#ffffff',
113
+ backgroundColor: '#767676'
114
+ },
115
+ onPress: onReloadPress
116
+ }));
117
+ }
61
118
 
119
+ if (failed) {
120
+ return /*#__PURE__*/_react.default.createElement(_reactNative.View, {
121
+ style: [viewStyle, styles.failed]
122
+ });
123
+ }
124
+
125
+ return children ? children : null;
126
+ }, [isViewable, isLoaded, errorCount.current, url]);
127
+ (0, _react.useEffect)(() => {
128
+ if (url === '') {
129
+ getNextPage === null || getNextPage === void 0 ? void 0 : getNextPage(sortKey);
130
+ }
131
+ }, []);
62
132
  return /*#__PURE__*/_react.default.createElement(_core.Image, {
63
133
  disableOutline: true,
64
- key: sourceUrl,
134
+ key: sortKey,
65
135
  onLoad: onLoad,
66
136
  onError: handleError,
67
137
  source: {
68
- uri: sourceUrl
138
+ uri: url
69
139
  },
70
140
  style: viewStyle,
71
- square: true
141
+ square: true,
142
+ Placeholder: Placeholder
72
143
  });
73
144
  }
74
145
 
@@ -77,7 +148,7 @@ var _default = /*#__PURE__*/_react.default.memo(ViewerItem, (prevProps, nextProp
77
148
  return false;
78
149
  }
79
150
 
80
- if (prevProps.props.sourceUrl !== nextProps.props.sourceUrl) {
151
+ if (prevProps.props.url !== nextProps.props.url) {
81
152
  return false;
82
153
  }
83
154
 
@@ -1 +1 @@
1
- {"version":3,"names":["styles","StyleSheet","create","placeholder","backgroundColor","ViewerItem","props","height","id","isViewable","onError","sourceUrl","width","isLoaded","setIsLoaded","useState","errorCount","useRef","onLoad","useCallback","current","handleError","count","viewStyle","Placeholder","uri","React","memo","prevProps","nextProps"],"sources":["ViewerItem.tsx"],"sourcesContent":["import React, { useCallback, useRef, useState } from 'react';\nimport { View } from 'react-native';\nimport { Image, StyleSheet } from '@fountain-ui/core';\nimport ComicViewerItemProps from './ComicViewerItemProps';\n\nconst styles = StyleSheet.create({\n placeholder: {\n backgroundColor: '#abcabc',\n },\n});\n\nfunction ViewerItem<T>({ props }: { props: ComicViewerItemProps<T> }) {\n const {\n height,\n id,\n isViewable,\n onError,\n sourceUrl,\n width,\n } = props;\n\n const [isLoaded, setIsLoaded] = useState(false);\n\n const errorCount = useRef<number>(0);\n\n const onLoad = useCallback(() => {\n errorCount.current = 0;\n setIsLoaded(true);\n }, []);\n\n const handleError = useCallback(() => {\n errorCount.current = errorCount.current + 1;\n\n onError && onError({\n id,\n count: errorCount.current\n });\n }, [id]);\n\n const viewStyle = { width, height };\n\n const Placeholder = () => (\n <View style={[\n viewStyle,\n styles.placeholder,\n ]}/>\n );\n\n if (!isViewable && !isLoaded) {\n return <Placeholder/>;\n }\n\n return (\n <Image\n disableOutline={true}\n key={sourceUrl}\n onLoad={onLoad}\n onError={handleError}\n source={{ uri: sourceUrl }}\n style={viewStyle}\n square={true}\n />\n );\n}\n\nexport default React.memo(ViewerItem, (prevProps, nextProps) => {\n if (prevProps.props.isViewable !== nextProps.props.isViewable) {\n return false;\n }\n\n if (prevProps.props.sourceUrl !== nextProps.props.sourceUrl) {\n return false;\n }\n\n return true;\n});\n"],"mappings":";;;;;;;AAAA;;AACA;;AACA;;;;;;AAGA,MAAMA,MAAM,GAAGC,gBAAA,CAAWC,MAAX,CAAkB;EAC7BC,WAAW,EAAE;IACTC,eAAe,EAAE;EADR;AADgB,CAAlB,CAAf;;AAMA,SAASC,UAAT,OAAsE;EAAA,IAA/C;IAAEC;EAAF,CAA+C;EAClE,MAAM;IACFC,MADE;IAEFC,EAFE;IAGFC,UAHE;IAIFC,OAJE;IAKFC,SALE;IAMFC;EANE,IAOFN,KAPJ;EASA,MAAM,CAACO,QAAD,EAAWC,WAAX,IAA0B,IAAAC,eAAA,EAAS,KAAT,CAAhC;EAEA,MAAMC,UAAU,GAAG,IAAAC,aAAA,EAAe,CAAf,CAAnB;EAEA,MAAMC,MAAM,GAAG,IAAAC,kBAAA,EAAY,MAAM;IAC7BH,UAAU,CAACI,OAAX,GAAqB,CAArB;IACAN,WAAW,CAAC,IAAD,CAAX;EACH,CAHc,EAGZ,EAHY,CAAf;EAKA,MAAMO,WAAW,GAAG,IAAAF,kBAAA,EAAY,MAAM;IAClCH,UAAU,CAACI,OAAX,GAAqBJ,UAAU,CAACI,OAAX,GAAqB,CAA1C;IAEAV,OAAO,IAAIA,OAAO,CAAC;MACfF,EADe;MAEfc,KAAK,EAAEN,UAAU,CAACI;IAFH,CAAD,CAAlB;EAIH,CAPmB,EAOjB,CAACZ,EAAD,CAPiB,CAApB;EASA,MAAMe,SAAS,GAAG;IAAEX,KAAF;IAASL;EAAT,CAAlB;;EAEA,MAAMiB,WAAW,GAAG,mBAChB,6BAAC,iBAAD;IAAM,KAAK,EAAE,CACTD,SADS,EAETvB,MAAM,CAACG,WAFE;EAAb,EADJ;;EAOA,IAAI,CAACM,UAAD,IAAe,CAACI,QAApB,EAA8B;IAC1B,oBAAO,6BAAC,WAAD,OAAP;EACH;;EAED,oBACI,6BAAC,WAAD;IACI,cAAc,EAAE,IADpB;IAEI,GAAG,EAAEF,SAFT;IAGI,MAAM,EAAEO,MAHZ;IAII,OAAO,EAAEG,WAJb;IAKI,MAAM,EAAE;MAAEI,GAAG,EAAEd;IAAP,CALZ;IAMI,KAAK,EAAEY,SANX;IAOI,MAAM,EAAE;EAPZ,EADJ;AAWH;;4BAEcG,cAAA,CAAMC,IAAN,CAAWtB,UAAX,EAAuB,CAACuB,SAAD,EAAYC,SAAZ,KAA0B;EAC5D,IAAID,SAAS,CAACtB,KAAV,CAAgBG,UAAhB,KAA+BoB,SAAS,CAACvB,KAAV,CAAgBG,UAAnD,EAA+D;IAC3D,OAAO,KAAP;EACH;;EAED,IAAImB,SAAS,CAACtB,KAAV,CAAgBK,SAAhB,KAA8BkB,SAAS,CAACvB,KAAV,CAAgBK,SAAlD,EAA6D;IACzD,OAAO,KAAP;EACH;;EAED,OAAO,IAAP;AACH,CAVc,C"}
1
+ {"version":3,"names":["useStyles","theme","useTheme","init","backgroundColor","palette","paper","grey","failed","reload","display","alignItems","ViewerItem","props","expiresAt","errorRetryCount","height","itemState","isViewable","sortKey","url","width","getNextPage","onError","onLoaded","isLoaded","setIsLoaded","useState","styles","errorCount","useRef","R","defaultTo","error","count","onLoad","useCallback","current","handleError","expired","Date","onReloadPress","viewStyle","Placeholder","children","borderRadius","color","useEffect","uri","React","memo","prevProps","nextProps"],"sources":["ViewerItem.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { View } from 'react-native';\nimport * as R from 'ramda';\nimport type { PlaceholderProps } from '@fountain-ui/core';\nimport { IconButton, Image, Spacer, useTheme } from '@fountain-ui/core';\nimport { NamedStylesStringUnion, UseStyles } from '@fountain-ui/styles';\nimport { Restart } from '@fountain-ui/icons';\nimport ComicViewerItemProps from './ComicViewerItemProps';\n\ntype PlaceholderStyles = NamedStylesStringUnion<'init' | 'failed' | 'reload'>;\n\nconst useStyles: UseStyles<PlaceholderStyles> = function (): PlaceholderStyles {\n const theme = useTheme();\n\n return {\n init: {\n backgroundColor: theme.palette.paper.grey,\n },\n failed: {\n backgroundColor: theme.palette.paper.grey,\n },\n reload: {\n backgroundColor: theme.palette.paper.grey,\n display: 'flex',\n alignItems: 'center',\n },\n };\n};\n\nfunction ViewerItem<T>({ props }: { props: ComicViewerItemProps<T> }) {\n const {\n expiresAt,\n errorRetryCount = 3,\n height,\n itemState,\n isViewable,\n sortKey,\n url,\n width,\n getNextPage,\n onError,\n onLoaded,\n } = props;\n\n const [isLoaded, setIsLoaded] = useState(false);\n\n const styles = useStyles();\n\n const errorCount = useRef<number>(R.defaultTo(0)(itemState?.error?.count));\n\n const onLoad = useCallback(() => {\n errorCount.current = 0;\n\n setIsLoaded(true);\n\n onLoaded && onLoaded(sortKey);\n }, [sortKey]);\n\n const handleError = useCallback(() => {\n errorCount.current = errorCount.current + 1;\n\n const expired = expiresAt ? new Date(expiresAt) <= new Date() : false;\n\n onError && onError({\n sortKey,\n count: errorCount.current,\n expired,\n });\n }, [errorCount.current]);\n\n const onReloadPress = useCallback(() => {\n errorCount.current = 1;\n\n onError && onError({\n sortKey,\n count: errorCount.current,\n expired: false,\n });\n }, [sortKey]);\n\n const viewStyle = { width, height };\n\n const Placeholder = useCallback((props: PlaceholderProps) => {\n const { children, failed } = props;\n\n if (!isViewable && !isLoaded) {\n return <View style={[\n viewStyle,\n styles.init,\n ]}/>;\n }\n\n if (errorCount.current >= errorRetryCount) {\n return <View style={[\n viewStyle,\n styles.reload,\n ]}>\n <Spacer size={20}/>\n\n <IconButton\n children={<Restart fill={'#ffffff'}/>}\n style={{\n width: 48,\n height: 48,\n borderRadius: 24,\n color: '#ffffff',\n backgroundColor: '#767676',\n }}\n onPress={onReloadPress}\n />\n </View>;\n }\n\n if (failed) {\n return (\n <View style={[\n viewStyle,\n styles.failed,\n ]}/>\n );\n }\n\n return children ? children : null;\n }, [isViewable, isLoaded, errorCount.current, url]);\n\n useEffect(() => {\n if (url === '') {\n getNextPage?.(sortKey);\n }\n }, []);\n\n return (\n <Image\n disableOutline={true}\n key={sortKey}\n onLoad={onLoad}\n onError={handleError}\n source={{ uri: url }}\n style={viewStyle}\n square={true}\n Placeholder={Placeholder}\n />\n );\n}\n\nexport default React.memo(ViewerItem, (prevProps, nextProps) => {\n if (prevProps.props.isViewable !== nextProps.props.isViewable) {\n return false;\n }\n\n if (prevProps.props.url !== nextProps.props.url) {\n return false;\n }\n\n return true;\n});\n"],"mappings":"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"}