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

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