mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-11-10 10:05:09 +03:00
Merge pull request #5485 from urbit/lf/recency-improvements
landscape: better leap searching
This commit is contained in:
commit
f1f57abec0
32419
pkg/interface/package-lock.json
generated
32419
pkg/interface/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -25,6 +25,7 @@
|
||||
"css-loader": "^3.6.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"formik": "^2.1.5",
|
||||
"fuzzy": "^0.1.3",
|
||||
"immer": "^9.0.2",
|
||||
"lodash": "^4.17.21",
|
||||
"moment": "^2.29.1",
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Box, Row, Text } from '@tlon/indigo-react';
|
||||
import { omit } from 'lodash';
|
||||
import Mousetrap from 'mousetrap';
|
||||
import fuzzy from 'fuzzy';
|
||||
import _ from 'lodash';
|
||||
import f from 'lodash/fp';
|
||||
import React, {
|
||||
@ -44,6 +45,19 @@ const SEARCHED_CATEGORIES = [
|
||||
const settingsSel = (s: SettingsState) => s.leap;
|
||||
const CAT_LIMIT = 6;
|
||||
|
||||
/**
|
||||
* Flatten `catMap` according to ordering in `cats`
|
||||
*/
|
||||
function flattenCattegoryMap(cats: string[], catMap: Map<string, OmniboxItem[]>) {
|
||||
let res = [] as OmniboxItem[];
|
||||
cats.forEach(cat => {
|
||||
res = res.concat(_.take(catMap.get(cat), CAT_LIMIT));
|
||||
});
|
||||
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
export function Omnibox(props: OmniboxProps): ReactElement {
|
||||
const location = useLocation();
|
||||
const history = useHistory();
|
||||
@ -124,29 +138,28 @@ export function Omnibox(props: OmniboxProps): ReactElement {
|
||||
);
|
||||
}, [index]);
|
||||
|
||||
const results = useMemo(() => {
|
||||
const [results, categoryOrder] = useMemo(
|
||||
(): [Map<string, OmniboxItem[]>, string[]] => {
|
||||
if (query.length <= 1) {
|
||||
return initialResults;
|
||||
return [initialResults, ['other']];
|
||||
}
|
||||
const q = query.toLowerCase();
|
||||
const resultsMap = new Map<string, OmniboxItem[]>();
|
||||
let categoryMaxes: Record<string, number> = {};
|
||||
|
||||
SEARCHED_CATEGORIES.map((category) => {
|
||||
const categoryIndex = index.get(category);
|
||||
resultsMap.set(
|
||||
category,
|
||||
categoryIndex.filter((result) => {
|
||||
return (
|
||||
result.title.toLowerCase().includes(q) ||
|
||||
result.link.toLowerCase().includes(q) ||
|
||||
result.app.toLowerCase().includes(q) ||
|
||||
(result.host !== null
|
||||
? result.host.toLowerCase().includes(q)
|
||||
: false)
|
||||
);
|
||||
})
|
||||
);
|
||||
const fuzzied = fuzzy
|
||||
.filter(q, categoryIndex, { extract: res => res.title });
|
||||
categoryMaxes[category] = fuzzied
|
||||
.map(a => a.score)
|
||||
.reduce((a,b) => Math.max(a,b), 0);
|
||||
resultsMap.set(category, fuzzied.map(a => a.original));
|
||||
});
|
||||
return resultsMap;
|
||||
let order = Object.entries(categoryMaxes)
|
||||
.sort(([,a],[,b]) => b - a)
|
||||
.map(([id]) => id);
|
||||
return [resultsMap, order];
|
||||
}, [query, index]);
|
||||
|
||||
const navigate = useCallback(
|
||||
@ -181,7 +194,7 @@ export function Omnibox(props: OmniboxProps): ReactElement {
|
||||
);
|
||||
|
||||
const setPreviousSelected = useCallback(() => {
|
||||
const flattenedResults = Array.from(results.values()).map(f.take(CAT_LIMIT)).flat();
|
||||
const flattenedResults = flattenCattegoryMap(categoryOrder, results);
|
||||
const totalLength = flattenedResults.length;
|
||||
if (selected.length) {
|
||||
const currentIndex = flattenedResults.indexOf(
|
||||
@ -201,10 +214,10 @@ export function Omnibox(props: OmniboxProps): ReactElement {
|
||||
const { app, link } = flattenedResults[totalLength - 1];
|
||||
setSelected([app, link]);
|
||||
}
|
||||
}, [results, selected]);
|
||||
}, [results, categoryOrder, selected]);
|
||||
|
||||
const setNextSelected = useCallback(() => {
|
||||
const flattenedResults = Array.from(results.values()).map(f.take(CAT_LIMIT)).flat();
|
||||
const flattenedResults = flattenCattegoryMap(categoryOrder, results);
|
||||
if (selected.length) {
|
||||
const currentIndex = flattenedResults.indexOf(
|
||||
// @ts-ignore unclear how to give this spread a return signature
|
||||
@ -223,7 +236,7 @@ export function Omnibox(props: OmniboxProps): ReactElement {
|
||||
const { app, link } = flattenedResults[0];
|
||||
setSelected([app, link]);
|
||||
}
|
||||
}, [selected, results]);
|
||||
}, [results, categoryOrder, selected]);
|
||||
|
||||
const setSelection = (app, link) => {
|
||||
setLeapCursor('pointer');
|
||||
@ -255,14 +268,15 @@ export function Omnibox(props: OmniboxProps): ReactElement {
|
||||
}
|
||||
if (evt.key === 'Enter') {
|
||||
evt.preventDefault();
|
||||
let values = flattenCattegoryMap(categoryOrder, results);
|
||||
if (selected.length) {
|
||||
navigate(selected[0], selected[1], evt.shiftKey);
|
||||
} else if (Array.from(results.values()).flat().length === 0) {
|
||||
} else if (values.length === 0) {
|
||||
return;
|
||||
} else {
|
||||
navigate(
|
||||
Array.from(results.values()).flat()[0].app,
|
||||
Array.from(results.values()).flat()[0].link,
|
||||
values[0].app,
|
||||
values[0].link,
|
||||
evt.shiftKey
|
||||
);
|
||||
}
|
||||
@ -275,15 +289,16 @@ export function Omnibox(props: OmniboxProps): ReactElement {
|
||||
query,
|
||||
props.show,
|
||||
results,
|
||||
categoryOrder,
|
||||
setPreviousSelected,
|
||||
setNextSelected
|
||||
]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const flattenedResultLinks: [string, string][] = Array.from(results.values())
|
||||
.flat()
|
||||
.map(result => [result.app, result.link]);
|
||||
const flattenedResultLinks: [string, string][] =
|
||||
flattenCattegoryMap(categoryOrder, results)
|
||||
.map(result => [result.app, result.link]);
|
||||
if (!flattenedResultLinks.includes(selected as [string, string])) {
|
||||
setSelected(flattenedResultLinks[0] || []);
|
||||
}
|
||||
@ -319,10 +334,10 @@ export function Omnibox(props: OmniboxProps): ReactElement {
|
||||
borderBottomLeftRadius={2}
|
||||
borderBottomRightRadius={2}
|
||||
>
|
||||
{SEARCHED_CATEGORIES.map(category =>
|
||||
{categoryOrder.map(category =>
|
||||
({
|
||||
category,
|
||||
categoryResults: _.take(results.get(category).sort(sortResults), CAT_LIMIT)
|
||||
categoryResults: _.take(results.get(category), CAT_LIMIT)
|
||||
})
|
||||
)
|
||||
.filter(category => category.categoryResults.length > 0)
|
||||
|
Loading…
Reference in New Issue
Block a user