Erste Version: Tauri-Grundgerüst, WinGet-Anbindung, Selbst-Updater und Release-Skript
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
commit
e0773ba299
84 files changed
+12688
No files matched your search
@@ -0,0 +1,146 @@
|
||||
//! VitosUpdater – einheitliche Paketverwaltung für Windows.
|
||||
|
||||
pub mod commands;
|
||||
pub mod error;
|
||||
pub mod logging;
|
||||
pub mod managers;
|
||||
pub mod models;
|
||||
pub mod process;
|
||||
pub mod settings;
|
||||
pub mod updater;
|
||||
|
||||
use std::path::PathBuf;
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
|
||||
use tauri::{Manager, PhysicalPosition, PhysicalSize, WebviewWindow, WindowEvent};
|
||||
|
||||
use settings::WindowState;
|
||||
|
||||
/// Letzte normale (nicht maximierte) Geometrie und Zähler für das Entprellen des Speicherns.
|
||||
struct WindowTracker {
|
||||
dir: PathBuf,
|
||||
normal: Mutex<Option<WindowState>>,
|
||||
generation: AtomicU64,
|
||||
}
|
||||
|
||||
fn restore_window(window: &WebviewWindow, saved: Option<WindowState>) {
|
||||
if let Some(state) = saved {
|
||||
let monitors: Vec<(i32, i32, u32, u32)> = window
|
||||
.available_monitors()
|
||||
.unwrap_or_default()
|
||||
.iter()
|
||||
.map(|m| (m.position().x, m.position().y, m.size().width, m.size().height))
|
||||
.collect();
|
||||
if settings::is_visible_on(&state, &monitors) {
|
||||
let _ = window.set_size(PhysicalSize::new(state.width, state.height));
|
||||
let _ = window.set_position(PhysicalPosition::new(state.x, state.y));
|
||||
}
|
||||
if state.maximized {
|
||||
let _ = window.maximize();
|
||||
}
|
||||
}
|
||||
let _ = window.show();
|
||||
}
|
||||
|
||||
fn track_window(window: &WebviewWindow, tracker: &Arc<WindowTracker>) {
|
||||
let maximized = window.is_maximized().unwrap_or(false);
|
||||
let minimized = window.is_minimized().unwrap_or(false);
|
||||
if minimized {
|
||||
return;
|
||||
}
|
||||
{
|
||||
let mut normal = tracker.normal.lock().unwrap_or_else(|e| e.into_inner());
|
||||
if !maximized {
|
||||
if let (Ok(pos), Ok(size)) = (window.outer_position(), window.inner_size()) {
|
||||
*normal = Some(WindowState { x: pos.x, y: pos.y, width: size.width, height: size.height, maximized: false });
|
||||
}
|
||||
} else if let Some(state) = normal.as_mut() {
|
||||
state.maximized = true;
|
||||
}
|
||||
}
|
||||
let generation = tracker.generation.fetch_add(1, Ordering::SeqCst) + 1;
|
||||
let tracker = Arc::clone(tracker);
|
||||
tauri::async_runtime::spawn(async move {
|
||||
tokio::time::sleep(Duration::from_millis(500)).await;
|
||||
if tracker.generation.load(Ordering::SeqCst) != generation {
|
||||
return;
|
||||
}
|
||||
let snapshot = *tracker.normal.lock().unwrap_or_else(|e| e.into_inner());
|
||||
if let Some(mut state) = snapshot {
|
||||
state.maximized = maximized;
|
||||
if let Err(err) = settings::save_window_state(&tracker.dir, &state) {
|
||||
tracing::warn!(%err, "Fensterzustand konnte nicht gespeichert werden");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Startet die Anwendung.
|
||||
pub fn run() {
|
||||
let dir = logging::data_dir();
|
||||
let _guard = logging::init(&dir);
|
||||
tracing::info!(version = env!("CARGO_PKG_VERSION"), "VitosUpdater startet");
|
||||
|
||||
let tracker = Arc::new(WindowTracker {
|
||||
dir: dir.clone(),
|
||||
normal: Mutex::new(settings::load_window_state(&dir)),
|
||||
generation: AtomicU64::new(0),
|
||||
});
|
||||
let saved = settings::load_window_state(&dir);
|
||||
let event_tracker = Arc::clone(&tracker);
|
||||
|
||||
let result = tauri::Builder::default()
|
||||
.plugin(tauri_plugin_single_instance::init(|app, _args, _cwd| {
|
||||
if let Some(window) = app.get_webview_window("main") {
|
||||
let _ = window.unminimize();
|
||||
let _ = window.show();
|
||||
let _ = window.set_focus();
|
||||
}
|
||||
}))
|
||||
.plugin(tauri_plugin_opener::init())
|
||||
.plugin(tauri_plugin_notification::init())
|
||||
.plugin(tauri_plugin_updater::Builder::new().build())
|
||||
.manage(commands::Registry::new())
|
||||
.manage(updater::UpdaterState::new(dir.clone()))
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
commands::detect_managers,
|
||||
commands::search_packages,
|
||||
commands::list_installed,
|
||||
commands::list_updates,
|
||||
commands::get_package_details,
|
||||
commands::list_sources,
|
||||
commands::install_winget_module,
|
||||
commands::install_app_installer,
|
||||
updater::updater_ready,
|
||||
updater::get_updater_status,
|
||||
updater::get_update_offer,
|
||||
updater::check_for_update,
|
||||
updater::snooze_update,
|
||||
updater::skip_update,
|
||||
updater::clear_skipped_version,
|
||||
updater::set_update_interval,
|
||||
updater::install_update,
|
||||
updater::take_update_notice,
|
||||
])
|
||||
.setup(move |app| {
|
||||
if let Some(window) = app.get_webview_window("main") {
|
||||
restore_window(&window, saved);
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
.on_window_event(move |window, event| {
|
||||
if matches!(event, WindowEvent::Moved(_) | WindowEvent::Resized(_)) {
|
||||
if let Some(webview) = window.app_handle().get_webview_window(window.label()) {
|
||||
track_window(&webview, &event_tracker);
|
||||
}
|
||||
}
|
||||
})
|
||||
.run(tauri::generate_context!());
|
||||
|
||||
if let Err(err) = result {
|
||||
tracing::error!(%err, "Anwendung wurde mit einem Fehler beendet");
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user