@wordpress/components
Version:
UI components for WordPress.
174 lines (144 loc) • 4.94 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = LinkPickerResults;
var _element = require("@wordpress/element");
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _reactNative = require("react-native");
var _components = require("@wordpress/components");
var _compose = require("@wordpress/compose");
var _data = require("@wordpress/data");
var _styles = _interopRequireDefault(require("./styles.scss"));
/**
* External dependencies
*/
/**
* WordPress dependencies
*/
/**
* Internal dependencies
*/
const PER_PAGE = 20;
const REQUEST_DEBOUNCE_DELAY = 400;
const MINIMUM_QUERY_SIZE = 2;
const meetsThreshold = query => MINIMUM_QUERY_SIZE <= query.length;
function LinkPickerResults(_ref) {
let {
query,
onLinkPicked,
directEntry
} = _ref;
const [links, setLinks] = (0, _element.useState)([directEntry]);
const [hasAllSuggestions, setHasAllSuggestions] = (0, _element.useState)(false);
const nextPage = (0, _element.useRef)(1);
const pendingRequest = (0, _element.useRef)();
const clearRequest = () => {
pendingRequest.current = null;
}; // A stable debounced function to fetch suggestions and append.
const {
fetchMoreSuggestions
} = (0, _data.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: (0, _compose.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.
(0, _element.useEffect)(() => clearRequest, []); // Any time the query changes, we reset pagination.
(0, _element.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) && (0, _element.createElement)(_reactNative.View, {
style: _styles.default.spinner
}, (0, _element.createElement)(_reactNative.ActivityIndicator, {
animating: true
}));
return (0, _element.createElement)(_components.BottomSheetConsumer, null, _ref4 => {
let {
listProps
} = _ref4;
return (0, _element.createElement)(_reactNative.FlatList, (0, _extends2.default)({
data: links,
keyboardShouldPersistTaps: "always",
renderItem: _ref5 => {
let {
item
} = _ref5;
return (0, _element.createElement)(_components.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.default.list]
}));
});
}
//# sourceMappingURL=link-picker-results.native.js.map