Compare commits
3 Commits
d5bc2a700f
...
ea88c755b5
Author | SHA1 | Date | |
---|---|---|---|
ea88c755b5 | |||
4c88ca0685 | |||
4e8ef3c0b4 |
97
Cargo.lock
generated
97
Cargo.lock
generated
@@ -417,6 +417,7 @@ dependencies = [
|
|||||||
"ctrlc",
|
"ctrlc",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"directories",
|
"directories",
|
||||||
|
"dotenvy",
|
||||||
"image",
|
"image",
|
||||||
"interprocess",
|
"interprocess",
|
||||||
"open",
|
"open",
|
||||||
@@ -425,9 +426,13 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_qs 0.13.0",
|
"serde_qs 0.13.0",
|
||||||
"sha256",
|
"sha256",
|
||||||
|
"tauri-winrt-notification",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"time",
|
||||||
"tokio",
|
"tokio",
|
||||||
"toml",
|
"toml",
|
||||||
|
"tracing",
|
||||||
|
"tracing-subscriber",
|
||||||
"tray-icon",
|
"tray-icon",
|
||||||
"uuid",
|
"uuid",
|
||||||
"windres",
|
"windres",
|
||||||
@@ -2379,7 +2384,7 @@ checksum = "f9c7c7c8ac16c798734b8a24560c1362120597c40d5e1459f09498f8f6c8f2ba"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"windows",
|
"windows 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2522,7 +2527,7 @@ dependencies = [
|
|||||||
"iana-time-zone-haiku",
|
"iana-time-zone-haiku",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"windows-core",
|
"windows-core 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -4467,6 +4472,15 @@ version = "2.0.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
|
checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quick-xml"
|
||||||
|
version = "0.31.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quick-xml"
|
name = "quick-xml"
|
||||||
version = "0.36.2"
|
version = "0.36.2"
|
||||||
@@ -4909,9 +4923,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls"
|
name = "rustls"
|
||||||
version = "0.23.14"
|
version = "0.23.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "415d9944693cb90382053259f89fbb077ea730ad7273047ec63b19bc9b160ba8"
|
checksum = "5fbb44d7acc4e873d613422379f69f237a1b141928c02f6bc6ccfddddc2d7993"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
@@ -4933,9 +4947,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-pki-types"
|
name = "rustls-pki-types"
|
||||||
version = "1.9.0"
|
version = "1.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55"
|
checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-webpki"
|
name = "rustls-webpki"
|
||||||
@@ -5725,6 +5739,18 @@ version = "0.12.16"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tauri-winrt-notification"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e3ecbfeedbd4e41fd66dc3c01951f49af81a824c4f493c02d91b837cf01caf69"
|
||||||
|
dependencies = [
|
||||||
|
"quick-xml 0.31.0",
|
||||||
|
"thiserror",
|
||||||
|
"windows 0.58.0",
|
||||||
|
"windows-version",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.13.0"
|
version = "3.13.0"
|
||||||
@@ -6132,6 +6158,7 @@ dependencies = [
|
|||||||
"sharded-slab",
|
"sharded-slab",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"thread_local",
|
"thread_local",
|
||||||
|
"time",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-core",
|
"tracing-core",
|
||||||
"tracing-log",
|
"tracing-log",
|
||||||
@@ -6632,7 +6659,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "597f2001b2e5fc1121e3d5b9791d3e78f05ba6bfa4641053846248e3a13661c3"
|
checksum = "597f2001b2e5fc1121e3d5b9791d3e78f05ba6bfa4641053846248e3a13661c3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quick-xml",
|
"quick-xml 0.36.2",
|
||||||
"quote",
|
"quote",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -6736,7 +6763,17 @@ version = "0.52.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be"
|
checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-core",
|
"windows-core 0.52.0",
|
||||||
|
"windows-targets 0.52.6",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows"
|
||||||
|
version = "0.58.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6"
|
||||||
|
dependencies = [
|
||||||
|
"windows-core 0.58.0",
|
||||||
"windows-targets 0.52.6",
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -6749,6 +6786,41 @@ dependencies = [
|
|||||||
"windows-targets 0.52.6",
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-core"
|
||||||
|
version = "0.58.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99"
|
||||||
|
dependencies = [
|
||||||
|
"windows-implement",
|
||||||
|
"windows-interface",
|
||||||
|
"windows-result",
|
||||||
|
"windows-strings",
|
||||||
|
"windows-targets 0.52.6",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-implement"
|
||||||
|
version = "0.58.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.79",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-interface"
|
||||||
|
version = "0.58.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.79",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-registry"
|
name = "windows-registry"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
@@ -6861,6 +6933,15 @@ dependencies = [
|
|||||||
"windows_x86_64_msvc 0.52.6",
|
"windows_x86_64_msvc 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-version"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6998aa457c9ba8ff2fb9f13e9d2a930dabcea28f1d0ab94d687d8b3654844515"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets 0.52.6",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_gnullvm"
|
name = "windows_aarch64_gnullvm"
|
||||||
version = "0.42.2"
|
version = "0.42.2"
|
||||||
|
@@ -63,8 +63,8 @@ dotenvy = { version = "0.15.7", optional = true }
|
|||||||
rand = { version = "0.8.5", optional = true }
|
rand = { version = "0.8.5", optional = true }
|
||||||
serde = { version = "1.0.210", features = ["std", "derive"], optional = false }
|
serde = { version = "1.0.210", features = ["std", "derive"], optional = false }
|
||||||
thiserror = { version = "1.0.64", optional = false }
|
thiserror = { version = "1.0.64", optional = false }
|
||||||
tokio = { version = "1.40.0", features = ["full"], optional = true }
|
|
||||||
time = { version = "0.3.36", optional = true }
|
time = { version = "0.3.36", optional = true }
|
||||||
|
tokio = { version = "1.40.0", features = ["full"], optional = true }
|
||||||
tracing = { version = "0.1.40", optional = false }
|
tracing = { version = "0.1.40", optional = false }
|
||||||
tracing-subscriber = { version = "0.3.18", features = [
|
tracing-subscriber = { version = "0.3.18", features = [
|
||||||
"env-filter",
|
"env-filter",
|
||||||
@@ -106,17 +106,17 @@ axum = { version = "0.7.7", optional = true }
|
|||||||
axum-macros = { version = "0.4.2", optional = true }
|
axum-macros = { version = "0.4.2", optional = true }
|
||||||
axum_session = { version = "0.14.0", optional = true }
|
axum_session = { version = "0.14.0", optional = true }
|
||||||
axum_session_sqlx = { version = "0.3.0", optional = true }
|
axum_session_sqlx = { version = "0.3.0", optional = true }
|
||||||
|
http = "1"
|
||||||
tower = { version = "0.4", optional = true, features = ["util"] }
|
tower = { version = "0.4", optional = true, features = ["util"] }
|
||||||
tower-http = { version = "0.6.1", features = ["trace", "fs"], optional = true }
|
tower-http = { version = "0.6.1", features = ["trace", "fs"], optional = true }
|
||||||
tower-layer = { version = "0.3.3", optional = true }
|
tower-layer = { version = "0.3.3", optional = true }
|
||||||
http = "1"
|
|
||||||
validator = "0.18.1"
|
validator = "0.18.1"
|
||||||
|
|
||||||
# OAuth2
|
# OAuth2
|
||||||
base64 = { version = "0.22.1", default-features = false }
|
base64 = { version = "0.22.1", default-features = false }
|
||||||
sha256 = { version = "1.5.0", optional = true } # this fucker has a dependency on tokio?!
|
|
||||||
jsonwebtoken = { version = "9.3.0", optional = true }
|
jsonwebtoken = { version = "9.3.0", optional = true }
|
||||||
serde_qs = "0.13.0"
|
serde_qs = "0.13.0"
|
||||||
|
sha256 = { version = "1.5.0", optional = true } # this fucker has a dependency on tokio?!
|
||||||
|
|
||||||
[[workspace.metadata.leptos]]
|
[[workspace.metadata.leptos]]
|
||||||
name = "avam"
|
name = "avam"
|
||||||
|
@@ -4,34 +4,36 @@ version = "0.1.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tokio = { version = "1.40.0", features = ["full"] }
|
|
||||||
|
|
||||||
tray-icon = "0.19"
|
|
||||||
image = "0.25"
|
|
||||||
winit = "0.30"
|
|
||||||
serde = { version = "1", features = ["derive"] }
|
|
||||||
config = "0.14.0"
|
|
||||||
toml = "0.8"
|
|
||||||
|
|
||||||
directories = "5.0"
|
|
||||||
|
|
||||||
anyhow = { version = "1.0" }
|
anyhow = { version = "1.0" }
|
||||||
thiserror = { version = "1.0" }
|
base64 = { version = "0.22.1", default-features = false }
|
||||||
winreg = "0.52.0"
|
|
||||||
interprocess = { version = "2.2.1", features = ["tokio"] }
|
|
||||||
open = "5.3.0"
|
|
||||||
clap = { version = "4.5.20", features = ["derive"] }
|
clap = { version = "4.5.20", features = ["derive"] }
|
||||||
derive_more = { version = "1.0", features = ["full"] }
|
config = "0.14.0"
|
||||||
uuid = { version = "1.10.0", features = ["fast-rng", "serde", "v4"] }
|
|
||||||
serde_qs = "0.13.0"
|
|
||||||
ctrlc = "3.4.5"
|
ctrlc = "3.4.5"
|
||||||
|
derive_more = { version = "1.0", features = ["full"] }
|
||||||
|
directories = "5.0"
|
||||||
|
dotenvy = "0.15.7"
|
||||||
|
image = "0.25"
|
||||||
|
interprocess = { version = "2.2.1", features = ["tokio"] }
|
||||||
|
tauri-winrt-notification = "0.6.0"
|
||||||
|
open = "5.3.0"
|
||||||
|
rand = "0.8.5"
|
||||||
reqwest = { version = "0.12.8", default-features = false, features = [
|
reqwest = { version = "0.12.8", default-features = false, features = [
|
||||||
"rustls-tls",
|
"rustls-tls",
|
||||||
"json",
|
"json",
|
||||||
] }
|
] }
|
||||||
rand = "0.8.5"
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
serde_qs = "0.13.0"
|
||||||
sha256 = "1.5.0"
|
sha256 = "1.5.0"
|
||||||
base64 = { version = "0.22.1", default-features = false }
|
thiserror = { version = "1.0" }
|
||||||
|
time = "0.3.36"
|
||||||
|
tokio = { version = "1.40.0", features = ["full"] }
|
||||||
|
toml = "0.8"
|
||||||
|
tracing = "0.1.40"
|
||||||
|
tracing-subscriber = { version = "0.3.18", features = ["time"] }
|
||||||
|
tray-icon = "0.19"
|
||||||
|
uuid = { version = "1.10.0", features = ["fast-rng", "serde", "v4"] }
|
||||||
|
winit = "0.30"
|
||||||
|
winreg = "0.52.0"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
windres = "0.2"
|
windres = "0.2"
|
||||||
|
@@ -1,15 +1,30 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use tauri_winrt_notification::Toast;
|
||||||
use tokio::sync::broadcast::{Receiver, Sender};
|
use tokio::sync::broadcast::{Receiver, Sender};
|
||||||
use tray_icon::menu::{MenuId, MenuItem};
|
use tray_icon::menu::{MenuId, MenuItem};
|
||||||
use winit::{
|
use winit::{
|
||||||
application::ApplicationHandler,
|
application::ApplicationHandler,
|
||||||
event::StartCause,
|
event::StartCause,
|
||||||
event_loop::{ActiveEventLoop, ControlFlow},
|
event_loop::{ActiveEventLoop, ControlFlow, EventLoop},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{config::Config, icon::TrayIcon, oauth, state_machine::Event, BASE_URL};
|
use crate::{config::Config, icon::TrayIcon, oauth, state_machine::Event, BASE_URL};
|
||||||
|
|
||||||
|
pub async fn start(
|
||||||
|
config: Config,
|
||||||
|
sender: Sender<Event>,
|
||||||
|
receiver: Receiver<Event>,
|
||||||
|
) -> Result<(), anyhow::Error> {
|
||||||
|
let mut app = App::new(config, sender, receiver)?;
|
||||||
|
let event_loop = EventLoop::new()?;
|
||||||
|
|
||||||
|
event_loop.run_app(&mut app)?;
|
||||||
|
tracing::info!("EventLoop Shutdown");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub struct App {
|
pub struct App {
|
||||||
config: Config,
|
config: Config,
|
||||||
tray_icon: TrayIcon,
|
tray_icon: TrayIcon,
|
||||||
@@ -112,7 +127,7 @@ impl ApplicationHandler for App {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
Event::Quit => {
|
Event::Quit => {
|
||||||
println!("Shutting down EventLoop");
|
tracing::info!("Shutting down EventLoop");
|
||||||
event_loop.exit()
|
event_loop.exit()
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
@@ -126,6 +141,14 @@ impl ApplicationHandler for App {
|
|||||||
let _ = self.sender.send(Event::Ready {
|
let _ = self.sender.send(Event::Ready {
|
||||||
config: self.config.clone(),
|
config: self.config.clone(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if !self.config.toast_shown() {
|
||||||
|
let _ = Toast::new(crate::AVAM_APP_ID)
|
||||||
|
.title("Avam is running in your system tray!")
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = self.config.set_toast_shown(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn window_event(
|
fn window_event(
|
||||||
|
@@ -15,6 +15,8 @@ use crate::{
|
|||||||
pub struct Config {
|
pub struct Config {
|
||||||
#[serde(with = "arc_rwlock_serde")]
|
#[serde(with = "arc_rwlock_serde")]
|
||||||
token: Arc<RwLock<Option<String>>>,
|
token: Arc<RwLock<Option<String>>>,
|
||||||
|
#[serde(with = "arc_rwlock_serde")]
|
||||||
|
toast_shown: Arc<RwLock<bool>>,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
code_verifier: Arc<RwLock<Option<CodeVerifier>>>,
|
code_verifier: Arc<RwLock<Option<CodeVerifier>>>,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
@@ -27,6 +29,7 @@ impl Default for Config {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
token: Default::default(),
|
token: Default::default(),
|
||||||
|
toast_shown: Default::default(),
|
||||||
code_verifier: Default::default(),
|
code_verifier: Default::default(),
|
||||||
code_challenge_method: Default::default(),
|
code_challenge_method: Default::default(),
|
||||||
open_browser: Arc::new(RwLock::new(true)),
|
open_browser: Arc::new(RwLock::new(true)),
|
||||||
@@ -49,6 +52,8 @@ pub enum ConfigError {
|
|||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Toml(#[from] toml::ser::Error),
|
Toml(#[from] toml::ser::Error),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
|
Config(#[from] config::ConfigError),
|
||||||
|
#[error(transparent)]
|
||||||
Unknown(#[from] anyhow::Error),
|
Unknown(#[from] anyhow::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,6 +69,18 @@ impl Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
pub(crate) fn toast_shown(&self) -> bool {
|
||||||
|
*self.toast_shown.read().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn set_toast_shown(&self, value: bool) -> Result<(), ConfigError> {
|
||||||
|
*self.toast_shown.write().unwrap() = value;
|
||||||
|
self.write()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
pub fn set_code_verifier(
|
pub fn set_code_verifier(
|
||||||
&self,
|
&self,
|
||||||
@@ -110,7 +127,12 @@ impl Config {
|
|||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let config: Self = config.try_deserialize().unwrap_or_default();
|
let token = config.get_string("token").ok();
|
||||||
|
let toast_shown = config.get_bool("toast_shown").unwrap_or_default();
|
||||||
|
let config = Self::default();
|
||||||
|
|
||||||
|
config.set_token(token)?;
|
||||||
|
config.set_toast_shown(toast_shown)?;
|
||||||
|
|
||||||
config.write()?;
|
config.write()?;
|
||||||
|
|
||||||
|
@@ -40,4 +40,23 @@ impl Dirs {
|
|||||||
c.push(".lock");
|
c.push(".lock");
|
||||||
Ok(c)
|
Ok(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
pub fn get_log_dir() -> Result<PathBuf, DirsError> {
|
||||||
|
let c = Self::get_config_dir()?;
|
||||||
|
let mut log_dir = c.parent().unwrap().to_path_buf();
|
||||||
|
log_dir.push("logs");
|
||||||
|
if !log_dir.exists() {
|
||||||
|
std::fs::create_dir_all(&log_dir)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(log_dir.to_path_buf())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
pub fn get_log_file() -> Result<PathBuf, DirsError> {
|
||||||
|
let mut l = Self::get_log_dir()?;
|
||||||
|
l.push("avam.log");
|
||||||
|
Ok(l)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -97,7 +97,7 @@ impl TrayIcon {
|
|||||||
if let Some(item) = self.menu_items.get(id) {
|
if let Some(item) = self.menu_items.get(id) {
|
||||||
if let Some(i) = self.menu.items().iter().find(|i| i.id() == id) {
|
if let Some(i) = self.menu.items().iter().find(|i| i.id() == id) {
|
||||||
if let Err(e) = item(i) {
|
if let Err(e) = item(i) {
|
||||||
eprintln!("{:#?}", e);
|
tracing::error!("{:#?}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||||
#![allow(clippy::needless_return)]
|
#![allow(clippy::needless_return)]
|
||||||
|
|
||||||
mod app;
|
mod app;
|
||||||
@@ -17,7 +18,9 @@ use oauth::{start_code_listener, start_code_to_token};
|
|||||||
use pipe::Pipe;
|
use pipe::Pipe;
|
||||||
use state_machine::Event;
|
use state_machine::Event;
|
||||||
use tokio::task::JoinSet;
|
use tokio::task::JoinSet;
|
||||||
|
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||||
|
|
||||||
|
pub static AVAM_APP_ID: &str = "AvamToast-ECEB71694A5E6105";
|
||||||
pub static BASE_URL: &str = "https://avam.avii.nl";
|
pub static BASE_URL: &str = "https://avam.avii.nl";
|
||||||
pub static PROJECT_NAME: &str = "Avii's Virtual Airline Manager";
|
pub static PROJECT_NAME: &str = "Avii's Virtual Airline Manager";
|
||||||
pub static COPYRIGHT: &str = "Avii's Virtual Airline Manager © 2024";
|
pub static COPYRIGHT: &str = "Avii's Virtual Airline Manager © 2024";
|
||||||
@@ -35,6 +38,10 @@ pub struct Arguments {
|
|||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), anyhow::Error> {
|
async fn main() -> Result<(), anyhow::Error> {
|
||||||
|
dotenvy::dotenv().ok();
|
||||||
|
|
||||||
|
init_logging()?;
|
||||||
|
|
||||||
let (event_sender, event_receiver) = tokio::sync::broadcast::channel(1);
|
let (event_sender, event_receiver) = tokio::sync::broadcast::channel(1);
|
||||||
let args = Arguments::parse();
|
let args = Arguments::parse();
|
||||||
|
|
||||||
@@ -43,6 +50,7 @@ async fn main() -> Result<(), anyhow::Error> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
register_url_scheme()?;
|
register_url_scheme()?;
|
||||||
|
register_notification_handler()?;
|
||||||
|
|
||||||
let config = Config::new()?;
|
let config = Config::new()?;
|
||||||
|
|
||||||
@@ -52,7 +60,7 @@ async fn main() -> Result<(), anyhow::Error> {
|
|||||||
let sender = event_sender.clone();
|
let sender = event_sender.clone();
|
||||||
let mut ctrl_c_counter = 0;
|
let mut ctrl_c_counter = 0;
|
||||||
ctrlc::set_handler(move || {
|
ctrlc::set_handler(move || {
|
||||||
println!("CTRL_C: Quit singal sent");
|
tracing::info!("CTRL_C: Quit singal sent");
|
||||||
ctrl_c_counter += 1;
|
ctrl_c_counter += 1;
|
||||||
if ctrl_c_counter >= 3 {
|
if ctrl_c_counter >= 3 {
|
||||||
let _ = unregister_url_scheme();
|
let _ = unregister_url_scheme();
|
||||||
@@ -61,7 +69,7 @@ async fn main() -> Result<(), anyhow::Error> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Err(e) = sender.send(Event::Quit) {
|
if let Err(e) = sender.send(Event::Quit) {
|
||||||
println!("{:#?}", e)
|
tracing::error!("{:#?}", e)
|
||||||
};
|
};
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@@ -86,7 +94,7 @@ async fn main() -> Result<(), anyhow::Error> {
|
|||||||
let c = config.clone();
|
let c = config.clone();
|
||||||
let sender = event_sender.clone();
|
let sender = event_sender.clone();
|
||||||
let receiver = event_receiver.resubscribe();
|
let receiver = event_receiver.resubscribe();
|
||||||
start_tray_icon(c, sender, receiver).await?;
|
app::start(c, sender, receiver).await?;
|
||||||
|
|
||||||
// Wait for everything to finish
|
// Wait for everything to finish
|
||||||
while let Some(result) = futures.join_next().await {
|
while let Some(result) = futures.join_next().await {
|
||||||
@@ -97,28 +105,12 @@ async fn main() -> Result<(), anyhow::Error> {
|
|||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
unregister_url_scheme()?;
|
unregister_url_scheme()?;
|
||||||
|
unregister_notification_handler()?;
|
||||||
Lock::unlock();
|
Lock::unlock();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
use app::App;
|
|
||||||
use tokio::sync::broadcast::{Receiver, Sender};
|
|
||||||
use winit::event_loop::EventLoop;
|
|
||||||
async fn start_tray_icon(
|
|
||||||
config: Config,
|
|
||||||
sender: Sender<Event>,
|
|
||||||
receiver: Receiver<Event>,
|
|
||||||
) -> Result<(), anyhow::Error> {
|
|
||||||
let mut app = App::new(config, sender, receiver)?;
|
|
||||||
let event_loop = EventLoop::new()?;
|
|
||||||
|
|
||||||
event_loop.run_app(&mut app)?;
|
|
||||||
println!("EventLoop Shutdonw");
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
@@ -178,3 +170,72 @@ fn unregister_url_scheme() -> Result<(), anyhow::Error> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn register_notification_handler() -> Result<(), anyhow::Error> {
|
||||||
|
use winreg::enums::*;
|
||||||
|
use winreg::RegKey;
|
||||||
|
|
||||||
|
let hkcu = RegKey::predef(HKEY_CURRENT_USER);
|
||||||
|
let avam_schema_root = hkcu.create_subkey(format!(
|
||||||
|
"Software\\Classes\\AppUserModelId\\{}",
|
||||||
|
AVAM_APP_ID
|
||||||
|
))?;
|
||||||
|
let current_exec = std::env::current_exe()?;
|
||||||
|
let mut icon = current_exec.parent().unwrap().to_path_buf();
|
||||||
|
icon.push("icon.png");
|
||||||
|
|
||||||
|
avam_schema_root
|
||||||
|
.0
|
||||||
|
.set_value("DisplayName", &crate::PROJECT_NAME)?;
|
||||||
|
avam_schema_root.0.set_value("IconBackgroundColor", &"0")?;
|
||||||
|
avam_schema_root
|
||||||
|
.0
|
||||||
|
.set_value("IconUri", &icon.to_str().unwrap())?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unregister_notification_handler() -> Result<(), anyhow::Error> {
|
||||||
|
use winreg::enums::*;
|
||||||
|
use winreg::RegKey;
|
||||||
|
|
||||||
|
let hkcu = RegKey::predef(HKEY_CURRENT_USER);
|
||||||
|
hkcu.delete_subkey_all(format!(
|
||||||
|
"Software\\Classes\\AppUserModelId\\{}",
|
||||||
|
AVAM_APP_ID
|
||||||
|
))
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init_logging() -> Result<(), anyhow::Error> {
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
use dirs::Dirs;
|
||||||
|
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
use std::{
|
||||||
|
fs::{self, File},
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
let log_file = Dirs::get_log_file()?;
|
||||||
|
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
if !log_file.exists() {
|
||||||
|
fs::write(&log_file, "")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
let file = File::options().append(true).open(&log_file)?;
|
||||||
|
|
||||||
|
let fmt = tracing_subscriber::fmt::layer();
|
||||||
|
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
let fmt = fmt.with_ansi(false).with_writer(Arc::new(file));
|
||||||
|
|
||||||
|
tracing_subscriber::registry().with(fmt).init();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
@@ -60,7 +60,7 @@ pub async fn start_code_to_token(
|
|||||||
tokio::select! {
|
tokio::select! {
|
||||||
_ = sleep(Duration::from_millis(100)) => {
|
_ = sleep(Duration::from_millis(100)) => {
|
||||||
if let Ok(Event::Quit) = event_receiver.try_recv() {
|
if let Ok(Event::Quit) = event_receiver.try_recv() {
|
||||||
println!("Shutting down Code Transformer");
|
tracing::info!("Shutting down Code Transformer");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,6 +90,6 @@ pub async fn start_code_to_token(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Code Transformer Shutdown");
|
tracing::info!("Code Transformer Shutdown");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@@ -61,20 +61,20 @@ impl Pipe {
|
|||||||
let new_sender = pipe_sender.clone();
|
let new_sender = pipe_sender.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
if let Err(e) = Self::handle_conn(conn, new_sender).await {
|
if let Err(e) = Self::handle_conn(conn, new_sender).await {
|
||||||
eprintln!("error while handling connection: {e}");
|
tracing::error!("error while handling connection: {e}");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
_ = sleep(Duration::from_millis(100)) => {
|
_ = sleep(Duration::from_millis(100)) => {
|
||||||
if let Ok(Event::Quit) = quit_signal.try_recv() {
|
if let Ok(Event::Quit) = quit_signal.try_recv() {
|
||||||
println!("Shutting down Code Listener");
|
tracing::info!("Shutting down Code Listener");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Code Listener Shutdown");
|
tracing::info!("Code Listener Shutdown");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -21,7 +21,7 @@ pub enum State {
|
|||||||
token: String,
|
token: String,
|
||||||
},
|
},
|
||||||
WaitForSim,
|
WaitForSim,
|
||||||
Running,
|
InSim,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
@@ -69,10 +69,10 @@ impl State {
|
|||||||
|
|
||||||
(State::Connect { .. }, Event::Connected) => todo!(), // Goto WaitForSim
|
(State::Connect { .. }, Event::Connected) => todo!(), // Goto WaitForSim
|
||||||
|
|
||||||
(State::WaitForSim, Event::SimConnected) => todo!(), // Goto Running
|
(State::WaitForSim, Event::SimConnected) => todo!(), // Goto InSim
|
||||||
|
|
||||||
(State::Running, Event::Disconnected) => todo!(), // Goto Connect
|
(_, Event::Disconnected) => todo!(), // Goto Connect
|
||||||
(State::Running, Event::SimDisconnected) => todo!(), // Goto WaitForSim
|
(State::InSim, Event::SimDisconnected) => todo!(), // Goto WaitForSim
|
||||||
|
|
||||||
(_, Event::Quit) => todo!(), // All events can go into quit, to shutdown the application
|
(_, Event::Quit) => todo!(), // All events can go into quit, to shutdown the application
|
||||||
|
|
||||||
@@ -115,12 +115,9 @@ impl State {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
State::Connect { token } => {
|
State::Connect { .. } => Ok(()),
|
||||||
println!("Holyshit we've got a token: {}", token);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
State::WaitForSim => Ok(()),
|
State::WaitForSim => Ok(()),
|
||||||
State::Running => Ok(()),
|
State::InSim => Ok(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -137,7 +134,7 @@ pub async fn start(
|
|||||||
loop {
|
loop {
|
||||||
if let Ok(event) = event_receiver.recv().await {
|
if let Ok(event) = event_receiver.recv().await {
|
||||||
if event == Event::Quit {
|
if event == Event::Quit {
|
||||||
println!("Shutting down State Machine");
|
tracing::info!("Shutting down State Machine");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,6 +150,6 @@ pub async fn start(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("State Machine Shutdown");
|
tracing::info!("State Machine Shutdown");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user