@fountain-ui/lab 2.0.0-beta.37 → 2.0.0-beta.38

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.
@@ -58,7 +58,6 @@ function ComicViewer(props) {
58
58
  initialScrollPercentage = 0,
59
59
  itemVisiblePercentThreshold = 0,
60
60
  intrinsicDimensions,
61
- maxContentWidth = MAXIMUM_WIDTH,
62
61
  onItemPress,
63
62
  viewportWidth,
64
63
  windowSize = 3,
@@ -66,7 +65,7 @@ function ComicViewer(props) {
66
65
  } = props;
67
66
  const flatListRef = (0, _react.useRef)(null);
68
67
  const maybeLoadableItemsIndexRange = (0, _react.useRef)([-1, 0]);
69
- const actualImageWidth = Math.min(viewportWidth, maxContentWidth);
68
+ const actualImageWidth = Math.min(viewportWidth, MAXIMUM_WIDTH);
70
69
  const initialImageStates = (0, _react.useMemo)(() => R.map(createInitialImageState, intrinsicDimensions), []);
71
70
  const imageStatesRef = (0, _react.useRef)(initialImageStates);
72
71
 
@@ -269,7 +268,6 @@ function ComicViewer(props) {
269
268
  keyExtractor: keyExtractor,
270
269
  onViewableItemsChanged: onViewableItemsChanged.current,
271
270
  ref: flatListRef,
272
- removeClippedSubviews: false,
273
271
  renderItem: renderItem,
274
272
  viewabilityConfig: viewabilityConfig,
275
273
  windowSize: windowSize
@@ -1 +1 @@
1
- {"version":3,"names":["appender","left","right","getHeightAccum","heights","R","mapAccum","keyExtractor","item","String","index","createInitialImageState","dimension","isNewUrlIncoming","totalErrorCount","mapImageStateToItemState","imageState","autoHandleErrorCount","url","urlState","reloadButtonVisible","validity","MAXIMUM_WIDTH","NUMBER_OF_ADJACENT_ITEM","ComicViewer","props","debounceMillis","getUrlByIndex","initialNumToRender","initialScrollPercentage","itemVisiblePercentThreshold","intrinsicDimensions","maxContentWidth","onItemPress","viewportWidth","windowSize","otherProps","flatListRef","useRef","maybeLoadableItemsIndexRange","actualImageWidth","Math","min","initialImageStates","useMemo","map","imageStatesRef","mapImageStatesToItemStates","imageStates","image","itemStates","setItemStates","useState","current","renderedDimensions","intrinsicDimension","width","height","layoutFromDimensions","useCallback","itemHeights","totalHeight","heightAccum","itemOffsets","prepend","getItemLayout","data","length","offset","viewabilityConfig","updateImageState","updateFunction","prevImageStates","newImageStates","prevItemStates","newItemStates","equals","loadUrlByIndex","indexes","filteredIndexes","filter","state","isNil","i","includes","urls","newUrl","get","undefined","loadMaybeLoadableItems","startIndex","endIndex","affectedIndexes","range","loadItemsDebounce","useDebounce","onViewableItemsChanged","viewableItems","orderedViewableItems","sort","a","b","firstViewableIndex","head","lastViewableItemIndex","last","max","renderItem","onError","onReloadPress","onLoad","useEffect","floor","scrollToOffset","animated"],"sources":["ComicViewer.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { FlatList, ListRenderItem, ViewToken } from 'react-native';\nimport * as R from 'ramda';\nimport { useDebounce } from '@fountain-ui/core';\nimport { default as ComicViewerProps, Dimension } from './ComicViewerProps';\nimport ViewerItem from './ViewerItem';\n\nconst appender = (left: number, right: number): [number, number] => [left + right, left + right];\nconst getHeightAccum = (heights: number[]): [number, number[]] => R.mapAccum(appender, 0, heights);\n\nconst keyExtractor = <T, >(item: ItemState) => String(item.index);\n\ninterface UrlState {\n url: string;\n validity: 'valid' | 'invalid' | 'unknown';\n}\n\ninterface ImageState {\n urlState?: UrlState;\n isNewUrlIncoming: boolean;\n totalErrorCount: number;\n dimension: Dimension;\n}\n\ninterface ItemState {\n index: number;\n url?: string;\n reloadButtonVisible: boolean;\n dimension: Dimension;\n}\n\nconst createInitialImageState = (dimension: Dimension): ImageState => ({\n isNewUrlIncoming: false,\n totalErrorCount: 0,\n dimension,\n});\n\nconst mapImageStateToItemState = (\n index: number,\n imageState: ImageState,\n autoHandleErrorCount: number,\n): ItemState => ({\n index,\n url: imageState.urlState?.url,\n reloadButtonVisible: (imageState.urlState?.validity !== 'valid') && imageState.totalErrorCount >= autoHandleErrorCount,\n dimension: imageState.dimension,\n});\n\nconst MAXIMUM_WIDTH = 720;\n\nconst NUMBER_OF_ADJACENT_ITEM = 5;\n\nexport default function ComicViewer(props: ComicViewerProps) {\n const {\n debounceMillis = 100,\n autoHandleErrorCount = 3,\n getUrlByIndex,\n initialNumToRender = 1,\n initialScrollPercentage = 0,\n itemVisiblePercentThreshold = 0,\n intrinsicDimensions,\n maxContentWidth = MAXIMUM_WIDTH,\n onItemPress,\n viewportWidth,\n windowSize = 3,\n ...otherProps\n } = props;\n\n const flatListRef = useRef<FlatList>(null);\n\n const maybeLoadableItemsIndexRange = useRef<[number, number]>([-1, 0]);\n\n const actualImageWidth = Math.min(viewportWidth, maxContentWidth);\n\n const initialImageStates = useMemo<Array<ImageState>>(() => R.map(createInitialImageState, intrinsicDimensions), []);\n const imageStatesRef = useRef<Array<ImageState>>(initialImageStates);\n\n const mapImageStatesToItemStates = (imageStates: Array<ImageState>): Array<ItemState> => {\n return imageStates.map((image, index) => mapImageStateToItemState(\n index, image, autoHandleErrorCount,\n ));\n };\n\n const [itemStates, setItemStates] = useState<Array<ItemState>>(() => {\n return mapImageStatesToItemStates(imageStatesRef.current);\n });\n\n const renderedDimensions = useMemo<Array<Dimension>>(() => {\n return R.map(intrinsicDimension => ({\n width: actualImageWidth,\n height: (intrinsicDimension.height * actualImageWidth) / intrinsicDimension.width,\n }), intrinsicDimensions);\n }, [actualImageWidth]);\n\n const layoutFromDimensions = useCallback(() => {\n const itemHeights = R.map(dimension => dimension.height, renderedDimensions);\n const [totalHeight, heightAccum] = getHeightAccum(itemHeights);\n const itemOffsets = R.prepend(0, heightAccum);\n\n const getItemLayout = (data: any, index: number) => ({\n index,\n length: itemHeights[index],\n offset: itemOffsets[index],\n });\n\n return {\n totalHeight,\n getItemLayout,\n };\n }, [renderedDimensions]);\n\n const { totalHeight, getItemLayout } = layoutFromDimensions();\n\n const viewabilityConfig = useMemo(() => ({\n itemVisiblePercentThreshold,\n }), [itemVisiblePercentThreshold]);\n\n const updateImageState = (updateFunction: (prev: ImageState, index: number) => ImageState) => {\n const prevImageStates = imageStatesRef.current;\n const newImageStates = prevImageStates.map(updateFunction);\n\n imageStatesRef.current = newImageStates;\n\n setItemStates(prevItemStates => {\n const newItemStates = mapImageStatesToItemStates(newImageStates);\n\n return R.equals(prevItemStates, newItemStates) ? prevItemStates : newItemStates;\n });\n };\n\n const loadUrlByIndex = async (indexes: number[]) => {\n const filteredIndexes = R.filter(index => {\n const state = imageStatesRef.current[index];\n\n return R.isNil(state.urlState)\n || (state.urlState?.validity === 'invalid' && !state.isNewUrlIncoming);\n }, indexes);\n\n updateImageState((imageState, i) => {\n return R.includes(i, filteredIndexes)\n ? { ...imageState, isNewUrlIncoming: true }\n : imageState;\n });\n\n try {\n const urls = await getUrlByIndex(filteredIndexes);\n\n updateImageState((imageState, i) => {\n const newUrl = urls?.get(i);\n const urlState = imageState.urlState;\n\n if (newUrl !== undefined && urlState?.validity !== 'valid') {\n return {\n ...imageState,\n urlState: {\n url: newUrl,\n validity: 'unknown',\n },\n };\n }\n\n return imageState;\n });\n } finally {\n updateImageState((imageState, i) => {\n return R.includes(i, filteredIndexes)\n ? { ...imageState, isNewUrlIncoming: false }\n : imageState;\n });\n }\n };\n\n const loadMaybeLoadableItems = async () => {\n const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n const affectedIndexes = R.range(startIndex, endIndex);\n\n await loadUrlByIndex(affectedIndexes);\n };\n\n const loadItemsDebounce = useDebounce(loadMaybeLoadableItems, debounceMillis);\n\n const onViewableItemsChanged = useRef(({ viewableItems }: { viewableItems: Array<ViewToken> }) => {\n const orderedViewableItems = R.sort((a, b) => (a.index || 0) - (b.index || 0), viewableItems);\n\n const firstViewableIndex = R.head(orderedViewableItems)?.index;\n const lastViewableItemIndex = R.last(orderedViewableItems)?.index;\n\n if (R.isNil(firstViewableIndex) || R.isNil(lastViewableItemIndex)) {\n return;\n }\n\n const startIndex = R.max(firstViewableIndex - NUMBER_OF_ADJACENT_ITEM, 0);\n const endIndex = R.min(lastViewableItemIndex + NUMBER_OF_ADJACENT_ITEM, itemStates.length - 1);\n\n maybeLoadableItemsIndexRange.current = [startIndex, endIndex + 1];\n\n loadItemsDebounce();\n });\n\n const renderItem: ListRenderItem<ItemState> = useCallback(({ item, index }) => {\n const onError = () => {\n updateImageState((imageState, i) => {\n const urlState = imageState.urlState;\n\n if (i === index && urlState !== undefined) {\n return {\n ...imageState,\n totalErrorCount: imageState.totalErrorCount + 1,\n urlState: {\n ...urlState,\n validity: 'invalid',\n },\n };\n }\n\n return imageState;\n });\n\n if (item.reloadButtonVisible) {\n return;\n }\n\n const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n if (index >= startIndex || index < endIndex) {\n loadItemsDebounce();\n }\n };\n\n const onReloadPress = () => {\n const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n if (index >= startIndex || index < endIndex) {\n loadUrlByIndex([index]);\n }\n };\n\n const onLoad = () => {\n updateImageState((imageState, i) => {\n const urlState = imageState.urlState;\n\n if (i === index && urlState !== undefined) {\n return {\n ...imageState,\n urlState: {\n ...urlState,\n validity: 'valid',\n },\n };\n }\n\n return imageState;\n });\n };\n\n return (\n <ViewerItem\n onError={onError}\n onLoad={onLoad}\n onPress={onItemPress}\n onReloadPress={onReloadPress}\n url={item.url}\n width={renderedDimensions[index]?.width ?? 0}\n height={renderedDimensions[index]?.height ?? 0}\n reloadButtonVisible={item.reloadButtonVisible}\n />\n );\n }, [onItemPress, renderedDimensions]);\n\n useEffect(() => {\n const offset = Math.floor((initialScrollPercentage / 100) * totalHeight);\n\n if (flatListRef.current) {\n flatListRef.current.scrollToOffset({ offset, animated: false });\n }\n }, []);\n\n return (\n <FlatList\n data={itemStates}\n getItemLayout={getItemLayout}\n initialNumToRender={initialNumToRender}\n keyExtractor={keyExtractor}\n onViewableItemsChanged={onViewableItemsChanged.current}\n ref={flatListRef}\n removeClippedSubviews={false}\n renderItem={renderItem}\n viewabilityConfig={viewabilityConfig}\n windowSize={windowSize}\n {...otherProps}\n />\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"names":["appender","left","right","getHeightAccum","heights","R","mapAccum","keyExtractor","item","String","index","createInitialImageState","dimension","isNewUrlIncoming","totalErrorCount","mapImageStateToItemState","imageState","autoHandleErrorCount","url","urlState","reloadButtonVisible","validity","MAXIMUM_WIDTH","NUMBER_OF_ADJACENT_ITEM","ComicViewer","props","debounceMillis","getUrlByIndex","initialNumToRender","initialScrollPercentage","itemVisiblePercentThreshold","intrinsicDimensions","onItemPress","viewportWidth","windowSize","otherProps","flatListRef","useRef","maybeLoadableItemsIndexRange","actualImageWidth","Math","min","initialImageStates","useMemo","map","imageStatesRef","mapImageStatesToItemStates","imageStates","image","itemStates","setItemStates","useState","current","renderedDimensions","intrinsicDimension","width","height","layoutFromDimensions","useCallback","itemHeights","totalHeight","heightAccum","itemOffsets","prepend","getItemLayout","data","length","offset","viewabilityConfig","updateImageState","updateFunction","prevImageStates","newImageStates","prevItemStates","newItemStates","equals","loadUrlByIndex","indexes","filteredIndexes","filter","state","isNil","i","includes","urls","newUrl","get","undefined","loadMaybeLoadableItems","startIndex","endIndex","affectedIndexes","range","loadItemsDebounce","useDebounce","onViewableItemsChanged","viewableItems","orderedViewableItems","sort","a","b","firstViewableIndex","head","lastViewableItemIndex","last","max","renderItem","onError","onReloadPress","onLoad","useEffect","floor","scrollToOffset","animated"],"sources":["ComicViewer.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { FlatList, ListRenderItem, ViewToken } from 'react-native';\nimport * as R from 'ramda';\nimport { useDebounce } from '@fountain-ui/core';\nimport { default as ComicViewerProps, Dimension } from './ComicViewerProps';\nimport ViewerItem from './ViewerItem';\n\nconst appender = (left: number, right: number): [number, number] => [left + right, left + right];\nconst getHeightAccum = (heights: number[]): [number, number[]] => R.mapAccum(appender, 0, heights);\n\nconst keyExtractor = <T, >(item: ItemState) => String(item.index);\n\ninterface UrlState {\n url: string;\n validity: 'valid' | 'invalid' | 'unknown';\n}\n\ninterface ImageState {\n urlState?: UrlState;\n isNewUrlIncoming: boolean;\n totalErrorCount: number;\n dimension: Dimension;\n}\n\ninterface ItemState {\n index: number;\n url?: string;\n reloadButtonVisible: boolean;\n dimension: Dimension;\n}\n\nconst createInitialImageState = (dimension: Dimension): ImageState => ({\n isNewUrlIncoming: false,\n totalErrorCount: 0,\n dimension,\n});\n\nconst mapImageStateToItemState = (\n index: number,\n imageState: ImageState,\n autoHandleErrorCount: number,\n): ItemState => ({\n index,\n url: imageState.urlState?.url,\n reloadButtonVisible: (imageState.urlState?.validity !== 'valid') && imageState.totalErrorCount >= autoHandleErrorCount,\n dimension: imageState.dimension,\n});\n\nconst MAXIMUM_WIDTH = 720;\n\nconst NUMBER_OF_ADJACENT_ITEM = 5;\n\nexport default function ComicViewer(props: ComicViewerProps) {\n const {\n debounceMillis = 100,\n autoHandleErrorCount = 3,\n getUrlByIndex,\n initialNumToRender = 1,\n initialScrollPercentage = 0,\n itemVisiblePercentThreshold = 0,\n intrinsicDimensions,\n onItemPress,\n viewportWidth,\n windowSize = 3,\n ...otherProps\n } = props;\n\n const flatListRef = useRef<FlatList>(null);\n\n const maybeLoadableItemsIndexRange = useRef<[number, number]>([-1, 0]);\n\n const actualImageWidth = Math.min(viewportWidth, MAXIMUM_WIDTH);\n\n const initialImageStates = useMemo<Array<ImageState>>(() => R.map(createInitialImageState, intrinsicDimensions), []);\n const imageStatesRef = useRef<Array<ImageState>>(initialImageStates);\n\n const mapImageStatesToItemStates = (imageStates: Array<ImageState>): Array<ItemState> => {\n return imageStates.map((image, index) => mapImageStateToItemState(\n index, image, autoHandleErrorCount,\n ));\n };\n\n const [itemStates, setItemStates] = useState<Array<ItemState>>(() => {\n return mapImageStatesToItemStates(imageStatesRef.current);\n });\n\n const renderedDimensions = useMemo<Array<Dimension>>(() => {\n return R.map(intrinsicDimension => ({\n width: actualImageWidth,\n height: (intrinsicDimension.height * actualImageWidth) / intrinsicDimension.width,\n }), intrinsicDimensions);\n }, [actualImageWidth]);\n\n const layoutFromDimensions = useCallback(() => {\n const itemHeights = R.map(dimension => dimension.height, renderedDimensions);\n const [totalHeight, heightAccum] = getHeightAccum(itemHeights);\n const itemOffsets = R.prepend(0, heightAccum);\n\n const getItemLayout = (data: any, index: number) => ({\n index,\n length: itemHeights[index],\n offset: itemOffsets[index],\n });\n\n return {\n totalHeight,\n getItemLayout,\n };\n }, [renderedDimensions]);\n\n const { totalHeight, getItemLayout } = layoutFromDimensions();\n\n const viewabilityConfig = useMemo(() => ({\n itemVisiblePercentThreshold,\n }), [itemVisiblePercentThreshold]);\n\n const updateImageState = (updateFunction: (prev: ImageState, index: number) => ImageState) => {\n const prevImageStates = imageStatesRef.current;\n const newImageStates = prevImageStates.map(updateFunction);\n\n imageStatesRef.current = newImageStates;\n\n setItemStates(prevItemStates => {\n const newItemStates = mapImageStatesToItemStates(newImageStates);\n\n return R.equals(prevItemStates, newItemStates) ? prevItemStates : newItemStates;\n });\n };\n\n const loadUrlByIndex = async (indexes: number[]) => {\n const filteredIndexes = R.filter(index => {\n const state = imageStatesRef.current[index];\n\n return R.isNil(state.urlState)\n || (state.urlState?.validity === 'invalid' && !state.isNewUrlIncoming);\n }, indexes);\n\n updateImageState((imageState, i) => {\n return R.includes(i, filteredIndexes)\n ? { ...imageState, isNewUrlIncoming: true }\n : imageState;\n });\n\n try {\n const urls = await getUrlByIndex(filteredIndexes);\n\n updateImageState((imageState, i) => {\n const newUrl = urls?.get(i);\n const urlState = imageState.urlState;\n\n if (newUrl !== undefined && urlState?.validity !== 'valid') {\n return {\n ...imageState,\n urlState: {\n url: newUrl,\n validity: 'unknown',\n },\n };\n }\n\n return imageState;\n });\n } finally {\n updateImageState((imageState, i) => {\n return R.includes(i, filteredIndexes)\n ? { ...imageState, isNewUrlIncoming: false }\n : imageState;\n });\n }\n };\n\n const loadMaybeLoadableItems = async () => {\n const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n const affectedIndexes = R.range(startIndex, endIndex);\n\n await loadUrlByIndex(affectedIndexes);\n };\n\n const loadItemsDebounce = useDebounce(loadMaybeLoadableItems, debounceMillis);\n\n const onViewableItemsChanged = useRef(({ viewableItems }: { viewableItems: Array<ViewToken> }) => {\n const orderedViewableItems = R.sort((a, b) => (a.index || 0) - (b.index || 0), viewableItems);\n\n const firstViewableIndex = R.head(orderedViewableItems)?.index;\n const lastViewableItemIndex = R.last(orderedViewableItems)?.index;\n\n if (R.isNil(firstViewableIndex) || R.isNil(lastViewableItemIndex)) {\n return;\n }\n\n const startIndex = R.max(firstViewableIndex - NUMBER_OF_ADJACENT_ITEM, 0);\n const endIndex = R.min(lastViewableItemIndex + NUMBER_OF_ADJACENT_ITEM, itemStates.length - 1);\n\n maybeLoadableItemsIndexRange.current = [startIndex, endIndex + 1];\n\n loadItemsDebounce();\n });\n\n const renderItem: ListRenderItem<ItemState> = useCallback(({ item, index }) => {\n const onError = () => {\n updateImageState((imageState, i) => {\n const urlState = imageState.urlState;\n\n if (i === index && urlState !== undefined) {\n return {\n ...imageState,\n totalErrorCount: imageState.totalErrorCount + 1,\n urlState: {\n ...urlState,\n validity: 'invalid',\n },\n };\n }\n\n return imageState;\n });\n\n if (item.reloadButtonVisible) {\n return;\n }\n\n const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n if (index >= startIndex || index < endIndex) {\n loadItemsDebounce();\n }\n };\n\n const onReloadPress = () => {\n const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n if (index >= startIndex || index < endIndex) {\n loadUrlByIndex([index]);\n }\n };\n\n const onLoad = () => {\n updateImageState((imageState, i) => {\n const urlState = imageState.urlState;\n\n if (i === index && urlState !== undefined) {\n return {\n ...imageState,\n urlState: {\n ...urlState,\n validity: 'valid',\n },\n };\n }\n\n return imageState;\n });\n };\n\n return (\n <ViewerItem\n onError={onError}\n onLoad={onLoad}\n onPress={onItemPress}\n onReloadPress={onReloadPress}\n url={item.url}\n width={renderedDimensions[index]?.width ?? 0}\n height={renderedDimensions[index]?.height ?? 0}\n reloadButtonVisible={item.reloadButtonVisible}\n />\n );\n }, [onItemPress, renderedDimensions]);\n\n useEffect(() => {\n const offset = Math.floor((initialScrollPercentage / 100) * totalHeight);\n\n if (flatListRef.current) {\n flatListRef.current.scrollToOffset({ offset, animated: false });\n }\n }, []);\n\n return (\n <FlatList\n data={itemStates}\n getItemLayout={getItemLayout}\n initialNumToRender={initialNumToRender}\n keyExtractor={keyExtractor}\n onViewableItemsChanged={onViewableItemsChanged.current}\n ref={flatListRef}\n renderItem={renderItem}\n viewabilityConfig={viewabilityConfig}\n windowSize={windowSize}\n {...otherProps}\n />\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["ComicViewerProps.ts"],"sourcesContent":["import React from 'react';\nimport { ComponentProps } from '@fountain-ui/core';\nimport { NativeScrollEvent, NativeSyntheticEvent } from 'react-native';\n\nexport interface Dimension {\n width: number;\n height: number;\n}\n\nexport default interface ComicViewerProps extends ComponentProps <{\n /**\n * Delay Time to call the error handler.\n * @default 100\n */\n debounceMillis?: number;\n\n /**\n * How many times handle onError directly when item error occur\n * @default 3\n */\n autoHandleErrorCount?: number;\n\n /**\n * How many items to render in the initial batch.\n * @default 1\n */\n initialNumToRender?: number;\n\n /**\n * Start at initialScrollPercentage.\n * If over 100, scroll to end.\n * @default 0\n */\n initialScrollPercentage?: number;\n\n /**\n * The value for FlatList viewabilityConfig.itemVisiblePercentThreshold.\n * @default 0\n */\n itemVisiblePercentThreshold?: number;\n\n /**\n * Dimensions of each Image considering viewport.\n */\n intrinsicDimensions: Array<Dimension>;\n\n /**\n * Max value of contents image width size.\n * @default 720\n */\n maxContentWidth?: number;\n\n /**\n * Width of viewport.\n */\n viewportWidth: number;\n\n /**\n * The value for FlatList windowSize.\n * @default 3\n */\n windowSize?: number;\n\n /**\n * Get contents urls by indexes.\n */\n getUrlByIndex: (indexes: Array<number>) => Promise<Map<number, string> | undefined> ;\n\n /**\n * Handle scroll event.\n * @param event Scroll event.\n */\n onScroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;\n\n /**\n * Handle item press event.\n */\n onItemPress?: () => void;\n\n /**\n * Component for comic viewer footer.\n */\n ListFooterComponent?: React.ReactElement;\n}> {}\n"],"mappings":""}
1
+ {"version":3,"names":[],"sources":["ComicViewerProps.ts"],"sourcesContent":["import React from 'react';\nimport { ComponentProps } from '@fountain-ui/core';\nimport { NativeScrollEvent, NativeSyntheticEvent } from 'react-native';\n\nexport interface Dimension {\n width: number;\n height: number;\n}\n\nexport default interface ComicViewerProps extends ComponentProps <{\n /**\n * Delay Time to call the error handler.\n * @default 100\n */\n debounceMillis?: number;\n\n /**\n * How many times handle onError directly when item error occur\n * @default 3\n */\n autoHandleErrorCount?: number;\n\n /**\n * How many items to render in the initial batch.\n * @default 1\n */\n initialNumToRender?: number;\n\n /**\n * Start at initialScrollPercentage.\n * If over 100, scroll to end.\n * @default 0\n */\n initialScrollPercentage?: number;\n\n /**\n * The value for FlatList viewabilityConfig.itemVisiblePercentThreshold.\n * @default 0\n */\n itemVisiblePercentThreshold?: number;\n\n /**\n * Dimensions of each Image considering viewport.\n */\n intrinsicDimensions: Array<Dimension>;\n\n /**\n * Width of viewport.\n */\n viewportWidth: number;\n\n /**\n * The value for FlatList windowSize.\n * @default 3\n */\n windowSize?: number;\n\n /**\n * Get contents urls by indexes.\n */\n getUrlByIndex: (indexes: Array<number>) => Promise<Map<number, string> | undefined> ;\n\n /**\n * Handle scroll event.\n * @param event Scroll event.\n */\n onScroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;\n\n /**\n * Handle item press event.\n */\n onItemPress?: () => void;\n\n /**\n * Component for comic viewer footer.\n */\n ListFooterComponent?: React.ReactElement;\n}> {}\n"],"mappings":""}
@@ -55,6 +55,7 @@ function ViewerItem(props) {
55
55
  }, /*#__PURE__*/_react.default.createElement(_reactNative.View, {
56
56
  style: styles.view
57
57
  }, /*#__PURE__*/_react.default.createElement(_core.Image, {
58
+ cache: 'web',
58
59
  disableDrag: true,
59
60
  disableLongClick: true,
60
61
  disableOutline: true,
@@ -1 +1 @@
1
- {"version":3,"names":["ViewerItem","props","height","url","width","onError","onLoad","onPress","onReloadPress","reloadButtonVisible","styles","view","image","error","placeholder","uri","EncodedTile","css","alignSelf"],"sources":["ViewerItem.tsx"],"sourcesContent":["import React from 'react';\nimport { Image, TouchableWithoutFeedback, View } from 'react-native';\nimport { css, Image as FuiImage, ImageProps } from '@fountain-ui/core';\nimport ReloadButton from './ReloadButton';\nimport EncodedTile from './EncodedTile';\n\nexport interface ViewerItemProps {\n /**\n * Image width.\n */\n width: number;\n\n /**\n * Image height.\n */\n height: number;\n\n /**\n * Image sourceUrl for displaying.\n */\n url?: string;\n\n /**\n * Error handler.\n */\n onError?: ImageProps['onError'];\n\n /**\n * Load handler.\n */\n onLoad?: ImageProps['onLoad'];\n\n /**\n * Handle Reload button press event.\n */\n onReloadPress?: ImageProps['onError'];\n\n /**\n * Handle item press event.\n */\n onPress?: () => void;\n\n /**\n * If true, reload button visible.\n * @default false\n */\n reloadButtonVisible?: boolean;\n}\n\nexport default function ViewerItem(props: ViewerItemProps) {\n const {\n height,\n url,\n width,\n onError,\n onLoad,\n onPress,\n onReloadPress,\n reloadButtonVisible = false,\n } = props;\n\n const styles = {\n view: {\n height,\n width: '100%',\n },\n image: {\n height,\n width,\n },\n };\n\n const error = reloadButtonVisible ? <ReloadButton onPress={onReloadPress}/> : null;\n\n const placeholder = <Image\n source={{ uri: EncodedTile }}\n resizeMode={'cover'}\n style={styles.image}\n />;\n\n return (\n <TouchableWithoutFeedback onPress={onPress}>\n <View style={styles.view}>\n <FuiImage\n disableDrag={true}\n disableLongClick={true}\n disableOutline={true}\n error={error}\n onError={onError}\n onLoad={onLoad}\n loading={'eager'}\n placeholder={placeholder}\n source={{ uri: url }}\n square={true}\n style={css([\n { alignSelf: 'center' },\n styles.image,\n ])}\n />\n </View>\n </TouchableWithoutFeedback>\n );\n};\n"],"mappings":";;;;;;;AAAA;;AACA;;AACA;;AACA;;AACA;;;;AA6Ce,SAASA,UAAT,CAAoBC,KAApB,EAA4C;EACvD,MAAM;IACFC,MADE;IAEFC,GAFE;IAGFC,KAHE;IAIFC,OAJE;IAKFC,MALE;IAMFC,OANE;IAOFC,aAPE;IAQFC,mBAAmB,GAAG;EARpB,IASFR,KATJ;EAWA,MAAMS,MAAM,GAAG;IACXC,IAAI,EAAE;MACFT,MADE;MAEFE,KAAK,EAAE;IAFL,CADK;IAKXQ,KAAK,EAAE;MACHV,MADG;MAEHE;IAFG;EALI,CAAf;EAWA,MAAMS,KAAK,GAAGJ,mBAAmB,gBAAG,6BAAC,qBAAD;IAAc,OAAO,EAAED;EAAvB,EAAH,GAA6C,IAA9E;;EAEA,MAAMM,WAAW,gBAAG,6BAAC,kBAAD;IAChB,MAAM,EAAE;MAAEC,GAAG,EAAEC;IAAP,CADQ;IAEhB,UAAU,EAAE,OAFI;IAGhB,KAAK,EAAEN,MAAM,CAACE;EAHE,EAApB;;EAMA,oBACI,6BAAC,qCAAD;IAA0B,OAAO,EAAEL;EAAnC,gBACI,6BAAC,iBAAD;IAAM,KAAK,EAAEG,MAAM,CAACC;EAApB,gBACI,6BAAC,WAAD;IACI,WAAW,EAAE,IADjB;IAEI,gBAAgB,EAAE,IAFtB;IAGI,cAAc,EAAE,IAHpB;IAII,KAAK,EAAEE,KAJX;IAKI,OAAO,EAAER,OALb;IAMI,MAAM,EAAEC,MANZ;IAOI,OAAO,EAAE,OAPb;IAQI,WAAW,EAAEQ,WARjB;IASI,MAAM,EAAE;MAAEC,GAAG,EAAEZ;IAAP,CATZ;IAUI,MAAM,EAAE,IAVZ;IAWI,KAAK,EAAE,IAAAc,SAAA,EAAI,CACP;MAAEC,SAAS,EAAE;IAAb,CADO,EAEPR,MAAM,CAACE,KAFA,CAAJ;EAXX,EADJ,CADJ,CADJ;AAsBH;;AAAA"}
1
+ {"version":3,"names":["ViewerItem","props","height","url","width","onError","onLoad","onPress","onReloadPress","reloadButtonVisible","styles","view","image","error","placeholder","uri","EncodedTile","css","alignSelf"],"sources":["ViewerItem.tsx"],"sourcesContent":["import React from 'react';\nimport { Image, TouchableWithoutFeedback, View } from 'react-native';\nimport { css, Image as FuiImage, ImageProps } from '@fountain-ui/core';\nimport ReloadButton from './ReloadButton';\nimport EncodedTile from './EncodedTile';\n\nexport interface ViewerItemProps {\n /**\n * Image width.\n */\n width: number;\n\n /**\n * Image height.\n */\n height: number;\n\n /**\n * Image sourceUrl for displaying.\n */\n url?: string;\n\n /**\n * Error handler.\n */\n onError?: ImageProps['onError'];\n\n /**\n * Load handler.\n */\n onLoad?: ImageProps['onLoad'];\n\n /**\n * Handle Reload button press event.\n */\n onReloadPress?: ImageProps['onError'];\n\n /**\n * Handle item press event.\n */\n onPress?: () => void;\n\n /**\n * If true, reload button visible.\n * @default false\n */\n reloadButtonVisible?: boolean;\n}\n\nexport default function ViewerItem(props: ViewerItemProps) {\n const {\n height,\n url,\n width,\n onError,\n onLoad,\n onPress,\n onReloadPress,\n reloadButtonVisible = false,\n } = props;\n\n const styles = {\n view: {\n height,\n width: '100%',\n },\n image: {\n height,\n width,\n },\n };\n\n const error = reloadButtonVisible ? <ReloadButton onPress={onReloadPress}/> : null;\n\n const placeholder = <Image\n source={{ uri: EncodedTile }}\n resizeMode={'cover'}\n style={styles.image}\n />;\n\n return (\n <TouchableWithoutFeedback onPress={onPress}>\n <View style={styles.view}>\n <FuiImage\n cache={'web'}\n disableDrag={true}\n disableLongClick={true}\n disableOutline={true}\n error={error}\n onError={onError}\n onLoad={onLoad}\n loading={'eager'}\n placeholder={placeholder}\n source={{ uri: url }}\n square={true}\n style={css([\n { alignSelf: 'center' },\n styles.image,\n ])}\n />\n </View>\n </TouchableWithoutFeedback>\n );\n};\n"],"mappings":";;;;;;;AAAA;;AACA;;AACA;;AACA;;AACA;;;;AA6Ce,SAASA,UAAT,CAAoBC,KAApB,EAA4C;EACvD,MAAM;IACFC,MADE;IAEFC,GAFE;IAGFC,KAHE;IAIFC,OAJE;IAKFC,MALE;IAMFC,OANE;IAOFC,aAPE;IAQFC,mBAAmB,GAAG;EARpB,IASFR,KATJ;EAWA,MAAMS,MAAM,GAAG;IACXC,IAAI,EAAE;MACFT,MADE;MAEFE,KAAK,EAAE;IAFL,CADK;IAKXQ,KAAK,EAAE;MACHV,MADG;MAEHE;IAFG;EALI,CAAf;EAWA,MAAMS,KAAK,GAAGJ,mBAAmB,gBAAG,6BAAC,qBAAD;IAAc,OAAO,EAAED;EAAvB,EAAH,GAA6C,IAA9E;;EAEA,MAAMM,WAAW,gBAAG,6BAAC,kBAAD;IAChB,MAAM,EAAE;MAAEC,GAAG,EAAEC;IAAP,CADQ;IAEhB,UAAU,EAAE,OAFI;IAGhB,KAAK,EAAEN,MAAM,CAACE;EAHE,EAApB;;EAMA,oBACI,6BAAC,qCAAD;IAA0B,OAAO,EAAEL;EAAnC,gBACI,6BAAC,iBAAD;IAAM,KAAK,EAAEG,MAAM,CAACC;EAApB,gBACI,6BAAC,WAAD;IACI,KAAK,EAAE,KADX;IAEI,WAAW,EAAE,IAFjB;IAGI,gBAAgB,EAAE,IAHtB;IAII,cAAc,EAAE,IAJpB;IAKI,KAAK,EAAEE,KALX;IAMI,OAAO,EAAER,OANb;IAOI,MAAM,EAAEC,MAPZ;IAQI,OAAO,EAAE,OARb;IASI,WAAW,EAAEQ,WATjB;IAUI,MAAM,EAAE;MAAEC,GAAG,EAAEZ;IAAP,CAVZ;IAWI,MAAM,EAAE,IAXZ;IAYI,KAAK,EAAE,IAAAc,SAAA,EAAI,CACP;MAAEC,SAAS,EAAE;IAAb,CADO,EAEPR,MAAM,CAACE,KAFA,CAAJ;EAZX,EADJ,CADJ,CADJ;AAuBH;;AAAA"}
@@ -40,7 +40,6 @@ export default function ComicViewer(props) {
40
40
  initialScrollPercentage = 0,
41
41
  itemVisiblePercentThreshold = 0,
42
42
  intrinsicDimensions,
43
- maxContentWidth = MAXIMUM_WIDTH,
44
43
  onItemPress,
45
44
  viewportWidth,
46
45
  windowSize = 3,
@@ -48,7 +47,7 @@ export default function ComicViewer(props) {
48
47
  } = props;
49
48
  const flatListRef = useRef(null);
50
49
  const maybeLoadableItemsIndexRange = useRef([-1, 0]);
51
- const actualImageWidth = Math.min(viewportWidth, maxContentWidth);
50
+ const actualImageWidth = Math.min(viewportWidth, MAXIMUM_WIDTH);
52
51
  const initialImageStates = useMemo(() => R.map(createInitialImageState, intrinsicDimensions), []);
53
52
  const imageStatesRef = useRef(initialImageStates);
54
53
 
@@ -251,7 +250,6 @@ export default function ComicViewer(props) {
251
250
  keyExtractor: keyExtractor,
252
251
  onViewableItemsChanged: onViewableItemsChanged.current,
253
252
  ref: flatListRef,
254
- removeClippedSubviews: false,
255
253
  renderItem: renderItem,
256
254
  viewabilityConfig: viewabilityConfig,
257
255
  windowSize: windowSize
@@ -1 +1 @@
1
- {"version":3,"names":["React","useCallback","useEffect","useMemo","useRef","useState","FlatList","R","useDebounce","ViewerItem","appender","left","right","getHeightAccum","heights","mapAccum","keyExtractor","item","String","index","createInitialImageState","dimension","isNewUrlIncoming","totalErrorCount","mapImageStateToItemState","imageState","autoHandleErrorCount","url","urlState","reloadButtonVisible","validity","MAXIMUM_WIDTH","NUMBER_OF_ADJACENT_ITEM","ComicViewer","props","debounceMillis","getUrlByIndex","initialNumToRender","initialScrollPercentage","itemVisiblePercentThreshold","intrinsicDimensions","maxContentWidth","onItemPress","viewportWidth","windowSize","otherProps","flatListRef","maybeLoadableItemsIndexRange","actualImageWidth","Math","min","initialImageStates","map","imageStatesRef","mapImageStatesToItemStates","imageStates","image","itemStates","setItemStates","current","renderedDimensions","intrinsicDimension","width","height","layoutFromDimensions","itemHeights","totalHeight","heightAccum","itemOffsets","prepend","getItemLayout","data","length","offset","viewabilityConfig","updateImageState","updateFunction","prevImageStates","newImageStates","prevItemStates","newItemStates","equals","loadUrlByIndex","indexes","filteredIndexes","filter","state","isNil","i","includes","urls","newUrl","get","undefined","loadMaybeLoadableItems","startIndex","endIndex","affectedIndexes","range","loadItemsDebounce","onViewableItemsChanged","viewableItems","orderedViewableItems","sort","a","b","firstViewableIndex","head","lastViewableItemIndex","last","max","renderItem","onError","onReloadPress","onLoad","floor","scrollToOffset","animated"],"sources":["ComicViewer.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { FlatList, ListRenderItem, ViewToken } from 'react-native';\nimport * as R from 'ramda';\nimport { useDebounce } from '@fountain-ui/core';\nimport { default as ComicViewerProps, Dimension } from './ComicViewerProps';\nimport ViewerItem from './ViewerItem';\n\nconst appender = (left: number, right: number): [number, number] => [left + right, left + right];\nconst getHeightAccum = (heights: number[]): [number, number[]] => R.mapAccum(appender, 0, heights);\n\nconst keyExtractor = <T, >(item: ItemState) => String(item.index);\n\ninterface UrlState {\n url: string;\n validity: 'valid' | 'invalid' | 'unknown';\n}\n\ninterface ImageState {\n urlState?: UrlState;\n isNewUrlIncoming: boolean;\n totalErrorCount: number;\n dimension: Dimension;\n}\n\ninterface ItemState {\n index: number;\n url?: string;\n reloadButtonVisible: boolean;\n dimension: Dimension;\n}\n\nconst createInitialImageState = (dimension: Dimension): ImageState => ({\n isNewUrlIncoming: false,\n totalErrorCount: 0,\n dimension,\n});\n\nconst mapImageStateToItemState = (\n index: number,\n imageState: ImageState,\n autoHandleErrorCount: number,\n): ItemState => ({\n index,\n url: imageState.urlState?.url,\n reloadButtonVisible: (imageState.urlState?.validity !== 'valid') && imageState.totalErrorCount >= autoHandleErrorCount,\n dimension: imageState.dimension,\n});\n\nconst MAXIMUM_WIDTH = 720;\n\nconst NUMBER_OF_ADJACENT_ITEM = 5;\n\nexport default function ComicViewer(props: ComicViewerProps) {\n const {\n debounceMillis = 100,\n autoHandleErrorCount = 3,\n getUrlByIndex,\n initialNumToRender = 1,\n initialScrollPercentage = 0,\n itemVisiblePercentThreshold = 0,\n intrinsicDimensions,\n maxContentWidth = MAXIMUM_WIDTH,\n onItemPress,\n viewportWidth,\n windowSize = 3,\n ...otherProps\n } = props;\n\n const flatListRef = useRef<FlatList>(null);\n\n const maybeLoadableItemsIndexRange = useRef<[number, number]>([-1, 0]);\n\n const actualImageWidth = Math.min(viewportWidth, maxContentWidth);\n\n const initialImageStates = useMemo<Array<ImageState>>(() => R.map(createInitialImageState, intrinsicDimensions), []);\n const imageStatesRef = useRef<Array<ImageState>>(initialImageStates);\n\n const mapImageStatesToItemStates = (imageStates: Array<ImageState>): Array<ItemState> => {\n return imageStates.map((image, index) => mapImageStateToItemState(\n index, image, autoHandleErrorCount,\n ));\n };\n\n const [itemStates, setItemStates] = useState<Array<ItemState>>(() => {\n return mapImageStatesToItemStates(imageStatesRef.current);\n });\n\n const renderedDimensions = useMemo<Array<Dimension>>(() => {\n return R.map(intrinsicDimension => ({\n width: actualImageWidth,\n height: (intrinsicDimension.height * actualImageWidth) / intrinsicDimension.width,\n }), intrinsicDimensions);\n }, [actualImageWidth]);\n\n const layoutFromDimensions = useCallback(() => {\n const itemHeights = R.map(dimension => dimension.height, renderedDimensions);\n const [totalHeight, heightAccum] = getHeightAccum(itemHeights);\n const itemOffsets = R.prepend(0, heightAccum);\n\n const getItemLayout = (data: any, index: number) => ({\n index,\n length: itemHeights[index],\n offset: itemOffsets[index],\n });\n\n return {\n totalHeight,\n getItemLayout,\n };\n }, [renderedDimensions]);\n\n const { totalHeight, getItemLayout } = layoutFromDimensions();\n\n const viewabilityConfig = useMemo(() => ({\n itemVisiblePercentThreshold,\n }), [itemVisiblePercentThreshold]);\n\n const updateImageState = (updateFunction: (prev: ImageState, index: number) => ImageState) => {\n const prevImageStates = imageStatesRef.current;\n const newImageStates = prevImageStates.map(updateFunction);\n\n imageStatesRef.current = newImageStates;\n\n setItemStates(prevItemStates => {\n const newItemStates = mapImageStatesToItemStates(newImageStates);\n\n return R.equals(prevItemStates, newItemStates) ? prevItemStates : newItemStates;\n });\n };\n\n const loadUrlByIndex = async (indexes: number[]) => {\n const filteredIndexes = R.filter(index => {\n const state = imageStatesRef.current[index];\n\n return R.isNil(state.urlState)\n || (state.urlState?.validity === 'invalid' && !state.isNewUrlIncoming);\n }, indexes);\n\n updateImageState((imageState, i) => {\n return R.includes(i, filteredIndexes)\n ? { ...imageState, isNewUrlIncoming: true }\n : imageState;\n });\n\n try {\n const urls = await getUrlByIndex(filteredIndexes);\n\n updateImageState((imageState, i) => {\n const newUrl = urls?.get(i);\n const urlState = imageState.urlState;\n\n if (newUrl !== undefined && urlState?.validity !== 'valid') {\n return {\n ...imageState,\n urlState: {\n url: newUrl,\n validity: 'unknown',\n },\n };\n }\n\n return imageState;\n });\n } finally {\n updateImageState((imageState, i) => {\n return R.includes(i, filteredIndexes)\n ? { ...imageState, isNewUrlIncoming: false }\n : imageState;\n });\n }\n };\n\n const loadMaybeLoadableItems = async () => {\n const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n const affectedIndexes = R.range(startIndex, endIndex);\n\n await loadUrlByIndex(affectedIndexes);\n };\n\n const loadItemsDebounce = useDebounce(loadMaybeLoadableItems, debounceMillis);\n\n const onViewableItemsChanged = useRef(({ viewableItems }: { viewableItems: Array<ViewToken> }) => {\n const orderedViewableItems = R.sort((a, b) => (a.index || 0) - (b.index || 0), viewableItems);\n\n const firstViewableIndex = R.head(orderedViewableItems)?.index;\n const lastViewableItemIndex = R.last(orderedViewableItems)?.index;\n\n if (R.isNil(firstViewableIndex) || R.isNil(lastViewableItemIndex)) {\n return;\n }\n\n const startIndex = R.max(firstViewableIndex - NUMBER_OF_ADJACENT_ITEM, 0);\n const endIndex = R.min(lastViewableItemIndex + NUMBER_OF_ADJACENT_ITEM, itemStates.length - 1);\n\n maybeLoadableItemsIndexRange.current = [startIndex, endIndex + 1];\n\n loadItemsDebounce();\n });\n\n const renderItem: ListRenderItem<ItemState> = useCallback(({ item, index }) => {\n const onError = () => {\n updateImageState((imageState, i) => {\n const urlState = imageState.urlState;\n\n if (i === index && urlState !== undefined) {\n return {\n ...imageState,\n totalErrorCount: imageState.totalErrorCount + 1,\n urlState: {\n ...urlState,\n validity: 'invalid',\n },\n };\n }\n\n return imageState;\n });\n\n if (item.reloadButtonVisible) {\n return;\n }\n\n const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n if (index >= startIndex || index < endIndex) {\n loadItemsDebounce();\n }\n };\n\n const onReloadPress = () => {\n const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n if (index >= startIndex || index < endIndex) {\n loadUrlByIndex([index]);\n }\n };\n\n const onLoad = () => {\n updateImageState((imageState, i) => {\n const urlState = imageState.urlState;\n\n if (i === index && urlState !== undefined) {\n return {\n ...imageState,\n urlState: {\n ...urlState,\n validity: 'valid',\n },\n };\n }\n\n return imageState;\n });\n };\n\n return (\n <ViewerItem\n onError={onError}\n onLoad={onLoad}\n onPress={onItemPress}\n onReloadPress={onReloadPress}\n url={item.url}\n width={renderedDimensions[index]?.width ?? 0}\n height={renderedDimensions[index]?.height ?? 0}\n reloadButtonVisible={item.reloadButtonVisible}\n />\n );\n }, [onItemPress, renderedDimensions]);\n\n useEffect(() => {\n const offset = Math.floor((initialScrollPercentage / 100) * totalHeight);\n\n if (flatListRef.current) {\n flatListRef.current.scrollToOffset({ offset, animated: false });\n }\n }, []);\n\n return (\n <FlatList\n data={itemStates}\n getItemLayout={getItemLayout}\n initialNumToRender={initialNumToRender}\n keyExtractor={keyExtractor}\n onViewableItemsChanged={onViewableItemsChanged.current}\n ref={flatListRef}\n removeClippedSubviews={false}\n renderItem={renderItem}\n viewabilityConfig={viewabilityConfig}\n windowSize={windowSize}\n {...otherProps}\n />\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"names":["React","useCallback","useEffect","useMemo","useRef","useState","FlatList","R","useDebounce","ViewerItem","appender","left","right","getHeightAccum","heights","mapAccum","keyExtractor","item","String","index","createInitialImageState","dimension","isNewUrlIncoming","totalErrorCount","mapImageStateToItemState","imageState","autoHandleErrorCount","url","urlState","reloadButtonVisible","validity","MAXIMUM_WIDTH","NUMBER_OF_ADJACENT_ITEM","ComicViewer","props","debounceMillis","getUrlByIndex","initialNumToRender","initialScrollPercentage","itemVisiblePercentThreshold","intrinsicDimensions","onItemPress","viewportWidth","windowSize","otherProps","flatListRef","maybeLoadableItemsIndexRange","actualImageWidth","Math","min","initialImageStates","map","imageStatesRef","mapImageStatesToItemStates","imageStates","image","itemStates","setItemStates","current","renderedDimensions","intrinsicDimension","width","height","layoutFromDimensions","itemHeights","totalHeight","heightAccum","itemOffsets","prepend","getItemLayout","data","length","offset","viewabilityConfig","updateImageState","updateFunction","prevImageStates","newImageStates","prevItemStates","newItemStates","equals","loadUrlByIndex","indexes","filteredIndexes","filter","state","isNil","i","includes","urls","newUrl","get","undefined","loadMaybeLoadableItems","startIndex","endIndex","affectedIndexes","range","loadItemsDebounce","onViewableItemsChanged","viewableItems","orderedViewableItems","sort","a","b","firstViewableIndex","head","lastViewableItemIndex","last","max","renderItem","onError","onReloadPress","onLoad","floor","scrollToOffset","animated"],"sources":["ComicViewer.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { FlatList, ListRenderItem, ViewToken } from 'react-native';\nimport * as R from 'ramda';\nimport { useDebounce } from '@fountain-ui/core';\nimport { default as ComicViewerProps, Dimension } from './ComicViewerProps';\nimport ViewerItem from './ViewerItem';\n\nconst appender = (left: number, right: number): [number, number] => [left + right, left + right];\nconst getHeightAccum = (heights: number[]): [number, number[]] => R.mapAccum(appender, 0, heights);\n\nconst keyExtractor = <T, >(item: ItemState) => String(item.index);\n\ninterface UrlState {\n url: string;\n validity: 'valid' | 'invalid' | 'unknown';\n}\n\ninterface ImageState {\n urlState?: UrlState;\n isNewUrlIncoming: boolean;\n totalErrorCount: number;\n dimension: Dimension;\n}\n\ninterface ItemState {\n index: number;\n url?: string;\n reloadButtonVisible: boolean;\n dimension: Dimension;\n}\n\nconst createInitialImageState = (dimension: Dimension): ImageState => ({\n isNewUrlIncoming: false,\n totalErrorCount: 0,\n dimension,\n});\n\nconst mapImageStateToItemState = (\n index: number,\n imageState: ImageState,\n autoHandleErrorCount: number,\n): ItemState => ({\n index,\n url: imageState.urlState?.url,\n reloadButtonVisible: (imageState.urlState?.validity !== 'valid') && imageState.totalErrorCount >= autoHandleErrorCount,\n dimension: imageState.dimension,\n});\n\nconst MAXIMUM_WIDTH = 720;\n\nconst NUMBER_OF_ADJACENT_ITEM = 5;\n\nexport default function ComicViewer(props: ComicViewerProps) {\n const {\n debounceMillis = 100,\n autoHandleErrorCount = 3,\n getUrlByIndex,\n initialNumToRender = 1,\n initialScrollPercentage = 0,\n itemVisiblePercentThreshold = 0,\n intrinsicDimensions,\n onItemPress,\n viewportWidth,\n windowSize = 3,\n ...otherProps\n } = props;\n\n const flatListRef = useRef<FlatList>(null);\n\n const maybeLoadableItemsIndexRange = useRef<[number, number]>([-1, 0]);\n\n const actualImageWidth = Math.min(viewportWidth, MAXIMUM_WIDTH);\n\n const initialImageStates = useMemo<Array<ImageState>>(() => R.map(createInitialImageState, intrinsicDimensions), []);\n const imageStatesRef = useRef<Array<ImageState>>(initialImageStates);\n\n const mapImageStatesToItemStates = (imageStates: Array<ImageState>): Array<ItemState> => {\n return imageStates.map((image, index) => mapImageStateToItemState(\n index, image, autoHandleErrorCount,\n ));\n };\n\n const [itemStates, setItemStates] = useState<Array<ItemState>>(() => {\n return mapImageStatesToItemStates(imageStatesRef.current);\n });\n\n const renderedDimensions = useMemo<Array<Dimension>>(() => {\n return R.map(intrinsicDimension => ({\n width: actualImageWidth,\n height: (intrinsicDimension.height * actualImageWidth) / intrinsicDimension.width,\n }), intrinsicDimensions);\n }, [actualImageWidth]);\n\n const layoutFromDimensions = useCallback(() => {\n const itemHeights = R.map(dimension => dimension.height, renderedDimensions);\n const [totalHeight, heightAccum] = getHeightAccum(itemHeights);\n const itemOffsets = R.prepend(0, heightAccum);\n\n const getItemLayout = (data: any, index: number) => ({\n index,\n length: itemHeights[index],\n offset: itemOffsets[index],\n });\n\n return {\n totalHeight,\n getItemLayout,\n };\n }, [renderedDimensions]);\n\n const { totalHeight, getItemLayout } = layoutFromDimensions();\n\n const viewabilityConfig = useMemo(() => ({\n itemVisiblePercentThreshold,\n }), [itemVisiblePercentThreshold]);\n\n const updateImageState = (updateFunction: (prev: ImageState, index: number) => ImageState) => {\n const prevImageStates = imageStatesRef.current;\n const newImageStates = prevImageStates.map(updateFunction);\n\n imageStatesRef.current = newImageStates;\n\n setItemStates(prevItemStates => {\n const newItemStates = mapImageStatesToItemStates(newImageStates);\n\n return R.equals(prevItemStates, newItemStates) ? prevItemStates : newItemStates;\n });\n };\n\n const loadUrlByIndex = async (indexes: number[]) => {\n const filteredIndexes = R.filter(index => {\n const state = imageStatesRef.current[index];\n\n return R.isNil(state.urlState)\n || (state.urlState?.validity === 'invalid' && !state.isNewUrlIncoming);\n }, indexes);\n\n updateImageState((imageState, i) => {\n return R.includes(i, filteredIndexes)\n ? { ...imageState, isNewUrlIncoming: true }\n : imageState;\n });\n\n try {\n const urls = await getUrlByIndex(filteredIndexes);\n\n updateImageState((imageState, i) => {\n const newUrl = urls?.get(i);\n const urlState = imageState.urlState;\n\n if (newUrl !== undefined && urlState?.validity !== 'valid') {\n return {\n ...imageState,\n urlState: {\n url: newUrl,\n validity: 'unknown',\n },\n };\n }\n\n return imageState;\n });\n } finally {\n updateImageState((imageState, i) => {\n return R.includes(i, filteredIndexes)\n ? { ...imageState, isNewUrlIncoming: false }\n : imageState;\n });\n }\n };\n\n const loadMaybeLoadableItems = async () => {\n const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n const affectedIndexes = R.range(startIndex, endIndex);\n\n await loadUrlByIndex(affectedIndexes);\n };\n\n const loadItemsDebounce = useDebounce(loadMaybeLoadableItems, debounceMillis);\n\n const onViewableItemsChanged = useRef(({ viewableItems }: { viewableItems: Array<ViewToken> }) => {\n const orderedViewableItems = R.sort((a, b) => (a.index || 0) - (b.index || 0), viewableItems);\n\n const firstViewableIndex = R.head(orderedViewableItems)?.index;\n const lastViewableItemIndex = R.last(orderedViewableItems)?.index;\n\n if (R.isNil(firstViewableIndex) || R.isNil(lastViewableItemIndex)) {\n return;\n }\n\n const startIndex = R.max(firstViewableIndex - NUMBER_OF_ADJACENT_ITEM, 0);\n const endIndex = R.min(lastViewableItemIndex + NUMBER_OF_ADJACENT_ITEM, itemStates.length - 1);\n\n maybeLoadableItemsIndexRange.current = [startIndex, endIndex + 1];\n\n loadItemsDebounce();\n });\n\n const renderItem: ListRenderItem<ItemState> = useCallback(({ item, index }) => {\n const onError = () => {\n updateImageState((imageState, i) => {\n const urlState = imageState.urlState;\n\n if (i === index && urlState !== undefined) {\n return {\n ...imageState,\n totalErrorCount: imageState.totalErrorCount + 1,\n urlState: {\n ...urlState,\n validity: 'invalid',\n },\n };\n }\n\n return imageState;\n });\n\n if (item.reloadButtonVisible) {\n return;\n }\n\n const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n if (index >= startIndex || index < endIndex) {\n loadItemsDebounce();\n }\n };\n\n const onReloadPress = () => {\n const [startIndex, endIndex] = maybeLoadableItemsIndexRange.current;\n if (index >= startIndex || index < endIndex) {\n loadUrlByIndex([index]);\n }\n };\n\n const onLoad = () => {\n updateImageState((imageState, i) => {\n const urlState = imageState.urlState;\n\n if (i === index && urlState !== undefined) {\n return {\n ...imageState,\n urlState: {\n ...urlState,\n validity: 'valid',\n },\n };\n }\n\n return imageState;\n });\n };\n\n return (\n <ViewerItem\n onError={onError}\n onLoad={onLoad}\n onPress={onItemPress}\n onReloadPress={onReloadPress}\n url={item.url}\n width={renderedDimensions[index]?.width ?? 0}\n height={renderedDimensions[index]?.height ?? 0}\n reloadButtonVisible={item.reloadButtonVisible}\n />\n );\n }, [onItemPress, renderedDimensions]);\n\n useEffect(() => {\n const offset = Math.floor((initialScrollPercentage / 100) * totalHeight);\n\n if (flatListRef.current) {\n flatListRef.current.scrollToOffset({ offset, animated: false });\n }\n }, []);\n\n return (\n <FlatList\n data={itemStates}\n getItemLayout={getItemLayout}\n initialNumToRender={initialNumToRender}\n keyExtractor={keyExtractor}\n onViewableItemsChanged={onViewableItemsChanged.current}\n ref={flatListRef}\n renderItem={renderItem}\n viewabilityConfig={viewabilityConfig}\n windowSize={windowSize}\n {...otherProps}\n />\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["ComicViewerProps.ts"],"sourcesContent":["import React from 'react';\nimport { ComponentProps } from '@fountain-ui/core';\nimport { NativeScrollEvent, NativeSyntheticEvent } from 'react-native';\n\nexport interface Dimension {\n width: number;\n height: number;\n}\n\nexport default interface ComicViewerProps extends ComponentProps <{\n /**\n * Delay Time to call the error handler.\n * @default 100\n */\n debounceMillis?: number;\n\n /**\n * How many times handle onError directly when item error occur\n * @default 3\n */\n autoHandleErrorCount?: number;\n\n /**\n * How many items to render in the initial batch.\n * @default 1\n */\n initialNumToRender?: number;\n\n /**\n * Start at initialScrollPercentage.\n * If over 100, scroll to end.\n * @default 0\n */\n initialScrollPercentage?: number;\n\n /**\n * The value for FlatList viewabilityConfig.itemVisiblePercentThreshold.\n * @default 0\n */\n itemVisiblePercentThreshold?: number;\n\n /**\n * Dimensions of each Image considering viewport.\n */\n intrinsicDimensions: Array<Dimension>;\n\n /**\n * Max value of contents image width size.\n * @default 720\n */\n maxContentWidth?: number;\n\n /**\n * Width of viewport.\n */\n viewportWidth: number;\n\n /**\n * The value for FlatList windowSize.\n * @default 3\n */\n windowSize?: number;\n\n /**\n * Get contents urls by indexes.\n */\n getUrlByIndex: (indexes: Array<number>) => Promise<Map<number, string> | undefined> ;\n\n /**\n * Handle scroll event.\n * @param event Scroll event.\n */\n onScroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;\n\n /**\n * Handle item press event.\n */\n onItemPress?: () => void;\n\n /**\n * Component for comic viewer footer.\n */\n ListFooterComponent?: React.ReactElement;\n}> {}\n"],"mappings":""}
1
+ {"version":3,"names":[],"sources":["ComicViewerProps.ts"],"sourcesContent":["import React from 'react';\nimport { ComponentProps } from '@fountain-ui/core';\nimport { NativeScrollEvent, NativeSyntheticEvent } from 'react-native';\n\nexport interface Dimension {\n width: number;\n height: number;\n}\n\nexport default interface ComicViewerProps extends ComponentProps <{\n /**\n * Delay Time to call the error handler.\n * @default 100\n */\n debounceMillis?: number;\n\n /**\n * How many times handle onError directly when item error occur\n * @default 3\n */\n autoHandleErrorCount?: number;\n\n /**\n * How many items to render in the initial batch.\n * @default 1\n */\n initialNumToRender?: number;\n\n /**\n * Start at initialScrollPercentage.\n * If over 100, scroll to end.\n * @default 0\n */\n initialScrollPercentage?: number;\n\n /**\n * The value for FlatList viewabilityConfig.itemVisiblePercentThreshold.\n * @default 0\n */\n itemVisiblePercentThreshold?: number;\n\n /**\n * Dimensions of each Image considering viewport.\n */\n intrinsicDimensions: Array<Dimension>;\n\n /**\n * Width of viewport.\n */\n viewportWidth: number;\n\n /**\n * The value for FlatList windowSize.\n * @default 3\n */\n windowSize?: number;\n\n /**\n * Get contents urls by indexes.\n */\n getUrlByIndex: (indexes: Array<number>) => Promise<Map<number, string> | undefined> ;\n\n /**\n * Handle scroll event.\n * @param event Scroll event.\n */\n onScroll?: (event: NativeSyntheticEvent<NativeScrollEvent>) => void;\n\n /**\n * Handle item press event.\n */\n onItemPress?: () => void;\n\n /**\n * Component for comic viewer footer.\n */\n ListFooterComponent?: React.ReactElement;\n}> {}\n"],"mappings":""}
@@ -39,6 +39,7 @@ export default function ViewerItem(props) {
39
39
  }, /*#__PURE__*/React.createElement(View, {
40
40
  style: styles.view
41
41
  }, /*#__PURE__*/React.createElement(FuiImage, {
42
+ cache: 'web',
42
43
  disableDrag: true,
43
44
  disableLongClick: true,
44
45
  disableOutline: true,
@@ -1 +1 @@
1
- {"version":3,"names":["React","Image","TouchableWithoutFeedback","View","css","FuiImage","ReloadButton","EncodedTile","ViewerItem","props","height","url","width","onError","onLoad","onPress","onReloadPress","reloadButtonVisible","styles","view","image","error","placeholder","uri","alignSelf"],"sources":["ViewerItem.tsx"],"sourcesContent":["import React from 'react';\nimport { Image, TouchableWithoutFeedback, View } from 'react-native';\nimport { css, Image as FuiImage, ImageProps } from '@fountain-ui/core';\nimport ReloadButton from './ReloadButton';\nimport EncodedTile from './EncodedTile';\n\nexport interface ViewerItemProps {\n /**\n * Image width.\n */\n width: number;\n\n /**\n * Image height.\n */\n height: number;\n\n /**\n * Image sourceUrl for displaying.\n */\n url?: string;\n\n /**\n * Error handler.\n */\n onError?: ImageProps['onError'];\n\n /**\n * Load handler.\n */\n onLoad?: ImageProps['onLoad'];\n\n /**\n * Handle Reload button press event.\n */\n onReloadPress?: ImageProps['onError'];\n\n /**\n * Handle item press event.\n */\n onPress?: () => void;\n\n /**\n * If true, reload button visible.\n * @default false\n */\n reloadButtonVisible?: boolean;\n}\n\nexport default function ViewerItem(props: ViewerItemProps) {\n const {\n height,\n url,\n width,\n onError,\n onLoad,\n onPress,\n onReloadPress,\n reloadButtonVisible = false,\n } = props;\n\n const styles = {\n view: {\n height,\n width: '100%',\n },\n image: {\n height,\n width,\n },\n };\n\n const error = reloadButtonVisible ? <ReloadButton onPress={onReloadPress}/> : null;\n\n const placeholder = <Image\n source={{ uri: EncodedTile }}\n resizeMode={'cover'}\n style={styles.image}\n />;\n\n return (\n <TouchableWithoutFeedback onPress={onPress}>\n <View style={styles.view}>\n <FuiImage\n disableDrag={true}\n disableLongClick={true}\n disableOutline={true}\n error={error}\n onError={onError}\n onLoad={onLoad}\n loading={'eager'}\n placeholder={placeholder}\n source={{ uri: url }}\n square={true}\n style={css([\n { alignSelf: 'center' },\n styles.image,\n ])}\n />\n </View>\n </TouchableWithoutFeedback>\n );\n};\n"],"mappings":"AAAA,OAAOA,KAAP,MAAkB,OAAlB;AACA,SAASC,KAAT,EAAgBC,wBAAhB,EAA0CC,IAA1C,QAAsD,cAAtD;AACA,SAASC,GAAT,EAAcH,KAAK,IAAII,QAAvB,QAAmD,mBAAnD;AACA,OAAOC,YAAP,MAAyB,gBAAzB;AACA,OAAOC,WAAP,MAAwB,eAAxB;AA6CA,eAAe,SAASC,UAAT,CAAoBC,KAApB,EAA4C;EACvD,MAAM;IACFC,MADE;IAEFC,GAFE;IAGFC,KAHE;IAIFC,OAJE;IAKFC,MALE;IAMFC,OANE;IAOFC,aAPE;IAQFC,mBAAmB,GAAG;EARpB,IASFR,KATJ;EAWA,MAAMS,MAAM,GAAG;IACXC,IAAI,EAAE;MACFT,MADE;MAEFE,KAAK,EAAE;IAFL,CADK;IAKXQ,KAAK,EAAE;MACHV,MADG;MAEHE;IAFG;EALI,CAAf;EAWA,MAAMS,KAAK,GAAGJ,mBAAmB,gBAAG,oBAAC,YAAD;IAAc,OAAO,EAAED;EAAvB,EAAH,GAA6C,IAA9E;EAEA,MAAMM,WAAW,gBAAG,oBAAC,KAAD;IAChB,MAAM,EAAE;MAAEC,GAAG,EAAEhB;IAAP,CADQ;IAEhB,UAAU,EAAE,OAFI;IAGhB,KAAK,EAAEW,MAAM,CAACE;EAHE,EAApB;EAMA,oBACI,oBAAC,wBAAD;IAA0B,OAAO,EAAEL;EAAnC,gBACI,oBAAC,IAAD;IAAM,KAAK,EAAEG,MAAM,CAACC;EAApB,gBACI,oBAAC,QAAD;IACI,WAAW,EAAE,IADjB;IAEI,gBAAgB,EAAE,IAFtB;IAGI,cAAc,EAAE,IAHpB;IAII,KAAK,EAAEE,KAJX;IAKI,OAAO,EAAER,OALb;IAMI,MAAM,EAAEC,MANZ;IAOI,OAAO,EAAE,OAPb;IAQI,WAAW,EAAEQ,WARjB;IASI,MAAM,EAAE;MAAEC,GAAG,EAAEZ;IAAP,CATZ;IAUI,MAAM,EAAE,IAVZ;IAWI,KAAK,EAAEP,GAAG,CAAC,CACP;MAAEoB,SAAS,EAAE;IAAb,CADO,EAEPN,MAAM,CAACE,KAFA,CAAD;EAXd,EADJ,CADJ,CADJ;AAsBH;AAAA"}
1
+ {"version":3,"names":["React","Image","TouchableWithoutFeedback","View","css","FuiImage","ReloadButton","EncodedTile","ViewerItem","props","height","url","width","onError","onLoad","onPress","onReloadPress","reloadButtonVisible","styles","view","image","error","placeholder","uri","alignSelf"],"sources":["ViewerItem.tsx"],"sourcesContent":["import React from 'react';\nimport { Image, TouchableWithoutFeedback, View } from 'react-native';\nimport { css, Image as FuiImage, ImageProps } from '@fountain-ui/core';\nimport ReloadButton from './ReloadButton';\nimport EncodedTile from './EncodedTile';\n\nexport interface ViewerItemProps {\n /**\n * Image width.\n */\n width: number;\n\n /**\n * Image height.\n */\n height: number;\n\n /**\n * Image sourceUrl for displaying.\n */\n url?: string;\n\n /**\n * Error handler.\n */\n onError?: ImageProps['onError'];\n\n /**\n * Load handler.\n */\n onLoad?: ImageProps['onLoad'];\n\n /**\n * Handle Reload button press event.\n */\n onReloadPress?: ImageProps['onError'];\n\n /**\n * Handle item press event.\n */\n onPress?: () => void;\n\n /**\n * If true, reload button visible.\n * @default false\n */\n reloadButtonVisible?: boolean;\n}\n\nexport default function ViewerItem(props: ViewerItemProps) {\n const {\n height,\n url,\n width,\n onError,\n onLoad,\n onPress,\n onReloadPress,\n reloadButtonVisible = false,\n } = props;\n\n const styles = {\n view: {\n height,\n width: '100%',\n },\n image: {\n height,\n width,\n },\n };\n\n const error = reloadButtonVisible ? <ReloadButton onPress={onReloadPress}/> : null;\n\n const placeholder = <Image\n source={{ uri: EncodedTile }}\n resizeMode={'cover'}\n style={styles.image}\n />;\n\n return (\n <TouchableWithoutFeedback onPress={onPress}>\n <View style={styles.view}>\n <FuiImage\n cache={'web'}\n disableDrag={true}\n disableLongClick={true}\n disableOutline={true}\n error={error}\n onError={onError}\n onLoad={onLoad}\n loading={'eager'}\n placeholder={placeholder}\n source={{ uri: url }}\n square={true}\n style={css([\n { alignSelf: 'center' },\n styles.image,\n ])}\n />\n </View>\n </TouchableWithoutFeedback>\n );\n};\n"],"mappings":"AAAA,OAAOA,KAAP,MAAkB,OAAlB;AACA,SAASC,KAAT,EAAgBC,wBAAhB,EAA0CC,IAA1C,QAAsD,cAAtD;AACA,SAASC,GAAT,EAAcH,KAAK,IAAII,QAAvB,QAAmD,mBAAnD;AACA,OAAOC,YAAP,MAAyB,gBAAzB;AACA,OAAOC,WAAP,MAAwB,eAAxB;AA6CA,eAAe,SAASC,UAAT,CAAoBC,KAApB,EAA4C;EACvD,MAAM;IACFC,MADE;IAEFC,GAFE;IAGFC,KAHE;IAIFC,OAJE;IAKFC,MALE;IAMFC,OANE;IAOFC,aAPE;IAQFC,mBAAmB,GAAG;EARpB,IASFR,KATJ;EAWA,MAAMS,MAAM,GAAG;IACXC,IAAI,EAAE;MACFT,MADE;MAEFE,KAAK,EAAE;IAFL,CADK;IAKXQ,KAAK,EAAE;MACHV,MADG;MAEHE;IAFG;EALI,CAAf;EAWA,MAAMS,KAAK,GAAGJ,mBAAmB,gBAAG,oBAAC,YAAD;IAAc,OAAO,EAAED;EAAvB,EAAH,GAA6C,IAA9E;EAEA,MAAMM,WAAW,gBAAG,oBAAC,KAAD;IAChB,MAAM,EAAE;MAAEC,GAAG,EAAEhB;IAAP,CADQ;IAEhB,UAAU,EAAE,OAFI;IAGhB,KAAK,EAAEW,MAAM,CAACE;EAHE,EAApB;EAMA,oBACI,oBAAC,wBAAD;IAA0B,OAAO,EAAEL;EAAnC,gBACI,oBAAC,IAAD;IAAM,KAAK,EAAEG,MAAM,CAACC;EAApB,gBACI,oBAAC,QAAD;IACI,KAAK,EAAE,KADX;IAEI,WAAW,EAAE,IAFjB;IAGI,gBAAgB,EAAE,IAHtB;IAII,cAAc,EAAE,IAJpB;IAKI,KAAK,EAAEE,KALX;IAMI,OAAO,EAAER,OANb;IAOI,MAAM,EAAEC,MAPZ;IAQI,OAAO,EAAE,OARb;IASI,WAAW,EAAEQ,WATjB;IAUI,MAAM,EAAE;MAAEC,GAAG,EAAEZ;IAAP,CAVZ;IAWI,MAAM,EAAE,IAXZ;IAYI,KAAK,EAAEP,GAAG,CAAC,CACP;MAAEoB,SAAS,EAAE;IAAb,CADO,EAEPN,MAAM,CAACE,KAFA,CAAD;EAZd,EADJ,CADJ,CADJ;AAuBH;AAAA"}
@@ -36,11 +36,6 @@ export default interface ComicViewerProps extends ComponentProps<{
36
36
  * Dimensions of each Image considering viewport.
37
37
  */
38
38
  intrinsicDimensions: Array<Dimension>;
39
- /**
40
- * Max value of contents image width size.
41
- * @default 720
42
- */
43
- maxContentWidth?: number;
44
39
  /**
45
40
  * Width of viewport.
46
41
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fountain-ui/lab",
3
- "version": "2.0.0-beta.37",
3
+ "version": "2.0.0-beta.38",
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": "cab7282d1bcb2e1b6fb0285c03d4ac5cd583b915"
73
+ "gitHead": "0805dd8cc34de6ecbcdf01d37a3e836c1dcfa592"
74
74
  }
@@ -59,7 +59,6 @@ export default function ComicViewer(props: ComicViewerProps) {
59
59
  initialScrollPercentage = 0,
60
60
  itemVisiblePercentThreshold = 0,
61
61
  intrinsicDimensions,
62
- maxContentWidth = MAXIMUM_WIDTH,
63
62
  onItemPress,
64
63
  viewportWidth,
65
64
  windowSize = 3,
@@ -70,7 +69,7 @@ export default function ComicViewer(props: ComicViewerProps) {
70
69
 
71
70
  const maybeLoadableItemsIndexRange = useRef<[number, number]>([-1, 0]);
72
71
 
73
- const actualImageWidth = Math.min(viewportWidth, maxContentWidth);
72
+ const actualImageWidth = Math.min(viewportWidth, MAXIMUM_WIDTH);
74
73
 
75
74
  const initialImageStates = useMemo<Array<ImageState>>(() => R.map(createInitialImageState, intrinsicDimensions), []);
76
75
  const imageStatesRef = useRef<Array<ImageState>>(initialImageStates);
@@ -281,7 +280,6 @@ export default function ComicViewer(props: ComicViewerProps) {
281
280
  keyExtractor={keyExtractor}
282
281
  onViewableItemsChanged={onViewableItemsChanged.current}
283
282
  ref={flatListRef}
284
- removeClippedSubviews={false}
285
283
  renderItem={renderItem}
286
284
  viewabilityConfig={viewabilityConfig}
287
285
  windowSize={windowSize}
@@ -44,12 +44,6 @@ export default interface ComicViewerProps extends ComponentProps <{
44
44
  */
45
45
  intrinsicDimensions: Array<Dimension>;
46
46
 
47
- /**
48
- * Max value of contents image width size.
49
- * @default 720
50
- */
51
- maxContentWidth?: number;
52
-
53
47
  /**
54
48
  * Width of viewport.
55
49
  */
@@ -82,6 +82,7 @@ export default function ViewerItem(props: ViewerItemProps) {
82
82
  <TouchableWithoutFeedback onPress={onPress}>
83
83
  <View style={styles.view}>
84
84
  <FuiImage
85
+ cache={'web'}
85
86
  disableDrag={true}
86
87
  disableLongClick={true}
87
88
  disableOutline={true}