From 67820a02ca2d87922a4d697c89dbeaea7f6632c9 Mon Sep 17 00:00:00 2001
From: thewh1teagle <61390950+thewh1teagle@users.noreply.github.com>
Date: Fri, 17 Jan 2025 05:37:43 +0200
Subject: [PATCH] Feat/keepawake (#481)

* bump version to 3.0.1 in tauri configuration

* feat: keep system awake

* feat: add Vulkan runtime to resources and refactor wget calls for platform compatibility

* feat: enhance wget command with progress bar and retry options

* refactor: remove unused file associations from tauri configuration

* feat: add function to clean updater files and integrate it into setup process

* fix: update app info logging to use the correct utility function

* style: update globals.css for print styling and remove header/footer margins

* chore: update tauri-plugin-keepawake to version 0.1.1

* fix: improve error handling in download_audio by using map_while for stderr output

* style: refine print styles in globals.css and improve button formatting in pdf

* refactor: remove unnecessary console logs related to keep awake functionality

* fix: don't use transparent effect on linux with settings

* style: enhance print styles to prevent blank pages and support dark/light mode

* fix: simplify default device checks using is_ok_and for better readability

* style: improve print styles for dark/light mode and prevent blank pages
---
 Cargo.lock                               | 602 ++++++++++++++++++++---
 desktop/bun.lockb                        | Bin 184259 -> 184719 bytes
 desktop/package.json                     |   5 +-
 desktop/src-tauri/Cargo.toml             |   1 +
 desktop/src-tauri/capabilities/main.json | 116 ++---
 desktop/src-tauri/src/cleaner.rs         |  27 +
 desktop/src-tauri/src/cmd/audio.rs       |   4 +-
 desktop/src-tauri/src/cmd/ytdlp.rs       |   2 +-
 desktop/src-tauri/src/main.rs            |   1 +
 desktop/src-tauri/src/setup.rs           |   2 +
 desktop/src-tauri/tauri.conf.json        |  30 +-
 desktop/src/components/SettingsModal.tsx |   4 +-
 desktop/src/globals.css                  |  60 ++-
 desktop/src/lib/utils.ts                 |  17 +
 desktop/src/pages/batch/viewModel.tsx    |   7 +-
 desktop/src/pages/home/Page.tsx          |   8 +-
 desktop/src/pages/home/viewModel.ts      |   7 +-
 scripts/pre_build.js                     |  37 +-
 18 files changed, 745 insertions(+), 185 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 5e1266ed..6d95a4ae 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -133,6 +133,43 @@ version = "1.0.93"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775"
 
+[[package]]
+name = "apple-bindgen"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38f109ee76f68b4767848cb5dc93bfcc7c425deca849c4c81fa11cdce525e3d2"
+dependencies = [
+ "apple-sdk",
+ "bindgen 0.63.0",
+ "derive_more",
+ "regex",
+ "serde",
+ "thiserror 1.0.69",
+ "toml 0.6.0",
+]
+
+[[package]]
+name = "apple-sdk"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a04f192a700686ee70008ff4e4eb76fe7d11814ab93b7ee9d48c36b9a9f0bd2a"
+dependencies = [
+ "plist",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "apple-sys"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "12b3a1c3342678cd72676d0c1644fde496c1f65ea41f51465f54a89cad3bdf34"
+dependencies = [
+ "apple-bindgen",
+ "apple-sdk",
+ "objc",
+]
+
 [[package]]
 name = "arbitrary"
 version = "1.4.1"
@@ -187,7 +224,17 @@ dependencies = [
  "wayland-backend",
  "wayland-client",
  "wayland-protocols",
- "zbus",
+ "zbus 4.0.1",
+]
+
+[[package]]
+name = "async-broadcast"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7c48ccdbf6ca6b121e0f586cbc0e73ae440e56c67c30fa0873b4e110d9c26d2b"
+dependencies = [
+ "event-listener 2.5.3",
+ "futures-core",
 ]
 
 [[package]]
@@ -196,7 +243,7 @@ version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "20cd0e2e25ea8e5f7e9df04578dc6cf5c83577fd09b1a46aaf5c85e1c33f2a7e"
 dependencies = [
- "event-listener",
+ "event-listener 5.3.1",
  "event-listener-strategy",
  "futures-core",
  "pin-project-lite",
@@ -222,20 +269,52 @@ checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec"
 dependencies = [
  "async-task",
  "concurrent-queue",
- "fastrand",
- "futures-lite",
+ "fastrand 2.2.0",
+ "futures-lite 2.5.0",
  "slab",
 ]
 
+[[package]]
+name = "async-fs"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06"
+dependencies = [
+ "async-lock 2.8.0",
+ "autocfg",
+ "blocking",
+ "futures-lite 1.13.0",
+]
+
 [[package]]
 name = "async-fs"
 version = "2.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a"
 dependencies = [
- "async-lock",
+ "async-lock 3.4.0",
  "blocking",
- "futures-lite",
+ "futures-lite 2.5.0",
+]
+
+[[package]]
+name = "async-io"
+version = "1.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af"
+dependencies = [
+ "async-lock 2.8.0",
+ "autocfg",
+ "cfg-if",
+ "concurrent-queue",
+ "futures-lite 1.13.0",
+ "log",
+ "parking",
+ "polling 2.8.0",
+ "rustix 0.37.28",
+ "slab",
+ "socket2 0.4.10",
+ "waker-fn",
 ]
 
 [[package]]
@@ -244,30 +323,56 @@ version = "2.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059"
 dependencies = [
- "async-lock",
+ "async-lock 3.4.0",
  "cfg-if",
  "concurrent-queue",
  "futures-io",
- "futures-lite",
+ "futures-lite 2.5.0",
  "parking",
- "polling",
- "rustix",
+ "polling 3.7.4",
+ "rustix 0.38.40",
  "slab",
  "tracing",
  "windows-sys 0.59.0",
 ]
 
+[[package]]
+name = "async-lock"
+version = "2.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b"
+dependencies = [
+ "event-listener 2.5.3",
+]
+
 [[package]]
 name = "async-lock"
 version = "3.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18"
 dependencies = [
- "event-listener",
+ "event-listener 5.3.1",
  "event-listener-strategy",
  "pin-project-lite",
 ]
 
+[[package]]
+name = "async-process"
+version = "1.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88"
+dependencies = [
+ "async-io 1.13.0",
+ "async-lock 2.8.0",
+ "async-signal",
+ "blocking",
+ "cfg-if",
+ "event-listener 3.1.0",
+ "futures-lite 1.13.0",
+ "rustix 0.38.40",
+ "windows-sys 0.48.0",
+]
+
 [[package]]
 name = "async-process"
 version = "2.3.0"
@@ -275,15 +380,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb"
 dependencies = [
  "async-channel",
- "async-io",
- "async-lock",
+ "async-io 2.4.0",
+ "async-lock 3.4.0",
  "async-signal",
  "async-task",
  "blocking",
  "cfg-if",
- "event-listener",
- "futures-lite",
- "rustix",
+ "event-listener 5.3.1",
+ "futures-lite 2.5.0",
+ "rustix 0.38.40",
  "tracing",
 ]
 
@@ -304,13 +409,13 @@ version = "0.2.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3"
 dependencies = [
- "async-io",
- "async-lock",
+ "async-io 2.4.0",
+ "async-lock 3.4.0",
  "atomic-waker",
  "cfg-if",
  "futures-core",
  "futures-io",
- "rustix",
+ "rustix 0.38.40",
  "signal-hook-registry",
  "slab",
  "windows-sys 0.59.0",
@@ -450,6 +555,28 @@ version = "0.22.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
 
+[[package]]
+name = "bindgen"
+version = "0.63.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "36d860121800b2a9a94f9b5604b332d5cffb234ce17609ea479d723dbc9d3885"
+dependencies = [
+ "bitflags 1.3.2",
+ "cexpr",
+ "clang-sys",
+ "lazy_static",
+ "lazycell",
+ "log",
+ "peeking_take_while",
+ "proc-macro2",
+ "quote",
+ "regex",
+ "rustc-hash 1.1.0",
+ "shlex",
+ "syn 1.0.109",
+ "which 4.4.2",
+]
+
 [[package]]
 name = "bindgen"
 version = "0.69.5"
@@ -539,7 +666,7 @@ dependencies = [
  "async-channel",
  "async-task",
  "futures-io",
- "futures-lite",
+ "futures-lite 2.5.0",
  "piper",
 ]
 
@@ -768,7 +895,7 @@ dependencies = [
  "anstream",
  "anstyle",
  "clap_lex",
- "strsim",
+ "strsim 0.11.1",
 ]
 
 [[package]]
@@ -1157,14 +1284,38 @@ dependencies = [
  "syn 2.0.87",
 ]
 
+[[package]]
+name = "darling"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850"
+dependencies = [
+ "darling_core 0.14.4",
+ "darling_macro 0.14.4",
+]
+
 [[package]]
 name = "darling"
 version = "0.20.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989"
 dependencies = [
- "darling_core",
- "darling_macro",
+ "darling_core 0.20.10",
+ "darling_macro 0.20.10",
+]
+
+[[package]]
+name = "darling_core"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0"
+dependencies = [
+ "fnv",
+ "ident_case",
+ "proc-macro2",
+ "quote",
+ "strsim 0.10.0",
+ "syn 1.0.109",
 ]
 
 [[package]]
@@ -1177,17 +1328,28 @@ dependencies = [
  "ident_case",
  "proc-macro2",
  "quote",
- "strsim",
+ "strsim 0.11.1",
  "syn 2.0.87",
 ]
 
+[[package]]
+name = "darling_macro"
+version = "0.14.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e"
+dependencies = [
+ "darling_core 0.14.4",
+ "quote",
+ "syn 1.0.109",
+]
+
 [[package]]
 name = "darling_macro"
 version = "0.20.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
 dependencies = [
- "darling_core",
+ "darling_core 0.20.10",
  "quote",
  "syn 2.0.87",
 ]
@@ -1236,6 +1398,37 @@ dependencies = [
  "syn 2.0.87",
 ]
 
+[[package]]
+name = "derive_builder"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f59169f400d8087f238c5c0c7db6a28af18681717f3b623227d92f397e938c7"
+dependencies = [
+ "derive_builder_macro",
+]
+
+[[package]]
+name = "derive_builder_core"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4ec317cc3e7ef0928b0ca6e4a634a4d6c001672ae210438cf114a83e56b018d"
+dependencies = [
+ "darling 0.14.4",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "derive_builder_macro"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "870368c3fb35b8031abb378861d4460f573b92238ec2152c927a21f77e3e0127"
+dependencies = [
+ "derive_builder_core",
+ "syn 1.0.109",
+]
+
 [[package]]
 name = "derive_more"
 version = "0.99.18"
@@ -1303,7 +1496,7 @@ version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
 dependencies = [
- "libloading 0.7.4",
+ "libloading 0.8.5",
 ]
 
 [[package]]
@@ -1483,6 +1676,23 @@ version = "3.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a5d9305ccc6942a704f4335694ecd3de2ea531b114ac2d51f5f843750787a92f"
 
+[[package]]
+name = "event-listener"
+version = "2.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
+
+[[package]]
+name = "event-listener"
+version = "3.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2"
+dependencies = [
+ "concurrent-queue",
+ "parking",
+ "pin-project-lite",
+]
+
 [[package]]
 name = "event-listener"
 version = "5.3.1"
@@ -1500,7 +1710,7 @@ version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1"
 dependencies = [
- "event-listener",
+ "event-listener 5.3.1",
  "pin-project-lite",
 ]
 
@@ -1524,6 +1734,15 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "fastrand"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
+dependencies = [
+ "instant",
+]
+
 [[package]]
 name = "fastrand"
 version = "2.2.0"
@@ -1692,13 +1911,28 @@ version = "0.3.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
 
+[[package]]
+name = "futures-lite"
+version = "1.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce"
+dependencies = [
+ "fastrand 1.9.0",
+ "futures-core",
+ "futures-io",
+ "memchr",
+ "parking",
+ "pin-project-lite",
+ "waker-fn",
+]
+
 [[package]]
 name = "futures-lite"
 version = "2.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cef40d21ae2c515b51041df9ed313ed21e572df340ea58a922a0aefe7e8891a1"
 dependencies = [
- "fastrand",
+ "fastrand 2.2.0",
  "futures-core",
  "futures-io",
  "parking",
@@ -1880,7 +2114,7 @@ version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "dc3655aa6818d65bc620d6911f05aa7b6aeb596291e1e9f79e52df85583d1e30"
 dependencies = [
- "rustix",
+ "rustix 0.38.40",
  "windows-targets 0.52.6",
 ]
 
@@ -2276,7 +2510,7 @@ dependencies = [
  "httpdate",
  "itoa 1.0.11",
  "pin-project-lite",
- "socket2",
+ "socket2 0.5.7",
  "tokio",
  "tower-service",
  "tracing",
@@ -2348,7 +2582,7 @@ dependencies = [
  "http-body 1.0.1",
  "hyper 1.5.0",
  "pin-project-lite",
- "socket2",
+ "socket2 0.5.7",
  "tokio",
  "tower-service",
  "tracing",
@@ -2601,6 +2835,17 @@ dependencies = [
  "cfg-if",
 ]
 
+[[package]]
+name = "io-lifetimes"
+version = "1.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
+dependencies = [
+ "hermit-abi 0.3.9",
+ "libc",
+ "windows-sys 0.48.0",
+]
+
 [[package]]
 name = "ipnet"
 version = "2.10.1"
@@ -2753,6 +2998,21 @@ dependencies = [
  "serde_json",
 ]
 
+[[package]]
+name = "keepawake"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a1e324a09aa048770b565b4ab2970bb9d1a7dac1038c68c2d243d8f7b6b1c90"
+dependencies = [
+ "apple-sys",
+ "cfg-if",
+ "core-foundation 0.9.4",
+ "derive_builder",
+ "thiserror 1.0.69",
+ "windows 0.52.0",
+ "zbus 3.15.1",
+]
+
 [[package]]
 name = "keyboard-types"
 version = "0.7.0"
@@ -2881,6 +3141,12 @@ dependencies = [
  "redox_syscall",
 ]
 
+[[package]]
+name = "linux-raw-sys"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
+
 [[package]]
 name = "linux-raw-sys"
 version = "0.4.14"
@@ -3210,6 +3476,15 @@ dependencies = [
  "minimal-lexical",
 ]
 
+[[package]]
+name = "nom8"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae01545c9c7fc4486ab7debaf2aad7003ac19431791868fb2e8066df97fad2f8"
+dependencies = [
+ "memchr",
+]
+
 [[package]]
 name = "nu-ansi-term"
 version = "0.46.0"
@@ -3831,6 +4106,12 @@ version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d61c5ce1153ab5b689d0c074c4e7fc613e942dfb7dd9eea5ab202d2ad91fe361"
 
+[[package]]
+name = "peeking_take_while"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
+
 [[package]]
 name = "percent-encoding"
 version = "2.3.1"
@@ -3990,7 +4271,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066"
 dependencies = [
  "atomic-waker",
- "fastrand",
+ "fastrand 2.2.0",
  "futures-io",
 ]
 
@@ -4026,6 +4307,22 @@ dependencies = [
  "miniz_oxide",
 ]
 
+[[package]]
+name = "polling"
+version = "2.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce"
+dependencies = [
+ "autocfg",
+ "bitflags 1.3.2",
+ "cfg-if",
+ "concurrent-queue",
+ "libc",
+ "log",
+ "pin-project-lite",
+ "windows-sys 0.48.0",
+]
+
 [[package]]
 name = "polling"
 version = "3.7.4"
@@ -4036,7 +4333,7 @@ dependencies = [
  "concurrent-queue",
  "hermit-abi 0.4.0",
  "pin-project-lite",
- "rustix",
+ "rustix 0.38.40",
  "tracing",
  "windows-sys 0.59.0",
 ]
@@ -4103,7 +4400,7 @@ version = "2.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24"
 dependencies = [
- "toml_datetime",
+ "toml_datetime 0.6.3",
  "toml_edit 0.20.2",
 ]
 
@@ -4205,7 +4502,7 @@ dependencies = [
  "quinn-udp",
  "rustc-hash 2.0.0",
  "rustls",
- "socket2",
+ "socket2 0.5.7",
  "thiserror 1.0.69",
  "tokio",
  "tracing",
@@ -4237,7 +4534,7 @@ dependencies = [
  "cfg_aliases",
  "libc",
  "once_cell",
- "socket2",
+ "socket2 0.5.7",
  "tracing",
  "windows-sys 0.59.0",
 ]
@@ -4632,6 +4929,20 @@ dependencies = [
  "semver",
 ]
 
+[[package]]
+name = "rustix"
+version = "0.37.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "519165d378b97752ca44bbe15047d5d3409e875f39327546b42ac81d7e18c1b6"
+dependencies = [
+ "bitflags 1.3.2",
+ "errno",
+ "io-lifetimes",
+ "libc",
+ "linux-raw-sys 0.3.8",
+ "windows-sys 0.48.0",
+]
+
 [[package]]
 name = "rustix"
 version = "0.38.40"
@@ -4641,7 +4952,7 @@ dependencies = [
  "bitflags 2.6.0",
  "errno",
  "libc",
- "linux-raw-sys",
+ "linux-raw-sys 0.4.14",
  "windows-sys 0.52.0",
 ]
 
@@ -4974,7 +5285,7 @@ version = "3.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9d846214a9854ef724f3da161b426242d8de7c1fc7de2f89bb1efcb154dca79d"
 dependencies = [
- "darling",
+ "darling 0.20.10",
  "proc-macro2",
  "quote",
  "syn 2.0.87",
@@ -5132,6 +5443,16 @@ version = "1.13.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
 
+[[package]]
+name = "socket2"
+version = "0.4.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
 [[package]]
 name = "socket2"
 version = "0.5.7"
@@ -5245,6 +5566,12 @@ dependencies = [
  "quote",
 ]
 
+[[package]]
+name = "strsim"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+
 [[package]]
 name = "strsim"
 version = "0.11.1"
@@ -5674,6 +6001,19 @@ dependencies = [
  "urlpattern",
 ]
 
+[[package]]
+name = "tauri-plugin-keepawake"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19695262819df92661139c607c5b5449b21ef5fa9429b8cb556e6c55bf34e5cb"
+dependencies = [
+ "keepawake",
+ "serde",
+ "tauri",
+ "tauri-plugin",
+ "thiserror 2.0.3",
+]
+
 [[package]]
 name = "tauri-plugin-os"
 version = "2.0.1"
@@ -5735,7 +6075,7 @@ dependencies = [
  "tauri",
  "thiserror 1.0.69",
  "windows-sys 0.59.0",
- "zbus",
+ "zbus 4.0.1",
 ]
 
 [[package]]
@@ -5898,9 +6238,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c"
 dependencies = [
  "cfg-if",
- "fastrand",
+ "fastrand 2.2.0",
  "once_cell",
- "rustix",
+ "rustix 0.38.40",
  "windows-sys 0.59.0",
 ]
 
@@ -6059,7 +6399,7 @@ dependencies = [
  "mio",
  "pin-project-lite",
  "signal-hook-registry",
- "socket2",
+ "socket2 0.5.7",
  "tokio-macros",
  "tracing",
  "windows-sys 0.52.0",
@@ -6110,6 +6450,18 @@ dependencies = [
  "tokio",
 ]
 
+[[package]]
+name = "toml"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fb9d890e4dc9298b70f740f615f2e05b9db37dce531f6b24fb77ac993f9f217"
+dependencies = [
+ "serde",
+ "serde_spanned",
+ "toml_datetime 0.5.1",
+ "toml_edit 0.18.1",
+]
+
 [[package]]
 name = "toml"
 version = "0.7.8"
@@ -6118,7 +6470,7 @@ checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257"
 dependencies = [
  "serde",
  "serde_spanned",
- "toml_datetime",
+ "toml_datetime 0.6.3",
  "toml_edit 0.19.15",
 ]
 
@@ -6130,10 +6482,19 @@ checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d"
 dependencies = [
  "serde",
  "serde_spanned",
- "toml_datetime",
+ "toml_datetime 0.6.3",
  "toml_edit 0.20.2",
 ]
 
+[[package]]
+name = "toml_datetime"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4553f467ac8e3d374bc9a177a26801e5d0f9b211aa1673fb137a403afd1c9cf5"
+dependencies = [
+ "serde",
+]
+
 [[package]]
 name = "toml_datetime"
 version = "0.6.3"
@@ -6143,6 +6504,19 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "toml_edit"
+version = "0.18.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56c59d8dd7d0dcbc6428bf7aa2f0e823e26e43b3c9aca15bbc9475d23e5fa12b"
+dependencies = [
+ "indexmap 1.9.3",
+ "nom8",
+ "serde",
+ "serde_spanned",
+ "toml_datetime 0.5.1",
+]
+
 [[package]]
 name = "toml_edit"
 version = "0.19.15"
@@ -6152,7 +6526,7 @@ dependencies = [
  "indexmap 2.6.0",
  "serde",
  "serde_spanned",
- "toml_datetime",
+ "toml_datetime 0.6.3",
  "winnow",
 ]
 
@@ -6165,7 +6539,7 @@ dependencies = [
  "indexmap 2.6.0",
  "serde",
  "serde_spanned",
- "toml_datetime",
+ "toml_datetime 0.6.3",
  "winnow",
 ]
 
@@ -6611,6 +6985,7 @@ dependencies = [
  "tauri-plugin-dialog",
  "tauri-plugin-fs",
  "tauri-plugin-http",
+ "tauri-plugin-keepawake",
  "tauri-plugin-os",
  "tauri-plugin-process",
  "tauri-plugin-shell",
@@ -6676,6 +7051,12 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "waker-fn"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7"
+
 [[package]]
 name = "walkdir"
 version = "2.5.0"
@@ -6795,7 +7176,7 @@ checksum = "056535ced7a150d45159d3a8dc30f91a2e2d588ca0b23f70e56033622b8016f6"
 dependencies = [
  "cc",
  "downcast-rs",
- "rustix",
+ "rustix 0.38.40",
  "scoped-tls",
  "smallvec",
  "wayland-sys",
@@ -6808,7 +7189,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b66249d3fc69f76fd74c82cc319300faa554e9d865dab1f7cd66cc20db10b280"
 dependencies = [
  "bitflags 2.6.0",
- "rustix",
+ "rustix 0.38.40",
  "wayland-backend",
  "wayland-scanner",
 ]
@@ -6961,7 +7342,7 @@ dependencies = [
  "either",
  "home",
  "once_cell",
- "rustix",
+ "rustix 0.38.40",
 ]
 
 [[package]]
@@ -6972,7 +7353,7 @@ checksum = "b4ee928febd44d98f2f459a4a79bd4d928591333a494a10a868418ac1b39cf1f"
 dependencies = [
  "either",
  "home",
- "rustix",
+ "rustix 0.38.40",
  "winsafe",
 ]
 
@@ -7525,7 +7906,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12"
 dependencies = [
  "gethostname 0.4.3",
- "rustix",
+ "rustix 0.38.40",
  "x11rb-protocol",
 ]
 
@@ -7542,8 +7923,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f"
 dependencies = [
  "libc",
- "linux-raw-sys",
- "rustix",
+ "linux-raw-sys 0.4.14",
+ "rustix 0.38.40",
 ]
 
 [[package]]
@@ -7580,25 +7961,66 @@ dependencies = [
  "synstructure",
 ]
 
+[[package]]
+name = "zbus"
+version = "3.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5acecd3f8422f198b1a2f954bcc812fe89f3fa4281646f3da1da7925db80085d"
+dependencies = [
+ "async-broadcast 0.5.1",
+ "async-executor",
+ "async-fs 1.6.0",
+ "async-io 1.13.0",
+ "async-lock 2.8.0",
+ "async-process 1.8.1",
+ "async-recursion",
+ "async-task",
+ "async-trait",
+ "blocking",
+ "byteorder",
+ "derivative",
+ "enumflags2",
+ "event-listener 2.5.3",
+ "futures-core",
+ "futures-sink",
+ "futures-util",
+ "hex",
+ "nix 0.26.4",
+ "once_cell",
+ "ordered-stream",
+ "rand 0.8.5",
+ "serde",
+ "serde_repr",
+ "sha1",
+ "static_assertions",
+ "tracing",
+ "uds_windows",
+ "winapi",
+ "xdg-home",
+ "zbus_macros 3.15.1",
+ "zbus_names 2.6.1",
+ "zvariant 3.15.1",
+]
+
 [[package]]
 name = "zbus"
 version = "4.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7b8e3d6ae3342792a6cc2340e4394334c7402f3d793b390d2c5494a4032b3030"
 dependencies = [
- "async-broadcast",
+ "async-broadcast 0.7.1",
  "async-executor",
- "async-fs",
- "async-io",
- "async-lock",
- "async-process",
+ "async-fs 2.1.2",
+ "async-io 2.4.0",
+ "async-lock 3.4.0",
+ "async-process 2.3.0",
  "async-recursion",
  "async-task",
  "async-trait",
  "blocking",
  "derivative",
  "enumflags2",
- "event-listener",
+ "event-listener 5.3.1",
  "futures-core",
  "futures-sink",
  "futures-util",
@@ -7615,9 +8037,23 @@ dependencies = [
  "uds_windows",
  "windows-sys 0.52.0",
  "xdg-home",
- "zbus_macros",
- "zbus_names",
- "zvariant",
+ "zbus_macros 4.0.1",
+ "zbus_names 3.0.0",
+ "zvariant 4.0.0",
+]
+
+[[package]]
+name = "zbus_macros"
+version = "3.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2207eb71efebda17221a579ca78b45c4c5f116f074eb745c3a172e688ccf89f5"
+dependencies = [
+ "proc-macro-crate 1.3.1",
+ "proc-macro2",
+ "quote",
+ "regex",
+ "syn 1.0.109",
+ "zvariant_utils",
 ]
 
 [[package]]
@@ -7634,6 +8070,17 @@ dependencies = [
  "zvariant_utils",
 ]
 
+[[package]]
+name = "zbus_names"
+version = "2.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "437d738d3750bed6ca9b8d423ccc7a8eb284f6b1d6d4e225a0e4e6258d864c8d"
+dependencies = [
+ "serde",
+ "static_assertions",
+ "zvariant 3.15.1",
+]
+
 [[package]]
 name = "zbus_names"
 version = "3.0.0"
@@ -7642,7 +8089,7 @@ checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c"
 dependencies = [
  "serde",
  "static_assertions",
- "zvariant",
+ "zvariant 4.0.0",
 ]
 
 [[package]]
@@ -7746,6 +8193,20 @@ dependencies = [
  "thiserror 1.0.69",
 ]
 
+[[package]]
+name = "zvariant"
+version = "3.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c5b4fcf3660d30fc33ae5cd97e2017b23a96e85afd7a1dd014534cd0bf34ba67"
+dependencies = [
+ "byteorder",
+ "enumflags2",
+ "libc",
+ "serde",
+ "static_assertions",
+ "zvariant_derive 3.15.1",
+]
+
 [[package]]
 name = "zvariant"
 version = "4.0.0"
@@ -7757,7 +8218,20 @@ dependencies = [
  "serde",
  "static_assertions",
  "url",
- "zvariant_derive",
+ "zvariant_derive 4.0.0",
+]
+
+[[package]]
+name = "zvariant_derive"
+version = "3.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0277758a8a0afc0e573e80ed5bfd9d9c2b48bd3108ffe09384f9f738c83f4a55"
+dependencies = [
+ "proc-macro-crate 1.3.1",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+ "zvariant_utils",
 ]
 
 [[package]]
diff --git a/desktop/bun.lockb b/desktop/bun.lockb
index e68b47f7e35b30dfdc29fb553f54d90423bd8e4a..25959f4e64224c319ca0087c57289e57188d19c5 100755
GIT binary patch
delta 31771
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
NR@z$nkox)k{~zLfO&0(F

delta 31458
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

diff --git a/desktop/package.json b/desktop/package.json
index a12032c4..927e15b0 100644
--- a/desktop/package.json
+++ b/desktop/package.json
@@ -11,6 +11,8 @@
     "lint": "eslint ."
   },
   "dependencies": {
+    "@fontsource/roboto": "^5.1.0",
+    "@formatjs/intl-durationformat": "^0.6.3",
     "@tauri-apps/api": "~2.1.1",
     "@tauri-apps/plugin-clipboard-manager": "~2.0.0",
     "@tauri-apps/plugin-deep-link": "~2.0.0",
@@ -23,8 +25,6 @@
     "@tauri-apps/plugin-store": "~2.1.0",
     "@tauri-apps/plugin-updater": "~2.0.0",
     "@tauri-apps/plugin-window-state": "~2.0.0",
-    "@fontsource/roboto": "^5.1.0",
-    "@formatjs/intl-durationformat": "^0.6.3",
     "docx": "^9.0.3",
     "format-duration": "^3.0.2",
     "i18next": "^23.16.5",
@@ -35,6 +35,7 @@
     "react-hot-toast": "^2.4.1",
     "react-i18next": "^15.1.1",
     "react-router-dom": "^6.28.0",
+    "tauri-plugin-keepawake-api": "^0.1.0",
     "usehooks-ts": "^3.1.0",
     "vite-plugin-svgr": "^4.3.0"
   },
diff --git a/desktop/src-tauri/Cargo.toml b/desktop/src-tauri/Cargo.toml
index 81283b00..e743017a 100644
--- a/desktop/src-tauri/Cargo.toml
+++ b/desktop/src-tauri/Cargo.toml
@@ -25,6 +25,7 @@ tauri-plugin-deep-link = "2"
 tauri-plugin-store = "2"
 tauri-plugin-single-instance = "2"
 tauri-plugin-clipboard-manager = "2"
+tauri-plugin-keepawake = "0.1.1"
 # Unsafe headers required for Ollama (to set Origin)
 tauri-plugin-http = { version = "2", features = ["unsafe-headers"] }
 
diff --git a/desktop/src-tauri/capabilities/main.json b/desktop/src-tauri/capabilities/main.json
index ff7f52bf..2a4e1fa0 100644
--- a/desktop/src-tauri/capabilities/main.json
+++ b/desktop/src-tauri/capabilities/main.json
@@ -1,12 +1,68 @@
 {
   "$schema": "../gen/schemas/desktop-schema.json",
-  "identifier": "migrated",
-  "description": "permissions that were migrated from v1",
+  "identifier": "default",
+  "description": "default permissions",
   "local": true,
   "windows": [
     "main"
   ],
   "permissions": [
+    "keepawake:allow-start",
+    "keepawake:allow-stop",
+    "http:default",
+    "http:allow-fetch",
+    "store:allow-set",
+    "store:allow-get",
+    "store:allow-has",
+    "store:allow-reset",
+    "store:allow-clear",
+    "store:allow-save",
+    "store:allow-load",
+    "store:allow-get-store",
+    "core:path:default",
+    "core:event:default",
+    "core:resources:default",
+    "core:menu:default",
+    "core:tray:default",
+    "fs:allow-remove",
+    "fs:allow-read-dir",
+    "fs:allow-read-text-file",
+    "fs:allow-app-write",
+    "os:allow-arch",
+    "os:allow-platform",
+    "os:allow-version",
+    "os:allow-os-type",
+    "os:allow-locale",
+    "core:window:default",
+    "core:window:allow-unminimize",
+    "core:window:allow-set-focus",
+    "core:window:allow-close",
+    "core:window:allow-destroy",
+    "core:window:allow-show",
+    "core:window:allow-is-visible",
+    "window-state:allow-restore-state",
+    "window-state:allow-save-window-state",
+    "core:webview:default",
+    "core:webview:allow-print",
+    "dialog:default",
+    "dialog:allow-open",
+    "dialog:allow-save",
+    "dialog:allow-ask",
+    "dialog:allow-message",
+    "process:allow-restart",
+    "core:app:default",
+    "core:app:allow-version",
+    "core:app:allow-name",
+    "updater:default",
+    "shell:allow-open",
+    "shell:allow-execute",
+    "shell:allow-kill",
+    "shell:allow-spawn",
+    "fs:default",
+    "fs:allow-exists",
+    "core:path:allow-basename",
+    "deep-link:allow-get-current",
+    "clipboard-manager:allow-write-text",
     {
       "identifier": "fs:scope",
       "allow": [
@@ -65,60 +121,6 @@
           "url": "http{s}?://localhost:*/*"
         }
       ]
-    },
-    "http:default",
-    "http:allow-fetch",
-    "store:allow-set",
-    "store:allow-get",
-    "store:allow-has",
-    "store:allow-reset",
-    "store:allow-clear",
-    "store:allow-save",
-    "store:allow-load",
-    "store:allow-get-store",
-    "core:path:default",
-    "core:event:default",
-    "core:resources:default",
-    "core:menu:default",
-    "core:tray:default",
-    "fs:allow-remove",
-    "fs:allow-read-dir",
-    "fs:allow-read-text-file",
-    "fs:allow-app-write",
-    "os:allow-arch",
-    "os:allow-platform",
-    "os:allow-version",
-    "os:allow-os-type",
-    "os:allow-locale",
-    "core:window:default",
-    "core:window:allow-unminimize",
-    "core:window:allow-set-focus",
-    "core:window:allow-close",
-    "core:window:allow-destroy",
-    "core:window:allow-show",
-    "core:window:allow-is-visible",
-    "window-state:allow-restore-state",
-    "window-state:allow-save-window-state",
-    "core:webview:default",
-    "core:webview:allow-print",
-    "dialog:default",
-    "dialog:allow-open",
-    "dialog:allow-save",
-    "dialog:allow-ask",
-    "dialog:allow-message",
-    "process:allow-restart",
-    "core:app:default",
-    "core:app:allow-version",
-    "core:app:allow-name",
-    "updater:default",
-    "shell:allow-open",
-    "shell:allow-execute",
-    "shell:allow-kill",
-    "shell:allow-spawn",
-    "fs:default",
-    "fs:allow-exists",
-    "core:path:allow-basename",
-    "deep-link:allow-get-current",
-    "clipboard-manager:allow-write-text"
+    }
   ]
 }
\ No newline at end of file
diff --git a/desktop/src-tauri/src/cleaner.rs b/desktop/src-tauri/src/cleaner.rs
index 322d4c82..bdc212bd 100644
--- a/desktop/src-tauri/src/cleaner.rs
+++ b/desktop/src-tauri/src/cleaner.rs
@@ -55,3 +55,30 @@ pub fn clean_old_files() -> Result<()> {
     }
     Ok(())
 }
+
+pub fn clean_updater_files() -> Result<()> {
+    let current_temp_dir = get_vibe_temp_folder();
+    let temp_dir = std::env::temp_dir();
+    let temp_dir = temp_dir.to_str().unwrap_or_default();
+    // Remove suffix
+    let temp_dir = temp_dir.strip_suffix('/').unwrap_or(temp_dir);
+    let temp_dir = temp_dir.strip_suffix('\\').unwrap_or(temp_dir);
+    let pattern = format!("{}/vibe*-updater*", temp_dir);
+    tracing::debug!("searching old files in {}", pattern);
+    for path in glob::glob(&pattern)? {
+        let path = path?;
+        if path == current_temp_dir {
+            tracing::debug!("Skip deletion of {}", current_temp_dir.display());
+            continue;
+        }
+        if path.is_dir() {
+            tracing::debug!("Clean old folder {}", path.display());
+            std::fs::remove_dir_all(&path)
+                .map_err(|e| eyre!("failed to delete {}: {:?}", path.display(), e))
+                .log_error();
+        } else {
+            tracing::debug!("Skipping non-directory path {}", path.display());
+        }
+    }
+    Ok(())
+}
diff --git a/desktop/src-tauri/src/cmd/audio.rs b/desktop/src-tauri/src/cmd/audio.rs
index 0e946c97..c54cebf8 100644
--- a/desktop/src-tauri/src/cmd/audio.rs
+++ b/desktop/src-tauri/src/cmd/audio.rs
@@ -40,11 +40,11 @@ pub fn get_audio_devices() -> Result<Vec<AudioDevice>> {
     tracing::debug!("Devices: ");
     for (device_index, device) in devices.enumerate() {
         let name = device.name()?;
-        let is_default_in = default_in.as_ref().map_or(false, |d| d == &name);
+        let is_default_in = default_in.as_ref().is_ok_and(|d| d == &name);
         let is_default_out = if cfg!(target_os = "macos") {
             false
         } else {
-            default_out.as_ref().map_or(false, |d| d == &name)
+            default_out.as_ref().is_ok_and(|d| d == &name)
         };
 
         let is_input = device.default_input_config().is_ok();
diff --git a/desktop/src-tauri/src/cmd/ytdlp.rs b/desktop/src-tauri/src/cmd/ytdlp.rs
index 060cd1ed..3ab0abe4 100644
--- a/desktop/src-tauri/src/cmd/ytdlp.rs
+++ b/desktop/src-tauri/src/cmd/ytdlp.rs
@@ -124,7 +124,7 @@ pub async fn download_audio(app_handle: AppHandle, url: String, out_path: String
         if let Some(stderr) = child.stderr.take() {
             stderr_output = BufReader::new(stderr)
                 .lines()
-                .filter_map(|line| line.ok())
+                .map_while(Result::ok)
                 .collect::<Vec<_>>()
                 .join("\n");
             eprintln!("Error: {}", stderr_output);
diff --git a/desktop/src-tauri/src/main.rs b/desktop/src-tauri/src/main.rs
index ff9bf403..ae46120c 100644
--- a/desktop/src-tauri/src/main.rs
+++ b/desktop/src-tauri/src/main.rs
@@ -64,6 +64,7 @@ fn main() -> Result<()> {
         .plugin(tauri_plugin_updater::Builder::default().build())
         .plugin(tauri_plugin_process::init())
         .plugin(tauri_plugin_shell::init())
+        .plugin(tauri_plugin_keepawake::init())
         .invoke_handler(tauri::generate_handler![
             cmd::download_file,
             cmd::get_cargo_features,
diff --git a/desktop/src-tauri/src/setup.rs b/desktop/src-tauri/src/setup.rs
index 8db90b71..3596e2f7 100644
--- a/desktop/src-tauri/src/setup.rs
+++ b/desktop/src-tauri/src/setup.rs
@@ -47,6 +47,7 @@ pub fn setup(app: &App) -> Result<(), Box<dyn std::error::Error>> {
     crate::logging::setup_logging(app.handle(), store).unwrap();
     crate::cleaner::clean_old_logs(app.handle()).log_error();
     crate::cleaner::clean_old_files().log_error();
+    crate::cleaner::clean_updater_files().log_error();
     tracing::debug!("Vibe App Running");
 
     // Crash handler
@@ -111,6 +112,7 @@ pub fn setup(app: &App) -> Result<(), Box<dyn std::error::Error>> {
 
     tracing::debug!("APP VERSION: {}", app.package_info().version.to_string());
     tracing::debug!("COMMIT HASH: {}", env!("COMMIT_HASH"));
+    tracing::debug!("App Info: {}", crate::utils::get_app_info());
 
     let app_handle = app.app_handle().clone();
     if is_cli_detected() {
diff --git a/desktop/src-tauri/tauri.conf.json b/desktop/src-tauri/tauri.conf.json
index 460fafa2..04f4c57d 100644
--- a/desktop/src-tauri/tauri.conf.json
+++ b/desktop/src-tauri/tauri.conf.json
@@ -1,7 +1,7 @@
 {
 	"$schema": "./gen/schemas/desktop-schema.json",
 	"productName": "vibe",
-	"version": "3.0.0",
+	"version": "3.0.1",
 	"identifier": "github.aaakk.us.kg.thewh1teagle.vibe",
 	"app": {
 		"windows": [],
@@ -45,33 +45,7 @@
 		],
 		"resources": {
 			"locales": "locales"
-		},
-		"fileAssociations": [
-			{
-				"description": "Video files",
-				"ext": [
-					"mp4",
-					"mkv",
-					"avi",
-					"mov",
-					"wmv",
-					"webm"
-				]
-			},
-			{
-				"description": "Audio files",
-				"ext": [
-					"mp3",
-					"wav",
-					"aac",
-					"flac",
-					"oga",
-					"ogg",
-					"opic",
-					"opus"
-				]
-			}
-		]
+		}
 	},
 	"plugins": {
 		"updater": {
diff --git a/desktop/src/components/SettingsModal.tsx b/desktop/src/components/SettingsModal.tsx
index 267bf566..dfea1686 100644
--- a/desktop/src/components/SettingsModal.tsx
+++ b/desktop/src/components/SettingsModal.tsx
@@ -1,5 +1,6 @@
 import { ModifyState, cx } from '~/lib/utils'
 import SettingsPage from '~/pages/settings/Page'
+import * as os from '@tauri-apps/plugin-os'
 
 interface SettingsModalProps {
 	visible: boolean
@@ -8,7 +9,8 @@ interface SettingsModalProps {
 export default function SettingsModal({ visible, setVisible }: SettingsModalProps) {
 	if (visible) {
 		return (
-			<div className={cx('modal modal-open backdrop-blur-3xl !bg-base-100 dark:!bg-transparent overflow-y-auto')}>
+			// Don't use transparent background on Linux since the backdrop doesn't work!
+			<div className={cx('modal modal-open backdrop-blur-3xl !bg-base-100 overflow-y-auto', os.platform() != 'linux' && 'dark:!bg-transparent')}>
 				<SettingsPage setVisible={setVisible} />
 			</div>
 		)
diff --git a/desktop/src/globals.css b/desktop/src/globals.css
index 8d2e932e..43661ec9 100644
--- a/desktop/src/globals.css
+++ b/desktop/src/globals.css
@@ -14,14 +14,12 @@
 }
 
 @media print {
+	html,
 	body * {
 		visibility: hidden;
 	}
 
-	.printable {
-		visibility: visible;
-	}
-
+	.printable,
 	.printable * {
 		visibility: visible;
 	}
@@ -31,5 +29,59 @@
 		left: 0;
 		top: 0;
 		height: 100vh;
+		width: 100vw;
+	}
+
+	/* remove header and footer */
+	@page {
+		margin: 0;
+		padding: 0;
+	}
+
+	.segment {
+		padding-left: 5px;
+		padding-right: 5px;
+	}
+
+	/* keep exact HTML colors! */
+	* {
+		print-color-adjust: exact;
+	}
+
+	/* Prevent blank page */
+	html,
+	body {
+		height: 100vh;
+		margin: 0 !important;
+		padding: 0 !important;
+		overflow: hidden;
+	}
+
+	body:last-child {
+		page-break-after: auto;
+	}
+
+	/* Dark mode */
+
+	[data-theme='dark'] * {
+		background: #181818 !important;
+	}
+
+	[data-theme='dark'] .segment {
+		color: white !important;
+	}
+
+	/* Light mode */
+	[data-theme='light'] * {
+		background: white !important;
+	}
+
+	[data-theme='light'] .segment {
+		color: black !important;
+	}
+
+	#footer,
+	#header {
+		all: unset;
 	}
 }
diff --git a/desktop/src/lib/utils.ts b/desktop/src/lib/utils.ts
index 57568849..cceee9ed 100644
--- a/desktop/src/lib/utils.ts
+++ b/desktop/src/lib/utils.ts
@@ -4,6 +4,7 @@ import * as fs from '@tauri-apps/plugin-fs'
 import * as config from './config'
 import { Dispatch, SetStateAction } from 'react'
 import { load } from '@tauri-apps/plugin-store'
+import * as keepAwake from 'tauri-plugin-keepawake-api'
 
 export interface NamedPath {
 	name: string
@@ -84,3 +85,19 @@ export async function getModelsFolder() {}
 export function formatSpeaker(speaker?: string, prefix = 'Speaker') {
 	return `${prefix} ${speaker ?? '?'}: `
 }
+
+export async function startKeepAwake() {
+	try {
+		keepAwake.start({ display: true, idle: true, sleep: true })
+	} catch (e) {
+		console.error(`Keep awake failed: ${e}`)
+	}
+}
+
+export async function stopKeepAwake() {
+	try {
+		keepAwake.stop()
+	} catch (e) {
+		console.error(`Keep awake failed: ${e}`)
+	}
+}
diff --git a/desktop/src/pages/batch/viewModel.tsx b/desktop/src/pages/batch/viewModel.tsx
index 86179f17..75bed13a 100644
--- a/desktop/src/pages/batch/viewModel.tsx
+++ b/desktop/src/pages/batch/viewModel.tsx
@@ -3,7 +3,7 @@ import { useEffect, useRef, useState } from 'react'
 import { useNavigate } from 'react-router-dom'
 import { TextFormat, formatExtensions } from '~/components/FormatSelect'
 import { Segment, Transcript, asJson, asSrt, asText, asVtt } from '~/lib/transcript'
-import { NamedPath, pathToNamedPath } from '~/lib/utils'
+import { NamedPath, pathToNamedPath, startKeepAwake, stopKeepAwake } from '~/lib/utils'
 import * as webview from '@tauri-apps/api/webviewWindow'
 import * as dialog from '@tauri-apps/plugin-dialog'
 import * as config from '~/lib/config'
@@ -112,6 +112,9 @@ export function viewModel() {
 		if (inProgress) {
 			return
 		}
+
+		startKeepAwake()
+
 		setInProgress(true)
 		let localIndex = 0
 		await invoke('load_model', { modelPath: preference.modelPath, gpuDevice: preference.gpuDevice })
@@ -176,6 +179,7 @@ export function viewModel() {
 				await new Promise((resolve) => setTimeout(resolve, 100))
 				setCurrentIndex(localIndex)
 			} catch (error) {
+				stopKeepAwake()
 				if (isAbortingRef.current) {
 					navigate('/')
 				} else {
@@ -185,6 +189,7 @@ export function viewModel() {
 				setCurrentIndex(localIndex)
 			}
 		}
+		stopKeepAwake()
 		setCurrentIndex(files.length + 1)
 		setInProgress(false)
 		setIsAborting(false)
diff --git a/desktop/src/pages/home/Page.tsx b/desktop/src/pages/home/Page.tsx
index b19c42fd..a7c81e9a 100644
--- a/desktop/src/pages/home/Page.tsx
+++ b/desktop/src/pages/home/Page.tsx
@@ -14,6 +14,7 @@ import { ReactComponent as MicrphoneIcon } from '~/icons/microphone.svg'
 import { ReactComponent as LinkIcon } from '~/icons/link.svg'
 import { useEffect } from 'react'
 import { webviewWindow } from '@tauri-apps/api'
+import * as keepAwake from 'tauri-plugin-keepawake-api'
 
 export default function Home() {
 	const { t } = useTranslation()
@@ -76,7 +77,12 @@ export default function Home() {
 
 						{vm.isRecording && (
 							<>
-								<button onMouseDown={vm.stopRecord} className="btn relative btn-success mt-3">
+								<button
+									onMouseDown={() => {
+										keepAwake.stop()
+										vm.stopRecord()
+									}}
+									className="btn relative btn-success mt-3">
 									<span className="loading loading-spinner"></span>
 									{t('common.stop-and-transcribe')}
 								</button>
diff --git a/desktop/src/pages/home/viewModel.ts b/desktop/src/pages/home/viewModel.ts
index f6a1674a..2fba7747 100644
--- a/desktop/src/pages/home/viewModel.ts
+++ b/desktop/src/pages/home/viewModel.ts
@@ -13,7 +13,7 @@ import { TextFormat } from '~/components/FormatSelect'
 import { AudioDevice } from '~/lib/audio'
 import * as config from '~/lib/config'
 import * as transcript from '~/lib/transcript'
-import { NamedPath, ls, openPath, pathToNamedPath } from '~/lib/utils'
+import { NamedPath, ls, openPath, pathToNamedPath, startKeepAwake, stopKeepAwake } from '~/lib/utils'
 import { getX86Features } from '~/lib/x86Features'
 import { ErrorModalContext } from '~/providers/ErrorModal'
 import { useFilesContext } from '~/providers/FilesProvider'
@@ -278,6 +278,7 @@ export function viewModel() {
 	}, [])
 
 	async function startRecord() {
+		startKeepAwake()
 		setSegments(null)
 		setSummarizeSegments(null)
 		setTranscriptTab('transcript')
@@ -298,6 +299,8 @@ export function viewModel() {
 	}
 
 	async function transcribe(path: string) {
+		startKeepAwake()
+
 		setSegments(null)
 		setSummarizeSegments(null)
 		setTranscriptTab('transcript')
@@ -330,11 +333,13 @@ export function viewModel() {
 			hotToast.success(t('common.transcribe-took', { total: String(total) }), { position: 'bottom-center' })
 		} catch (error) {
 			if (!abortRef.current) {
+				stopKeepAwake()
 				console.error('error: ', error)
 				setErrorModal?.({ log: String(error), open: true })
 				setLoading(false)
 			}
 		} finally {
+			stopKeepAwake()
 			setLoading(false)
 			setIsAborting(false)
 			setProgress(null)
diff --git a/scripts/pre_build.js b/scripts/pre_build.js
index 8a3d8fe1..a379f952 100755
--- a/scripts/pre_build.js
+++ b/scripts/pre_build.js
@@ -17,6 +17,14 @@ function hasFeature(name) {
 	return process.argv.includes(`--${name}`) || process.argv.includes(name)
 }
 
+async function wget(url, path) {
+	if (platform === 'windows') {
+		await $`C:\\msys64\\usr\\bin\\wget.exe --show-progress --progress=bar:force:noscroll --tries=10 -nc ${url} -O ${path}`
+	} else {
+		await $`wget --show-progress --progress=bar:force:noscroll --tries=10 -nc ${url} -O ${path}`
+	}
+}
+
 const config = {
 	ffmpegRealname: 'ffmpeg',
 	openblasRealname: 'openblas',
@@ -58,13 +66,7 @@ const config = {
 	macos: {
 		ffmpegName: 'ffmpeg-6.1-macOS-default',
 		ffmpegUrl: 'https://master.dl.sourceforge.net/project/avbuild/macOS/ffmpeg-6.1-macOS-default.tar.xz?viasf=1',
-	},
-	diarization: {
-		embedModelUrl: 'https://github.com/thewh1teagle/vibe/releases/download/v0.0.1/wespeaker_en_voxceleb_CAM++.onnx',
-		embedModelFilename: 'wespeaker_en_voxceleb_CAM++.onnx',
-		segmentModelUrl: 'https://github.com/thewh1teagle/vibe/releases/download/v0.0.1/segmentation-3.0.onnx',
-		segmentModelFilename: 'segmentation-3.0.onnx',
-	},
+	}
 }
 
 // Export for Github actions
@@ -92,7 +94,7 @@ if (platform == 'linux') {
 if (platform == 'windows') {
 	// Setup FFMPEG
 	if (!(await fs.exists(config.ffmpegRealname))) {
-		await $`C:\\msys64\\usr\\bin\\wget.exe -nc --show-progress ${config.windows.ffmpegUrl} -O ${config.windows.ffmpegName}.7z`
+		await wget(config.windows.ffmpegUrl, `${config.windows.ffmpegName}.7z`)
 		await $`'C:\\Program Files\\7-Zip\\7z.exe' x ${config.windows.ffmpegName}.7z`
 		await $`mv ${config.windows.ffmpegName} ${config.ffmpegRealname}`
 		await $`rm -rf ${config.windows.ffmpegName}.7z`
@@ -101,7 +103,7 @@ if (platform == 'windows') {
 
 	// Setup OpenBlas
 	if (!(await fs.exists(config.openblasRealname)) && hasFeature('openblas')) {
-		await $`C:\\msys64\\usr\\bin\\wget.exe -nc --show-progress ${config.windows.openBlasUrl} -O ${config.windows.openBlasName}.zip`
+		await wget(config.windows.openBlasUrl, `${config.windows.openBlasName}.zip`)
 		await $`"C:\\Program Files\\7-Zip\\7z.exe" x ${config.windows.openBlasName}.zip -o${config.openblasRealname}`
 		await $`rm ${config.windows.openBlasName}.zip`
 		fs.cp(path.join(config.openblasRealname, 'include'), path.join(config.openblasRealname, 'lib'), { recursive: true, force: true })
@@ -111,12 +113,12 @@ if (platform == 'windows') {
 
 	// Setup Vulkan
 	if (!(await fs.exists(config.vulkanSdkRealName)) && hasFeature('vulkan')) {
-		await $`C:\\msys64\\usr\\bin\\wget.exe -nc --show-progress ${config.windows.vulkanSdkUrl} -O ${config.windows.vulkanSdkName}.exe`
+		await wget(config.windows.vulkanSdkUrl, `${config.windows.vulkanSdkName}.exe`)
 		let executable = path.join(cwd, `${config.windows.vulkanSdkName}.exe`)
 		let vulkanSdkRoot = path.join(cwd, config.vulkanSdkRealName)
 		await $`${executable} --root ${vulkanSdkRoot} --accept-licenses --default-answer --confirm-command install copy_only=1` // copy_only=1 to run without admin rights
 
-		await $`C:\\msys64\\usr\\bin\\wget.exe -nc --show-progress ${config.windows.vulkanRuntimeUrl} -O ${config.windows.vulkanRuntimeName}.zip`
+		await wget(config.windows.vulkanRuntimeUrl, `${config.windows.vulkanRuntimeName}.zip`)
 		await $`"C:\\Program Files\\7-Zip\\7z.exe" x ${config.windows.vulkanRuntimeName}.zip` // 7z file inside
 		await $`mv ${config.windows.vulkanRuntimeName} ${config.vulkanRuntimeRealName}`
 		await $`rm ${config.windows.vulkanSdkName}.exe`
@@ -133,7 +135,7 @@ if (platform == 'windows') {
 if (platform == 'macos') {
 	// Setup FFMPEG
 	if (!(await fs.exists(config.ffmpegRealname))) {
-		await $`wget -nc --show-progress ${config.macos.ffmpegUrl} -O ${config.macos.ffmpegName}.tar.xz`
+		await wget(config.macos.ffmpegUrl, `${config.macos.ffmpegName}.tar.xz`)
 		await $`tar xf ${config.macos.ffmpegName}.tar.xz`
 		await $`mv ${config.macos.ffmpegName} ${config.ffmpegRealname}`
 		await $`rm ${config.macos.ffmpegName}.tar.xz`
@@ -222,17 +224,6 @@ if (hasFeature('rocm')) {
 	}
 }
 
-// Diarization
-if (!(await fs.exists(config.diarization.embedModelFilename))) {
-	if (platform == 'windows') {
-		await $`C:\\msys64\\usr\\bin\\wget.exe -nc --show-progress ${config.diarization.embedModelUrl} -O ${config.diarization.embedModelFilename}`
-		await $`C:\\msys64\\usr\\bin\\wget.exe -nc --show-progress ${config.diarization.segmentModelUrl} -O ${config.diarization.segmentModelFilename}`
-	} else {
-		await $`wget -nc --show-progress ${config.diarization.embedModelUrl} -O ${config.diarization.embedModelFilename}`
-		await $`wget -nc --show-progress ${config.diarization.segmentModelUrl} -O ${config.diarization.segmentModelFilename}`
-	}
-}
-
 // Development hints
 if (!process.env.GITHUB_ENV) {
 	console.log('\nCommands to build 🔨:')