Skip to content

Commit

Permalink
feat(MouseInteraction): added option to customize single and double c…
Browse files Browse the repository at this point in the history
…lick behavior
  • Loading branch information
oliverschwendener committed Feb 21, 2024
1 parent ed2584a commit 4f82b04
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 21 deletions.
28 changes: 26 additions & 2 deletions src/renderer/Core/Components/BasicSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,30 @@ export const BasicSearch = ({
}
};

const clickHandlers: Record<string, (s: SearchResultItem) => void> = {
selectSearchResultItem: (s) =>
setSelectedItemIndex(searchResultItems.findIndex((searchResultItem) => searchResultItem.id === s.id)),
invokeSearchResultItem: (s) => contextBridge.invokeAction(s.defaultAction),
};

const handleSearchResultItemClickEvent = (searchResultItem: SearchResultItem) => {
const singleClickBehavior = contextBridge.getSettingValue(
"keyboardAndMouse.singleClickBehavior",
"selectSearchResultItem",
);

clickHandlers[singleClickBehavior](searchResultItem);
};

const handleSearchResultItemDoubleClickEvent = (searchResultItem: SearchResultItem) => {
const doubleClickBehavior = contextBridge.getSettingValue(
"keyboardAndMouse.doubleClickBehavior",
"invokeSearchResultItem",
);

clickHandlers[doubleClickBehavior](searchResultItem);
};

useEffect(() => {
if (!searchTerm) {
setIsLoading(false);
Expand Down Expand Up @@ -127,8 +151,8 @@ export const BasicSearch = ({
) : (
<SearchResultList
containerRef={contentRef}
onSearchResultItemClick={(i) => setSelectedItemIndex(i)}
onSearchResultItemDoubleClick={(s) => contextBridge.invokeAction(s.defaultAction)}
onSearchResultItemClick={(s) => handleSearchResultItemClickEvent(s)}
onSearchResultItemDoubleClick={(s) => handleSearchResultItemDoubleClickEvent(s)}
searchResultItems={searchResultItems}
favorites={[]}
selectedItemIndex={selectedItemIndex}
Expand Down
19 changes: 19 additions & 0 deletions src/renderer/Core/I18n/getCoreTranslations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,25 @@ export const getCoreTranslations = (): { namespace: string; translations: Transl
},
},
},
{
namespace: "settingsKeyboardAndMouse",
translations: {
"en-US": {
title: "Keyboard & Mouse",
singleClickBehavior: "Single click behavior",
doubleClickBehavior: "Double click behavior",
selectSearchResultItem: "Select search result item",
invokeSearchResultItem: "Invoke search result item",
},
"de-CH": {
title: "Tastatur & Maus",
singleClickBehavior: "Einfachklick-Verhalten",
doubleClickBehavior: "Doppelklick-Verhalten",
selectSearchResultItem: "Suchergebniss anwählen",
invokeSearchResultItem: "Suchergebniss ausführen",
},
},
},
{
namespace: "settingsDebug",
translations: {
Expand Down
27 changes: 24 additions & 3 deletions src/renderer/Core/Search/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ export const Search = ({ searchResultItems, excludedSearchResultItemIds, favorit
setInstantSearchResultItems(contextBridge.getInstantSearchResultItems(updatedSearchTerm));
};

const { value: singleClickBehavior } = useSetting({
key: "keyboardAndMouse.singleClickBehavior",
defaultValue: "selectSearchResultItem",
});

const { value: doubleClickBehavior } = useSetting({
defaultValue: "invokeSearchResultItem",
key: "keyboardAndMouse.doubleClickBehavior",
});

const { value: fuzziness } = useSetting({ key: "searchEngine.fuzziness", defaultValue: 0.5 });
const { value: maxResultLength } = useSetting({ key: "searchEngine.maxResultLength", defaultValue: 50 });

Expand Down Expand Up @@ -141,10 +151,21 @@ export const Search = ({ searchResultItems, excludedSearchResultItemIds, favorit
}
};

const handleSearchResultItemClickEvent = (index: number) => setSelectedSearchResultItemIndex(index);
const clickHandlers: Record<string, (s: SearchResultItem) => void> = {
selectSearchResultItem: (s) =>
setSelectedSearchResultItemIndex(
filteredSearchResultItems.findIndex((searchResultItem) => searchResultItem.id === s.id),
),
invokeSearchResultItem: (s) => invokeAction(s.defaultAction),
};

const handleSearchResultItemClickEvent = (searchResultItem: SearchResultItem) => {
clickHandlers[singleClickBehavior](searchResultItem);
};

const handleSearchResultItemDoubleClickEvent = (searchResultItem: SearchResultItem) =>
searchResultItem.defaultAction && invokeAction(searchResultItem.defaultAction);
const handleSearchResultItemDoubleClickEvent = (searchResultItem: SearchResultItem) => {
clickHandlers[doubleClickBehavior](searchResultItem);
};

const closeConfirmationDialog = () => {
setConfirmationDialogAction(undefined);
Expand Down
4 changes: 2 additions & 2 deletions src/renderer/Core/Search/SearchResultList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type SearchResultListProps = {
searchResultItems: SearchResultItem[];
favorites: string[];
searchTerm?: string;
onSearchResultItemClick: (index: number) => void;
onSearchResultItemClick: (searchResultItem: SearchResultItem) => void;
onSearchResultItemDoubleClick: (searchResultItem: SearchResultItem) => void;
};

Expand Down Expand Up @@ -50,7 +50,7 @@ export const SearchResultList = ({
isSelected={selectedItemIndex === index}
isFavorite={favorites.includes(searchResultItem.id)}
searchResultItem={searchResultItem}
onClick={() => onSearchResultItemClick(index)}
onClick={() => onSearchResultItemClick(searchResultItem)}
onDoubleClick={() => onSearchResultItemDoubleClick(searchResultItem)}
/>
))}
Expand Down
60 changes: 60 additions & 0 deletions src/renderer/Core/Settings/Pages/KeyboardAndMouse.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { useSetting } from "@Core/Hooks";
import { Dropdown, Field, Option } from "@fluentui/react-components";
import { useTranslation } from "react-i18next";
import { Section } from "../Section";
import { SectionList } from "../SectionList";

export const KeyboardAndMouse = () => {
const { t } = useTranslation();
const ns = "settingsKeyboardAndMouse";

const { value: singleClickBehavior, updateValue: setSingleClickBehavior } = useSetting({
key: "keyboardAndMouse.singleClickBehavior",
defaultValue: "selectSearchResultItem",
});

const { value: doubleClickBehavior, updateValue: setDoubleClickBehavior } = useSetting({
key: "keyboardAndMouse.doubleClickBehavior",
defaultValue: "invokeSearchResultItem",
});

const clickBehaviorOptions: Record<string, string> = {
selectSearchResultItem: t("selectSearchResultItem", { ns }),
invokeSearchResultItem: t("invokeSearchResultItem", { ns }),
};

return (
<SectionList>
<Section>
<Field label={t("singleClickBehavior", { ns })}>
<Dropdown
selectedOptions={[singleClickBehavior]}
value={clickBehaviorOptions[singleClickBehavior]}
onOptionSelect={(_, { optionValue }) => optionValue && setSingleClickBehavior(optionValue)}
>
{Object.keys(clickBehaviorOptions).map((clickBehaviorOption) => (
<Option key={clickBehaviorOption} value={clickBehaviorOption}>
{clickBehaviorOptions[clickBehaviorOption]}
</Option>
))}
</Dropdown>
</Field>
</Section>
<Section>
<Field label={t("doubleClickBehavior", { ns })}>
<Dropdown
selectedOptions={[doubleClickBehavior]}
value={clickBehaviorOptions[doubleClickBehavior]}
onOptionSelect={(_, { optionValue }) => optionValue && setDoubleClickBehavior(optionValue)}
>
{Object.keys(clickBehaviorOptions).map((clickBehaviorOption) => (
<Option key={clickBehaviorOption} value={clickBehaviorOption}>
{clickBehaviorOptions[clickBehaviorOption]}
</Option>
))}
</Dropdown>
</Field>
</Section>
</SectionList>
);
};
37 changes: 23 additions & 14 deletions src/renderer/Core/Settings/Pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import {
AppsAddIn16Regular,
Bug16Regular,
Info16Regular,
PaintBrush16Regular,
Search16Regular,
Settings16Regular,
AppsAddInRegular,
BugRegular,
InfoRegular,
KeyboardMouse16Regular,
PaintBrushRegular,
SearchRegular,
SettingsRegular,
StarRegular,
Window16Regular,
WindowRegular,
} from "@fluentui/react-icons";
import type { ReactElement } from "react";
import { About } from "./About";
Expand All @@ -15,6 +16,7 @@ import { Debug } from "./Debug";
import { Extensions } from "./Extensions";
import { Favorites } from "./Favorites";
import { General } from "./General";
import { KeyboardAndMouse } from "./KeyboardAndMouse";
import { SearchEngine } from "./SearchEngine";
import { Window } from "./Window";

Expand All @@ -32,28 +34,35 @@ export const settingsPages: SettingsPage[] = [
relativePath: "general",
absolutePath: "/settings/general",
element: <General />,
icon: <Settings16Regular />,
icon: <SettingsRegular />,
},
{
translation: { key: "title", namespace: "settingsWindow" },
relativePath: "window",
absolutePath: "/settings/window",
element: <Window />,
icon: <Window16Regular />,
icon: <WindowRegular />,
},
{
translation: { key: "title", namespace: "settingsAppearance" },
relativePath: "appearance",
absolutePath: "/settings/appearance",
element: <Appearance />,
icon: <PaintBrush16Regular />,
icon: <PaintBrushRegular />,
},
{
translation: { key: "title", namespace: "settingsKeyboardAndMouse" },
absolutePath: "/settings/keyboard-and-mouse",
element: <KeyboardAndMouse />,
relativePath: "keyboard-and-mouse",
icon: <KeyboardMouse16Regular />,
},
{
translation: { key: "title", namespace: "settingsSearchEngine" },
relativePath: "search-engine",
absolutePath: "/settings/search-engine",
element: <SearchEngine />,
icon: <Search16Regular />,
icon: <SearchRegular />,
},
{
translation: { key: "title", namespace: "settingsFavorites" },
Expand All @@ -67,20 +76,20 @@ export const settingsPages: SettingsPage[] = [
relativePath: "extensions",
absolutePath: "/settings/extensions",
element: <Extensions />,
icon: <AppsAddIn16Regular />,
icon: <AppsAddInRegular />,
},
{
translation: { key: "title", namespace: "settingsAbout" },
relativePath: "about",
absolutePath: "/settings/about",
element: <About />,
icon: <Info16Regular />,
icon: <InfoRegular />,
},
{
translation: { key: "title", namespace: "settingsDebug" },
relativePath: "debug",
absolutePath: "/settings/debug",
element: <Debug />,
icon: <Bug16Regular />,
icon: <BugRegular />,
},
];

0 comments on commit 4f82b04

Please sign in to comment.