@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.
- package/build/commonjs/ComicViewer/ComicViewer.js +62 -33
- package/build/commonjs/ComicViewer/ComicViewer.js.map +1 -1
- package/build/commonjs/ComicViewer/ComicViewerItemProps.js.map +1 -1
- package/build/commonjs/ComicViewer/ComicViewerProps.js +12 -0
- package/build/commonjs/ComicViewer/ComicViewerProps.js.map +1 -1
- package/build/commonjs/ComicViewer/ViewerItem.js +94 -23
- package/build/commonjs/ComicViewer/ViewerItem.js.map +1 -1
- package/build/module/ComicViewer/ComicViewer.js +61 -33
- package/build/module/ComicViewer/ComicViewer.js.map +1 -1
- package/build/module/ComicViewer/ComicViewerItemProps.js.map +1 -1
- package/build/module/ComicViewer/ComicViewerProps.js +6 -1
- package/build/module/ComicViewer/ComicViewerProps.js.map +1 -1
- package/build/module/ComicViewer/ViewerItem.js +95 -25
- package/build/module/ComicViewer/ViewerItem.js.map +1 -1
- package/build/typescript/ComicViewer/ComicViewerItemProps.d.ts +12 -1
- package/build/typescript/ComicViewer/ComicViewerProps.d.ts +61 -12
- package/package.json +2 -2
- package/src/ComicViewer/ComicViewer.tsx +70 -30
- package/src/ComicViewer/ComicViewerItemProps.ts +16 -1
- package/src/ComicViewer/ComicViewerProps.ts +70 -10
- package/src/ComicViewer/ViewerItem.tsx +107 -27
|
@@ -3,6 +3,7 @@ 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
7
|
import ViewerItem from './ViewerItem';
|
|
7
8
|
|
|
8
9
|
const getItemHeights = items => R.map(content => content.height)(items);
|
|
@@ -11,7 +12,7 @@ const appender = (left, right) => [left + right, left + right];
|
|
|
11
12
|
|
|
12
13
|
const getHeightAccum = itemHeights => R.mapAccum(appender, 0, itemHeights);
|
|
13
14
|
|
|
14
|
-
const keyExtractor = item => item.
|
|
15
|
+
const keyExtractor = item => `${item.sortKey}`;
|
|
15
16
|
|
|
16
17
|
export default function ComicViewer(props) {
|
|
17
18
|
const {
|
|
@@ -22,21 +23,29 @@ export default function ComicViewer(props) {
|
|
|
22
23
|
initialScrollPercentage = 0,
|
|
23
24
|
itemVisiblePercentThreshold = 0,
|
|
24
25
|
onError,
|
|
26
|
+
onScroll,
|
|
27
|
+
getNextPage,
|
|
25
28
|
viewerWidth,
|
|
26
29
|
windowSize = 3,
|
|
30
|
+
pageUnit,
|
|
31
|
+
ListFooterComponent,
|
|
27
32
|
...otherProps
|
|
28
33
|
} = props;
|
|
29
34
|
const flatListRef = useRef(null);
|
|
30
35
|
const errors = useRef(new Map());
|
|
31
36
|
const debounceTimeOut = useRef(null);
|
|
32
|
-
const resourceString = R.toString(R.map(itemData => itemData.
|
|
37
|
+
const resourceString = R.toString(R.map(itemData => itemData.url)(data));
|
|
33
38
|
const initialItems = R.map(itemData => ({ ...itemData,
|
|
34
39
|
isViewable: false,
|
|
35
40
|
width: viewerWidth,
|
|
36
41
|
height: itemData.height * viewerWidth / itemData.width
|
|
37
42
|
}))(data);
|
|
38
43
|
const [items, setItems] = useState(initialItems);
|
|
39
|
-
const
|
|
44
|
+
const initialItemState = R.map(() => ({
|
|
45
|
+
state: STATE.UNLOAD
|
|
46
|
+
}))(data);
|
|
47
|
+
const itemStates = useRef(initialItemState);
|
|
48
|
+
const itemHeights = [...getItemHeights(items)];
|
|
40
49
|
const itemHeightAccum = getHeightAccum(itemHeights);
|
|
41
50
|
const viewabilityConfig = useMemo(() => ({
|
|
42
51
|
itemVisiblePercentThreshold
|
|
@@ -54,67 +63,84 @@ export default function ComicViewer(props) {
|
|
|
54
63
|
viewableItems
|
|
55
64
|
} = _ref;
|
|
56
65
|
setItems(prev => {
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
isViewable: R.includes(prevItem.
|
|
66
|
+
const viewableItemSortKeys = R.map(viewableItem => viewableItem.item.sortKey)(viewableItems);
|
|
67
|
+
const newItems = R.map(prevItem => ({ ...prevItem,
|
|
68
|
+
isViewable: R.includes(prevItem.sortKey, viewableItemSortKeys)
|
|
60
69
|
}))([...prev]);
|
|
70
|
+
return newItems;
|
|
61
71
|
});
|
|
62
72
|
});
|
|
73
|
+
const itemLoadedHandler = useCallback(sortKey => {
|
|
74
|
+
const itemState = itemStates.current[sortKey - 1];
|
|
75
|
+
itemState.state = STATE.LOADED;
|
|
76
|
+
itemState.error = undefined;
|
|
77
|
+
}, [itemStates]);
|
|
78
|
+
const itemErrorHandler = useCallback(errorInfo => {
|
|
79
|
+
const {
|
|
80
|
+
sortKey,
|
|
81
|
+
count
|
|
82
|
+
} = errorInfo;
|
|
63
83
|
|
|
64
|
-
|
|
65
|
-
const isRetryLimited = R.any(error => error.count >= errorRetryCount)(errors);
|
|
66
|
-
|
|
67
|
-
if (isRetryLimited) {
|
|
84
|
+
if (count >= errorRetryCount) {
|
|
68
85
|
return;
|
|
69
86
|
}
|
|
70
87
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
errors.current.set(errorInfo.id, errorInfo.count);
|
|
76
|
-
|
|
77
|
-
if (debounceTimeOut.current) {
|
|
78
|
-
clearTimeout(debounceTimeOut.current);
|
|
79
|
-
}
|
|
88
|
+
errors.current.set(sortKey, errorInfo);
|
|
89
|
+
const itemState = itemStates.current[sortKey - 1];
|
|
90
|
+
itemState.state = STATE.FAIL;
|
|
91
|
+
itemState.error = errorInfo;
|
|
80
92
|
|
|
81
|
-
|
|
93
|
+
const handleError = () => {
|
|
82
94
|
const errorsArray = Array.from(errors.current.entries());
|
|
83
95
|
const errorsInfo = R.map(_ref2 => {
|
|
84
96
|
let [key, value] = _ref2;
|
|
85
|
-
return
|
|
86
|
-
id: key,
|
|
87
|
-
count: value
|
|
88
|
-
};
|
|
97
|
+
return value;
|
|
89
98
|
})(errorsArray);
|
|
90
|
-
|
|
99
|
+
onError && onError([...errorsInfo]);
|
|
91
100
|
errors.current.clear();
|
|
92
|
-
}
|
|
93
|
-
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
if (debounceTimeOut.current) {
|
|
104
|
+
clearTimeout(debounceTimeOut.current);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (errors.current.size === pageUnit) {
|
|
108
|
+
handleError();
|
|
109
|
+
} else {
|
|
110
|
+
debounceTimeOut.current = setTimeout(handleError, errorDebounceMillis);
|
|
111
|
+
}
|
|
112
|
+
}, [errors.current, itemStates]);
|
|
94
113
|
const renderItem = useCallback(_ref3 => {
|
|
95
114
|
let {
|
|
96
115
|
item
|
|
97
116
|
} = _ref3;
|
|
117
|
+
const itemState = itemStates.current[item.sortKey - 1];
|
|
98
118
|
const props = { ...item,
|
|
99
|
-
|
|
119
|
+
itemState,
|
|
120
|
+
errorRetryCount,
|
|
121
|
+
onError: itemErrorHandler,
|
|
122
|
+
onLoaded: itemLoadedHandler,
|
|
123
|
+
getNextPage
|
|
100
124
|
};
|
|
101
125
|
return /*#__PURE__*/React.createElement(ViewerItem, {
|
|
102
126
|
props: props
|
|
103
127
|
});
|
|
104
|
-
}, []);
|
|
128
|
+
}, [resourceString, itemStates, itemErrorHandler, itemLoadedHandler]);
|
|
105
129
|
useEffect(() => {
|
|
106
130
|
setItems(prev => {
|
|
107
131
|
return R.map(prevItem => {
|
|
108
|
-
const currentData = R.find(currentItemData => prevItem.
|
|
132
|
+
const currentData = R.find(currentItemData => prevItem.sortKey === currentItemData.sortKey)(data);
|
|
109
133
|
|
|
110
|
-
if (currentData && currentData.
|
|
134
|
+
if (currentData && itemStates.current[currentData.sortKey - 1].state !== STATE.LOADED && currentData.url !== prevItem.url) {
|
|
111
135
|
return { ...prevItem,
|
|
112
|
-
|
|
136
|
+
url: currentData.url,
|
|
137
|
+
expiresAt: currentData.expiresAt
|
|
113
138
|
};
|
|
114
139
|
}
|
|
115
140
|
|
|
116
141
|
return prevItem;
|
|
117
142
|
})([...prev]);
|
|
143
|
+
;
|
|
118
144
|
});
|
|
119
145
|
}, [resourceString]);
|
|
120
146
|
useEffect(() => {
|
|
@@ -141,10 +167,12 @@ export default function ComicViewer(props) {
|
|
|
141
167
|
initialNumToRender: initialNumToRender,
|
|
142
168
|
keyExtractor: keyExtractor,
|
|
143
169
|
onViewableItemsChanged: onViewableItemsChanged.current,
|
|
170
|
+
onScroll: onScroll,
|
|
144
171
|
ref: flatListRef,
|
|
145
172
|
renderItem: renderItem,
|
|
146
173
|
viewabilityConfig: viewabilityConfig,
|
|
147
|
-
windowSize: windowSize
|
|
174
|
+
windowSize: windowSize,
|
|
175
|
+
ListFooterComponent: ListFooterComponent
|
|
148
176
|
}, otherProps));
|
|
149
177
|
}
|
|
150
178
|
;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","useCallback","useEffect","useMemo","useRef","useState","FlatList","R","ViewerItem","getItemHeights","items","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","errors","Map","debounceTimeOut","resourceString","toString","itemData","sourceUrl","initialItems","isViewable","width","setItems","itemHeightAccum","viewabilityConfig","getItemLayout","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","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":["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","initialNumToRender","initialScrollPercentage","itemVisiblePercentThreshold","onError","onScroll","getNextPage","viewerWidth","windowSize","pageUnit","ListFooterComponent","otherProps","flatListRef","errors","Map","debounceTimeOut","resourceString","toString","itemData","url","initialItems","isViewable","width","setItems","initialItemState","state","UNLOAD","itemStates","itemHeightAccum","viewabilityConfig","getItemLayout","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","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 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["ComicViewerProps.ts"],"sourcesContent":["import { ComponentProps } from '@fountain-ui/core';\n\nexport interface ErrorInfo {\n /**\n * ComicViewerItemData.
|
|
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":"AAIA,OAAO,MAAMA,KAAK,GAAG;EACjBC,MAAM,EAAE,QADS;EAEjBC,OAAO,EAAE,SAFQ;EAGjBC,MAAM,EAAE,QAHS;EAIjBC,IAAI,EAAE;AAJW,CAAd"}
|
|
@@ -1,60 +1,130 @@
|
|
|
1
|
-
import React, { useCallback, useRef, useState } from 'react';
|
|
1
|
+
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import { View } from 'react-native';
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
import * as R from 'ramda';
|
|
4
|
+
import { IconButton, Image, Spacer, useTheme } from '@fountain-ui/core';
|
|
5
|
+
import { Restart } from '@fountain-ui/icons';
|
|
6
|
+
|
|
7
|
+
const useStyles = function () {
|
|
8
|
+
const theme = useTheme();
|
|
9
|
+
return {
|
|
10
|
+
init: {
|
|
11
|
+
backgroundColor: theme.palette.paper.grey
|
|
12
|
+
},
|
|
13
|
+
failed: {
|
|
14
|
+
backgroundColor: theme.palette.paper.grey
|
|
15
|
+
},
|
|
16
|
+
reload: {
|
|
17
|
+
backgroundColor: theme.palette.paper.grey,
|
|
18
|
+
display: 'flex',
|
|
19
|
+
alignItems: 'center'
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
};
|
|
9
23
|
|
|
10
24
|
function ViewerItem(_ref) {
|
|
25
|
+
var _itemState$error;
|
|
26
|
+
|
|
11
27
|
let {
|
|
12
28
|
props
|
|
13
29
|
} = _ref;
|
|
14
30
|
const {
|
|
31
|
+
expiresAt,
|
|
32
|
+
errorRetryCount = 3,
|
|
15
33
|
height,
|
|
16
|
-
|
|
34
|
+
itemState,
|
|
17
35
|
isViewable,
|
|
36
|
+
sortKey,
|
|
37
|
+
url,
|
|
38
|
+
width,
|
|
39
|
+
getNextPage,
|
|
18
40
|
onError,
|
|
19
|
-
|
|
20
|
-
width
|
|
41
|
+
onLoaded
|
|
21
42
|
} = props;
|
|
22
43
|
const [isLoaded, setIsLoaded] = useState(false);
|
|
23
|
-
const
|
|
44
|
+
const styles = useStyles();
|
|
45
|
+
const errorCount = 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));
|
|
24
46
|
const onLoad = useCallback(() => {
|
|
25
47
|
errorCount.current = 0;
|
|
26
48
|
setIsLoaded(true);
|
|
27
|
-
|
|
49
|
+
onLoaded && onLoaded(sortKey);
|
|
50
|
+
}, [sortKey]);
|
|
28
51
|
const handleError = useCallback(() => {
|
|
29
52
|
errorCount.current = errorCount.current + 1;
|
|
53
|
+
const expired = expiresAt ? new Date(expiresAt) <= new Date() : false;
|
|
54
|
+
onError && onError({
|
|
55
|
+
sortKey,
|
|
56
|
+
count: errorCount.current,
|
|
57
|
+
expired
|
|
58
|
+
});
|
|
59
|
+
}, [errorCount.current]);
|
|
60
|
+
const onReloadPress = useCallback(() => {
|
|
61
|
+
errorCount.current = 1;
|
|
30
62
|
onError && onError({
|
|
31
|
-
|
|
32
|
-
count: errorCount.current
|
|
63
|
+
sortKey,
|
|
64
|
+
count: errorCount.current,
|
|
65
|
+
expired: false
|
|
33
66
|
});
|
|
34
|
-
}, [
|
|
67
|
+
}, [sortKey]);
|
|
35
68
|
const viewStyle = {
|
|
36
69
|
width,
|
|
37
70
|
height
|
|
38
71
|
};
|
|
72
|
+
const Placeholder = useCallback(props => {
|
|
73
|
+
const {
|
|
74
|
+
children,
|
|
75
|
+
failed
|
|
76
|
+
} = props;
|
|
39
77
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
78
|
+
if (!isViewable && !isLoaded) {
|
|
79
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
80
|
+
style: [viewStyle, styles.init]
|
|
81
|
+
});
|
|
82
|
+
}
|
|
43
83
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
84
|
+
if (errorCount.current >= errorRetryCount) {
|
|
85
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
86
|
+
style: [viewStyle, styles.reload]
|
|
87
|
+
}, /*#__PURE__*/React.createElement(Spacer, {
|
|
88
|
+
size: 20
|
|
89
|
+
}), /*#__PURE__*/React.createElement(IconButton, {
|
|
90
|
+
children: /*#__PURE__*/React.createElement(Restart, {
|
|
91
|
+
fill: '#ffffff'
|
|
92
|
+
}),
|
|
93
|
+
style: {
|
|
94
|
+
width: 48,
|
|
95
|
+
height: 48,
|
|
96
|
+
borderRadius: 24,
|
|
97
|
+
color: '#ffffff',
|
|
98
|
+
backgroundColor: '#767676'
|
|
99
|
+
},
|
|
100
|
+
onPress: onReloadPress
|
|
101
|
+
}));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (failed) {
|
|
105
|
+
return /*#__PURE__*/React.createElement(View, {
|
|
106
|
+
style: [viewStyle, styles.failed]
|
|
107
|
+
});
|
|
108
|
+
}
|
|
47
109
|
|
|
110
|
+
return children ? children : null;
|
|
111
|
+
}, [isViewable, isLoaded, errorCount.current, url]);
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
if (url === '') {
|
|
114
|
+
getNextPage === null || getNextPage === void 0 ? void 0 : getNextPage(sortKey);
|
|
115
|
+
}
|
|
116
|
+
}, []);
|
|
48
117
|
return /*#__PURE__*/React.createElement(Image, {
|
|
49
118
|
disableOutline: true,
|
|
50
|
-
key:
|
|
119
|
+
key: sortKey,
|
|
51
120
|
onLoad: onLoad,
|
|
52
121
|
onError: handleError,
|
|
53
122
|
source: {
|
|
54
|
-
uri:
|
|
123
|
+
uri: url
|
|
55
124
|
},
|
|
56
125
|
style: viewStyle,
|
|
57
|
-
square: true
|
|
126
|
+
square: true,
|
|
127
|
+
Placeholder: Placeholder
|
|
58
128
|
});
|
|
59
129
|
}
|
|
60
130
|
|
|
@@ -63,7 +133,7 @@ export default /*#__PURE__*/React.memo(ViewerItem, (prevProps, nextProps) => {
|
|
|
63
133
|
return false;
|
|
64
134
|
}
|
|
65
135
|
|
|
66
|
-
if (prevProps.props.
|
|
136
|
+
if (prevProps.props.url !== nextProps.props.url) {
|
|
67
137
|
return false;
|
|
68
138
|
}
|
|
69
139
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","useCallback","useRef","useState","View","Image","
|
|
1
|
+
{"version":3,"names":["React","useCallback","useEffect","useRef","useState","View","R","IconButton","Image","Spacer","useTheme","Restart","useStyles","theme","init","backgroundColor","palette","paper","grey","failed","reload","display","alignItems","ViewerItem","props","expiresAt","errorRetryCount","height","itemState","isViewable","sortKey","url","width","getNextPage","onError","onLoaded","isLoaded","setIsLoaded","styles","errorCount","defaultTo","error","count","onLoad","current","handleError","expired","Date","onReloadPress","viewStyle","Placeholder","children","borderRadius","color","uri","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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"}
|
|
@@ -1,12 +1,23 @@
|
|
|
1
|
-
import { ComicViewerItemData, ErrorInfo } from './ComicViewerProps';
|
|
1
|
+
import { ComicViewerItemData, ErrorInfo, ComicViewerItemState } from './ComicViewerProps';
|
|
2
2
|
declare type ComicViewerItemProps<T> = ComicViewerItemData<T> & {
|
|
3
3
|
/**
|
|
4
4
|
* FlatListItem is viewable in screen.
|
|
5
5
|
*/
|
|
6
6
|
isViewable: boolean;
|
|
7
|
+
/**
|
|
8
|
+
* How many times retry onError when same item error occur
|
|
9
|
+
* @default 3
|
|
10
|
+
*/
|
|
11
|
+
errorRetryCount?: number;
|
|
7
12
|
/**
|
|
8
13
|
* Error handler
|
|
9
14
|
*/
|
|
10
15
|
onError?: (errorInfo: ErrorInfo) => void;
|
|
16
|
+
/**
|
|
17
|
+
* Load handler
|
|
18
|
+
*/
|
|
19
|
+
onLoaded?: (sortKey: number) => void;
|
|
20
|
+
getNextPage?: (sortKey: number) => void;
|
|
21
|
+
itemState?: ComicViewerItemState;
|
|
11
22
|
};
|
|
12
23
|
export default ComicViewerItemProps;
|
|
@@ -1,13 +1,36 @@
|
|
|
1
|
+
import React from 'react';
|
|
1
2
|
import { ComponentProps } from '@fountain-ui/core';
|
|
3
|
+
import { NativeScrollEvent, NativeSyntheticEvent } from 'react-native';
|
|
4
|
+
export declare const STATE: {
|
|
5
|
+
readonly UNLOAD: "unload";
|
|
6
|
+
readonly LOADING: "loading";
|
|
7
|
+
readonly LOADED: "loaded";
|
|
8
|
+
readonly FAIL: "fail";
|
|
9
|
+
};
|
|
10
|
+
export declare type LoadingState = typeof STATE[keyof typeof STATE];
|
|
11
|
+
export interface ComicViewerItemState {
|
|
12
|
+
/**
|
|
13
|
+
* Content's loading state.
|
|
14
|
+
*/
|
|
15
|
+
state: LoadingState;
|
|
16
|
+
/***
|
|
17
|
+
* Content's error Info.
|
|
18
|
+
*/
|
|
19
|
+
error?: ErrorInfo;
|
|
20
|
+
}
|
|
2
21
|
export interface ErrorInfo {
|
|
3
22
|
/**
|
|
4
|
-
* ComicViewerItemData.
|
|
23
|
+
* ComicViewerItemData.sortKey.
|
|
5
24
|
*/
|
|
6
|
-
|
|
25
|
+
sortKey: number;
|
|
7
26
|
/**
|
|
8
27
|
* Number of times an error occurred.
|
|
9
28
|
*/
|
|
10
29
|
count: number;
|
|
30
|
+
/**
|
|
31
|
+
* Content is Expired: true
|
|
32
|
+
*/
|
|
33
|
+
expired: boolean;
|
|
11
34
|
}
|
|
12
35
|
export declare type ComicViewerItemData<T = {}> = T & {
|
|
13
36
|
/**
|
|
@@ -17,15 +40,23 @@ export declare type ComicViewerItemData<T = {}> = T & {
|
|
|
17
40
|
/**
|
|
18
41
|
* Unique value for identifying.
|
|
19
42
|
*/
|
|
20
|
-
id:
|
|
43
|
+
id: number | undefined;
|
|
21
44
|
/**
|
|
22
45
|
* Image sourceUrl for displaying.
|
|
23
46
|
*/
|
|
24
|
-
|
|
47
|
+
url: string;
|
|
25
48
|
/**
|
|
26
49
|
* Image width.
|
|
27
50
|
*/
|
|
28
51
|
width: number;
|
|
52
|
+
/**
|
|
53
|
+
* SortKey
|
|
54
|
+
*/
|
|
55
|
+
sortKey: number;
|
|
56
|
+
/**
|
|
57
|
+
* Image expire date.
|
|
58
|
+
*/
|
|
59
|
+
expiresAt: string;
|
|
29
60
|
};
|
|
30
61
|
export default interface ComicViewerProps<T> extends ComponentProps<{
|
|
31
62
|
/**
|
|
@@ -43,9 +74,9 @@ export default interface ComicViewerProps<T> extends ComponentProps<{
|
|
|
43
74
|
*/
|
|
44
75
|
errorRetryCount?: number;
|
|
45
76
|
/**
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
77
|
+
* How many items to render in the initial batch.
|
|
78
|
+
* @default 1
|
|
79
|
+
*/
|
|
49
80
|
initialNumToRender?: number;
|
|
50
81
|
/**
|
|
51
82
|
* Start at initialScrollPercentage.
|
|
@@ -58,11 +89,6 @@ export default interface ComicViewerProps<T> extends ComponentProps<{
|
|
|
58
89
|
* @default 0
|
|
59
90
|
*/
|
|
60
91
|
itemVisiblePercentThreshold?: number;
|
|
61
|
-
/**
|
|
62
|
-
* Handling all viewerItem errors at once.
|
|
63
|
-
* @param errors Array of ViewerItems errorInfo.
|
|
64
|
-
*/
|
|
65
|
-
onError?: (errors: ErrorInfo[]) => void;
|
|
66
92
|
/**
|
|
67
93
|
* Comic viewer width.
|
|
68
94
|
*/
|
|
@@ -72,5 +98,28 @@ export default interface ComicViewerProps<T> extends ComponentProps<{
|
|
|
72
98
|
* @default 3
|
|
73
99
|
*/
|
|
74
100
|
windowSize?: number;
|
|
101
|
+
/**
|
|
102
|
+
* How many images in one page.
|
|
103
|
+
*/
|
|
104
|
+
pageUnit: number;
|
|
105
|
+
/**
|
|
106
|
+
* Method for getting next page contents.
|
|
107
|
+
* @param sortKey
|
|
108
|
+
*/
|
|
109
|
+
getNextPage?: (sortKey: number) => void;
|
|
110
|
+
/**
|
|
111
|
+
* Handling all viewerItem errors at once.
|
|
112
|
+
* @param errors Array of ViewerItems errorInfo.
|
|
113
|
+
*/
|
|
114
|
+
onError?: (errors: ErrorInfo[]) => void;
|
|
115
|
+
/**
|
|
116
|
+
* Handle scroll event.
|
|
117
|
+
* @param event Scroll event.
|
|
118
|
+
*/
|
|
119
|
+
onScroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;
|
|
120
|
+
/**
|
|
121
|
+
* Component for comic viewer footer.
|
|
122
|
+
*/
|
|
123
|
+
ListFooterComponent?: React.ReactElement;
|
|
75
124
|
}> {
|
|
76
125
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fountain-ui/lab",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.30",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "Fountain-UI Team",
|
|
6
6
|
"description": "Incubator for Fountain-UI React components.",
|
|
@@ -70,5 +70,5 @@
|
|
|
70
70
|
"publishConfig": {
|
|
71
71
|
"access": "public"
|
|
72
72
|
},
|
|
73
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "0c9f01b22179356577219f06bc6a21f6eb3f554c"
|
|
74
74
|
}
|