Skip to content

Commit

Permalink
Return exact matches when searching for an instruction (#7330)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexandreSi authored Jan 22, 2025
1 parent f805182 commit 6ab736a
Show file tree
Hide file tree
Showing 7 changed files with 256 additions and 72 deletions.
16 changes: 7 additions & 9 deletions newIDE/app/src/AssetStore/BehaviorStore/BehaviorStoreContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
import { type Filters } from '../../Utils/GDevelopServices/Filters';
import {
useSearchStructuredItem,
type SearchMatch,
type SearchResult,
} from '../../UI/Search/UseSearchStructuredItem';
import PreferencesContext from '../../MainFrame/Preferences/PreferencesContext';
import { BEHAVIORS_FETCH_TIMEOUT } from '../../Utils/GlobalFetchTimeouts';
Expand Down Expand Up @@ -38,10 +38,9 @@ export type SearchableBehaviorMetadata = {|

type BehaviorStoreState = {|
filters: ?Filters,
searchResults: ?Array<{|
item: BehaviorShortHeader | SearchableBehaviorMetadata,
matches: SearchMatch[],
|}>,
searchResults: ?Array<
SearchResult<BehaviorShortHeader | SearchableBehaviorMetadata>
>,
fetchBehaviors: () => void,
error: ?Error,
searchText: string,
Expand Down Expand Up @@ -244,10 +243,9 @@ export const BehaviorStoreStateProvider = ({
[firstBehaviorIds, installedBehaviorMetadataList]
);

const searchResults: ?Array<{|
item: BehaviorShortHeader | SearchableBehaviorMetadata,
matches: SearchMatch[],
|}> = useSearchStructuredItem(allBehaviors, {
const searchResults: ?Array<
SearchResult<BehaviorShortHeader | SearchableBehaviorMetadata>
> = useSearchStructuredItem(allBehaviors, {
searchText,
chosenItemCategory: chosenCategory,
chosenCategory: filtersState.chosenCategory,
Expand Down
14 changes: 5 additions & 9 deletions newIDE/app/src/AssetStore/ExampleStore/ExampleStoreContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
import { type Filters } from '../../Utils/GDevelopServices/Filters';
import {
useSearchStructuredItem,
type SearchMatch,
type SearchResult,
} from '../../UI/Search/UseSearchStructuredItem';
import { EXAMPLES_FETCH_TIMEOUT } from '../../Utils/GlobalFetchTimeouts';

Expand All @@ -18,10 +18,7 @@ const firstExampleIds = [];

type ExampleStoreState = {|
exampleFilters: ?Filters,
exampleShortHeadersSearchResults: ?Array<{|
item: ExampleShortHeader,
matches: SearchMatch[],
|}>,
exampleShortHeadersSearchResults: ?Array<SearchResult<ExampleShortHeader>>,
fetchExamplesAndFilters: () => void,
exampleShortHeaders: ?Array<ExampleShortHeader>,
error: ?Error,
Expand Down Expand Up @@ -133,10 +130,9 @@ export const ExampleStoreStateProvider = ({
);

const { chosenCategory, chosenFilters } = filtersState;
const exampleShortHeadersSearchResults: ?Array<{|
item: ExampleShortHeader,
matches: SearchMatch[],
|}> = useSearchStructuredItem(exampleShortHeadersById, {
const exampleShortHeadersSearchResults: ?Array<
SearchResult<ExampleShortHeader>
> = useSearchStructuredItem(exampleShortHeadersById, {
searchText,
chosenCategory,
chosenFilters,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
import { type Filters } from '../../Utils/GDevelopServices/Filters';
import {
useSearchStructuredItem,
type SearchMatch,
type SearchResult,
} from '../../UI/Search/UseSearchStructuredItem';
import PreferencesContext from '../../MainFrame/Preferences/PreferencesContext';
import { EXTENSIONS_FETCH_TIMEOUT } from '../../Utils/GlobalFetchTimeouts';
Expand All @@ -21,10 +21,7 @@ const excludedCommunityTiers = new Set(['community']);

type ExtensionStoreState = {|
filters: ?Filters,
searchResults: ?Array<{|
item: ExtensionShortHeader,
matches: SearchMatch[],
|}>,
searchResults: ?Array<SearchResult<ExtensionShortHeader>>,
fetchExtensionsAndFilters: () => void,
error: ?Error,
searchText: string,
Expand Down Expand Up @@ -177,10 +174,9 @@ export const ExtensionStoreStateProvider = ({
[extensionShortHeadersByName]
);

const searchResults: ?Array<{|
item: ExtensionShortHeader,
matches: SearchMatch[],
|}> = useSearchStructuredItem(extensionShortHeadersByName, {
const searchResults: ?Array<
SearchResult<ExtensionShortHeader>
> = useSearchStructuredItem(extensionShortHeadersByName, {
searchText,
chosenItemCategory: chosenCategory,
chosenCategory: filtersState.chosenCategory,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { type FiltersState, useFilters } from '../../UI/Search/FiltersChooser';
import { type Filters } from '../../Utils/GDevelopServices/Filters';
import {
useSearchStructuredItem,
type SearchMatch,
type SearchResult,
} from '../../UI/Search/UseSearchStructuredItem';
import { useSearchItem } from '../../UI/Search/UseSearchItem';
import {
Expand Down Expand Up @@ -44,10 +44,9 @@ type PrivateGameTemplateStoreState = {|
setInitialGameTemplateUserFriendlySlug: string => void,
},
exampleStore: {
privateGameTemplateListingDatasSearchResults: ?Array<{|
item: PrivateGameTemplateListingData,
matches: SearchMatch[],
|}>,
privateGameTemplateListingDatasSearchResults: ?Array<
SearchResult<PrivateGameTemplateListingData>
>,
searchText: string,
setSearchText: string => void,
filtersState: FiltersState,
Expand Down Expand Up @@ -284,10 +283,9 @@ export const PrivateGameTemplateStoreStateProvider = ({

const currentPage = shopNavigationState.getCurrentPage();

const privateGameTemplateListingDatasSearchResultsForExampleStore: ?Array<{|
item: PrivateGameTemplateListingData,
matches: SearchMatch[],
|}> = useSearchStructuredItem(privateGameTemplateListingDatasById, {
const privateGameTemplateListingDatasSearchResultsForExampleStore: ?Array<
SearchResult<PrivateGameTemplateListingData>
> = useSearchStructuredItem(privateGameTemplateListingDatasById, {
searchText: exampleStoreSearchText,
chosenCategory: filtersStateForExampleStore.chosenCategory,
chosenFilters: filtersStateForExampleStore.chosenFilters,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@ import EmptyMessage from '../../UI/EmptyMessage';
import { type EventsScope } from '../../InstructionOrExpression/EventsScope';
import {
type SearchResult,
tuneMatches,
sortResultsUsingExactMatches,
sharedFuseConfiguration,
getFuseSearchQueryForMultipleKeys,
nullifySingleCharacterMatches,
augmentSearchResult,
} from '../../UI/Search/UseSearchStructuredItem';
import { Column, Line } from '../../UI/Grid';
import { enumerateFoldersInContainer } from '../../ObjectsList/EnumerateObjectFolderOrObject';
Expand Down Expand Up @@ -283,6 +285,7 @@ const InstructionOrObjectSelector = React.forwardRef<
const instructionSearchApiRef = React.useRef<Fuse>(
new Fuse(allInstructionsInfoRef.current, {
...sharedFuseConfiguration,
includeScore: true, // Use Fuse.js score to sort results that don't contain exact matches.
keys: [
{ name: 'displayedName', weight: 5 },
{ name: 'fullGroupName', weight: 1 },
Expand Down Expand Up @@ -457,6 +460,7 @@ const InstructionOrObjectSelector = React.forwardRef<

const search = React.useCallback((searchText: string) => {
if (!searchText) return;
const lowerCaseSearchText = searchText.toLowerCase();

const matchingInstructions = moveDeprecatedInstructionsDown(
instructionSearchApiRef.current
Expand All @@ -467,10 +471,16 @@ const InstructionOrObjectSelector = React.forwardRef<
'description',
])
)
.map(result => ({
item: result.item,
matches: tuneMatches(result, searchText),
}))
.map(nullifySingleCharacterMatches)
.filter(Boolean)
.map(result => augmentSearchResult(result, lowerCaseSearchText))
.sort(
sortResultsUsingExactMatches([
'displayedName',
'description',
'fullGroupName',
])
)
);

setSearchResults({ instructions: matchingInstructions });
Expand Down Expand Up @@ -676,7 +686,7 @@ const InstructionOrObjectSelector = React.forwardRef<
[displayedInstructionsList, isSearching]
);

const hasNoObjects = !isSearching && !allObjectsList.length;
const displayEmptyMessage = !isSearching && !allObjectsList.length;
const searchHasNoResults = isSearching && !hasResults;

return (
Expand Down Expand Up @@ -737,7 +747,7 @@ const InstructionOrObjectSelector = React.forwardRef<
</Column>
</Line>
)}
{hasNoObjects ? (
{displayEmptyMessage && currentTab === 'objects' ? (
<EmptyMessage>{getEmptyMessage(scope)}</EmptyMessage>
) : searchHasNoResults ? (
<EmptyMessage>
Expand All @@ -753,7 +763,7 @@ const InstructionOrObjectSelector = React.forwardRef<
display:
(currentTab === 'objects' || isSearching) &&
!searchHasNoResults &&
!hasNoObjects
!displayEmptyMessage
? 'unset'
: 'none',
}}
Expand Down
60 changes: 37 additions & 23 deletions newIDE/app/src/UI/Dialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,24 +135,30 @@ const useStylesForDialogContent = ({
forceScroll,
}: {|
forceScroll: boolean,
|}) =>
makeStyles({
root: {
...(forceScroll ? { overflowY: 'scroll' } : {}), // Force a scrollbar to prevent layout shifts.
'&::-webkit-scrollbar': {
width: 11,
},
'&::-webkit-scrollbar-track': {
background: 'rgba(0, 0, 0, 0.04)',
borderRadius: 6,
},
'&::-webkit-scrollbar-thumb': {
border: '3px solid rgba(0, 0, 0, 0)',
backgroundClip: 'padding-box',
borderRadius: 6,
},
},
})();
|}) => {
const useStyles = React.useMemo(
() =>
makeStyles({
root: {
...(forceScroll ? { overflowY: 'scroll' } : {}), // Force a scrollbar to prevent layout shifts.
'&::-webkit-scrollbar': {
width: 11,
},
'&::-webkit-scrollbar-track': {
background: 'rgba(0, 0, 0, 0.04)',
borderRadius: 6,
},
'&::-webkit-scrollbar-thumb': {
border: '3px solid rgba(0, 0, 0, 0)',
backgroundClip: 'padding-box',
borderRadius: 6,
},
},
}),
[forceScroll]
);
return useStyles();
};

// We support a subset of the props supported by Material-UI v0.x Dialog
// They should be self descriptive - refer to Material UI docs otherwise.
Expand Down Expand Up @@ -364,6 +370,18 @@ const Dialog = ({
: minHeight === 'sm'
? styles.minHeightForSmallHeightModal
: undefined;
const paperStyle = React.useMemo(
() => ({
backgroundColor: gdevelopTheme.dialog.backgroundColor,
minHeight: paperMinHeight,
...getAvoidSoftKeyboardStyle(softKeyboardBottomOffset),
}),
[
gdevelopTheme.dialog.backgroundColor,
paperMinHeight,
softKeyboardBottomOffset,
]
);

return (
<MuiDialog
Expand All @@ -378,11 +396,7 @@ const Dialog = ({
})}
PaperProps={{
id,
style: {
backgroundColor: gdevelopTheme.dialog.backgroundColor,
minHeight: paperMinHeight,
...getAvoidSoftKeyboardStyle(softKeyboardBottomOffset),
},
style: paperStyle,
}}
maxWidth={
maxWidth !== undefined
Expand Down
Loading

0 comments on commit 6ab736a

Please sign in to comment.