UNPKG

@wordpress/components

Version:
160 lines (139 loc) 4.54 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import { createElement } from "@wordpress/element"; /** * External dependencies */ import { ActivityIndicator, FlatList, View } from 'react-native'; /** * WordPress dependencies */ import { BottomSheet, BottomSheetConsumer } from '@wordpress/components'; import { debounce } from '@wordpress/compose'; import { useState, useEffect, useRef } from '@wordpress/element'; import { useSelect } from '@wordpress/data'; /** * Internal dependencies */ import styles from './styles.scss'; const PER_PAGE = 20; const REQUEST_DEBOUNCE_DELAY = 400; const MINIMUM_QUERY_SIZE = 2; const meetsThreshold = query => MINIMUM_QUERY_SIZE <= query.length; export default function LinkPickerResults(_ref) { let { query, onLinkPicked, directEntry } = _ref; const [links, setLinks] = useState([directEntry]); const [hasAllSuggestions, setHasAllSuggestions] = useState(false); const nextPage = useRef(1); const pendingRequest = useRef(); const clearRequest = () => { pendingRequest.current = null; }; // A stable debounced function to fetch suggestions and append. const { fetchMoreSuggestions } = useSelect(select => { const { getSettings } = select('core/block-editor'); const fetchLinkSuggestions = async _ref2 => { let { search } = _ref2; if (meetsThreshold(search)) { return await getSettings().__experimentalFetchLinkSuggestions(search, { page: nextPage.current, type: 'post', perPage: PER_PAGE }); } }; const fetchMore = async _ref3 => { let { query: search, links: currentSuggestions } = _ref3; // Return early if we've already detected the end of data or we are // already awaiting a response. if (hasAllSuggestions || pendingRequest.current) { return; } const request = fetchLinkSuggestions({ search }); pendingRequest.current = request; const suggestions = await request; // Only update links for the most recent request. if (suggestions && request === pendingRequest.current) { // Since we don't have the response header, we check if the results // are truncated to determine we've reached the end. if (suggestions.length < PER_PAGE) { setHasAllSuggestions(true); } setLinks([...currentSuggestions, ...suggestions]); nextPage.current++; } clearRequest(); }; return { fetchMoreSuggestions: debounce(fetchMore, REQUEST_DEBOUNCE_DELAY) }; // Disable eslint rule for now, to avoid introducing a regression // (see https://github.com/WordPress/gutenberg/pull/23922#discussion_r1170634879). // eslint-disable-next-line react-hooks/exhaustive-deps }, []); // Prevent setting state when unmounted. useEffect(() => clearRequest, []); // Any time the query changes, we reset pagination. useEffect(() => { clearRequest(); nextPage.current = 1; setHasAllSuggestions(false); setLinks([directEntry]); fetchMoreSuggestions({ query, links: [directEntry] }); // Disable reason: deferring this refactor to the native team. // see https://github.com/WordPress/gutenberg/pull/41166 // eslint-disable-next-line react-hooks/exhaustive-deps }, [query]); const onEndReached = () => fetchMoreSuggestions({ query, links }); const spinner = !hasAllSuggestions && meetsThreshold(query) && createElement(View, { style: styles.spinner }, createElement(ActivityIndicator, { animating: true })); return createElement(BottomSheetConsumer, null, _ref4 => { let { listProps } = _ref4; return createElement(FlatList, _extends({ data: links, keyboardShouldPersistTaps: "always", renderItem: _ref5 => { let { item } = _ref5; return createElement(BottomSheet.LinkSuggestionItemCell, { suggestion: item, onLinkPicked: onLinkPicked }); }, keyExtractor: _ref6 => { let { url, type } = _ref6; return `${url}-${type}`; }, onEndReached: onEndReached, onEndReachedThreshold: 0.1, initialNumToRender: PER_PAGE, ListFooterComponent: spinner }, listProps, { contentContainerStyle: [...listProps.contentContainerStyle, styles.list] })); }); } //# sourceMappingURL=link-picker-results.native.js.map