One-click backups for AT Protocol

fix: background backups

Turtlepaw 0b4913ae 324ebe0b

+3
bun.lock
··· 23 23 "@tauri-apps/plugin-autostart": "~2.5.0", 24 24 "@tauri-apps/plugin-deep-link": "~2.4.0", 25 25 "@tauri-apps/plugin-fs": "~2.4.0", 26 + "@tauri-apps/plugin-log": "~2", 26 27 "@tauri-apps/plugin-opener": "^2.4.0", 27 28 "@tauri-apps/plugin-process": "~2.3.0", 28 29 "@tauri-apps/plugin-shell": "~2.3.0", ··· 648 649 "@tauri-apps/plugin-deep-link": ["@tauri-apps/plugin-deep-link@2.4.0", "", { "dependencies": { "@tauri-apps/api": "^2.6.0" } }, "sha512-scFldWG5FDqLgbHauS5FtsE563Bo00sqYhhWTYwNzIOZFdOJtNY6tBqzqGJ8I1aehPtEVA0LcTNaq8fmDQbDGg=="], 649 650 650 651 "@tauri-apps/plugin-fs": ["@tauri-apps/plugin-fs@2.4.0", "", { "dependencies": { "@tauri-apps/api": "^2.6.0" } }, "sha512-Sp8AdDcbyXyk6LD6Pmdx44SH3LPeNAvxR2TFfq/8CwqzfO1yOyV+RzT8fov0NNN7d9nvW7O7MtMAptJ42YXA5g=="], 652 + 653 + "@tauri-apps/plugin-log": ["@tauri-apps/plugin-log@2.6.0", "", { "dependencies": { "@tauri-apps/api": "^2.6.0" } }, "sha512-gVp3l31akA1Jk2bZsTA0hMFD5/gLe49Nw1btu5lViau0QqgC2XyT79LSwvy7a44ewtQbSexchqIg7oTJKMIbXQ=="], 651 654 652 655 "@tauri-apps/plugin-opener": ["@tauri-apps/plugin-opener@2.4.0", "", { "dependencies": { "@tauri-apps/api": "^2.6.0" } }, "sha512-43VyN8JJtvKWJY72WI/KNZszTpDpzHULFxQs0CJBIYUdCRowQ6Q1feWTDb979N7nldqSuDOaBupZ6wz2nvuWwQ=="], 653 656
+1
package.json
··· 29 29 "@tauri-apps/plugin-autostart": "~2.5.0", 30 30 "@tauri-apps/plugin-deep-link": "~2.4.0", 31 31 "@tauri-apps/plugin-fs": "~2.4.0", 32 + "@tauri-apps/plugin-log": "~2", 32 33 "@tauri-apps/plugin-opener": "^2.4.0", 33 34 "@tauri-apps/plugin-process": "~2.3.0", 34 35 "@tauri-apps/plugin-shell": "~2.3.0",
+286
src-tauri/Cargo.lock
··· 18 18 checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" 19 19 20 20 [[package]] 21 + name = "ahash" 22 + version = "0.7.8" 23 + source = "registry+https://github.com/rust-lang/crates.io-index" 24 + checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" 25 + dependencies = [ 26 + "getrandom 0.2.16", 27 + "once_cell", 28 + "version_check", 29 + ] 30 + 31 + [[package]] 21 32 name = "aho-corasick" 22 33 version = "1.1.3" 23 34 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 48 59 checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" 49 60 50 61 [[package]] 62 + name = "android_log-sys" 63 + version = "0.3.2" 64 + source = "registry+https://github.com/rust-lang/crates.io-index" 65 + checksum = "84521a3cf562bc62942e294181d9eef17eb38ceb8c68677bc49f144e4c3d4f8d" 66 + 67 + [[package]] 68 + name = "android_logger" 69 + version = "0.15.1" 70 + source = "registry+https://github.com/rust-lang/crates.io-index" 71 + checksum = "dbb4e440d04be07da1f1bf44fb4495ebd58669372fe0cffa6e48595ac5bd88a3" 72 + dependencies = [ 73 + "android_log-sys", 74 + "env_filter", 75 + "log", 76 + ] 77 + 78 + [[package]] 51 79 name = "android_system_properties" 52 80 version = "0.1.5" 53 81 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 70 98 dependencies = [ 71 99 "derive_arbitrary", 72 100 ] 101 + 102 + [[package]] 103 + name = "arrayvec" 104 + version = "0.7.6" 105 + source = "registry+https://github.com/rust-lang/crates.io-index" 106 + checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" 73 107 74 108 [[package]] 75 109 name = "async-broadcast" ··· 216 250 "tauri-plugin-autostart", 217 251 "tauri-plugin-deep-link", 218 252 "tauri-plugin-fs", 253 + "tauri-plugin-log", 219 254 "tauri-plugin-opener", 220 255 "tauri-plugin-process", 221 256 "tauri-plugin-shell", ··· 315 350 ] 316 351 317 352 [[package]] 353 + name = "bitvec" 354 + version = "1.0.1" 355 + source = "registry+https://github.com/rust-lang/crates.io-index" 356 + checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" 357 + dependencies = [ 358 + "funty", 359 + "radium", 360 + "tap", 361 + "wyz", 362 + ] 363 + 364 + [[package]] 318 365 name = "block-buffer" 319 366 version = "0.10.4" 320 367 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 355 402 ] 356 403 357 404 [[package]] 405 + name = "borsh" 406 + version = "1.5.7" 407 + source = "registry+https://github.com/rust-lang/crates.io-index" 408 + checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce" 409 + dependencies = [ 410 + "borsh-derive", 411 + "cfg_aliases", 412 + ] 413 + 414 + [[package]] 415 + name = "borsh-derive" 416 + version = "1.5.7" 417 + source = "registry+https://github.com/rust-lang/crates.io-index" 418 + checksum = "fdd1d3c0c2f5833f22386f252fe8ed005c7f59fdcddeef025c01b4c3b9fd9ac3" 419 + dependencies = [ 420 + "once_cell", 421 + "proc-macro-crate 3.3.0", 422 + "proc-macro2", 423 + "quote", 424 + "syn 2.0.104", 425 + ] 426 + 427 + [[package]] 358 428 name = "brotli" 359 429 version = "8.0.1" 360 430 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 382 452 checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" 383 453 384 454 [[package]] 455 + name = "byte-unit" 456 + version = "5.1.6" 457 + source = "registry+https://github.com/rust-lang/crates.io-index" 458 + checksum = "e1cd29c3c585209b0cbc7309bfe3ed7efd8c84c21b7af29c8bfae908f8777174" 459 + dependencies = [ 460 + "rust_decimal", 461 + "serde", 462 + "utf8-width", 463 + ] 464 + 465 + [[package]] 466 + name = "bytecheck" 467 + version = "0.6.12" 468 + source = "registry+https://github.com/rust-lang/crates.io-index" 469 + checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" 470 + dependencies = [ 471 + "bytecheck_derive", 472 + "ptr_meta", 473 + "simdutf8", 474 + ] 475 + 476 + [[package]] 477 + name = "bytecheck_derive" 478 + version = "0.6.12" 479 + source = "registry+https://github.com/rust-lang/crates.io-index" 480 + checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" 481 + dependencies = [ 482 + "proc-macro2", 483 + "quote", 484 + "syn 1.0.109", 485 + ] 486 + 487 + [[package]] 385 488 name = "bytemuck" 386 489 version = "1.23.1" 387 490 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 991 1094 ] 992 1095 993 1096 [[package]] 1097 + name = "env_filter" 1098 + version = "0.1.3" 1099 + source = "registry+https://github.com/rust-lang/crates.io-index" 1100 + checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" 1101 + dependencies = [ 1102 + "log", 1103 + "regex", 1104 + ] 1105 + 1106 + [[package]] 994 1107 name = "equivalent" 995 1108 version = "1.0.2" 996 1109 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1050 1163 checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" 1051 1164 dependencies = [ 1052 1165 "simd-adler32", 1166 + ] 1167 + 1168 + [[package]] 1169 + name = "fern" 1170 + version = "0.7.1" 1171 + source = "registry+https://github.com/rust-lang/crates.io-index" 1172 + checksum = "4316185f709b23713e41e3195f90edef7fb00c3ed4adc79769cf09cc762a3b29" 1173 + dependencies = [ 1174 + "log", 1053 1175 ] 1054 1176 1055 1177 [[package]] ··· 1127 1249 ] 1128 1250 1129 1251 [[package]] 1252 + name = "funty" 1253 + version = "2.0.0" 1254 + source = "registry+https://github.com/rust-lang/crates.io-index" 1255 + checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" 1256 + 1257 + [[package]] 1130 1258 name = "futf" 1131 1259 version = "0.1.5" 1132 1260 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1536 1664 version = "0.12.3" 1537 1665 source = "registry+https://github.com/rust-lang/crates.io-index" 1538 1666 checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 1667 + dependencies = [ 1668 + "ahash", 1669 + ] 1539 1670 1540 1671 [[package]] 1541 1672 name = "hashbrown" ··· 2099 2230 version = "0.4.27" 2100 2231 source = "registry+https://github.com/rust-lang/crates.io-index" 2101 2232 checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" 2233 + dependencies = [ 2234 + "value-bag", 2235 + ] 2102 2236 2103 2237 [[package]] 2104 2238 name = "lru-slab" ··· 2302 2436 "proc-macro2", 2303 2437 "quote", 2304 2438 "syn 2.0.104", 2439 + ] 2440 + 2441 + [[package]] 2442 + name = "num_threads" 2443 + version = "0.1.7" 2444 + source = "registry+https://github.com/rust-lang/crates.io-index" 2445 + checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" 2446 + dependencies = [ 2447 + "libc", 2305 2448 ] 2306 2449 2307 2450 [[package]] ··· 2975 3118 ] 2976 3119 2977 3120 [[package]] 3121 + name = "ptr_meta" 3122 + version = "0.1.4" 3123 + source = "registry+https://github.com/rust-lang/crates.io-index" 3124 + checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" 3125 + dependencies = [ 3126 + "ptr_meta_derive", 3127 + ] 3128 + 3129 + [[package]] 3130 + name = "ptr_meta_derive" 3131 + version = "0.1.4" 3132 + source = "registry+https://github.com/rust-lang/crates.io-index" 3133 + checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" 3134 + dependencies = [ 3135 + "proc-macro2", 3136 + "quote", 3137 + "syn 1.0.109", 3138 + ] 3139 + 3140 + [[package]] 2978 3141 name = "quick-xml" 2979 3142 version = "0.38.0" 2980 3143 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3052 3215 version = "5.3.0" 3053 3216 source = "registry+https://github.com/rust-lang/crates.io-index" 3054 3217 checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" 3218 + 3219 + [[package]] 3220 + name = "radium" 3221 + version = "0.7.0" 3222 + source = "registry+https://github.com/rust-lang/crates.io-index" 3223 + checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" 3055 3224 3056 3225 [[package]] 3057 3226 name = "rand" ··· 3250 3419 checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 3251 3420 3252 3421 [[package]] 3422 + name = "rend" 3423 + version = "0.4.2" 3424 + source = "registry+https://github.com/rust-lang/crates.io-index" 3425 + checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" 3426 + dependencies = [ 3427 + "bytecheck", 3428 + ] 3429 + 3430 + [[package]] 3253 3431 name = "reqwest" 3254 3432 version = "0.12.22" 3255 3433 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3305 3483 ] 3306 3484 3307 3485 [[package]] 3486 + name = "rkyv" 3487 + version = "0.7.45" 3488 + source = "registry+https://github.com/rust-lang/crates.io-index" 3489 + checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b" 3490 + dependencies = [ 3491 + "bitvec", 3492 + "bytecheck", 3493 + "bytes", 3494 + "hashbrown 0.12.3", 3495 + "ptr_meta", 3496 + "rend", 3497 + "rkyv_derive", 3498 + "seahash", 3499 + "tinyvec", 3500 + "uuid", 3501 + ] 3502 + 3503 + [[package]] 3504 + name = "rkyv_derive" 3505 + version = "0.7.45" 3506 + source = "registry+https://github.com/rust-lang/crates.io-index" 3507 + checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0" 3508 + dependencies = [ 3509 + "proc-macro2", 3510 + "quote", 3511 + "syn 1.0.109", 3512 + ] 3513 + 3514 + [[package]] 3308 3515 name = "rust-ini" 3309 3516 version = "0.21.2" 3310 3517 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3315 3522 ] 3316 3523 3317 3524 [[package]] 3525 + name = "rust_decimal" 3526 + version = "1.37.2" 3527 + source = "registry+https://github.com/rust-lang/crates.io-index" 3528 + checksum = "b203a6425500a03e0919c42d3c47caca51e79f1132046626d2c8871c5092035d" 3529 + dependencies = [ 3530 + "arrayvec", 3531 + "borsh", 3532 + "bytes", 3533 + "num-traits", 3534 + "rand 0.8.5", 3535 + "rkyv", 3536 + "serde", 3537 + "serde_json", 3538 + ] 3539 + 3540 + [[package]] 3318 3541 name = "rustc-demangle" 3319 3542 version = "0.1.25" 3320 3543 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3460 3683 version = "1.2.0" 3461 3684 source = "registry+https://github.com/rust-lang/crates.io-index" 3462 3685 checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 3686 + 3687 + [[package]] 3688 + name = "seahash" 3689 + version = "4.1.0" 3690 + source = "registry+https://github.com/rust-lang/crates.io-index" 3691 + checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" 3463 3692 3464 3693 [[package]] 3465 3694 name = "selectors" ··· 3723 3952 checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" 3724 3953 3725 3954 [[package]] 3955 + name = "simdutf8" 3956 + version = "0.1.5" 3957 + source = "registry+https://github.com/rust-lang/crates.io-index" 3958 + checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" 3959 + 3960 + [[package]] 3726 3961 name = "siphasher" 3727 3962 version = "0.3.11" 3728 3963 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3970 4205 ] 3971 4206 3972 4207 [[package]] 4208 + name = "tap" 4209 + version = "1.0.1" 4210 + source = "registry+https://github.com/rust-lang/crates.io-index" 4211 + checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" 4212 + 4213 + [[package]] 3973 4214 name = "tar" 3974 4215 version = "0.4.44" 3975 4216 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 4173 4414 ] 4174 4415 4175 4416 [[package]] 4417 + name = "tauri-plugin-log" 4418 + version = "2.6.0" 4419 + source = "registry+https://github.com/rust-lang/crates.io-index" 4420 + checksum = "a59139183e0907cec1499dddee4e085f5a801dc659efa0848ee224f461371426" 4421 + dependencies = [ 4422 + "android_logger", 4423 + "byte-unit", 4424 + "fern", 4425 + "log", 4426 + "objc2 0.6.1", 4427 + "objc2-foundation 0.3.1", 4428 + "serde", 4429 + "serde_json", 4430 + "serde_repr", 4431 + "swift-rs", 4432 + "tauri", 4433 + "tauri-plugin", 4434 + "thiserror 2.0.12", 4435 + "time", 4436 + ] 4437 + 4438 + [[package]] 4176 4439 name = "tauri-plugin-opener" 4177 4440 version = "2.4.0" 4178 4441 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 4478 4741 dependencies = [ 4479 4742 "deranged", 4480 4743 "itoa", 4744 + "libc", 4481 4745 "num-conv", 4746 + "num_threads", 4482 4747 "powerfmt", 4483 4748 "serde", 4484 4749 "time-core", ··· 4943 5208 checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" 4944 5209 4945 5210 [[package]] 5211 + name = "utf8-width" 5212 + version = "0.1.7" 5213 + source = "registry+https://github.com/rust-lang/crates.io-index" 5214 + checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" 5215 + 5216 + [[package]] 4946 5217 name = "utf8_iter" 4947 5218 version = "1.0.4" 4948 5219 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 4959 5230 "serde", 4960 5231 "wasm-bindgen", 4961 5232 ] 5233 + 5234 + [[package]] 5235 + name = "value-bag" 5236 + version = "1.11.1" 5237 + source = "registry+https://github.com/rust-lang/crates.io-index" 5238 + checksum = "943ce29a8a743eb10d6082545d861b24f9d1b160b7d741e0f2cdf726bec909c5" 4962 5239 4963 5240 [[package]] 4964 5241 name = "version-compare" ··· 5726 6003 "windows-core", 5727 6004 "windows-version", 5728 6005 "x11-dl", 6006 + ] 6007 + 6008 + [[package]] 6009 + name = "wyz" 6010 + version = "0.5.1" 6011 + source = "registry+https://github.com/rust-lang/crates.io-index" 6012 + checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" 6013 + dependencies = [ 6014 + "tap", 5729 6015 ] 5730 6016 5731 6017 [[package]]
+1
src-tauri/Cargo.toml
··· 33 33 chrono = { version = "0.4", features = ["serde"] } 34 34 tauri-plugin-websocket = "2" 35 35 tauri-plugin-single-instance = { version = "2", features = ["deep-link"] } 36 + tauri-plugin-log = "2" 36 37 37 38 [target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies] 38 39 tauri-plugin-autostart = "2"
+54 -29
src-tauri/src/background.rs
··· 1 + use chrono::{DateTime, Utc}; 1 2 use serde::{Deserialize, Serialize}; 2 3 use serde_json::json; 3 4 use std::sync::Arc; 4 5 use std::time::{Duration, Instant}; 5 - use tauri::{AppHandle, Emitter}; 6 + use tauri::{App, AppHandle, Emitter, Manager}; 6 7 use tauri_plugin_store::StoreExt; 7 8 use tokio::sync::Mutex; 8 9 use tokio::time::sleep; 9 10 10 11 #[derive(Debug, Clone, Serialize, Deserialize)] 11 12 pub struct BackupSettings { 12 - pub frequency: String, // "daily" or "weekly" 13 - pub last_backup_date: Option<String>, 13 + pub backupFrequency: String, // "daily" or "weekly" 14 + pub lastBackupDate: Option<String>, 14 15 } 15 16 16 17 pub struct BackgroundScheduler { ··· 35 36 drop(is_running); 36 37 37 38 let is_running = self.is_running.clone(); 38 - let app = self.app.clone(); // <-- assuming it's Arc<App> 39 + let app = self.app.clone(); 39 40 40 41 tokio::spawn(async move { 41 - let mut last_check = Instant::now(); 42 - 43 - while *is_running.lock().await { 44 - if last_check.elapsed() >= Duration::from_secs(30 * 60) { 45 - last_check = Instant::now(); 42 + loop { 43 + // Your shared flag 44 + if !*is_running.lock().await { 45 + break; 46 + } 46 47 47 - if let Err(e) = Self::check_and_perform_backup(app.clone()).await { 48 - eprintln!("Background backup check failed: {}", e); 49 - } 48 + // Use cloned app 49 + if let Err(e) = Self::check_and_perform_backup(&app).await { 50 + eprintln!("Background backup check failed: {}", e); 50 51 } 51 52 52 - sleep(Duration::from_secs(5 * 60)).await; 53 + sleep(Duration::from_secs(30 * 60)).await; 53 54 } 54 55 }); 55 56 } ··· 59 60 *is_running = false; 60 61 } 61 62 62 - async fn check_and_perform_backup(app: AppHandle) -> Result<(), Box<dyn std::error::Error>> { 63 + async fn check_and_perform_backup(app: &AppHandle) -> Result<(), Box<dyn std::error::Error>> { 64 + println!("Background: Checking if backup is needed..."); 63 65 // Get settings from store 64 66 let store = app.store("settings.json")?; 65 67 let raw_settings: Option<serde_json::Value> = store.get("settings"); 66 68 67 69 let value = raw_settings.unwrap_or(json!({ 68 - "frequency": "daily", 70 + "backupFrequency": "daily", 69 71 "last_backup_date": null 70 72 })); 71 73 ··· 76 78 println!("Background: Backup due, starting backup..."); 77 79 78 80 // Emit event to frontend to perform backup 79 - app.emit("perform-backup", ())?; 80 - 81 - // Update last backup date 82 - let mut updated_settings = settings; 83 - updated_settings.last_backup_date = Some(chrono::Utc::now().to_rfc3339()); 84 - store.set("settings", json!(updated_settings)); 85 - store.save()?; 81 + match app.emit("perform-backup", serde_json::json!({})) { 82 + Ok(_) => println!("Event emitted successfully"), 83 + Err(e) => eprintln!("Failed to emit event: {}", e), 84 + } 86 85 87 86 println!("Background: Backup completed"); 88 87 } ··· 93 92 async fn should_perform_backup( 94 93 settings: &BackupSettings, 95 94 ) -> Result<bool, Box<dyn std::error::Error>> { 96 - if settings.last_backup_date.is_none() { 95 + println!("[DEBUG] Checking if backup should be performed..."); 96 + 97 + if settings.lastBackupDate.is_none() { 98 + println!("[DEBUG] No last_backup_date found; should perform backup."); 97 99 return Ok(true); 98 100 } 99 101 100 - let last_backup = 101 - chrono::DateTime::parse_from_rfc3339(&settings.last_backup_date.as_ref().unwrap())?; 102 - let now = chrono::Utc::now(); 102 + let last_backup_str = settings.lastBackupDate.as_ref().unwrap(); 103 + println!("[DEBUG] Last backup date string: {}", last_backup_str); 104 + 105 + let last_backup = DateTime::parse_from_rfc3339(last_backup_str)?; 106 + let now = Utc::now(); 103 107 let time_diff = now.signed_duration_since(last_backup); 104 108 105 - let required_interval = match settings.frequency.as_str() { 109 + println!("[DEBUG] Current time: {}", now); 110 + println!("[DEBUG] Last backup time: {}", last_backup); 111 + println!( 112 + "[DEBUG] Time since last backup: {} seconds", 113 + time_diff.num_seconds() 114 + ); 115 + 116 + let required_interval = match settings.backupFrequency.as_str() { 106 117 "daily" => chrono::Duration::days(1), 107 118 "weekly" => chrono::Duration::weeks(1), 108 - _ => chrono::Duration::days(1), 119 + other => { 120 + println!("[DEBUG] Unknown frequency '{}', defaulting to daily", other); 121 + chrono::Duration::days(1) 122 + } 109 123 }; 110 124 125 + println!( 126 + "[DEBUG] Required interval (seconds): {}", 127 + required_interval.num_seconds() 128 + ); 129 + println!( 130 + "[DEBUG] Should perform backup? {}", 131 + time_diff >= required_interval 132 + ); 133 + 111 134 Ok(time_diff >= required_interval) 112 135 } 113 136 } 114 137 115 138 #[tauri::command] 116 - pub async fn start_background_scheduler(app: AppHandle) { 139 + pub async fn start_background_scheduler(app: AppHandle) -> Result<(), String> { 140 + println!("Starting background scheduler..."); 117 141 let scheduler = BackgroundScheduler::new(app); 118 142 scheduler.start().await; 143 + Ok(()) 119 144 } 120 145 121 146 #[tauri::command]
+5 -1
src-tauri/src/lib.rs
··· 7 7 8 8 mod background; 9 9 mod tray; 10 - use background::{start_background_scheduler, stop_background_scheduler}; 10 + use background::stop_background_scheduler; 11 11 use tray::create_system_tray; 12 + 13 + use crate::background::{start_background_scheduler, BackgroundScheduler}; 12 14 13 15 #[tauri::command] 14 16 fn greet(name: &str) -> String { ··· 18 20 #[cfg_attr(mobile, tauri::mobile_entry_point)] 19 21 pub fn run() { 20 22 let builder = tauri::Builder::default() 23 + .plugin(tauri_plugin_log::Builder::new().build()) 21 24 .plugin(tauri_plugin_websocket::init()) 22 25 .plugin(tauri_plugin_shell::init()) 23 26 .plugin(tauri_plugin_process::init()) ··· 37 40 .expect("no main window") 38 41 .set_focus(); 39 42 })) 43 + .plugin(tauri_plugin_log::Builder::new().build()) 40 44 .invoke_handler(tauri::generate_handler![ 41 45 greet, 42 46 start_background_scheduler,
+12
src/App.tsx
··· 27 27 } from "@/components/ui/dialog"; 28 28 import { Progress } from "./components/ui/progress"; 29 29 import { MarkdownRenderer } from "./components/ui/markdown-renderer"; 30 + import { warn, debug, trace, info, error } from "@tauri-apps/plugin-log"; 31 + 32 + function forwardConsole( 33 + fnName: "log" | "debug" | "info" | "warn" | "error", 34 + logger: (message: string) => Promise<void> 35 + ) { 36 + const original = console[fnName]; 37 + console[fnName] = (message) => { 38 + original(message); 39 + logger(message); 40 + }; 41 + } 30 42 31 43 function AppContent() { 32 44 const { isLoading, isAuthenticated, profile, client, login, logout, agent } =
+18 -7
src/lib/backgroundBackup.ts
··· 3 3 import { BackupAgent } from "./backup"; 4 4 import { settingsManager } from "./settings"; 5 5 import { toast } from "sonner"; 6 + import { warn, debug, trace, info, error } from "@tauri-apps/plugin-log"; 7 + import { getCurrentWindow } from "@tauri-apps/api/window"; 6 8 7 9 export class BackgroundBackupService { 8 10 private static instance: BackgroundBackupService; ··· 20 22 async initialize(): Promise<void> { 21 23 if (this.isInitialized) return; 22 24 23 - // Start the background scheduler 25 + // Listen for backup events from the background scheduler 26 + const unlisten = await listen("perform-backup", async () => { 27 + console.log("Background backup event received"); 28 + info("Background backup event received"); 29 + await this.performBackgroundBackup(); 30 + }); 31 + 32 + const window = getCurrentWindow(); 33 + const unlistenwb = await window.listen("perform-backup", async () => { 34 + console.log("Background backup event received"); 35 + await this.performBackgroundBackup(); 36 + }); 37 + 38 + console.log("Background backup service initialized"); 39 + 40 + //Start the background scheduler 24 41 try { 25 42 await invoke("start_background_scheduler"); 26 43 console.log("Background backup scheduler started"); 27 44 } catch (error) { 28 45 console.error("Failed to start background scheduler:", error); 29 46 } 30 - 31 - // Listen for backup events from the background scheduler 32 - await listen("perform-backup", async () => { 33 - console.log("Background backup event received"); 34 - await this.performBackgroundBackup(); 35 - }); 36 47 37 48 this.isInitialized = true; 38 49 }
+1
src/routes/Home.tsx
··· 43 43 DialogTrigger, 44 44 } from "@/components/ui/dialog"; 45 45 import { getCurrentWindow } from "@tauri-apps/api/window"; 46 + import { appDataDir } from "@tauri-apps/api/path"; 46 47 47 48 export function Home({ 48 49 profile,