repo_description: A cross-platform desktop All-in-One assistant tool for Claude Code, Codex, OpenCode, openclaw & Gemini CLI.
repo_topics: ai-tools claude-code codex desktop-app mcp minimax omo open-source openclaw openclaw-ui opencode provider-management rust skills skills-management tauri typescript wsl-support
code: import { useState, useCallback } from "react";
  import { useTranslation } from "react-i18next";
  import { toast } from "sonner";
  import { promptsApi, type Prompt, type AppId } from "@/lib/api";
  
  export function usePromptActions(appId: AppId) {
    const { t } = useTranslation();
    const [prompts, setPrompts] = useState<Record<string, Prompt>>({});
    const [loading, setLoading] = useState(false);
    const [currentFileContent, setCurrentFileContent] = useState<string | null>(
      null,
    );
  
    const reload = useCallback(async () => {
      setLoading(true);
      try {
        const data = await promptsApi.getPrompts(appId);
        setPrompts(data);
  
        // 同时加载当前文件内容
        try {
          const content = await promptsApi.getCurrentFileContent(appId);
          setCurrentFileContent(content);
        } catch (error) {
          setCurrentFileContent(null);
        }
      } catch (error) {
        toast.error(t("prompts.loadFailed"));
      } finally {
        setLoading(false);
      }
    }, [appId, t]);
  
    const savePrompt = useCallback(
      async (id: string, prompt: Prompt) => {
        try {
          await promptsApi.upsertPrompt(appId, id, prompt);
          await reload();
          toast.success(t("prompts.saveSuccess"), { closeButton: true });
        } catch (error) {
          toast.error(t("prompts.saveFailed"));
          throw error;
        }
      },
      [appId, reload, t],
    );
  
    const deletePrompt = useCallback(
      async (id: string) => {
        try {
          await promptsApi.deletePrompt(appId, id);
          await reload();
          toast.success(t("prompts.deleteSuccess"), { closeButton: true });
        } catch (error) {
          toast.error(t("prompts.deleteFailed"));
          throw error;
        }
      },
      [appId, reload, t],
    );
  
    const enablePrompt = useCallback(
      async (id: string) => {
        try {
          await promptsApi.enablePrompt(appId, id);
          await reload();
          toast.success(t("prompts.enableSuccess"), { closeButton: true });
        } catch (error) {
          toast.error(t("prompts.enableFailed"));
          throw error;
        }
      },
      [appId, reload, t],
    );
  
    const toggleEnabled = useCallback(
      async (id: string, enabled: boolean) => {
        // Optimistic update
        const previousPrompts = prompts;
  
        // 如果要启用当前提示词，先禁用其他所有提示词
        if (enabled) {
          const updatedPrompts = Object.keys(prompts).reduce(
            (acc, key) => {
              acc[key] = {
                ...prompts[key],
                enabled: key === id,
              };
              return acc;
            },
            {} as Record<string, Prompt>,
          );
          setPrompts(updatedPrompts);
        } else {
          setPrompts((prev) => ({
            ...prev,
            [id]: {
              ...prev[id],
              enabled: false,
            },
          }));
        }
  
        try {
          if (enabled) {
            await promptsApi.enablePrompt(appId, id);
            toast.success(t("prompts.enableSuccess"), { closeButton: true });
          } else {
            // 禁用提示词 - 需要后端支持
            await promptsApi.upsertPrompt(appId, id, {
              ...prompts[id],
              enabled: false,
            });
            toast.success(t("prompts.disableSuccess"), { closeButton: true });
          }
          await reload();
        } catch (error) {
          // Rollback on failure
          setPrompts(previousPrompts);
          toast.error(
            enabled ? t("prompts.enableFailed") : t("prompts.disableFailed"),
          );
          throw error;
        }
      },
      [appId, prompts, reload, t],
    );
  
    const importFromFile = useCallback(async () => {
      try {
        const id = await promptsApi.importFromFile(appId);
        await reload();
        toast.success(t("prompts.importSuccess"), { closeButton: true });
        return id;
      } catch (error) {
        toast.error(t("prompts.importFailed"));
        throw error;
      }
    }, [appId, reload, t]);
  
    return {
      prompts,
      loading,
      currentFileContent,
      reload,
      savePrompt,
      deletePrompt,
      enablePrompt,
      toggleEnabled,
      importFromFile,
    };
  }
  