feat: expose assistant global shortcuts

This commit is contained in:
ajnart committed 2026-08-14 11:32:10 +02:00
1 parent 4b647ec2c9
commit 73e4b80a26
9 files changed
+90 -28

No files matched your search

@@ -22,6 +22,7 @@ import type { inferSearchInteractionOptions } from "../lib/interaction";
import type { SearchMode } from "../lib/mode";
import { searchModes } from "../modes";
import { useHomeEmptyGroupsWithPreferences } from "../modes/help/home-empty-groups";
import { contextSpecificSearchGroups } from "../modes/home/context-specific-group";
import { mediaRequestSearchScopeAtom, selectAction, spotlightActions, spotlightStore } from "../spotlight-store";
import { SpotlightChildrenActions } from "./actions/children-actions";
import { SpotlightActionGroups } from "./actions/groups/action-group";
@@ -244,7 +245,9 @@ const SpotlightWithActiveMode = ({ modeState, queryState, activeMode }: Spotligh
pushChildrenOptions(options);
}}
query={query}
groups={mode === defaultMode && query.length === 0 ? [...homeEmptyGroups] : groups}
groups={
mode === defaultMode && query.length === 0 ? [...homeEmptyGroups, contextSpecificSearchGroups] : groups
}
/>
)}
</MantineSpotlight.ActionsList>
@@ -29,8 +29,8 @@ export const contextSpecificActionsSearchGroups = createGroup<ContextSpecificIte
</Group>
);
},
useInteraction(option) {
return option.interaction();
useInteraction(option, query) {
return option.interaction(query);
},
filter(query, option) {
return option.name.toLowerCase().includes(query.toLowerCase());
@@ -0,0 +1,25 @@
import { describe, expect, test } from "vitest";
import type { ContextSpecificItem } from "./context";
import { shouldShowContextSpecificResult } from "./context-specific-group";
const item = (overrides: Partial<ContextSpecificItem> = {}): ContextSpecificItem => ({
id: "result",
name: "Matching result",
icon: "/icon.png",
interaction: () => ({ type: "none" }),
...overrides,
});
describe("contextSpecificSearchGroups", () => {
test("keeps an always-visible fallback in every default search", () => {
expect(shouldShowContextSpecificResult("unrelated query", item({ alwaysVisible: true }))).toBe(true);
expect(shouldShowContextSpecificResult("", item({ alwaysVisible: true }))).toBe(true);
});
test("shows ordinary local results only when their names match", () => {
expect(shouldShowContextSpecificResult("matching", item())).toBe(true);
expect(shouldShowContextSpecificResult("unrelated query", item())).toBe(false);
expect(shouldShowContextSpecificResult("", item())).toBe(false);
});
});
@@ -4,6 +4,12 @@ import { createGroup } from "../../lib/group";
import type { ContextSpecificItem } from "./context";
import { useSpotlightContextResults } from "./context";
export const shouldShowContextSpecificResult = (query: string, option: ContextSpecificItem) => {
if (option.alwaysVisible) return true;
if (query.length === 0) return false;
return option.name.toLowerCase().includes(query.toLowerCase());
};
export const contextSpecificSearchGroups = createGroup<ContextSpecificItem>({
title: (t) => t("search.mode.home.group.local.title"),
keyPath: "id",
@@ -29,12 +35,10 @@ export const contextSpecificSearchGroups = createGroup<ContextSpecificItem>({
</Group>
);
},
useInteraction(option) {
return option.interaction();
},
filter(query, option) {
return option.name.toLowerCase().includes(query.toLowerCase());
useInteraction(option, query) {
return option.interaction(query);
},
filter: shouldShowContextSpecificResult,
useOptions() {
return useSpotlightContextResults();
},
@@ -10,10 +10,11 @@ export type ContextSpecificItem = {
id: string;
name: string;
icon: TablerIcon | string;
interaction: () => inferSearchInteractionDefinition<SearchInteraction>;
interaction: (query: string) => inferSearchInteractionDefinition<SearchInteraction>;
disabled?: boolean;
description?: string;
unavailable?: boolean;
alwaysVisible?: boolean;
};
interface SpotlightContextProps {