mirror of
https://github.com/purrgrammer/grimoire.git
synced 2026-04-10 15:36:53 +02:00
* feat: add clickable example commands to welcome screen Add 4 example commands to the welcome splash screen to make the client more friendly on cold start and to new users: - nip 29: View relay-based groups spec - profile verbiricha@habla.news: Explore a Nostr profile - req -k 1 -l 20: Query recent notes - nips: Browse all NIPs Commands are clickable and execute directly, opening the appropriate window without requiring users to type or use the command palette. Changes: - Update GrimoireWelcome component with EXAMPLE_COMMANDS constant - Add onExecuteCommand prop to handle direct command execution - Update WorkspaceView to pass handleExecuteCommand callback - Use parseAndExecuteCommand from command-parser for execution * fix: lint --------- Co-authored-by: Claude <noreply@anthropic.com>
91 lines
2.3 KiB
TypeScript
91 lines
2.3 KiB
TypeScript
import { useGrimoire } from "@/core/state";
|
|
import { Mosaic, MosaicWindow, MosaicBranch } from "react-mosaic-component";
|
|
import { WindowToolbar } from "./WindowToolbar";
|
|
import { WindowTile } from "./WindowTitle";
|
|
import { GrimoireWelcome } from "./GrimoireWelcome";
|
|
import { useAppShell } from "./layouts/AppShellContext";
|
|
import { parseAndExecuteCommand } from "@/lib/command-parser";
|
|
|
|
export function WorkspaceView() {
|
|
const { state, updateLayout, removeWindow, addWindow } = useGrimoire();
|
|
const { openCommandLauncher } = useAppShell();
|
|
|
|
const handleRemoveWindow = (id: string) => {
|
|
removeWindow(id);
|
|
};
|
|
|
|
const handleExecuteCommand = async (commandString: string) => {
|
|
const result = await parseAndExecuteCommand(
|
|
commandString,
|
|
state.activeAccount?.pubkey,
|
|
);
|
|
|
|
if (result.error || !result.props || !result.command) {
|
|
console.error("Failed to execute command:", result.error);
|
|
return;
|
|
}
|
|
|
|
addWindow(
|
|
result.command.appId,
|
|
result.props,
|
|
commandString,
|
|
result.globalFlags?.windowProps?.title,
|
|
);
|
|
};
|
|
|
|
const renderTile = (id: string, path: MosaicBranch[]) => {
|
|
const window = state.windows[id];
|
|
|
|
if (!window) {
|
|
return (
|
|
<MosaicWindow
|
|
path={path}
|
|
title="Unknown Window"
|
|
toolbarControls={<WindowToolbar />}
|
|
>
|
|
<div className="p-4 text-muted-foreground">
|
|
Window not found: {id}
|
|
</div>
|
|
</MosaicWindow>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<WindowTile
|
|
id={id}
|
|
window={window}
|
|
path={path}
|
|
onClose={handleRemoveWindow}
|
|
onEditCommand={openCommandLauncher}
|
|
/>
|
|
);
|
|
};
|
|
|
|
const activeWorkspace = state.workspaces[state.activeWorkspaceId];
|
|
|
|
if (!activeWorkspace) return null;
|
|
|
|
return (
|
|
<>
|
|
{activeWorkspace.layout === null ? (
|
|
<GrimoireWelcome
|
|
onLaunchCommand={openCommandLauncher}
|
|
onExecuteCommand={handleExecuteCommand}
|
|
/>
|
|
) : (
|
|
<Mosaic
|
|
renderTile={renderTile}
|
|
value={activeWorkspace.layout}
|
|
onChange={updateLayout}
|
|
onRelease={(node) => {
|
|
if (typeof node === "string") {
|
|
handleRemoveWindow(node);
|
|
}
|
|
}}
|
|
className="mosaic-blueprint-theme"
|
|
/>
|
|
)}
|
|
</>
|
|
);
|
|
}
|