diff --git a/Cargo.lock b/Cargo.lock index 35add73cdb..c6c852072f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4326,6 +4326,7 @@ dependencies = [ "tauri-plugin-dialog", "tauri-plugin-extensions", "tauri-plugin-flag", + "tauri-plugin-fs", "tauri-plugin-fs-db", "tauri-plugin-fs-sync", "tauri-plugin-fs2", diff --git a/Cargo.toml b/Cargo.toml index fa5a7b3730..aefa82bc9f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -124,6 +124,7 @@ tauri-plugin-autostart = "2.5" tauri-plugin-clipboard-manager = "2.3" tauri-plugin-deep-link = "2.4" tauri-plugin-dialog = "2.3" +tauri-plugin-fs = "2.2" tauri-plugin-http = { version = "2.5", features = ["unsafe-headers"] } tauri-plugin-opener = "2.5" tauri-plugin-os = "2.3" diff --git a/apps/desktop/package.json b/apps/desktop/package.json index ccb0385800..47e70efc0d 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -44,6 +44,7 @@ "@hypr/plugin-deeplink2": "workspace:*", "@hypr/plugin-detect": "workspace:*", "@hypr/plugin-extensions": "workspace:*", + "@hypr/plugin-flag": "workspace:*", "@hypr/plugin-fs-db": "workspace:*", "@hypr/plugin-fs-sync": "workspace:*", "@hypr/plugin-fs2": "workspace:*", @@ -72,7 +73,6 @@ "@hypr/plugin-tracing": "workspace:*", "@hypr/plugin-updater2": "workspace:*", "@hypr/plugin-windows": "workspace:*", - "@hypr/plugin-flag": "workspace:*", "@hypr/store": "workspace:*", "@hypr/tinybase-utils": "workspace:*", "@hypr/tiptap": "workspace:^", @@ -96,6 +96,7 @@ "@tauri-apps/plugin-autostart": "^2.5.1", "@tauri-apps/plugin-deep-link": "^2.4.6", "@tauri-apps/plugin-dialog": "^2.6.0", + "@tauri-apps/plugin-fs": "^2.4.5", "@tauri-apps/plugin-http": "^2.5.6", "@tauri-apps/plugin-opener": "^2.5.3", "@tauri-apps/plugin-os": "^2.3.2", diff --git a/apps/desktop/src-tauri/Cargo.toml b/apps/desktop/src-tauri/Cargo.toml index 0184110807..83ff6632e4 100644 --- a/apps/desktop/src-tauri/Cargo.toml +++ b/apps/desktop/src-tauri/Cargo.toml @@ -37,6 +37,7 @@ tauri-plugin-detect = { workspace = true } tauri-plugin-dialog = { workspace = true } tauri-plugin-extensions = { workspace = true } tauri-plugin-flag = { workspace = true } +tauri-plugin-fs = { workspace = true } tauri-plugin-fs-db = { workspace = true } tauri-plugin-fs-sync = { workspace = true } tauri-plugin-fs2 = { workspace = true } diff --git a/apps/desktop/src-tauri/capabilities/default.json b/apps/desktop/src-tauri/capabilities/default.json index 70d531f762..5cff3f8a90 100644 --- a/apps/desktop/src-tauri/capabilities/default.json +++ b/apps/desktop/src-tauri/capabilities/default.json @@ -67,6 +67,8 @@ ] }, "misc:default", + "fs:default", + "fs:allow-write-text-file", "fs-db:default", "fs-sync:default", "fs2:default", diff --git a/apps/desktop/src-tauri/src/lib.rs b/apps/desktop/src-tauri/src/lib.rs index 76a0c104f7..7b2a8628de 100644 --- a/apps/desktop/src-tauri/src/lib.rs +++ b/apps/desktop/src-tauri/src/lib.rs @@ -77,6 +77,7 @@ pub async fn main() { .plugin(tauri_plugin_opener::init()) .plugin(tauri_plugin_opener2::init()) .plugin(tauri_plugin_dialog::init()) + .plugin(tauri_plugin_fs::init()) .plugin(tauri_plugin_analytics::init()) .plugin(tauri_plugin_bedrock::init()) .plugin(tauri_plugin_importer::init()) diff --git a/apps/desktop/src/components/feedback/feedback-modal.tsx b/apps/desktop/src/components/feedback/feedback-modal.tsx index 39266e7582..96ba51b6d2 100644 --- a/apps/desktop/src/components/feedback/feedback-modal.tsx +++ b/apps/desktop/src/components/feedback/feedback-modal.tsx @@ -1,3 +1,6 @@ +import { downloadDir } from "@tauri-apps/api/path"; +import { save } from "@tauri-apps/plugin-dialog"; +import { writeTextFile } from "@tauri-apps/plugin-fs"; import { arch, version as osVersion, platform } from "@tauri-apps/plugin-os"; import { Bug, Lightbulb, X } from "lucide-react"; import { useCallback, useEffect, useState } from "react"; @@ -42,7 +45,6 @@ export function FeedbackModal() { const [type, setType] = useState(initialType); const [description, setDescription] = useState(""); const [isSubmitting, setIsSubmitting] = useState(false); - const [gitHash, setGitHash] = useState(""); const [attachLogs, setAttachLogs] = useState(false); useEffect(() => { @@ -64,12 +66,8 @@ export function FeedbackModal() { useEffect(() => { if (isOpen) { setType(initialType); - miscCommands.getGitHash().then((result) => { - setGitHash(result.status === "ok" ? result.data : "unknown"); - }); } else { setDescription(""); - setGitHash(""); setAttachLogs(false); } }, [isOpen, initialType]); @@ -99,26 +97,20 @@ export function FeedbackModal() { const title = firstLine || (type === "bug" ? "Bug Report" : "Feature Request"); - let logSection = ""; - if (attachLogs) { - const logContent = await getLogContent(); - if (logContent) { - logSection = ` + const currentType = type; + const shouldAttachLogs = attachLogs; -## Application Logs (last 1000 lines, redacted) -
-Click to expand logs + close(); -\`\`\` -${logContent} -\`\`\` + const logSection = shouldAttachLogs + ? ` -
-`; - } - } +## Application Logs +Logs will be saved to a file. Please attach the saved log file to this issue. +` + : ""; - if (type === "bug") { + if (currentType === "bug") { const body = `## Description ${trimmedDescription} @@ -156,7 +148,25 @@ ${logSection} await openerCommands.openUrl(url.toString(), null); } - close(); + if (shouldAttachLogs) { + const logContent = await getLogContent(); + if (logContent) { + const defaultPath = await downloadDir(); + const timestamp = new Date().toISOString().replace(/[:.]/g, "-"); + const defaultFileName = `hyprnote-logs-${timestamp}.txt`; + + const filePath = await save({ + title: "Save Application Logs", + defaultPath: `${defaultPath}/${defaultFileName}`, + filters: [{ name: "Text Files", extensions: ["txt", "log"] }], + }); + + if (filePath) { + await writeTextFile(filePath, logContent); + await openerCommands.revealItemInDir(filePath); + } + } + } } catch (error) { console.error("Failed to submit feedback:", error); } finally { @@ -267,15 +277,9 @@ ${logSection} htmlFor="attach-logs" className="text-sm text-neutral-600 cursor-pointer" > - Attach application logs (user info redacted) + Save application logs to file (for manual attachment) - - {gitHash && ( -
- {gitHash} -
- )}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d19284fbd7..f2c45f961f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -437,6 +437,9 @@ importers: '@tauri-apps/plugin-dialog': specifier: ^2.6.0 version: 2.6.0 + '@tauri-apps/plugin-fs': + specifier: ^2.4.5 + version: 2.4.5 '@tauri-apps/plugin-http': specifier: ^2.5.6 version: 2.5.6 @@ -7685,6 +7688,9 @@ packages: '@tauri-apps/plugin-dialog@2.6.0': resolution: {integrity: sha512-q4Uq3eY87TdcYzXACiYSPhmpBA76shgmQswGkSVio4C82Sz2W4iehe9TnKYwbq7weHiL88Yw19XZm7v28+Micg==} + '@tauri-apps/plugin-fs@2.4.5': + resolution: {integrity: sha512-dVxWWGE6VrOxC7/jlhyE+ON/Cc2REJlM35R3PJX3UvFw2XwYhLGQVAIyrehenDdKjotipjYEVc4YjOl3qq90fA==} + '@tauri-apps/plugin-http@2.5.6': resolution: {integrity: sha512-KhCK3TDNDF4vdz75/j+KNQipYKf+295Visa8r32QcXScg0+D3JwShcCM6D+FN8WuDF24X3KSiAB8QtRxW6jKRA==} @@ -15185,6 +15191,7 @@ packages: tar@6.2.1: resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} engines: {node: '>=10'} + deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exhorbitant rates) by contacting i@izs.me tar@7.5.2: resolution: {integrity: sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg==} @@ -23186,6 +23193,10 @@ snapshots: dependencies: '@tauri-apps/api': 2.9.1 + '@tauri-apps/plugin-fs@2.4.5': + dependencies: + '@tauri-apps/api': 2.9.1 + '@tauri-apps/plugin-http@2.5.6': dependencies: '@tauri-apps/api': 2.9.1