From e1be08cb762520e7ddc938469df2f52dbb1d897c Mon Sep 17 00:00:00 2001 From: haex Date: Sun, 9 Nov 2025 23:58:40 +0100 Subject: [PATCH] Add openFile support for opening files with system viewer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added new filesystem handler for opening files with the system's default viewer: - Implemented haextension.fs.openFile handler in filesystem.ts - Writes files to temp directory and opens with openPath from opener plugin - Added Tauri permissions: opener:allow-open-path with $TEMP/** scope - Added filesystem permissions for temp directory access This enables extensions to open files (like images) in the native system viewer where users can zoom and interact with them naturally. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src-tauri/capabilities/default.json | 13 ++++++++- src-tauri/gen/schemas/capabilities.json | 2 +- src/composables/handlers/filesystem.ts | 35 +++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index a96e6d8..20aeb6b 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -30,10 +30,15 @@ "fs:allow-resource-write-recursive", "fs:allow-download-read-recursive", "fs:allow-download-write-recursive", + "fs:allow-temp-read-recursive", + "fs:allow-temp-write-recursive", "fs:default", { "identifier": "fs:scope", - "allow": [{ "path": "**" }] + "allow": [ + { "path": "**" }, + { "path": "$TEMP/**" } + ] }, "http:allow-fetch-send", "http:allow-fetch", @@ -44,6 +49,12 @@ "notification:allow-is-permission-granted", "notification:default", "opener:allow-open-url", + { + "identifier": "opener:allow-open-path", + "allow": [ + { "path": "$TEMP/**" } + ] + }, "opener:default", "os:allow-hostname", "os:default", diff --git a/src-tauri/gen/schemas/capabilities.json b/src-tauri/gen/schemas/capabilities.json index 8e86d50..c70aff2 100644 --- a/src-tauri/gen/schemas/capabilities.json +++ b/src-tauri/gen/schemas/capabilities.json @@ -1 +1 @@ -{"default":{"identifier":"default","description":"Capability for the main window","local":true,"windows":["main"],"permissions":["core:default","core:webview:allow-create-webview-window","core:webview:allow-create-webview","core:webview:allow-webview-show","core:webview:default","core:window:allow-create","core:window:allow-get-all-windows","core:window:allow-show","core:window:default","dialog:default","fs:allow-appconfig-read-recursive","fs:allow-appconfig-write-recursive","fs:allow-appdata-read-recursive","fs:allow-appdata-write-recursive","fs:allow-applocaldata-read-recursive","fs:allow-applocaldata-write-recursive","fs:allow-read-file","fs:allow-write-file","fs:allow-read-dir","fs:allow-mkdir","fs:allow-exists","fs:allow-remove","fs:allow-resource-read-recursive","fs:allow-resource-write-recursive","fs:allow-download-read-recursive","fs:allow-download-write-recursive","fs:default",{"identifier":"fs:scope","allow":[{"path":"**"}]},"http:allow-fetch-send","http:allow-fetch","http:default","notification:allow-create-channel","notification:allow-list-channels","notification:allow-notify","notification:allow-is-permission-granted","notification:default","opener:allow-open-url","opener:default","os:allow-hostname","os:default","store:default"]}} \ No newline at end of file +{"default":{"identifier":"default","description":"Capability for the main window","local":true,"windows":["main"],"permissions":["core:default","core:webview:allow-create-webview-window","core:webview:allow-create-webview","core:webview:allow-webview-show","core:webview:default","core:window:allow-create","core:window:allow-get-all-windows","core:window:allow-show","core:window:default","dialog:default","fs:allow-appconfig-read-recursive","fs:allow-appconfig-write-recursive","fs:allow-appdata-read-recursive","fs:allow-appdata-write-recursive","fs:allow-applocaldata-read-recursive","fs:allow-applocaldata-write-recursive","fs:allow-read-file","fs:allow-write-file","fs:allow-read-dir","fs:allow-mkdir","fs:allow-exists","fs:allow-remove","fs:allow-resource-read-recursive","fs:allow-resource-write-recursive","fs:allow-download-read-recursive","fs:allow-download-write-recursive","fs:allow-temp-read-recursive","fs:allow-temp-write-recursive","fs:default",{"identifier":"fs:scope","allow":[{"path":"**"},{"path":"$TEMP/**"}]},"http:allow-fetch-send","http:allow-fetch","http:default","notification:allow-create-channel","notification:allow-list-channels","notification:allow-notify","notification:allow-is-permission-granted","notification:default","opener:allow-open-url",{"identifier":"opener:allow-open-path","allow":[{"path":"$TEMP/**"}]},"opener:default","os:allow-hostname","os:default","store:default"]}} \ No newline at end of file diff --git a/src/composables/handlers/filesystem.ts b/src/composables/handlers/filesystem.ts index a429f68..7d1d4f1 100644 --- a/src/composables/handlers/filesystem.ts +++ b/src/composables/handlers/filesystem.ts @@ -1,5 +1,7 @@ import { save } from '@tauri-apps/plugin-dialog' import { writeFile } from '@tauri-apps/plugin-fs' +import { openPath } from '@tauri-apps/plugin-opener' +import { tempDir, join } from '@tauri-apps/api/path' import type { IHaexHubExtension } from '~/types/haexhub' import type { ExtensionRequest } from './types' @@ -42,6 +44,39 @@ export async function handleFilesystemMethodAsync( } } + case 'haextension.fs.openFile': { + const params = request.params as { + data: number[] + fileName: string + mimeType?: string + } + + try { + // Convert number array back to Uint8Array + const data = new Uint8Array(params.data) + + // Get temp directory and create file path + const tempDirPath = await tempDir() + const tempFilePath = await join(tempDirPath, params.fileName) + + // Write file to temp directory + await writeFile(tempFilePath, data) + + // Open file with system's default viewer + await openPath(tempFilePath) + + return { + success: true, + } + } + catch (error) { + console.error('[Filesystem] Error opening file:', error) + return { + success: false, + } + } + } + default: throw new Error(`Unknown filesystem method: ${request.method}`) }