mod commands;
mod config;
#[cfg(desktop)]
mod connection;
#[cfg(mobile)]
#[path = "android/connection.rs"]
mod connection;
mod elevation;
mod export;
mod import;
mod models;
mod profiles;
mod settings;
mod stats;
mod storage;
mod subscriptions;
mod sysproxy;
use connection::Connection;
#[cfg(desktop)]
use tauri::menu::{Menu, MenuItem};
#[cfg(desktop)]
use tauri::tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent};
use tauri::{AppHandle, Manager};
#[cfg(desktop)]
use tauri_plugin_autostart::ManagerExt;
/// Аргумент, с которым автозапуск системы стартует приложение.
pub const AUTOSTART_ARG: &str = "--autostart";
/// Маркер «этот запуск пришёл из автозапуска» для редиректа через задачу
/// Планировщика (adminLaunch): задача запускает exe без аргументов, поэтому
/// обычный процесс перед редиректом оставляет файл-маркер
/// (см. elevation::admin_launch_startup).
pub const AUTOSTART_MARKER: &str = "autostart-redirect.flag";
/// Запущены ли мы автозапуском системы: по аргументу `--autostart` либо по
/// свежему маркеру от процесса, средиректившего нас через Планировщик.
/// Маркер одноразовый — удаляется при любом исходе.
#[cfg(desktop)]
fn launched_via_autostart(app: &AppHandle) -> bool {
let by_arg = std::env::args().any(|a| a == AUTOSTART_ARG);
let mut by_marker = false;
if let Ok(marker) = storage::path(app, AUTOSTART_MARKER) {
if marker.exists() {
by_marker = std::fs::metadata(&marker)
.and_then(|m| m.modified())
.ok()
.and_then(|t| t.elapsed().ok())
.is_some_and(|age| age < std::time::Duration::from_secs(120));
let _ = std::fs::remove_file(&marker);
}
}
by_arg || by_marker
}
/// Перерегистрирует включённый автозапуск: записи, сделанные до появления
/// `--autostart`, не содержат аргумента — enable() идемпотентно докидывает его.
#[cfg(desktop)]
fn refresh_autostart(app: &AppHandle) {
let autolaunch = app.autolaunch();
if autolaunch.is_enabled().unwrap_or(false) {
let _ = autolaunch.enable();
}
}
/// Показывает и фокусирует главное окно (из трея).
#[cfg(desktop)]
fn show_main(app: &AppHandle) {
if let Some(w) = app.get_webview_window("main") {
let _ = w.show();
let _ = w.unminimize();
let _ = w.set_focus();
}
}
/// Иконка в системном трее с меню (Показать / Скрыть / Выход).
#[cfg(desktop)]
fn tray_menu(app: &AppHandle, language: &str) -> tauri::Result