mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-05-16 17:59:32 +08:00
feat(workspace): make directory paths clickable and rename "Today's Note" to "Add Memory"
Add open_workspace_directory Tauri command to open workspace/memory dirs in the system file manager. Rename dailyMemory.createToday across all locales.
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
use regex::Regex;
|
||||
use std::sync::LazyLock;
|
||||
use tauri::AppHandle;
|
||||
use tauri_plugin_opener::OpenerExt;
|
||||
|
||||
use crate::config::write_text_file;
|
||||
use crate::openclaw_config::get_openclaw_dir;
|
||||
@@ -336,3 +338,25 @@ pub async fn write_workspace_file(filename: String, content: String) -> Result<(
|
||||
write_text_file(&path, &content)
|
||||
.map_err(|e| format!("Failed to write workspace file {filename}: {e}"))
|
||||
}
|
||||
|
||||
/// Open the workspace or memory directory in the system file manager.
|
||||
/// `subdir`: "workspace" opens `~/.openclaw/workspace/`,
|
||||
/// "memory" opens `~/.openclaw/workspace/memory/`.
|
||||
#[tauri::command]
|
||||
pub async fn open_workspace_directory(handle: AppHandle, subdir: String) -> Result<bool, String> {
|
||||
let dir = match subdir.as_str() {
|
||||
"memory" => get_openclaw_dir().join("workspace").join("memory"),
|
||||
_ => get_openclaw_dir().join("workspace"),
|
||||
};
|
||||
|
||||
if !dir.exists() {
|
||||
std::fs::create_dir_all(&dir).map_err(|e| format!("Failed to create directory: {e}"))?;
|
||||
}
|
||||
|
||||
handle
|
||||
.opener()
|
||||
.open_path(dir.to_string_lossy().to_string(), None::<String>)
|
||||
.map_err(|e| format!("Failed to open directory: {e}"))?;
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
@@ -1052,6 +1052,7 @@ pub fn run() {
|
||||
commands::write_daily_memory_file,
|
||||
commands::delete_daily_memory_file,
|
||||
commands::search_daily_memory_files,
|
||||
commands::open_workspace_directory,
|
||||
]);
|
||||
|
||||
let app = builder
|
||||
|
||||
@@ -7,7 +7,7 @@ import React, {
|
||||
} from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { toast } from "sonner";
|
||||
import { Calendar, Trash2, Plus, Search, X } from "lucide-react";
|
||||
import { Calendar, Trash2, Plus, Search, X, FolderOpen } from "lucide-react";
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
@@ -352,8 +352,13 @@ const DailyMemoryPanel: React.FC<DailyMemoryPanelProps> = ({
|
||||
<div className="space-y-4">
|
||||
{/* Header with path, search, and create button */}
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<p className="text-sm text-muted-foreground shrink-0">
|
||||
<p
|
||||
className="text-sm text-muted-foreground shrink-0 cursor-pointer hover:text-foreground transition-colors inline-flex items-center gap-1"
|
||||
onClick={() => workspaceApi.openDirectory("memory")}
|
||||
title={t("workspace.openDirectory")}
|
||||
>
|
||||
~/.openclaw/workspace/memory/
|
||||
<FolderOpen className="w-3.5 h-3.5" />
|
||||
</p>
|
||||
<div className="flex items-center gap-1.5">
|
||||
<Button
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
Circle,
|
||||
Calendar,
|
||||
ChevronRight,
|
||||
FolderOpen,
|
||||
} from "lucide-react";
|
||||
import type { LucideIcon } from "lucide-react";
|
||||
import { workspaceApi } from "@/lib/api/workspace";
|
||||
@@ -83,8 +84,13 @@ const WorkspaceFilesPanel: React.FC = () => {
|
||||
|
||||
return (
|
||||
<div className="px-6 pt-4 pb-8">
|
||||
<p className="text-sm text-muted-foreground mb-6">
|
||||
<p
|
||||
className="text-sm text-muted-foreground mb-6 cursor-pointer hover:text-foreground transition-colors inline-flex items-center gap-1"
|
||||
onClick={() => workspaceApi.openDirectory("workspace")}
|
||||
title={t("workspace.openDirectory")}
|
||||
>
|
||||
~/.openclaw/workspace/
|
||||
<FolderOpen className="w-3.5 h-3.5" />
|
||||
</p>
|
||||
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
|
||||
|
||||
@@ -1193,12 +1193,13 @@
|
||||
"saveSuccess": "Saved successfully",
|
||||
"saveFailed": "Failed to save",
|
||||
"loadFailed": "Failed to load",
|
||||
"openDirectory": "Open in file manager",
|
||||
"dailyMemory": {
|
||||
"title": "Daily Memory",
|
||||
"sectionTitle": "Daily Memory",
|
||||
"cardTitle": "Daily Memory Files",
|
||||
"cardDescription": "Browse & manage daily memories",
|
||||
"createToday": "Today's Note",
|
||||
"createToday": "Add Memory",
|
||||
"empty": "No daily memory files yet",
|
||||
"loadFailed": "Failed to load daily memory files",
|
||||
"createFailed": "Failed to create daily memory file",
|
||||
|
||||
@@ -1193,12 +1193,13 @@
|
||||
"saveSuccess": "保存しました",
|
||||
"saveFailed": "保存に失敗しました",
|
||||
"loadFailed": "読み込みに失敗しました",
|
||||
"openDirectory": "ファイルマネージャーで開く",
|
||||
"dailyMemory": {
|
||||
"title": "デイリーメモリー",
|
||||
"sectionTitle": "デイリーメモリー",
|
||||
"cardTitle": "デイリーメモリーファイル",
|
||||
"cardDescription": "デイリーメモリーの閲覧・管理",
|
||||
"createToday": "今日のノート",
|
||||
"createToday": "メモリーを追加",
|
||||
"empty": "デイリーメモリーファイルはまだありません",
|
||||
"loadFailed": "デイリーメモリーファイルの読み込みに失敗しました",
|
||||
"createFailed": "デイリーメモリーファイルの作成に失敗しました",
|
||||
|
||||
@@ -1193,12 +1193,13 @@
|
||||
"saveSuccess": "保存成功",
|
||||
"saveFailed": "保存失败",
|
||||
"loadFailed": "读取失败",
|
||||
"openDirectory": "在文件管理器中打开",
|
||||
"dailyMemory": {
|
||||
"title": "每日记忆",
|
||||
"sectionTitle": "每日记忆",
|
||||
"cardTitle": "每日记忆文件",
|
||||
"cardDescription": "浏览管理每日记忆",
|
||||
"createToday": "今日笔记",
|
||||
"createToday": "添加记忆",
|
||||
"empty": "暂无每日记忆文件",
|
||||
"loadFailed": "加载每日记忆文件失败",
|
||||
"createFailed": "创建每日记忆文件失败",
|
||||
|
||||
@@ -49,4 +49,8 @@ export const workspaceApi = {
|
||||
query,
|
||||
});
|
||||
},
|
||||
|
||||
async openDirectory(subdir: "workspace" | "memory"): Promise<void> {
|
||||
await invoke("open_workspace_directory", { subdir });
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user