From 037e033f35277dcc94d135a42c2c47d2bc86c195 Mon Sep 17 00:00:00 2001 From: Weilin Cai <1261249659@qq.com> Date: Tue, 7 Apr 2026 16:02:23 +0800 Subject: [PATCH] fix: re-authorize recent project directories before opening --- apps/desktop/src-tauri/src/lib.rs | 17 +++++++++++++++ .../__tests__/stores/document-store.test.ts | 21 +++++++++++++++++++ apps/desktop/src/stores/document-store.ts | 2 ++ 3 files changed, 40 insertions(+) diff --git a/apps/desktop/src-tauri/src/lib.rs b/apps/desktop/src-tauri/src/lib.rs index 9f14f51..d720552 100644 --- a/apps/desktop/src-tauri/src/lib.rs +++ b/apps/desktop/src-tauri/src/lib.rs @@ -7,6 +7,7 @@ mod uv; mod zotero; use std::path::Path; +use tauri_plugin_fs::FsExt; use tauri::{Emitter, Manager, WebviewUrl, WebviewWindowBuilder}; /// Entry point for the `--tectonic-compile` subprocess mode. @@ -198,6 +199,21 @@ fn create_new_window(app: tauri::AppHandle) -> Result<(), String> { Ok(()) } +#[tauri::command] +fn allow_project_directory(app: tauri::AppHandle, root_path: String) -> Result<(), String> { + let fs_scope = app.fs_scope(); + fs_scope + .allow_directory(&root_path, true) + .map_err(|e| format!("Failed to allow project directory: {}", e))?; + + let asset_scope = app.state::(); + asset_scope + .allow_directory(&root_path, true) + .map_err(|e| format!("Failed to allow project assets: {}", e))?; + + Ok(()) +} + // --- Debug logging from JS (survives white-screen crashes) --- #[tauri::command] @@ -349,6 +365,7 @@ pub fn run() { }) .invoke_handler(tauri::generate_handler![ create_new_window, + allow_project_directory, detect_editors, open_in_editor, js_log, diff --git a/apps/desktop/src/__tests__/stores/document-store.test.ts b/apps/desktop/src/__tests__/stores/document-store.test.ts index 43b9e76..929dd71 100644 --- a/apps/desktop/src/__tests__/stores/document-store.test.ts +++ b/apps/desktop/src/__tests__/stores/document-store.test.ts @@ -1,4 +1,6 @@ import { describe, it, expect, beforeEach, vi } from "vitest"; +import { invoke } from "@tauri-apps/api/core"; +import { readDir, readTextFile } from "@tauri-apps/plugin-fs"; import { writeTextFile } from "@tauri-apps/plugin-fs"; import { useDocumentStore, @@ -42,6 +44,7 @@ function makeFile(overrides: Partial = {}): ProjectFile { describe("useDocumentStore", () => { beforeEach(() => { + vi.clearAllMocks(); clearPdfBytesCache(); useDocumentStore.setState({ projectRoot: "/project", @@ -83,6 +86,24 @@ describe("useDocumentStore", () => { }); }); + describe("openProject", () => { + it("re-authorizes the project directory before scanning", async () => { + vi.mocked(invoke).mockResolvedValue(undefined); + vi.mocked(readDir).mockResolvedValue([ + { name: "main.tex", isDirectory: false }, + ] as any); + vi.mocked(readTextFile).mockResolvedValue("\\documentclass{article}"); + + await useDocumentStore + .getState() + .openProject("E:/overleaf-cache/论文项目"); + + expect(invoke).toHaveBeenCalledWith("allow_project_directory", { + rootPath: "E:/overleaf-cache/论文项目", + }); + }); + }); + describe("insertAtCursor", () => { it("inserts text at cursor position", () => { useDocumentStore.getState().insertAtCursor(", Beautiful"); diff --git a/apps/desktop/src/stores/document-store.ts b/apps/desktop/src/stores/document-store.ts index 32cecc8..12c582d 100644 --- a/apps/desktop/src/stores/document-store.ts +++ b/apps/desktop/src/stores/document-store.ts @@ -1,4 +1,5 @@ import { create } from "zustand"; +import { invoke } from "@tauri-apps/api/core"; import { scanProjectFolder, readTexFileContent, @@ -266,6 +267,7 @@ export const useDocumentStore = create()((set, get) => ({ openProject: async (rootPath: string) => { log.info(`Opening project: ${rootPath}`); + await invoke("allow_project_directory", { rootPath }); const { files: fsFiles, folders: fsFolders } = await scanProjectFolder(rootPath); const projectFiles: ProjectFile[] = [];