@fountain-ui/lab 2.0.0-beta.33 → 2.0.0-beta.34
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 +6 -5
- package/build/commonjs/ComicViewer/ComicViewer.js.map +1 -1
- package/build/commonjs/ComicViewer/ComicViewerProps.js.map +1 -1
- package/build/commonjs/ComicViewer/ViewerItem.js +39 -20
- package/build/commonjs/ComicViewer/ViewerItem.js.map +1 -1
- package/build/module/ComicViewer/ComicViewer.js +6 -5
- package/build/module/ComicViewer/ComicViewer.js.map +1 -1
- package/build/module/ComicViewer/ComicViewerProps.js.map +1 -1
- package/build/module/ComicViewer/ViewerItem.js +41 -22
- package/build/module/ComicViewer/ViewerItem.js.map +1 -1
- package/build/typescript/ComicViewer/ComicViewerProps.d.ts +8 -0
- package/package.json +2 -2
- package/src/ComicViewer/ComicViewer.tsx +10 -10
- package/src/ComicViewer/ComicViewerProps.ts +10 -0
- package/src/ComicViewer/ViewerItem.tsx +44 -29
|
@@ -36,6 +36,7 @@ function ComicViewer(props) {
|
|
|
36
36
|
data,
|
|
37
37
|
errorDebounceMillis = 500,
|
|
38
38
|
errorRetryCount = 3,
|
|
39
|
+
responseTimestamp,
|
|
39
40
|
initialNumToRender = 1,
|
|
40
41
|
initialScrollPercentage = 0,
|
|
41
42
|
itemVisiblePercentThreshold = 0,
|
|
@@ -52,7 +53,6 @@ function ComicViewer(props) {
|
|
|
52
53
|
const flatListRef = (0, _react.useRef)(null);
|
|
53
54
|
const errors = (0, _react.useRef)(new Map());
|
|
54
55
|
const debounceTimeOut = (0, _react.useRef)(null);
|
|
55
|
-
const resourceString = R.toString(R.map(itemData => itemData.url)(data));
|
|
56
56
|
const imageWidth = Math.min(viewerWidth, 720);
|
|
57
57
|
const initialItems = R.map(itemData => ({ ...itemData,
|
|
58
58
|
isViewable: false,
|
|
@@ -62,7 +62,7 @@ function ComicViewer(props) {
|
|
|
62
62
|
const [items, setItems] = (0, _react.useState)(initialItems);
|
|
63
63
|
const initialItemState = R.map(itemData => ({
|
|
64
64
|
sortKey: itemData.sortKey,
|
|
65
|
-
state: R.
|
|
65
|
+
state: R.isNil(itemData.id) ? _ComicViewerProps.STATE.INIT : _ComicViewerProps.STATE.URL_LOADED
|
|
66
66
|
}))(data);
|
|
67
67
|
const itemStates = (0, _react.useRef)(initialItemState);
|
|
68
68
|
const itemHeights = [...getItemHeights(items)];
|
|
@@ -159,6 +159,7 @@ function ComicViewer(props) {
|
|
|
159
159
|
const itemState = R.find(state => state.sortKey === item.sortKey)(itemStates.current);
|
|
160
160
|
const props = { ...item,
|
|
161
161
|
itemState,
|
|
162
|
+
responseTimestamp,
|
|
162
163
|
errorRetryCount,
|
|
163
164
|
onError: itemErrorHandler,
|
|
164
165
|
onLoaded: itemLoadedHandler,
|
|
@@ -168,14 +169,14 @@ function ComicViewer(props) {
|
|
|
168
169
|
return /*#__PURE__*/_react.default.createElement(_ViewerItem.default, {
|
|
169
170
|
props: props
|
|
170
171
|
});
|
|
171
|
-
}, [
|
|
172
|
+
}, [responseTimestamp, itemErrorHandler, itemLoadedHandler, onItemPress]);
|
|
172
173
|
(0, _react.useEffect)(() => {
|
|
173
174
|
setItems(prev => {
|
|
174
175
|
return R.map(prevItem => {
|
|
175
176
|
const currentData = R.find(currentItemData => prevItem.sortKey === currentItemData.sortKey)(data);
|
|
176
177
|
const itemState = R.find(state => state.sortKey === (currentData === null || currentData === void 0 ? void 0 : currentData.sortKey))(itemStates.current);
|
|
177
178
|
|
|
178
|
-
if (currentData && itemState && itemState.state !== _ComicViewerProps.STATE.LOADED
|
|
179
|
+
if (currentData && currentData.id && itemState && itemState.state !== _ComicViewerProps.STATE.LOADED) {
|
|
179
180
|
itemState.state = _ComicViewerProps.STATE.URL_LOADED;
|
|
180
181
|
return { ...prevItem,
|
|
181
182
|
url: currentData.url,
|
|
@@ -187,7 +188,7 @@ function ComicViewer(props) {
|
|
|
187
188
|
})([...prev]);
|
|
188
189
|
;
|
|
189
190
|
});
|
|
190
|
-
}, [
|
|
191
|
+
}, [responseTimestamp]);
|
|
191
192
|
(0, _react.useEffect)(() => {
|
|
192
193
|
const newItems = R.map(item => ({ ...item,
|
|
193
194
|
width: imageWidth,
|
|
@@ -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":["getItemHeights","items","R","map","content","height","appender","left","right","getHeightAccum","itemHeights","mapAccum","keyExtractor","item","sortKey","ComicViewer","props","data","errorDebounceMillis","errorRetryCount","responseTimestamp","initialNumToRender","initialScrollPercentage","itemVisiblePercentThreshold","onError","onScroll","onItemPress","getNextPage","viewerWidth","windowSize","pageUnit","ListFooterComponent","otherProps","flatListRef","useRef","errors","Map","debounceTimeOut","imageWidth","Math","min","initialItems","itemData","isViewable","width","setItems","useState","initialItemState","state","isNil","id","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","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","url","expiresAt","totalHeight","floor","scrollToOffset","animated"],"sources":["ComicViewer.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { FlatList, ListRenderItem, ViewToken } from 'react-native';\nimport * as R from 'ramda';\nimport {\n ComicViewerItemData,\n ComicViewerItemState,\n default as ComicViewerProps,\n ErrorInfo,\n STATE,\n} from './ComicViewerProps';\nimport type ComicViewerItemProps from './ComicViewerItemProps';\nimport ViewerItem from './ViewerItem';\n\nconst getItemHeights = <T, >(items: ComicViewerItemProps<T>[]): number[] => R.map((content: ComicViewerItemProps<T>) => content.height)(items);\nconst appender = (left: number, right: number): [number, number] => [left + right, left + right];\nconst getHeightAccum = (itemHeights: number[]): [number, number[]] => R.mapAccum(appender, 0, itemHeights);\n\nconst keyExtractor = <T, >(item: ComicViewerItemProps<T>) => `${item.sortKey}`;\n\nexport default function ComicViewer<T>(props: ComicViewerProps<T>) {\n const {\n data,\n errorDebounceMillis = 500,\n errorRetryCount = 3,\n responseTimestamp,\n initialNumToRender = 1,\n initialScrollPercentage = 0,\n itemVisiblePercentThreshold = 0,\n onError,\n onScroll,\n onItemPress,\n getNextPage,\n viewerWidth,\n windowSize = 3,\n pageUnit,\n ListFooterComponent,\n ...otherProps\n } = props;\n\n const flatListRef = useRef<FlatList>(null);\n\n const errors = useRef<Map<number, ErrorInfo>>(new Map());\n\n const debounceTimeOut = useRef<NodeJS.Timeout | null>(null);\n\n const imageWidth = Math.min(viewerWidth, 720);\n const initialItems = R.map((itemData: ComicViewerItemData<T>) => ({\n ...itemData,\n isViewable: false,\n width: imageWidth,\n height: (itemData.height * imageWidth) / itemData.width,\n }))(data);\n\n const [items, setItems] = useState<ComicViewerItemProps<T>[]>(initialItems);\n\n const initialItemState: ComicViewerItemState[] = R.map((itemData: ComicViewerItemData<T>) => ({\n sortKey: itemData.sortKey,\n state: R.isNil(itemData.id) ? STATE.INIT : STATE.URL_LOADED,\n }))(data);\n\n const itemStates = useRef<Array<ComicViewerItemState>>(initialItemState);\n\n const itemHeights = [...getItemHeights(items)];\n const itemHeightAccum = getHeightAccum(itemHeights);\n\n const viewabilityConfig = useMemo(() => ({\n itemVisiblePercentThreshold,\n }), [itemVisiblePercentThreshold]);\n\n const getItemLayout = useCallback((data: any, index: number) => {\n const offsets = R.prepend(0, itemHeightAccum[1]);\n\n return {\n length: itemHeights[index],\n offset: offsets[index],\n index,\n };\n }, [itemHeights]);\n\n const onViewableItemsChanged = useRef(({ viewableItems }: {\n viewableItems: Array<ViewToken>,\n }) => {\n setItems((prev: ComicViewerItemProps<T>[]) => {\n const viewableItemSortKeys: number[] = R.map((viewableItem: ViewToken) => viewableItem.item.sortKey)(viewableItems);\n const firstViewableSortKey = R.head(viewableItemSortKeys);\n const lastViewableItemSortKey = R.last(viewableItemSortKeys);\n const firstItem = R.head(prev);\n const lastItem = R.last(prev);\n\n if (R.isNil(firstViewableSortKey)\n || R.isNil(lastViewableItemSortKey)\n || R.isNil(firstItem)\n || R.isNil(lastItem)\n ) {\n return prev;\n }\n\n const frontBoundary = R.max(firstItem.sortKey, firstViewableSortKey - 1);\n const backBoundary = R.min(lastItem.sortKey, lastViewableItemSortKey + 1);\n\n const viewableItemBoundary = R.range(frontBoundary, backBoundary + 1);\n const newItems = R.map((prevItem: ComicViewerItemProps<T>) => ({\n ...prevItem,\n isViewable: R.includes(prevItem.sortKey, viewableItemBoundary),\n }))([...prev]);\n\n return newItems;\n });\n });\n\n const itemLoadedHandler = useCallback((sortKey: number) => {\n const itemState: ComicViewerItemState | undefined = R.find((state: ComicViewerItemState) => state.sortKey === sortKey)(itemStates.current);\n\n if (R.isNil(itemState)) {\n return;\n }\n\n itemState.state = STATE.LOADED;\n itemState.error = undefined;\n }, [itemStates]);\n\n const itemErrorHandler = useCallback((errorInfo: ErrorInfo) => {\n const { sortKey, count } = errorInfo;\n\n if (count >= errorRetryCount) {\n return;\n }\n\n errors.current.set(sortKey, errorInfo);\n\n const itemState: ComicViewerItemState | undefined = R.find((state: ComicViewerItemState) => state.sortKey === sortKey)(itemStates.current);\n\n if (R.isNil(itemState)) {\n return;\n }\n\n itemState.state = STATE.FAIL;\n itemState.error = errorInfo;\n\n const handleError = () => {\n const errorsArray = Array.from(errors.current.entries());\n const errorsInfo = R.map(([key, value]: [number, ErrorInfo]) => value)(errorsArray);\n\n onError && onError([...errorsInfo]);\n errors.current.clear();\n };\n\n if (debounceTimeOut.current) {\n clearTimeout(debounceTimeOut.current);\n }\n\n if (errors.current.size === pageUnit) {\n handleError();\n } else {\n debounceTimeOut.current = setTimeout(handleError, errorDebounceMillis);\n }\n }, [errors.current, itemStates]);\n\n const renderItem: ListRenderItem<ComicViewerItemProps<T>> = useCallback(({ item }) => {\n const itemState: ComicViewerItemState | undefined = R.find((state: ComicViewerItemState) => state.sortKey === item.sortKey)(itemStates.current);\n\n const props = {\n ...item,\n itemState,\n responseTimestamp,\n errorRetryCount,\n onError: itemErrorHandler,\n onLoaded: itemLoadedHandler,\n onItemPress,\n getNextPage,\n };\n\n return <ViewerItem props={props}/>;\n }, [responseTimestamp, itemErrorHandler, itemLoadedHandler, onItemPress]);\n\n useEffect(() => {\n setItems((prev: ComicViewerItemProps<T>[]) => {\n return R.map((prevItem: ComicViewerItemProps<T>) => {\n const currentData: ComicViewerItemData | undefined = R.find((currentItemData: ComicViewerItemData<T>) => prevItem.sortKey === currentItemData.sortKey)(data);\n const itemState: ComicViewerItemState | undefined = R.find((state: ComicViewerItemState) => state.sortKey === currentData?.sortKey)(itemStates.current);\n\n if (currentData\n && currentData.id\n && itemState\n && itemState.state !== STATE.LOADED) {\n\n itemState.state = STATE.URL_LOADED;\n\n return {\n ...prevItem,\n url: currentData.url,\n expiresAt: currentData.expiresAt,\n };\n }\n\n return prevItem;\n })([...prev]);\n ;\n });\n }, [responseTimestamp]);\n\n useEffect(() => {\n const newItems = R.map((item: ComicViewerItemProps<T>) => ({\n ...item,\n width: imageWidth,\n height: (item.height * imageWidth) / item.width,\n }))(items);\n\n setItems(newItems);\n }, [imageWidth]);\n\n useEffect(() => {\n const totalHeight = itemHeightAccum[0];\n const offset = Math.floor((initialScrollPercentage / 100) * totalHeight);\n\n if (flatListRef.current) {\n flatListRef.current.scrollToOffset({ offset, animated: false });\n }\n }, [flatListRef.current]);\n\n return (\n <FlatList\n data={items}\n getItemLayout={getItemLayout}\n initialNumToRender={initialNumToRender}\n keyExtractor={keyExtractor}\n onViewableItemsChanged={onViewableItemsChanged.current}\n onScroll={onScroll}\n ref={flatListRef}\n renderItem={renderItem}\n viewabilityConfig={viewabilityConfig}\n windowSize={windowSize}\n ListFooterComponent={ListFooterComponent}\n {...otherProps}\n />\n );\n};"],"mappings":"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"}
|
|
@@ -1 +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":["STATE","INIT","URL_LOADED","LOADED","FAIL"],"sources":["ComicViewerProps.ts"],"sourcesContent":["import React from 'react';\nimport { ComponentProps } from '@fountain-ui/core';\nimport { NativeScrollEvent, NativeSyntheticEvent } from 'react-native';\n\nexport const STATE = {\n INIT: 'init',\n URL_LOADED: 'url_loaded',\n LOADED: 'loaded',\n FAIL: 'fail',\n} as const;\n\nexport type LoadingState = typeof STATE[keyof typeof STATE];\n\nexport interface ComicViewerItemState{\n /**\n * Comic viewer item sortKey.\n */\n sortKey: number;\n\n /**\n * Content's loading state.\n */\n state: LoadingState;\n\n /***\n * Content's error Info.\n */\n error?: ErrorInfo;\n}\n\nexport interface ErrorInfo {\n /**\n * ComicViewerItemData.sortKey.\n */\n sortKey: number;\n\n /**\n * Number of times an error occurred.\n */\n count: number;\n\n /**\n * Content is Expired: true\n */\n expired: boolean;\n}\n\nexport type ComicViewerItemData<T = {}> = T & {\n /**\n * Image height.\n */\n height: number;\n\n /**\n * Unique value for identifying.\n */\n id: number | undefined;\n\n /**\n * Image sourceUrl for displaying.\n */\n url: string;\n\n /**\n * Image width.\n */\n width: number;\n\n /**\n * SortKey\n */\n sortKey: number;\n\n /**\n * Image expire date.\n */\n expiresAt: string;\n\n /***\n * Timestamp when get content response\n */\n responseTimestamp: number;\n}\n\nexport default interface ComicViewerProps<T> extends ComponentProps <{\n /**\n * Data for render.\n */\n data: ComicViewerItemData<T>[];\n\n /**\n * Delay Time to call the error handler.\n * @default 500\n */\n errorDebounceMillis?: number;\n\n /**\n * How many times retry onError when same item error occur\n * @default 3\n */\n errorRetryCount?: number;\n\n /**\n * How many items to render in the initial batch.\n * @default 1\n */\n initialNumToRender?: number;\n\n /**\n * Start at initialScrollPercentage.\n * If over 100, scroll to end.\n * @default 0\n */\n initialScrollPercentage?: number;\n\n /**\n * The value for FlatList viewabilityConfig.itemVisiblePercentThreshold.\n * @default 0\n */\n itemVisiblePercentThreshold?: number;\n\n /***\n * Timestamp when get content response\n */\n responseTimestamp: number;\n\n /**\n * Comic viewer width.\n */\n viewerWidth: number;\n\n /**\n * The value for FlatList windowSize.\n * @default 3\n */\n windowSize?: number;\n\n /**\n * How many images in one page.\n */\n pageUnit: number;\n\n /**\n * Method for getting next page contents.\n * @param sortKey\n */\n getNextPage?: (sortKey: number) => void;\n\n /**\n * Handling all viewerItem errors at once.\n * @param errors Array of ViewerItems errorInfo.\n */\n onError?: (errors: ErrorInfo[]) => void;\n\n /**\n * Handle scroll event.\n * @param event Scroll event.\n */\n onScroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;\n\n /**\n * Handle item press event.\n */\n onItemPress?: () => void;\n\n /**\n * Component for comic viewer footer.\n */\n ListFooterComponent?: React.ReactElement;\n}> {}"],"mappings":";;;;;;AAIO,MAAMA,KAAK,GAAG;EACjBC,IAAI,EAAE,MADW;EAEjBC,UAAU,EAAE,YAFK;EAGjBC,MAAM,EAAE,QAHS;EAIjBC,IAAI,EAAE;AAJW,CAAd"}
|
|
@@ -22,21 +22,13 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
|
|
|
22
22
|
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; }
|
|
23
23
|
|
|
24
24
|
const useStyles = function () {
|
|
25
|
-
const theme = (0, _core.useTheme)();
|
|
26
25
|
return {
|
|
27
26
|
root: {
|
|
28
27
|
display: 'flex',
|
|
29
28
|
flexDirection: 'row',
|
|
30
29
|
justifyContent: 'center'
|
|
31
30
|
},
|
|
32
|
-
init: {
|
|
33
|
-
backgroundColor: theme.palette.paper.grey
|
|
34
|
-
},
|
|
35
|
-
failed: {
|
|
36
|
-
backgroundColor: theme.palette.paper.grey
|
|
37
|
-
},
|
|
38
31
|
reload: {
|
|
39
|
-
backgroundColor: theme.palette.paper.grey,
|
|
40
32
|
display: 'flex',
|
|
41
33
|
alignItems: 'center'
|
|
42
34
|
}
|
|
@@ -56,6 +48,7 @@ function ViewerItem(_ref) {
|
|
|
56
48
|
itemState,
|
|
57
49
|
isViewable,
|
|
58
50
|
sortKey,
|
|
51
|
+
responseTimestamp,
|
|
59
52
|
url,
|
|
60
53
|
width,
|
|
61
54
|
getNextPage,
|
|
@@ -70,7 +63,7 @@ function ViewerItem(_ref) {
|
|
|
70
63
|
errorCount.current = 0;
|
|
71
64
|
setIsLoaded(true);
|
|
72
65
|
onLoaded && onLoaded(sortKey);
|
|
73
|
-
}, [sortKey]);
|
|
66
|
+
}, [sortKey, onLoaded]);
|
|
74
67
|
const handleError = (0, _react.useCallback)(() => {
|
|
75
68
|
errorCount.current = errorCount.current + 1;
|
|
76
69
|
const now = new Date();
|
|
@@ -81,7 +74,7 @@ function ViewerItem(_ref) {
|
|
|
81
74
|
count: errorCount.current,
|
|
82
75
|
expired
|
|
83
76
|
});
|
|
84
|
-
}, [errorCount.current]);
|
|
77
|
+
}, [errorCount.current, onError]);
|
|
85
78
|
const onReloadPress = (0, _react.useCallback)(() => {
|
|
86
79
|
errorCount.current = 1;
|
|
87
80
|
onError && onError({
|
|
@@ -89,7 +82,7 @@ function ViewerItem(_ref) {
|
|
|
89
82
|
count: errorCount.current,
|
|
90
83
|
expired: false
|
|
91
84
|
});
|
|
92
|
-
}, [sortKey]);
|
|
85
|
+
}, [sortKey, onError]);
|
|
93
86
|
const viewStyle = {
|
|
94
87
|
width: '100%',
|
|
95
88
|
height,
|
|
@@ -109,14 +102,22 @@ function ViewerItem(_ref) {
|
|
|
109
102
|
failed
|
|
110
103
|
} = props;
|
|
111
104
|
|
|
112
|
-
if (!(isViewable || isLoaded
|
|
113
|
-
return /*#__PURE__*/_react.default.createElement(_reactNative.
|
|
114
|
-
|
|
105
|
+
if (!(isViewable || isLoaded || failed) || (itemState === null || itemState === void 0 ? void 0 : itemState.state) === _ComicViewerProps.STATE.FAIL || (itemState === null || itemState === void 0 ? void 0 : itemState.state) === _ComicViewerProps.STATE.INIT) {
|
|
106
|
+
return /*#__PURE__*/_react.default.createElement(_reactNative.ImageBackground, {
|
|
107
|
+
source: {
|
|
108
|
+
uri: 'https://ssl.pstatic.net/static/m/comic/im/2012/bg_viewbody.jpg'
|
|
109
|
+
},
|
|
110
|
+
resizeMode: "repeat",
|
|
111
|
+
style: viewStyle
|
|
115
112
|
});
|
|
116
113
|
}
|
|
117
114
|
|
|
118
115
|
if (errorCount.current >= errorRetryCount) {
|
|
119
|
-
return /*#__PURE__*/_react.default.createElement(_reactNative.
|
|
116
|
+
return /*#__PURE__*/_react.default.createElement(_reactNative.ImageBackground, {
|
|
117
|
+
source: {
|
|
118
|
+
uri: 'https://ssl.pstatic.net/static/m/comic/im/2012/bg_viewbody.jpg'
|
|
119
|
+
},
|
|
120
|
+
resizeMode: "repeat",
|
|
120
121
|
style: [viewStyle, styles.reload]
|
|
121
122
|
}, /*#__PURE__*/_react.default.createElement(_core.Spacer, {
|
|
122
123
|
size: 20
|
|
@@ -135,8 +136,14 @@ function ViewerItem(_ref) {
|
|
|
135
136
|
}));
|
|
136
137
|
}
|
|
137
138
|
|
|
138
|
-
return
|
|
139
|
-
|
|
139
|
+
return /*#__PURE__*/_react.default.createElement(_reactNative.ImageBackground, {
|
|
140
|
+
source: {
|
|
141
|
+
uri: 'https://ssl.pstatic.net/static/m/comic/im/2012/bg_viewbody.jpg'
|
|
142
|
+
},
|
|
143
|
+
resizeMode: "repeat",
|
|
144
|
+
style: viewStyle
|
|
145
|
+
}, children);
|
|
146
|
+
}, [isViewable, isLoaded, errorCount.current, itemState === null || itemState === void 0 ? void 0 : itemState.state, responseTimestamp]);
|
|
140
147
|
(0, _react.useEffect)(() => {
|
|
141
148
|
if ((itemState === null || itemState === void 0 ? void 0 : itemState.state) === _ComicViewerProps.STATE.INIT) {
|
|
142
149
|
getNextPage === null || getNextPage === void 0 ? void 0 : getNextPage(sortKey);
|
|
@@ -148,6 +155,7 @@ function ViewerItem(_ref) {
|
|
|
148
155
|
}, /*#__PURE__*/_react.default.createElement(_reactNative.View, {
|
|
149
156
|
style: [styles.root, viewStyle]
|
|
150
157
|
}, /*#__PURE__*/_react.default.createElement(_core.Image, {
|
|
158
|
+
failDependency: [url, expiresAt, responseTimestamp],
|
|
151
159
|
disableOutline: true,
|
|
152
160
|
key: sortKey,
|
|
153
161
|
disableLongClick: true,
|
|
@@ -160,19 +168,26 @@ function ViewerItem(_ref) {
|
|
|
160
168
|
},
|
|
161
169
|
style: imageStyle,
|
|
162
170
|
square: true,
|
|
163
|
-
Placeholder: Placeholder
|
|
171
|
+
Placeholder: Placeholder,
|
|
172
|
+
disablePlaceholder: true
|
|
164
173
|
})));
|
|
165
174
|
}
|
|
166
175
|
|
|
167
176
|
var _default = /*#__PURE__*/_react.default.memo(ViewerItem, (prevProps, nextProps) => {
|
|
168
|
-
var _prevProps$props$item, _nextProps$props$item;
|
|
177
|
+
var _prevProps$props$item, _nextProps$props$item, _prevProps$props$item2;
|
|
169
178
|
|
|
170
179
|
if (prevProps.props.isViewable !== nextProps.props.isViewable) {
|
|
171
180
|
return false;
|
|
172
|
-
}
|
|
181
|
+
} // NO NEED ?
|
|
182
|
+
|
|
173
183
|
|
|
174
184
|
if (prevProps.props.url !== nextProps.props.url) {
|
|
175
185
|
return false;
|
|
186
|
+
} // NO NEED ?
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
if (prevProps.props.expiresAt !== nextProps.props.expiresAt) {
|
|
190
|
+
return false;
|
|
176
191
|
}
|
|
177
192
|
|
|
178
193
|
if (prevProps.props.width !== nextProps.props.width) {
|
|
@@ -183,6 +198,10 @@ var _default = /*#__PURE__*/_react.default.memo(ViewerItem, (prevProps, nextProp
|
|
|
183
198
|
return false;
|
|
184
199
|
}
|
|
185
200
|
|
|
201
|
+
if (((_prevProps$props$item2 = prevProps.props.itemState) === null || _prevProps$props$item2 === void 0 ? void 0 : _prevProps$props$item2.state) !== _ComicViewerProps.STATE.LOADED && prevProps.props.responseTimestamp !== nextProps.props.responseTimestamp) {
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
|
|
186
205
|
return true;
|
|
187
206
|
});
|
|
188
207
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useStyles","theme","useTheme","root","display","flexDirection","justifyContent","init","backgroundColor","palette","paper","grey","failed","reload","alignItems","ViewerItem","props","expiresAt","errorRetryCount","height","itemState","isViewable","sortKey","url","width","getNextPage","onError","onLoaded","onItemPress","isLoaded","setIsLoaded","useState","styles","errorCount","useRef","R","defaultTo","error","count","onLoad","useCallback","current","handleError","now","Date","utcNow","getTime","getTimezoneOffset","expired","onReloadPress","viewStyle","Platform","select","web","imageStyle","Placeholder","children","state","STATE","INIT","borderRadius","color","useEffect","uri","React","memo","prevProps","nextProps"],"sources":["ViewerItem.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { Platform, TouchableOpacity, 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';\nimport { STATE } from './ComicViewerProps';\n\ntype PlaceholderStyles = NamedStylesStringUnion<'init' | 'failed' | 'reload' | 'root'>;\n\nconst useStyles: UseStyles<PlaceholderStyles> = function (): PlaceholderStyles {\n const theme = useTheme();\n\n return {\n root: {\n display: 'flex',\n flexDirection: 'row',\n justifyContent: 'center',\n },\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 onItemPress,\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 now = new Date();\n const utcNow = now.getTime() + (now.getTimezoneOffset() * 60 * 1000);\n const expired = new Date(expiresAt).getTime() <= utcNow;\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 = {\n width: '100%',\n height,\n ...Platform.select({\n web: { 'cursor': 'default' },\n }),\n };\n\n const imageStyle = { width, height };\n\n const Placeholder = useCallback((props: PlaceholderProps) => {\n const { children, failed } = props;\n\n if (!(isViewable || isLoaded)\n || failed\n || itemState?.state === STATE.INIT\n ) {\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 return children;\n }, [isViewable, isLoaded, errorCount.current, url, onItemPress]);\n\n useEffect(() => {\n if (itemState?.state === STATE.INIT) {\n getNextPage?.(sortKey);\n }\n }, []);\n\n return (\n <TouchableOpacity\n activeOpacity={1}\n onPress={onItemPress}\n >\n <View\n style={[\n styles.root,\n viewStyle,\n ]}\n >\n <Image\n disableOutline={true}\n key={sortKey}\n disableLongClick={true}\n disableDrag={true}\n onLoad={onLoad}\n onError={handleError}\n loading={'eager'}\n source={{ uri: url }}\n style={imageStyle}\n square={true}\n Placeholder={Placeholder}\n />\n </View>\n </TouchableOpacity>\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 if (prevProps.props.width !== nextProps.props.width) {\n return false;\n }\n\n if (prevProps.props.itemState?.state !== nextProps.props.itemState?.state) {\n return false;\n }\n\n return true;\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["useStyles","root","display","flexDirection","justifyContent","reload","alignItems","ViewerItem","props","expiresAt","errorRetryCount","height","itemState","isViewable","sortKey","responseTimestamp","url","width","getNextPage","onError","onLoaded","onItemPress","isLoaded","setIsLoaded","useState","styles","errorCount","useRef","R","defaultTo","error","count","onLoad","useCallback","current","handleError","now","Date","utcNow","getTime","getTimezoneOffset","expired","onReloadPress","viewStyle","Platform","select","web","imageStyle","Placeholder","children","failed","state","STATE","FAIL","INIT","uri","borderRadius","color","backgroundColor","useEffect","React","memo","prevProps","nextProps","LOADED"],"sources":["ViewerItem.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { ImageBackground, Platform, TouchableOpacity, View } from 'react-native';\nimport * as R from 'ramda';\nimport type { PlaceholderProps } from '@fountain-ui/core';\nimport { IconButton, Image, Spacer } from '@fountain-ui/core';\nimport { NamedStylesStringUnion, UseStyles } from '@fountain-ui/styles';\nimport { Restart } from '@fountain-ui/icons';\nimport ComicViewerItemProps from './ComicViewerItemProps';\nimport { STATE } from './ComicViewerProps';\n\ntype PlaceholderStyles = NamedStylesStringUnion<'reload' | 'root'>;\n\nconst useStyles: UseStyles<PlaceholderStyles> = function (): PlaceholderStyles {\n return {\n root: {\n display: 'flex',\n flexDirection: 'row',\n justifyContent: 'center',\n },\n reload: {\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 responseTimestamp,\n url,\n width,\n getNextPage,\n onError,\n onLoaded,\n onItemPress,\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, onLoaded]);\n\n const handleError = useCallback(() => {\n errorCount.current = errorCount.current + 1;\n\n const now = new Date();\n const utcNow = now.getTime() + (now.getTimezoneOffset() * 60 * 1000);\n const expired = new Date(expiresAt).getTime() <= utcNow;\n\n onError && onError({\n sortKey,\n count: errorCount.current,\n expired,\n });\n }, [errorCount.current, onError]);\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, onError]);\n\n const viewStyle = {\n width: '100%',\n height,\n ...Platform.select({\n web: { 'cursor': 'default' },\n }),\n };\n\n const imageStyle = { width, height };\n\n const Placeholder = useCallback((props: PlaceholderProps) => {\n const { children, failed } = props;\n\n if (!(isViewable || isLoaded || failed)\n || (itemState?.state === STATE.FAIL)\n || itemState?.state === STATE.INIT\n ) {\n return <ImageBackground\n source={{ uri: 'https://ssl.pstatic.net/static/m/comic/im/2012/bg_viewbody.jpg' }}\n resizeMode=\"repeat\"\n style={viewStyle}\n />;\n }\n\n if (errorCount.current >= errorRetryCount) {\n return <ImageBackground\n source={{ uri: 'https://ssl.pstatic.net/static/m/comic/im/2012/bg_viewbody.jpg' }}\n resizeMode=\"repeat\"\n style={[\n viewStyle,\n styles.reload,\n ]}\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 </ImageBackground>;\n }\n\n return <ImageBackground\n source={{ uri: 'https://ssl.pstatic.net/static/m/comic/im/2012/bg_viewbody.jpg' }}\n resizeMode=\"repeat\"\n style={viewStyle}\n >\n {children}\n </ImageBackground>;\n }, [isViewable, isLoaded, errorCount.current, itemState?.state, responseTimestamp]);\n\n useEffect(() => {\n if (itemState?.state === STATE.INIT) {\n getNextPage?.(sortKey);\n }\n }, []);\n\n return (\n <TouchableOpacity\n activeOpacity={1}\n onPress={onItemPress}\n >\n <View\n style={[\n styles.root,\n viewStyle,\n ]}\n >\n <Image\n failDependency={[url, expiresAt, responseTimestamp]}\n disableOutline={true}\n key={sortKey}\n disableLongClick={true}\n disableDrag={true}\n onLoad={onLoad}\n onError={handleError}\n loading={'eager'}\n source={{ uri: url }}\n style={imageStyle}\n square={true}\n Placeholder={Placeholder}\n disablePlaceholder={true}\n />\n </View>\n </TouchableOpacity>\n );\n}\n\nexport default React.memo(ViewerItem, (prevProps, nextProps) => {\n if (prevProps.props.isViewable !== nextProps.props.isViewable) {\n return false;\n }\n\n // NO NEED ?\n if (prevProps.props.url !== nextProps.props.url) {\n return false;\n }\n\n // NO NEED ?\n if (prevProps.props.expiresAt !== nextProps.props.expiresAt) {\n return false;\n }\n\n if (prevProps.props.width !== nextProps.props.width) {\n return false;\n }\n\n if (prevProps.props.itemState?.state !== nextProps.props.itemState?.state) {\n return false;\n }\n\n if (prevProps.props.itemState?.state !== STATE.LOADED && prevProps.props.responseTimestamp !== nextProps.props.responseTimestamp) {\n return false;\n }\n\n return true;\n});"],"mappings":"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"}
|
|
@@ -19,6 +19,7 @@ export default function ComicViewer(props) {
|
|
|
19
19
|
data,
|
|
20
20
|
errorDebounceMillis = 500,
|
|
21
21
|
errorRetryCount = 3,
|
|
22
|
+
responseTimestamp,
|
|
22
23
|
initialNumToRender = 1,
|
|
23
24
|
initialScrollPercentage = 0,
|
|
24
25
|
itemVisiblePercentThreshold = 0,
|
|
@@ -35,7 +36,6 @@ export default function ComicViewer(props) {
|
|
|
35
36
|
const flatListRef = useRef(null);
|
|
36
37
|
const errors = useRef(new Map());
|
|
37
38
|
const debounceTimeOut = useRef(null);
|
|
38
|
-
const resourceString = R.toString(R.map(itemData => itemData.url)(data));
|
|
39
39
|
const imageWidth = Math.min(viewerWidth, 720);
|
|
40
40
|
const initialItems = R.map(itemData => ({ ...itemData,
|
|
41
41
|
isViewable: false,
|
|
@@ -45,7 +45,7 @@ export default function ComicViewer(props) {
|
|
|
45
45
|
const [items, setItems] = useState(initialItems);
|
|
46
46
|
const initialItemState = R.map(itemData => ({
|
|
47
47
|
sortKey: itemData.sortKey,
|
|
48
|
-
state: R.
|
|
48
|
+
state: R.isNil(itemData.id) ? STATE.INIT : STATE.URL_LOADED
|
|
49
49
|
}))(data);
|
|
50
50
|
const itemStates = useRef(initialItemState);
|
|
51
51
|
const itemHeights = [...getItemHeights(items)];
|
|
@@ -142,6 +142,7 @@ export default function ComicViewer(props) {
|
|
|
142
142
|
const itemState = R.find(state => state.sortKey === item.sortKey)(itemStates.current);
|
|
143
143
|
const props = { ...item,
|
|
144
144
|
itemState,
|
|
145
|
+
responseTimestamp,
|
|
145
146
|
errorRetryCount,
|
|
146
147
|
onError: itemErrorHandler,
|
|
147
148
|
onLoaded: itemLoadedHandler,
|
|
@@ -151,14 +152,14 @@ export default function ComicViewer(props) {
|
|
|
151
152
|
return /*#__PURE__*/React.createElement(ViewerItem, {
|
|
152
153
|
props: props
|
|
153
154
|
});
|
|
154
|
-
}, [
|
|
155
|
+
}, [responseTimestamp, itemErrorHandler, itemLoadedHandler, onItemPress]);
|
|
155
156
|
useEffect(() => {
|
|
156
157
|
setItems(prev => {
|
|
157
158
|
return R.map(prevItem => {
|
|
158
159
|
const currentData = R.find(currentItemData => prevItem.sortKey === currentItemData.sortKey)(data);
|
|
159
160
|
const itemState = R.find(state => state.sortKey === (currentData === null || currentData === void 0 ? void 0 : currentData.sortKey))(itemStates.current);
|
|
160
161
|
|
|
161
|
-
if (currentData && itemState && itemState.state !== STATE.LOADED
|
|
162
|
+
if (currentData && currentData.id && itemState && itemState.state !== STATE.LOADED) {
|
|
162
163
|
itemState.state = STATE.URL_LOADED;
|
|
163
164
|
return { ...prevItem,
|
|
164
165
|
url: currentData.url,
|
|
@@ -170,7 +171,7 @@ export default function ComicViewer(props) {
|
|
|
170
171
|
})([...prev]);
|
|
171
172
|
;
|
|
172
173
|
});
|
|
173
|
-
}, [
|
|
174
|
+
}, [responseTimestamp]);
|
|
174
175
|
useEffect(() => {
|
|
175
176
|
const newItems = R.map(item => ({ ...item,
|
|
176
177
|
width: imageWidth,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","useCallback","useEffect","useMemo","useRef","useState","FlatList","R","STATE","ViewerItem","getItemHeights","items","map","content","height","appender","left","right","getHeightAccum","itemHeights","mapAccum","keyExtractor","item","sortKey","ComicViewer","props","data","errorDebounceMillis","errorRetryCount","initialNumToRender","initialScrollPercentage","itemVisiblePercentThreshold","onError","onScroll","onItemPress","getNextPage","viewerWidth","windowSize","pageUnit","ListFooterComponent","otherProps","flatListRef","errors","Map","debounceTimeOut","resourceString","toString","itemData","url","imageWidth","Math","min","initialItems","isViewable","width","setItems","initialItemState","state","isEmpty","expiresAt","INIT","URL_LOADED","itemStates","itemHeightAccum","viewabilityConfig","getItemLayout","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","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":["React","useCallback","useEffect","useMemo","useRef","useState","FlatList","R","STATE","ViewerItem","getItemHeights","items","map","content","height","appender","left","right","getHeightAccum","itemHeights","mapAccum","keyExtractor","item","sortKey","ComicViewer","props","data","errorDebounceMillis","errorRetryCount","responseTimestamp","initialNumToRender","initialScrollPercentage","itemVisiblePercentThreshold","onError","onScroll","onItemPress","getNextPage","viewerWidth","windowSize","pageUnit","ListFooterComponent","otherProps","flatListRef","errors","Map","debounceTimeOut","imageWidth","Math","min","initialItems","itemData","isViewable","width","setItems","initialItemState","state","isNil","id","INIT","URL_LOADED","itemStates","itemHeightAccum","viewabilityConfig","getItemLayout","index","offsets","prepend","length","offset","onViewableItemsChanged","viewableItems","prev","viewableItemSortKeys","viewableItem","firstViewableSortKey","head","lastViewableItemSortKey","last","firstItem","lastItem","frontBoundary","max","backBoundary","viewableItemBoundary","range","newItems","prevItem","includes","itemLoadedHandler","itemState","find","current","LOADED","error","undefined","itemErrorHandler","errorInfo","count","set","FAIL","handleError","errorsArray","Array","from","entries","errorsInfo","key","value","clear","clearTimeout","size","setTimeout","renderItem","onLoaded","currentData","currentItemData","url","expiresAt","totalHeight","floor","scrollToOffset","animated"],"sources":["ComicViewer.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { FlatList, ListRenderItem, ViewToken } from 'react-native';\nimport * as R from 'ramda';\nimport {\n ComicViewerItemData,\n ComicViewerItemState,\n default as ComicViewerProps,\n ErrorInfo,\n STATE,\n} from './ComicViewerProps';\nimport type ComicViewerItemProps from './ComicViewerItemProps';\nimport ViewerItem from './ViewerItem';\n\nconst getItemHeights = <T, >(items: ComicViewerItemProps<T>[]): number[] => R.map((content: ComicViewerItemProps<T>) => content.height)(items);\nconst appender = (left: number, right: number): [number, number] => [left + right, left + right];\nconst getHeightAccum = (itemHeights: number[]): [number, number[]] => R.mapAccum(appender, 0, itemHeights);\n\nconst keyExtractor = <T, >(item: ComicViewerItemProps<T>) => `${item.sortKey}`;\n\nexport default function ComicViewer<T>(props: ComicViewerProps<T>) {\n const {\n data,\n errorDebounceMillis = 500,\n errorRetryCount = 3,\n responseTimestamp,\n initialNumToRender = 1,\n initialScrollPercentage = 0,\n itemVisiblePercentThreshold = 0,\n onError,\n onScroll,\n onItemPress,\n getNextPage,\n viewerWidth,\n windowSize = 3,\n pageUnit,\n ListFooterComponent,\n ...otherProps\n } = props;\n\n const flatListRef = useRef<FlatList>(null);\n\n const errors = useRef<Map<number, ErrorInfo>>(new Map());\n\n const debounceTimeOut = useRef<NodeJS.Timeout | null>(null);\n\n const imageWidth = Math.min(viewerWidth, 720);\n const initialItems = R.map((itemData: ComicViewerItemData<T>) => ({\n ...itemData,\n isViewable: false,\n width: imageWidth,\n height: (itemData.height * imageWidth) / itemData.width,\n }))(data);\n\n const [items, setItems] = useState<ComicViewerItemProps<T>[]>(initialItems);\n\n const initialItemState: ComicViewerItemState[] = R.map((itemData: ComicViewerItemData<T>) => ({\n sortKey: itemData.sortKey,\n state: R.isNil(itemData.id) ? STATE.INIT : STATE.URL_LOADED,\n }))(data);\n\n const itemStates = useRef<Array<ComicViewerItemState>>(initialItemState);\n\n const itemHeights = [...getItemHeights(items)];\n const itemHeightAccum = getHeightAccum(itemHeights);\n\n const viewabilityConfig = useMemo(() => ({\n itemVisiblePercentThreshold,\n }), [itemVisiblePercentThreshold]);\n\n const getItemLayout = useCallback((data: any, index: number) => {\n const offsets = R.prepend(0, itemHeightAccum[1]);\n\n return {\n length: itemHeights[index],\n offset: offsets[index],\n index,\n };\n }, [itemHeights]);\n\n const onViewableItemsChanged = useRef(({ viewableItems }: {\n viewableItems: Array<ViewToken>,\n }) => {\n setItems((prev: ComicViewerItemProps<T>[]) => {\n const viewableItemSortKeys: number[] = R.map((viewableItem: ViewToken) => viewableItem.item.sortKey)(viewableItems);\n const firstViewableSortKey = R.head(viewableItemSortKeys);\n const lastViewableItemSortKey = R.last(viewableItemSortKeys);\n const firstItem = R.head(prev);\n const lastItem = R.last(prev);\n\n if (R.isNil(firstViewableSortKey)\n || R.isNil(lastViewableItemSortKey)\n || R.isNil(firstItem)\n || R.isNil(lastItem)\n ) {\n return prev;\n }\n\n const frontBoundary = R.max(firstItem.sortKey, firstViewableSortKey - 1);\n const backBoundary = R.min(lastItem.sortKey, lastViewableItemSortKey + 1);\n\n const viewableItemBoundary = R.range(frontBoundary, backBoundary + 1);\n const newItems = R.map((prevItem: ComicViewerItemProps<T>) => ({\n ...prevItem,\n isViewable: R.includes(prevItem.sortKey, viewableItemBoundary),\n }))([...prev]);\n\n return newItems;\n });\n });\n\n const itemLoadedHandler = useCallback((sortKey: number) => {\n const itemState: ComicViewerItemState | undefined = R.find((state: ComicViewerItemState) => state.sortKey === sortKey)(itemStates.current);\n\n if (R.isNil(itemState)) {\n return;\n }\n\n itemState.state = STATE.LOADED;\n itemState.error = undefined;\n }, [itemStates]);\n\n const itemErrorHandler = useCallback((errorInfo: ErrorInfo) => {\n const { sortKey, count } = errorInfo;\n\n if (count >= errorRetryCount) {\n return;\n }\n\n errors.current.set(sortKey, errorInfo);\n\n const itemState: ComicViewerItemState | undefined = R.find((state: ComicViewerItemState) => state.sortKey === sortKey)(itemStates.current);\n\n if (R.isNil(itemState)) {\n return;\n }\n\n itemState.state = STATE.FAIL;\n itemState.error = errorInfo;\n\n const handleError = () => {\n const errorsArray = Array.from(errors.current.entries());\n const errorsInfo = R.map(([key, value]: [number, ErrorInfo]) => value)(errorsArray);\n\n onError && onError([...errorsInfo]);\n errors.current.clear();\n };\n\n if (debounceTimeOut.current) {\n clearTimeout(debounceTimeOut.current);\n }\n\n if (errors.current.size === pageUnit) {\n handleError();\n } else {\n debounceTimeOut.current = setTimeout(handleError, errorDebounceMillis);\n }\n }, [errors.current, itemStates]);\n\n const renderItem: ListRenderItem<ComicViewerItemProps<T>> = useCallback(({ item }) => {\n const itemState: ComicViewerItemState | undefined = R.find((state: ComicViewerItemState) => state.sortKey === item.sortKey)(itemStates.current);\n\n const props = {\n ...item,\n itemState,\n responseTimestamp,\n errorRetryCount,\n onError: itemErrorHandler,\n onLoaded: itemLoadedHandler,\n onItemPress,\n getNextPage,\n };\n\n return <ViewerItem props={props}/>;\n }, [responseTimestamp, itemErrorHandler, itemLoadedHandler, onItemPress]);\n\n useEffect(() => {\n setItems((prev: ComicViewerItemProps<T>[]) => {\n return R.map((prevItem: ComicViewerItemProps<T>) => {\n const currentData: ComicViewerItemData | undefined = R.find((currentItemData: ComicViewerItemData<T>) => prevItem.sortKey === currentItemData.sortKey)(data);\n const itemState: ComicViewerItemState | undefined = R.find((state: ComicViewerItemState) => state.sortKey === currentData?.sortKey)(itemStates.current);\n\n if (currentData\n && currentData.id\n && itemState\n && itemState.state !== STATE.LOADED) {\n\n itemState.state = STATE.URL_LOADED;\n\n return {\n ...prevItem,\n url: currentData.url,\n expiresAt: currentData.expiresAt,\n };\n }\n\n return prevItem;\n })([...prev]);\n ;\n });\n }, [responseTimestamp]);\n\n useEffect(() => {\n const newItems = R.map((item: ComicViewerItemProps<T>) => ({\n ...item,\n width: imageWidth,\n height: (item.height * imageWidth) / item.width,\n }))(items);\n\n setItems(newItems);\n }, [imageWidth]);\n\n useEffect(() => {\n const totalHeight = itemHeightAccum[0];\n const offset = Math.floor((initialScrollPercentage / 100) * totalHeight);\n\n if (flatListRef.current) {\n flatListRef.current.scrollToOffset({ offset, animated: false });\n }\n }, [flatListRef.current]);\n\n return (\n <FlatList\n data={items}\n getItemLayout={getItemLayout}\n initialNumToRender={initialNumToRender}\n keyExtractor={keyExtractor}\n onViewableItemsChanged={onViewableItemsChanged.current}\n onScroll={onScroll}\n ref={flatListRef}\n renderItem={renderItem}\n viewabilityConfig={viewabilityConfig}\n windowSize={windowSize}\n ListFooterComponent={ListFooterComponent}\n {...otherProps}\n />\n );\n};"],"mappings":"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"}
|
|
@@ -1 +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":"AAIA,OAAO,MAAMA,KAAK,GAAG;EACjBC,IAAI,EAAE,MADW;EAEjBC,UAAU,EAAE,YAFK;EAGjBC,MAAM,EAAE,QAHS;EAIjBC,IAAI,EAAE;AAJW,CAAd"}
|
|
1
|
+
{"version":3,"names":["STATE","INIT","URL_LOADED","LOADED","FAIL"],"sources":["ComicViewerProps.ts"],"sourcesContent":["import React from 'react';\nimport { ComponentProps } from '@fountain-ui/core';\nimport { NativeScrollEvent, NativeSyntheticEvent } from 'react-native';\n\nexport const STATE = {\n INIT: 'init',\n URL_LOADED: 'url_loaded',\n LOADED: 'loaded',\n FAIL: 'fail',\n} as const;\n\nexport type LoadingState = typeof STATE[keyof typeof STATE];\n\nexport interface ComicViewerItemState{\n /**\n * Comic viewer item sortKey.\n */\n sortKey: number;\n\n /**\n * Content's loading state.\n */\n state: LoadingState;\n\n /***\n * Content's error Info.\n */\n error?: ErrorInfo;\n}\n\nexport interface ErrorInfo {\n /**\n * ComicViewerItemData.sortKey.\n */\n sortKey: number;\n\n /**\n * Number of times an error occurred.\n */\n count: number;\n\n /**\n * Content is Expired: true\n */\n expired: boolean;\n}\n\nexport type ComicViewerItemData<T = {}> = T & {\n /**\n * Image height.\n */\n height: number;\n\n /**\n * Unique value for identifying.\n */\n id: number | undefined;\n\n /**\n * Image sourceUrl for displaying.\n */\n url: string;\n\n /**\n * Image width.\n */\n width: number;\n\n /**\n * SortKey\n */\n sortKey: number;\n\n /**\n * Image expire date.\n */\n expiresAt: string;\n\n /***\n * Timestamp when get content response\n */\n responseTimestamp: number;\n}\n\nexport default interface ComicViewerProps<T> extends ComponentProps <{\n /**\n * Data for render.\n */\n data: ComicViewerItemData<T>[];\n\n /**\n * Delay Time to call the error handler.\n * @default 500\n */\n errorDebounceMillis?: number;\n\n /**\n * How many times retry onError when same item error occur\n * @default 3\n */\n errorRetryCount?: number;\n\n /**\n * How many items to render in the initial batch.\n * @default 1\n */\n initialNumToRender?: number;\n\n /**\n * Start at initialScrollPercentage.\n * If over 100, scroll to end.\n * @default 0\n */\n initialScrollPercentage?: number;\n\n /**\n * The value for FlatList viewabilityConfig.itemVisiblePercentThreshold.\n * @default 0\n */\n itemVisiblePercentThreshold?: number;\n\n /***\n * Timestamp when get content response\n */\n responseTimestamp: number;\n\n /**\n * Comic viewer width.\n */\n viewerWidth: number;\n\n /**\n * The value for FlatList windowSize.\n * @default 3\n */\n windowSize?: number;\n\n /**\n * How many images in one page.\n */\n pageUnit: number;\n\n /**\n * Method for getting next page contents.\n * @param sortKey\n */\n getNextPage?: (sortKey: number) => void;\n\n /**\n * Handling all viewerItem errors at once.\n * @param errors Array of ViewerItems errorInfo.\n */\n onError?: (errors: ErrorInfo[]) => void;\n\n /**\n * Handle scroll event.\n * @param event Scroll event.\n */\n onScroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;\n\n /**\n * Handle item press event.\n */\n onItemPress?: () => void;\n\n /**\n * Component for comic viewer footer.\n */\n ListFooterComponent?: React.ReactElement;\n}> {}"],"mappings":"AAIA,OAAO,MAAMA,KAAK,GAAG;EACjBC,IAAI,EAAE,MADW;EAEjBC,UAAU,EAAE,YAFK;EAGjBC,MAAM,EAAE,QAHS;EAIjBC,IAAI,EAAE;AAJW,CAAd"}
|
|
@@ -1,26 +1,18 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
-
import { Platform, TouchableOpacity, View } from 'react-native';
|
|
2
|
+
import { ImageBackground, Platform, TouchableOpacity, View } from 'react-native';
|
|
3
3
|
import * as R from 'ramda';
|
|
4
|
-
import { IconButton, Image, Spacer
|
|
4
|
+
import { IconButton, Image, Spacer } from '@fountain-ui/core';
|
|
5
5
|
import { Restart } from '@fountain-ui/icons';
|
|
6
6
|
import { STATE } from './ComicViewerProps';
|
|
7
7
|
|
|
8
8
|
const useStyles = function () {
|
|
9
|
-
const theme = useTheme();
|
|
10
9
|
return {
|
|
11
10
|
root: {
|
|
12
11
|
display: 'flex',
|
|
13
12
|
flexDirection: 'row',
|
|
14
13
|
justifyContent: 'center'
|
|
15
14
|
},
|
|
16
|
-
init: {
|
|
17
|
-
backgroundColor: theme.palette.paper.grey
|
|
18
|
-
},
|
|
19
|
-
failed: {
|
|
20
|
-
backgroundColor: theme.palette.paper.grey
|
|
21
|
-
},
|
|
22
15
|
reload: {
|
|
23
|
-
backgroundColor: theme.palette.paper.grey,
|
|
24
16
|
display: 'flex',
|
|
25
17
|
alignItems: 'center'
|
|
26
18
|
}
|
|
@@ -40,6 +32,7 @@ function ViewerItem(_ref) {
|
|
|
40
32
|
itemState,
|
|
41
33
|
isViewable,
|
|
42
34
|
sortKey,
|
|
35
|
+
responseTimestamp,
|
|
43
36
|
url,
|
|
44
37
|
width,
|
|
45
38
|
getNextPage,
|
|
@@ -54,7 +47,7 @@ function ViewerItem(_ref) {
|
|
|
54
47
|
errorCount.current = 0;
|
|
55
48
|
setIsLoaded(true);
|
|
56
49
|
onLoaded && onLoaded(sortKey);
|
|
57
|
-
}, [sortKey]);
|
|
50
|
+
}, [sortKey, onLoaded]);
|
|
58
51
|
const handleError = useCallback(() => {
|
|
59
52
|
errorCount.current = errorCount.current + 1;
|
|
60
53
|
const now = new Date();
|
|
@@ -65,7 +58,7 @@ function ViewerItem(_ref) {
|
|
|
65
58
|
count: errorCount.current,
|
|
66
59
|
expired
|
|
67
60
|
});
|
|
68
|
-
}, [errorCount.current]);
|
|
61
|
+
}, [errorCount.current, onError]);
|
|
69
62
|
const onReloadPress = useCallback(() => {
|
|
70
63
|
errorCount.current = 1;
|
|
71
64
|
onError && onError({
|
|
@@ -73,7 +66,7 @@ function ViewerItem(_ref) {
|
|
|
73
66
|
count: errorCount.current,
|
|
74
67
|
expired: false
|
|
75
68
|
});
|
|
76
|
-
}, [sortKey]);
|
|
69
|
+
}, [sortKey, onError]);
|
|
77
70
|
const viewStyle = {
|
|
78
71
|
width: '100%',
|
|
79
72
|
height,
|
|
@@ -93,14 +86,22 @@ function ViewerItem(_ref) {
|
|
|
93
86
|
failed
|
|
94
87
|
} = props;
|
|
95
88
|
|
|
96
|
-
if (!(isViewable || isLoaded
|
|
97
|
-
return /*#__PURE__*/React.createElement(
|
|
98
|
-
|
|
89
|
+
if (!(isViewable || isLoaded || failed) || (itemState === null || itemState === void 0 ? void 0 : itemState.state) === STATE.FAIL || (itemState === null || itemState === void 0 ? void 0 : itemState.state) === STATE.INIT) {
|
|
90
|
+
return /*#__PURE__*/React.createElement(ImageBackground, {
|
|
91
|
+
source: {
|
|
92
|
+
uri: 'https://ssl.pstatic.net/static/m/comic/im/2012/bg_viewbody.jpg'
|
|
93
|
+
},
|
|
94
|
+
resizeMode: "repeat",
|
|
95
|
+
style: viewStyle
|
|
99
96
|
});
|
|
100
97
|
}
|
|
101
98
|
|
|
102
99
|
if (errorCount.current >= errorRetryCount) {
|
|
103
|
-
return /*#__PURE__*/React.createElement(
|
|
100
|
+
return /*#__PURE__*/React.createElement(ImageBackground, {
|
|
101
|
+
source: {
|
|
102
|
+
uri: 'https://ssl.pstatic.net/static/m/comic/im/2012/bg_viewbody.jpg'
|
|
103
|
+
},
|
|
104
|
+
resizeMode: "repeat",
|
|
104
105
|
style: [viewStyle, styles.reload]
|
|
105
106
|
}, /*#__PURE__*/React.createElement(Spacer, {
|
|
106
107
|
size: 20
|
|
@@ -119,8 +120,14 @@ function ViewerItem(_ref) {
|
|
|
119
120
|
}));
|
|
120
121
|
}
|
|
121
122
|
|
|
122
|
-
return
|
|
123
|
-
|
|
123
|
+
return /*#__PURE__*/React.createElement(ImageBackground, {
|
|
124
|
+
source: {
|
|
125
|
+
uri: 'https://ssl.pstatic.net/static/m/comic/im/2012/bg_viewbody.jpg'
|
|
126
|
+
},
|
|
127
|
+
resizeMode: "repeat",
|
|
128
|
+
style: viewStyle
|
|
129
|
+
}, children);
|
|
130
|
+
}, [isViewable, isLoaded, errorCount.current, itemState === null || itemState === void 0 ? void 0 : itemState.state, responseTimestamp]);
|
|
124
131
|
useEffect(() => {
|
|
125
132
|
if ((itemState === null || itemState === void 0 ? void 0 : itemState.state) === STATE.INIT) {
|
|
126
133
|
getNextPage === null || getNextPage === void 0 ? void 0 : getNextPage(sortKey);
|
|
@@ -132,6 +139,7 @@ function ViewerItem(_ref) {
|
|
|
132
139
|
}, /*#__PURE__*/React.createElement(View, {
|
|
133
140
|
style: [styles.root, viewStyle]
|
|
134
141
|
}, /*#__PURE__*/React.createElement(Image, {
|
|
142
|
+
failDependency: [url, expiresAt, responseTimestamp],
|
|
135
143
|
disableOutline: true,
|
|
136
144
|
key: sortKey,
|
|
137
145
|
disableLongClick: true,
|
|
@@ -144,19 +152,26 @@ function ViewerItem(_ref) {
|
|
|
144
152
|
},
|
|
145
153
|
style: imageStyle,
|
|
146
154
|
square: true,
|
|
147
|
-
Placeholder: Placeholder
|
|
155
|
+
Placeholder: Placeholder,
|
|
156
|
+
disablePlaceholder: true
|
|
148
157
|
})));
|
|
149
158
|
}
|
|
150
159
|
|
|
151
160
|
export default /*#__PURE__*/React.memo(ViewerItem, (prevProps, nextProps) => {
|
|
152
|
-
var _prevProps$props$item, _nextProps$props$item;
|
|
161
|
+
var _prevProps$props$item, _nextProps$props$item, _prevProps$props$item2;
|
|
153
162
|
|
|
154
163
|
if (prevProps.props.isViewable !== nextProps.props.isViewable) {
|
|
155
164
|
return false;
|
|
156
|
-
}
|
|
165
|
+
} // NO NEED ?
|
|
166
|
+
|
|
157
167
|
|
|
158
168
|
if (prevProps.props.url !== nextProps.props.url) {
|
|
159
169
|
return false;
|
|
170
|
+
} // NO NEED ?
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
if (prevProps.props.expiresAt !== nextProps.props.expiresAt) {
|
|
174
|
+
return false;
|
|
160
175
|
}
|
|
161
176
|
|
|
162
177
|
if (prevProps.props.width !== nextProps.props.width) {
|
|
@@ -167,6 +182,10 @@ export default /*#__PURE__*/React.memo(ViewerItem, (prevProps, nextProps) => {
|
|
|
167
182
|
return false;
|
|
168
183
|
}
|
|
169
184
|
|
|
185
|
+
if (((_prevProps$props$item2 = prevProps.props.itemState) === null || _prevProps$props$item2 === void 0 ? void 0 : _prevProps$props$item2.state) !== STATE.LOADED && prevProps.props.responseTimestamp !== nextProps.props.responseTimestamp) {
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
|
|
170
189
|
return true;
|
|
171
190
|
});
|
|
172
191
|
//# sourceMappingURL=ViewerItem.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","useCallback","useEffect","useRef","useState","Platform","TouchableOpacity","View","R","IconButton","Image","Spacer","useTheme","Restart","STATE","useStyles","theme","root","display","flexDirection","justifyContent","init","backgroundColor","palette","paper","grey","failed","reload","alignItems","ViewerItem","props","expiresAt","errorRetryCount","height","itemState","isViewable","sortKey","url","width","getNextPage","onError","onLoaded","onItemPress","isLoaded","setIsLoaded","styles","errorCount","defaultTo","error","count","onLoad","current","handleError","now","Date","utcNow","getTime","getTimezoneOffset","expired","onReloadPress","viewStyle","select","web","imageStyle","Placeholder","children","state","INIT","borderRadius","color","uri","memo","prevProps","nextProps"],"sources":["ViewerItem.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { Platform, TouchableOpacity, 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';\nimport { STATE } from './ComicViewerProps';\n\ntype PlaceholderStyles = NamedStylesStringUnion<'init' | 'failed' | 'reload' | 'root'>;\n\nconst useStyles: UseStyles<PlaceholderStyles> = function (): PlaceholderStyles {\n const theme = useTheme();\n\n return {\n root: {\n display: 'flex',\n flexDirection: 'row',\n justifyContent: 'center',\n },\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 onItemPress,\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 now = new Date();\n const utcNow = now.getTime() + (now.getTimezoneOffset() * 60 * 1000);\n const expired = new Date(expiresAt).getTime() <= utcNow;\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 = {\n width: '100%',\n height,\n ...Platform.select({\n web: { 'cursor': 'default' },\n }),\n };\n\n const imageStyle = { width, height };\n\n const Placeholder = useCallback((props: PlaceholderProps) => {\n const { children, failed } = props;\n\n if (!(isViewable || isLoaded)\n || failed\n || itemState?.state === STATE.INIT\n ) {\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 return children;\n }, [isViewable, isLoaded, errorCount.current, url, onItemPress]);\n\n useEffect(() => {\n if (itemState?.state === STATE.INIT) {\n getNextPage?.(sortKey);\n }\n }, []);\n\n return (\n <TouchableOpacity\n activeOpacity={1}\n onPress={onItemPress}\n >\n <View\n style={[\n styles.root,\n viewStyle,\n ]}\n >\n <Image\n disableOutline={true}\n key={sortKey}\n disableLongClick={true}\n disableDrag={true}\n onLoad={onLoad}\n onError={handleError}\n loading={'eager'}\n source={{ uri: url }}\n style={imageStyle}\n square={true}\n Placeholder={Placeholder}\n />\n </View>\n </TouchableOpacity>\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 if (prevProps.props.width !== nextProps.props.width) {\n return false;\n }\n\n if (prevProps.props.itemState?.state !== nextProps.props.itemState?.state) {\n return false;\n }\n\n return true;\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["React","useCallback","useEffect","useRef","useState","ImageBackground","Platform","TouchableOpacity","View","R","IconButton","Image","Spacer","Restart","STATE","useStyles","root","display","flexDirection","justifyContent","reload","alignItems","ViewerItem","props","expiresAt","errorRetryCount","height","itemState","isViewable","sortKey","responseTimestamp","url","width","getNextPage","onError","onLoaded","onItemPress","isLoaded","setIsLoaded","styles","errorCount","defaultTo","error","count","onLoad","current","handleError","now","Date","utcNow","getTime","getTimezoneOffset","expired","onReloadPress","viewStyle","select","web","imageStyle","Placeholder","children","failed","state","FAIL","INIT","uri","borderRadius","color","backgroundColor","memo","prevProps","nextProps","LOADED"],"sources":["ViewerItem.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { ImageBackground, Platform, TouchableOpacity, View } from 'react-native';\nimport * as R from 'ramda';\nimport type { PlaceholderProps } from '@fountain-ui/core';\nimport { IconButton, Image, Spacer } from '@fountain-ui/core';\nimport { NamedStylesStringUnion, UseStyles } from '@fountain-ui/styles';\nimport { Restart } from '@fountain-ui/icons';\nimport ComicViewerItemProps from './ComicViewerItemProps';\nimport { STATE } from './ComicViewerProps';\n\ntype PlaceholderStyles = NamedStylesStringUnion<'reload' | 'root'>;\n\nconst useStyles: UseStyles<PlaceholderStyles> = function (): PlaceholderStyles {\n return {\n root: {\n display: 'flex',\n flexDirection: 'row',\n justifyContent: 'center',\n },\n reload: {\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 responseTimestamp,\n url,\n width,\n getNextPage,\n onError,\n onLoaded,\n onItemPress,\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, onLoaded]);\n\n const handleError = useCallback(() => {\n errorCount.current = errorCount.current + 1;\n\n const now = new Date();\n const utcNow = now.getTime() + (now.getTimezoneOffset() * 60 * 1000);\n const expired = new Date(expiresAt).getTime() <= utcNow;\n\n onError && onError({\n sortKey,\n count: errorCount.current,\n expired,\n });\n }, [errorCount.current, onError]);\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, onError]);\n\n const viewStyle = {\n width: '100%',\n height,\n ...Platform.select({\n web: { 'cursor': 'default' },\n }),\n };\n\n const imageStyle = { width, height };\n\n const Placeholder = useCallback((props: PlaceholderProps) => {\n const { children, failed } = props;\n\n if (!(isViewable || isLoaded || failed)\n || (itemState?.state === STATE.FAIL)\n || itemState?.state === STATE.INIT\n ) {\n return <ImageBackground\n source={{ uri: 'https://ssl.pstatic.net/static/m/comic/im/2012/bg_viewbody.jpg' }}\n resizeMode=\"repeat\"\n style={viewStyle}\n />;\n }\n\n if (errorCount.current >= errorRetryCount) {\n return <ImageBackground\n source={{ uri: 'https://ssl.pstatic.net/static/m/comic/im/2012/bg_viewbody.jpg' }}\n resizeMode=\"repeat\"\n style={[\n viewStyle,\n styles.reload,\n ]}\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 </ImageBackground>;\n }\n\n return <ImageBackground\n source={{ uri: 'https://ssl.pstatic.net/static/m/comic/im/2012/bg_viewbody.jpg' }}\n resizeMode=\"repeat\"\n style={viewStyle}\n >\n {children}\n </ImageBackground>;\n }, [isViewable, isLoaded, errorCount.current, itemState?.state, responseTimestamp]);\n\n useEffect(() => {\n if (itemState?.state === STATE.INIT) {\n getNextPage?.(sortKey);\n }\n }, []);\n\n return (\n <TouchableOpacity\n activeOpacity={1}\n onPress={onItemPress}\n >\n <View\n style={[\n styles.root,\n viewStyle,\n ]}\n >\n <Image\n failDependency={[url, expiresAt, responseTimestamp]}\n disableOutline={true}\n key={sortKey}\n disableLongClick={true}\n disableDrag={true}\n onLoad={onLoad}\n onError={handleError}\n loading={'eager'}\n source={{ uri: url }}\n style={imageStyle}\n square={true}\n Placeholder={Placeholder}\n disablePlaceholder={true}\n />\n </View>\n </TouchableOpacity>\n );\n}\n\nexport default React.memo(ViewerItem, (prevProps, nextProps) => {\n if (prevProps.props.isViewable !== nextProps.props.isViewable) {\n return false;\n }\n\n // NO NEED ?\n if (prevProps.props.url !== nextProps.props.url) {\n return false;\n }\n\n // NO NEED ?\n if (prevProps.props.expiresAt !== nextProps.props.expiresAt) {\n return false;\n }\n\n if (prevProps.props.width !== nextProps.props.width) {\n return false;\n }\n\n if (prevProps.props.itemState?.state !== nextProps.props.itemState?.state) {\n return false;\n }\n\n if (prevProps.props.itemState?.state !== STATE.LOADED && prevProps.props.responseTimestamp !== nextProps.props.responseTimestamp) {\n return false;\n }\n\n return true;\n});"],"mappings":"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"}
|
|
@@ -61,6 +61,10 @@ export declare type ComicViewerItemData<T = {}> = T & {
|
|
|
61
61
|
* Image expire date.
|
|
62
62
|
*/
|
|
63
63
|
expiresAt: string;
|
|
64
|
+
/***
|
|
65
|
+
* Timestamp when get content response
|
|
66
|
+
*/
|
|
67
|
+
responseTimestamp: number;
|
|
64
68
|
};
|
|
65
69
|
export default interface ComicViewerProps<T> extends ComponentProps<{
|
|
66
70
|
/**
|
|
@@ -93,6 +97,10 @@ export default interface ComicViewerProps<T> extends ComponentProps<{
|
|
|
93
97
|
* @default 0
|
|
94
98
|
*/
|
|
95
99
|
itemVisiblePercentThreshold?: number;
|
|
100
|
+
/***
|
|
101
|
+
* Timestamp when get content response
|
|
102
|
+
*/
|
|
103
|
+
responseTimestamp: number;
|
|
96
104
|
/**
|
|
97
105
|
* Comic viewer width.
|
|
98
106
|
*/
|
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.34",
|
|
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": "44aa49c39c8a9f0986b9d12e06a8a2cfc3766ed9"
|
|
74
74
|
}
|
|
@@ -22,6 +22,7 @@ export default function ComicViewer<T>(props: ComicViewerProps<T>) {
|
|
|
22
22
|
data,
|
|
23
23
|
errorDebounceMillis = 500,
|
|
24
24
|
errorRetryCount = 3,
|
|
25
|
+
responseTimestamp,
|
|
25
26
|
initialNumToRender = 1,
|
|
26
27
|
initialScrollPercentage = 0,
|
|
27
28
|
itemVisiblePercentThreshold = 0,
|
|
@@ -42,8 +43,6 @@ export default function ComicViewer<T>(props: ComicViewerProps<T>) {
|
|
|
42
43
|
|
|
43
44
|
const debounceTimeOut = useRef<NodeJS.Timeout | null>(null);
|
|
44
45
|
|
|
45
|
-
const resourceString = R.toString(R.map((itemData: ComicViewerItemData) => itemData.url)(data));
|
|
46
|
-
|
|
47
46
|
const imageWidth = Math.min(viewerWidth, 720);
|
|
48
47
|
const initialItems = R.map((itemData: ComicViewerItemData<T>) => ({
|
|
49
48
|
...itemData,
|
|
@@ -55,9 +54,9 @@ export default function ComicViewer<T>(props: ComicViewerProps<T>) {
|
|
|
55
54
|
const [items, setItems] = useState<ComicViewerItemProps<T>[]>(initialItems);
|
|
56
55
|
|
|
57
56
|
const initialItemState: ComicViewerItemState[] = R.map((itemData: ComicViewerItemData<T>) => ({
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
sortKey: itemData.sortKey,
|
|
58
|
+
state: R.isNil(itemData.id) ? STATE.INIT : STATE.URL_LOADED,
|
|
59
|
+
}))(data);
|
|
61
60
|
|
|
62
61
|
const itemStates = useRef<Array<ComicViewerItemState>>(initialItemState);
|
|
63
62
|
|
|
@@ -163,6 +162,7 @@ export default function ComicViewer<T>(props: ComicViewerProps<T>) {
|
|
|
163
162
|
const props = {
|
|
164
163
|
...item,
|
|
165
164
|
itemState,
|
|
165
|
+
responseTimestamp,
|
|
166
166
|
errorRetryCount,
|
|
167
167
|
onError: itemErrorHandler,
|
|
168
168
|
onLoaded: itemLoadedHandler,
|
|
@@ -171,7 +171,7 @@ export default function ComicViewer<T>(props: ComicViewerProps<T>) {
|
|
|
171
171
|
};
|
|
172
172
|
|
|
173
173
|
return <ViewerItem props={props}/>;
|
|
174
|
-
}, [
|
|
174
|
+
}, [responseTimestamp, itemErrorHandler, itemLoadedHandler, onItemPress]);
|
|
175
175
|
|
|
176
176
|
useEffect(() => {
|
|
177
177
|
setItems((prev: ComicViewerItemProps<T>[]) => {
|
|
@@ -180,9 +180,9 @@ export default function ComicViewer<T>(props: ComicViewerProps<T>) {
|
|
|
180
180
|
const itemState: ComicViewerItemState | undefined = R.find((state: ComicViewerItemState) => state.sortKey === currentData?.sortKey)(itemStates.current);
|
|
181
181
|
|
|
182
182
|
if (currentData
|
|
183
|
+
&& currentData.id
|
|
183
184
|
&& itemState
|
|
184
|
-
&& itemState.state !== STATE.LOADED
|
|
185
|
-
&& (currentData.url !== prevItem.url)) {
|
|
185
|
+
&& itemState.state !== STATE.LOADED) {
|
|
186
186
|
|
|
187
187
|
itemState.state = STATE.URL_LOADED;
|
|
188
188
|
|
|
@@ -197,7 +197,7 @@ export default function ComicViewer<T>(props: ComicViewerProps<T>) {
|
|
|
197
197
|
})([...prev]);
|
|
198
198
|
;
|
|
199
199
|
});
|
|
200
|
-
}, [
|
|
200
|
+
}, [responseTimestamp]);
|
|
201
201
|
|
|
202
202
|
useEffect(() => {
|
|
203
203
|
const newItems = R.map((item: ComicViewerItemProps<T>) => ({
|
|
@@ -234,4 +234,4 @@ export default function ComicViewer<T>(props: ComicViewerProps<T>) {
|
|
|
234
234
|
{...otherProps}
|
|
235
235
|
/>
|
|
236
236
|
);
|
|
237
|
-
};
|
|
237
|
+
};
|
|
@@ -75,6 +75,11 @@ export type ComicViewerItemData<T = {}> = T & {
|
|
|
75
75
|
* Image expire date.
|
|
76
76
|
*/
|
|
77
77
|
expiresAt: string;
|
|
78
|
+
|
|
79
|
+
/***
|
|
80
|
+
* Timestamp when get content response
|
|
81
|
+
*/
|
|
82
|
+
responseTimestamp: number;
|
|
78
83
|
}
|
|
79
84
|
|
|
80
85
|
export default interface ComicViewerProps<T> extends ComponentProps <{
|
|
@@ -114,6 +119,11 @@ export default interface ComicViewerProps<T> extends ComponentProps <{
|
|
|
114
119
|
*/
|
|
115
120
|
itemVisiblePercentThreshold?: number;
|
|
116
121
|
|
|
122
|
+
/***
|
|
123
|
+
* Timestamp when get content response
|
|
124
|
+
*/
|
|
125
|
+
responseTimestamp: number;
|
|
126
|
+
|
|
117
127
|
/**
|
|
118
128
|
* Comic viewer width.
|
|
119
129
|
*/
|
|
@@ -1,32 +1,23 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
-
import { Platform, TouchableOpacity, View } from 'react-native';
|
|
2
|
+
import { ImageBackground, Platform, TouchableOpacity, View } from 'react-native';
|
|
3
3
|
import * as R from 'ramda';
|
|
4
4
|
import type { PlaceholderProps } from '@fountain-ui/core';
|
|
5
|
-
import { IconButton, Image, Spacer
|
|
5
|
+
import { IconButton, Image, Spacer } from '@fountain-ui/core';
|
|
6
6
|
import { NamedStylesStringUnion, UseStyles } from '@fountain-ui/styles';
|
|
7
7
|
import { Restart } from '@fountain-ui/icons';
|
|
8
8
|
import ComicViewerItemProps from './ComicViewerItemProps';
|
|
9
9
|
import { STATE } from './ComicViewerProps';
|
|
10
10
|
|
|
11
|
-
type PlaceholderStyles = NamedStylesStringUnion<'
|
|
11
|
+
type PlaceholderStyles = NamedStylesStringUnion<'reload' | 'root'>;
|
|
12
12
|
|
|
13
13
|
const useStyles: UseStyles<PlaceholderStyles> = function (): PlaceholderStyles {
|
|
14
|
-
const theme = useTheme();
|
|
15
|
-
|
|
16
14
|
return {
|
|
17
15
|
root: {
|
|
18
16
|
display: 'flex',
|
|
19
17
|
flexDirection: 'row',
|
|
20
18
|
justifyContent: 'center',
|
|
21
19
|
},
|
|
22
|
-
init: {
|
|
23
|
-
backgroundColor: theme.palette.paper.grey,
|
|
24
|
-
},
|
|
25
|
-
failed: {
|
|
26
|
-
backgroundColor: theme.palette.paper.grey,
|
|
27
|
-
},
|
|
28
20
|
reload: {
|
|
29
|
-
backgroundColor: theme.palette.paper.grey,
|
|
30
21
|
display: 'flex',
|
|
31
22
|
alignItems: 'center',
|
|
32
23
|
},
|
|
@@ -41,6 +32,7 @@ function ViewerItem<T>({ props }: { props: ComicViewerItemProps<T> }) {
|
|
|
41
32
|
itemState,
|
|
42
33
|
isViewable,
|
|
43
34
|
sortKey,
|
|
35
|
+
responseTimestamp,
|
|
44
36
|
url,
|
|
45
37
|
width,
|
|
46
38
|
getNextPage,
|
|
@@ -61,7 +53,7 @@ function ViewerItem<T>({ props }: { props: ComicViewerItemProps<T> }) {
|
|
|
61
53
|
setIsLoaded(true);
|
|
62
54
|
|
|
63
55
|
onLoaded && onLoaded(sortKey);
|
|
64
|
-
}, [sortKey]);
|
|
56
|
+
}, [sortKey, onLoaded]);
|
|
65
57
|
|
|
66
58
|
const handleError = useCallback(() => {
|
|
67
59
|
errorCount.current = errorCount.current + 1;
|
|
@@ -75,7 +67,7 @@ function ViewerItem<T>({ props }: { props: ComicViewerItemProps<T> }) {
|
|
|
75
67
|
count: errorCount.current,
|
|
76
68
|
expired,
|
|
77
69
|
});
|
|
78
|
-
}, [errorCount.current]);
|
|
70
|
+
}, [errorCount.current, onError]);
|
|
79
71
|
|
|
80
72
|
const onReloadPress = useCallback(() => {
|
|
81
73
|
errorCount.current = 1;
|
|
@@ -85,7 +77,7 @@ function ViewerItem<T>({ props }: { props: ComicViewerItemProps<T> }) {
|
|
|
85
77
|
count: errorCount.current,
|
|
86
78
|
expired: false,
|
|
87
79
|
});
|
|
88
|
-
}, [sortKey]);
|
|
80
|
+
}, [sortKey, onError]);
|
|
89
81
|
|
|
90
82
|
const viewStyle = {
|
|
91
83
|
width: '100%',
|
|
@@ -100,21 +92,26 @@ function ViewerItem<T>({ props }: { props: ComicViewerItemProps<T> }) {
|
|
|
100
92
|
const Placeholder = useCallback((props: PlaceholderProps) => {
|
|
101
93
|
const { children, failed } = props;
|
|
102
94
|
|
|
103
|
-
if (!(isViewable || isLoaded)
|
|
104
|
-
||
|
|
95
|
+
if (!(isViewable || isLoaded || failed)
|
|
96
|
+
|| (itemState?.state === STATE.FAIL)
|
|
105
97
|
|| itemState?.state === STATE.INIT
|
|
106
98
|
) {
|
|
107
|
-
return <
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
99
|
+
return <ImageBackground
|
|
100
|
+
source={{ uri: 'https://ssl.pstatic.net/static/m/comic/im/2012/bg_viewbody.jpg' }}
|
|
101
|
+
resizeMode="repeat"
|
|
102
|
+
style={viewStyle}
|
|
103
|
+
/>;
|
|
111
104
|
}
|
|
112
105
|
|
|
113
106
|
if (errorCount.current >= errorRetryCount) {
|
|
114
|
-
return <
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
107
|
+
return <ImageBackground
|
|
108
|
+
source={{ uri: 'https://ssl.pstatic.net/static/m/comic/im/2012/bg_viewbody.jpg' }}
|
|
109
|
+
resizeMode="repeat"
|
|
110
|
+
style={[
|
|
111
|
+
viewStyle,
|
|
112
|
+
styles.reload,
|
|
113
|
+
]}
|
|
114
|
+
>
|
|
118
115
|
<Spacer size={20}/>
|
|
119
116
|
|
|
120
117
|
<IconButton
|
|
@@ -128,11 +125,17 @@ function ViewerItem<T>({ props }: { props: ComicViewerItemProps<T> }) {
|
|
|
128
125
|
}}
|
|
129
126
|
onPress={onReloadPress}
|
|
130
127
|
/>
|
|
131
|
-
</
|
|
128
|
+
</ImageBackground>;
|
|
132
129
|
}
|
|
133
130
|
|
|
134
|
-
return
|
|
135
|
-
|
|
131
|
+
return <ImageBackground
|
|
132
|
+
source={{ uri: 'https://ssl.pstatic.net/static/m/comic/im/2012/bg_viewbody.jpg' }}
|
|
133
|
+
resizeMode="repeat"
|
|
134
|
+
style={viewStyle}
|
|
135
|
+
>
|
|
136
|
+
{children}
|
|
137
|
+
</ImageBackground>;
|
|
138
|
+
}, [isViewable, isLoaded, errorCount.current, itemState?.state, responseTimestamp]);
|
|
136
139
|
|
|
137
140
|
useEffect(() => {
|
|
138
141
|
if (itemState?.state === STATE.INIT) {
|
|
@@ -152,6 +155,7 @@ function ViewerItem<T>({ props }: { props: ComicViewerItemProps<T> }) {
|
|
|
152
155
|
]}
|
|
153
156
|
>
|
|
154
157
|
<Image
|
|
158
|
+
failDependency={[url, expiresAt, responseTimestamp]}
|
|
155
159
|
disableOutline={true}
|
|
156
160
|
key={sortKey}
|
|
157
161
|
disableLongClick={true}
|
|
@@ -163,6 +167,7 @@ function ViewerItem<T>({ props }: { props: ComicViewerItemProps<T> }) {
|
|
|
163
167
|
style={imageStyle}
|
|
164
168
|
square={true}
|
|
165
169
|
Placeholder={Placeholder}
|
|
170
|
+
disablePlaceholder={true}
|
|
166
171
|
/>
|
|
167
172
|
</View>
|
|
168
173
|
</TouchableOpacity>
|
|
@@ -174,10 +179,16 @@ export default React.memo(ViewerItem, (prevProps, nextProps) => {
|
|
|
174
179
|
return false;
|
|
175
180
|
}
|
|
176
181
|
|
|
182
|
+
// NO NEED ?
|
|
177
183
|
if (prevProps.props.url !== nextProps.props.url) {
|
|
178
184
|
return false;
|
|
179
185
|
}
|
|
180
186
|
|
|
187
|
+
// NO NEED ?
|
|
188
|
+
if (prevProps.props.expiresAt !== nextProps.props.expiresAt) {
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
|
|
181
192
|
if (prevProps.props.width !== nextProps.props.width) {
|
|
182
193
|
return false;
|
|
183
194
|
}
|
|
@@ -186,5 +197,9 @@ export default React.memo(ViewerItem, (prevProps, nextProps) => {
|
|
|
186
197
|
return false;
|
|
187
198
|
}
|
|
188
199
|
|
|
200
|
+
if (prevProps.props.itemState?.state !== STATE.LOADED && prevProps.props.responseTimestamp !== nextProps.props.responseTimestamp) {
|
|
201
|
+
return false;
|
|
202
|
+
}
|
|
203
|
+
|
|
189
204
|
return true;
|
|
190
|
-
});
|
|
205
|
+
});
|