Fix desktop slash commands (#8341)
Signed-off-by: Douwe Osinga <douwe@squareup.com> Co-authored-by: Douwe Osinga <douwe@squareup.com>
This commit is contained in:
@@ -17,6 +17,10 @@ const i18n = defineMessages({
|
|||||||
id: 'mentionPopover.scanningFiles',
|
id: 'mentionPopover.scanningFiles',
|
||||||
defaultMessage: 'Scanning files...',
|
defaultMessage: 'Scanning files...',
|
||||||
},
|
},
|
||||||
|
loadingCommands: {
|
||||||
|
id: 'mentionPopover.loadingCommands',
|
||||||
|
defaultMessage: 'Loading commands...',
|
||||||
|
},
|
||||||
itemsFound: {
|
itemsFound: {
|
||||||
id: 'mentionPopover.itemsFound',
|
id: 'mentionPopover.itemsFound',
|
||||||
defaultMessage: '{count, plural, one {# item} other {# items}} found',
|
defaultMessage: '{count, plural, one {# item} other {# items}} found',
|
||||||
@@ -25,6 +29,10 @@ const i18n = defineMessages({
|
|||||||
id: 'mentionPopover.noItemsFound',
|
id: 'mentionPopover.noItemsFound',
|
||||||
defaultMessage: 'No items found matching "{query}"',
|
defaultMessage: 'No items found matching "{query}"',
|
||||||
},
|
},
|
||||||
|
noCommandsFound: {
|
||||||
|
id: 'mentionPopover.noCommandsFound',
|
||||||
|
defaultMessage: 'No commands found matching "{query}"',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
type DisplayItemType = CommandType | 'Directory' | 'File';
|
type DisplayItemType = CommandType | 'Directory' | 'File';
|
||||||
@@ -374,30 +382,11 @@ const MentionPopover = forwardRef<
|
|||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
const scanFilesFromRoot = useCallback(async () => {
|
const getDefaultStartPath = (): string => {
|
||||||
setIsLoading(true);
|
if (window.electron.platform === 'win32') return 'C:\\Users';
|
||||||
try {
|
if (window.electron.platform === 'linux') return '/home';
|
||||||
let startPath = currentWorkingDir;
|
return '/Users';
|
||||||
|
};
|
||||||
if (!startPath) {
|
|
||||||
if (window.electron.platform === 'win32') {
|
|
||||||
startPath = 'C:\\Users';
|
|
||||||
} else if (window.electron.platform === 'linux') {
|
|
||||||
startPath = '/home';
|
|
||||||
} else {
|
|
||||||
startPath = '/Users'; // Default to macOS
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const scannedFiles = await scanDirectoryFromRoot(startPath);
|
|
||||||
setItems(scannedFiles);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error scanning items from root:', error);
|
|
||||||
setItems([]);
|
|
||||||
} finally {
|
|
||||||
setIsLoading(false);
|
|
||||||
}
|
|
||||||
}, [scanDirectoryFromRoot, currentWorkingDir]);
|
|
||||||
|
|
||||||
const compareByType = (a: DisplayItemWithMatch, b: DisplayItemWithMatch) => {
|
const compareByType = (a: DisplayItemWithMatch, b: DisplayItemWithMatch) => {
|
||||||
const orderA = typeOrder[a.itemType] ?? Number.MAX_SAFE_INTEGER;
|
const orderA = typeOrder[a.itemType] ?? Number.MAX_SAFE_INTEGER;
|
||||||
@@ -485,28 +474,50 @@ const MentionPopover = forwardRef<
|
|||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
let cancelled = false;
|
||||||
|
|
||||||
const loadData = async () => {
|
const loadData = async () => {
|
||||||
if (isSlashCommand) {
|
setItems([]);
|
||||||
const response = await getSlashCommands({
|
setIsLoading(true);
|
||||||
query: { working_dir: currentWorkingDir },
|
try {
|
||||||
throwOnError: true,
|
if (isSlashCommand) {
|
||||||
});
|
const response = await getSlashCommands({
|
||||||
const commandItems: DisplayItem[] = (response.data?.commands || []).map((cmd) => ({
|
query: { working_dir: currentWorkingDir },
|
||||||
name: cmd.command,
|
throwOnError: true,
|
||||||
extra: cmd.help,
|
});
|
||||||
itemType: cmd.command_type,
|
if (cancelled) return;
|
||||||
relativePath: cmd.command,
|
const commandItems: DisplayItem[] = (response.data?.commands || []).map((cmd) => ({
|
||||||
}));
|
name: cmd.command,
|
||||||
setItems(commandItems);
|
extra: cmd.help,
|
||||||
} else {
|
itemType: cmd.command_type,
|
||||||
await scanFilesFromRoot();
|
relativePath: cmd.command,
|
||||||
|
}));
|
||||||
|
setItems(commandItems);
|
||||||
|
} else {
|
||||||
|
const scannedFiles = await scanDirectoryFromRoot(currentWorkingDir || getDefaultStartPath());
|
||||||
|
if (cancelled) return;
|
||||||
|
setItems(scannedFiles);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
if (!cancelled) {
|
||||||
|
console.error('Error loading popover items:', error);
|
||||||
|
setItems([]);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (!cancelled) {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isOpen) {
|
if (isOpen) {
|
||||||
loadData();
|
loadData();
|
||||||
}
|
}
|
||||||
}, [isOpen, isSlashCommand, scanFilesFromRoot, currentWorkingDir]);
|
|
||||||
|
return () => {
|
||||||
|
cancelled = true;
|
||||||
|
};
|
||||||
|
}, [isOpen, isSlashCommand, scanDirectoryFromRoot, currentWorkingDir]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleClickOutside = (event: MouseEvent) => {
|
const handleClickOutside = (event: MouseEvent) => {
|
||||||
@@ -561,7 +572,7 @@ const MentionPopover = forwardRef<
|
|||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<div className="flex items-center justify-center py-4">
|
<div className="flex items-center justify-center py-4">
|
||||||
<div className="animate-spin rounded-full h-4 w-4 border-t-2 border-b-2"></div>
|
<div className="animate-spin rounded-full h-4 w-4 border-t-2 border-b-2"></div>
|
||||||
<span className="ml-2 text-sm text-text-secondary">{intl.formatMessage(i18n.scanningFiles)}</span>
|
<span className="ml-2 text-sm text-text-secondary">{intl.formatMessage(isSlashCommand ? i18n.loadingCommands : i18n.scanningFiles)}</span>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
@@ -596,7 +607,7 @@ const MentionPopover = forwardRef<
|
|||||||
|
|
||||||
{!isLoading && displayItems.length === 0 && query && (
|
{!isLoading && displayItems.length === 0 && query && (
|
||||||
<div className="p-4 text-center text-text-secondary text-sm">
|
<div className="p-4 text-center text-text-secondary text-sm">
|
||||||
{intl.formatMessage(i18n.noItemsFound, { query })}
|
{intl.formatMessage(isSlashCommand ? i18n.noCommandsFound : i18n.noItemsFound, { query })}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2021,6 +2021,12 @@
|
|||||||
"mentionPopover.itemsFound": {
|
"mentionPopover.itemsFound": {
|
||||||
"defaultMessage": "{count,plural,one{# item found} other{# items found}}"
|
"defaultMessage": "{count,plural,one{# item found} other{# items found}}"
|
||||||
},
|
},
|
||||||
|
"mentionPopover.loadingCommands": {
|
||||||
|
"defaultMessage": "Loading commands..."
|
||||||
|
},
|
||||||
|
"mentionPopover.noCommandsFound": {
|
||||||
|
"defaultMessage": "No commands found matching \"{query}\""
|
||||||
|
},
|
||||||
"mentionPopover.noItemsFound": {
|
"mentionPopover.noItemsFound": {
|
||||||
"defaultMessage": "No items found matching \"{query}\""
|
"defaultMessage": "No items found matching \"{query}\""
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user