Skip to content

Commit

Permalink
Incorporate feedback into system tray PR and merge it with new rust c…
Browse files Browse the repository at this point in the history
…ore structure.

Co-authored-by: Neuroblack <[email protected]>
  • Loading branch information
Raphiiko and neuroblack committed May 19, 2023
2 parents 81c6a92 + 4222e5a commit 7776f99
Show file tree
Hide file tree
Showing 18 changed files with 523 additions and 179 deletions.
4 changes: 2 additions & 2 deletions src-shared/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 13 additions & 2 deletions src-tauri/src/commands/splash.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::system_tray::SYSTEMTRAY_MANAGER;
use log::debug;
use tauri::Manager;

Expand All @@ -8,6 +9,16 @@ pub async fn close_splashscreen(window: tauri::Window) {
if let Some(splashscreen) = window.get_window("splashscreen") {
splashscreen.close().unwrap();
}
// Show main window
window.get_window("main").unwrap().show().unwrap();

// Show the window if the "Start in system tray" option is set to false.
// Otherwise, keep the window hidden until the user clicks the system tray icon to show it.
if !SYSTEMTRAY_MANAGER
.lock()
.await
.as_ref()
.unwrap()
.start_in_tray
{
window.get_window("main").unwrap().show().unwrap();
}
}
11 changes: 10 additions & 1 deletion src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ mod image_cache;
mod openvr;
mod os;
mod osc;
mod system_tray;
mod utils;
mod vrc_log_parser;

Expand All @@ -25,6 +26,7 @@ use tauri::{plugin::TauriPlugin, Manager, Wry};
use tauri_plugin_log::{LogTarget, RotationStrategy};

fn main() {
// Construct Oyasumi Tauri application
let app = tauri::Builder::default()
.plugin(tauri_plugin_store::Builder::default().build())
.plugin(tauri_plugin_fs_extra::init())
Expand All @@ -42,8 +44,11 @@ fn main() {
}
Ok(())
})
.system_tray(system_tray::init_system_tray())
.on_system_tray_event(system_tray::handle_system_tray_events())
.on_window_event(system_tray::handle_window_events())
.invoke_handler(configure_command_handlers());

// Run Oyasumi
app.run(tauri::generate_context!())
.expect("An error occurred while running the application");
}
Expand All @@ -65,6 +70,8 @@ fn configure_command_handlers() -> impl Fn(tauri::Invoke) {
osc::commands::osc_valid_addr,
osc::commands::start_osc_server,
osc::commands::stop_osc_server,
system_tray::commands::set_close_to_system_tray,
system_tray::commands::set_start_in_system_tray,
elevated_sidecar::commands::elevation_sidecar_running,
elevated_sidecar::commands::start_elevation_sidecar,
vrc_log_parser::commands::init_vrc_log_watcher,
Expand Down Expand Up @@ -123,6 +130,8 @@ async fn app_setup(app_handle: tauri::AppHandle) {
}
// Get dependencies
let cache_dir = app_handle.path_resolver().app_cache_dir().unwrap();
// Initialize the system tray manager
system_tray::init().await;
// Initialize Image Cache
image_cache::init(cache_dir).await;
// Initialize OpenVR Manager
Expand Down
15 changes: 15 additions & 0 deletions src-tauri/src/system_tray/commands.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use super::{SystemTrayManager, SYSTEMTRAY_MANAGER};

#[tauri::command]
pub async fn set_close_to_system_tray(enabled: bool) {
let mut manager_guard = SYSTEMTRAY_MANAGER.lock().await;
let mut manager: &mut SystemTrayManager = manager_guard.as_mut().unwrap();
manager.close_to_tray = enabled;
}

#[tauri::command]
pub async fn set_start_in_system_tray(enabled: bool) {
let mut manager_guard = SYSTEMTRAY_MANAGER.lock().await;
let mut manager: &mut SystemTrayManager = manager_guard.as_mut().unwrap();
manager.start_in_tray = enabled;
}
79 changes: 79 additions & 0 deletions src-tauri/src/system_tray/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
pub mod commands;

use tauri::{AppHandle, CustomMenuItem, Runtime, SystemTray, SystemTrayEvent, SystemTrayMenu};
use tauri::{GlobalWindowEvent, Manager};
use tokio::sync::Mutex;

const QUIT: &str = "quit";

lazy_static! {
pub static ref SYSTEMTRAY_MANAGER: Mutex<Option<SystemTrayManager>> = Default::default();
}

#[derive(Debug, Clone)]
pub struct SystemTrayManager {
pub close_to_tray: bool,
pub start_in_tray: bool,
}

impl SystemTrayManager {
pub fn new() -> SystemTrayManager {
SystemTrayManager {
close_to_tray: false,
start_in_tray: false,
}
}
}

pub async fn init() {
// Initialize the system tray manager
let system_tray_manager = SystemTrayManager::new();
*SYSTEMTRAY_MANAGER.lock().await = Some(system_tray_manager);
}

// Initializes the system tray with menus.
pub fn init_system_tray() -> SystemTray {
// Menus
let menu_quit = CustomMenuItem::new(QUIT, "Quit");

let tray_menu = SystemTrayMenu::new()
//.add_native_item(SystemTrayMenuItem::Separator)
.add_item(menu_quit);

SystemTray::new().with_menu(tray_menu)
}

pub fn handle_system_tray_events<R: Runtime>(
) -> impl Fn(&AppHandle<R>, SystemTrayEvent) + Send + Sync + 'static {
|app, event| {
match event {
SystemTrayEvent::MenuItemClick { id, .. } => {
if id.as_str() == QUIT {
std::process::exit(0);
}
}
// When clicking the tray icon, restore and focus window.
SystemTrayEvent::LeftClick { .. } => {
let window = app.get_window("main").unwrap();
window.show().unwrap();
window.set_focus().unwrap();
}
_ => {}
};
}
}

pub fn handle_window_events<R: Runtime>() -> impl Fn(GlobalWindowEvent<R>) + Send + Sync + 'static {
|event| {
if let tauri::WindowEvent::CloseRequested { api, .. } = event.event() {
let manager_guard = tauri::async_runtime::block_on(SYSTEMTRAY_MANAGER.lock());
let manager = manager_guard.as_ref().unwrap();
if manager.close_to_tray {
event.window().hide().unwrap();
api.prevent_close();
} else {
std::process::exit(0);
}
}
}
}
15 changes: 13 additions & 2 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ import localeKO from '@angular/common/locales/ko';
import { ResolutionAutomationsViewComponent } from './views/dashboard-view/views/resolution-automations-view/resolution-automations-view.component';
import { RenderResolutionAutomationService } from './services/render-resolution-automation.service';
import { OscGeneralAutomationsService } from './services/osc-general-automations.service';
import { SystemTrayService } from './services/system-tray.service';
import pMinDelay from 'p-min-delay';
import { SPLASH_MIN_DURATION } from './globals';
import { ModalService } from './services/modal.service';
Expand Down Expand Up @@ -237,6 +238,7 @@ export class AppModule {
private brightnessControlService: BrightnessControlService,
private brightnessControlAutomationService: BrightnessControlAutomationService,
private renderResolutionAutomationService: RenderResolutionAutomationService,
private systemTrayService: SystemTrayService,
private eventLog: EventLogService
) {
this.init();
Expand All @@ -249,8 +251,12 @@ export class AppModule {
await CachedValue.cleanCache();
// Preload assets
await this.preloadAssets();
// Initialize app settings and event log
await Promise.all([this.appSettingsService.init(), this.eventLog.init()]);
// Initialize base utilities
await Promise.all([
this.appSettingsService.init(),
this.eventLog.init(),
this.systemTrayService.init(),
]);
// Initialize telemetry
await Promise.all([this.telemetryService.init()]);
// Initialize general utility services
Expand Down Expand Up @@ -299,6 +305,11 @@ export class AppModule {
SPLASH_MIN_DURATION
);
// Close the splash screen after initialization
await Promise.all([
this.appSettingsService.init(),
this.eventLog.init(),
this.systemTrayService.init(),
]);
await invoke('close_splashscreen');
// Show language selection modal if user hasn't picked a language yet
const settings = await firstValueFrom(this.appSettingsService.settings);
Expand Down
18 changes: 6 additions & 12 deletions src/app/migrations/app-settings.migrations.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { cloneDeep } from 'lodash';
import { cloneDeep, merge } from 'lodash';
import { APP_SETTINGS_DEFAULT, AppSettings } from '../models/settings';
import { info } from 'tauri-plugin-log-api';

const migrations: { [v: number]: (data: any) => any } = {
1: toLatest,
1: resetToLatest,
2: from1to2,
3: from2to3,
4: from3to4,
Expand All @@ -14,7 +14,7 @@ export function migrateAppSettings(data: any): AppSettings {
let currentVersion = data.version || 0;
// Reset to latest when the current version is higher than the latest
if (currentVersion > APP_SETTINGS_DEFAULT.version) {
data = toLatest(data);
data = resetToLatest(data);
info(
`[app-settings-migrations] Reset future app settings version back to version ${
currentVersion + ''
Expand All @@ -26,10 +26,11 @@ export function migrateAppSettings(data: any): AppSettings {
currentVersion = data.version;
info(`[app-settings-migrations] Migrated app settings to version ${currentVersion + ''}`);
}
data = merge({}, APP_SETTINGS_DEFAULT, data);
return data as AppSettings;
}

function toLatest(data: any): any {
function resetToLatest(data: any): any {
// Reset to latest
data = cloneDeep(APP_SETTINGS_DEFAULT);
return data;
Expand All @@ -38,8 +39,6 @@ function toLatest(data: any): any {
function from4to5(data: any): any {
data.version = 5;
data.userLanguagePicked = true;
data.oscEnableExpressionMenu = APP_SETTINGS_DEFAULT.oscEnableExpressionMenu;
data.oscEnableExternalControl = APP_SETTINGS_DEFAULT.oscEnableExternalControl;
return data;
}

Expand All @@ -53,12 +52,7 @@ function from3to4(data: any): any {

function from2to3(data: any): any {
data.version = 3;
data.oscSendingHost = APP_SETTINGS_DEFAULT.oscSendingHost;
data.oscSendingPort = APP_SETTINGS_DEFAULT.oscSendingPort;
data.oscReceivingHost = APP_SETTINGS_DEFAULT.oscReceivingHost;
data.oscReceivingPort = APP_SETTINGS_DEFAULT.oscReceivingPort;
data.enableXSOverlayNotifications = APP_SETTINGS_DEFAULT.enableXSOverlayNotifications;
data.enableDesktopNotifications = APP_SETTINGS_DEFAULT.enableDesktopNotifications;
// Missing keys are now always added by default
return data;
}

Expand Down
53 changes: 11 additions & 42 deletions src/app/migrations/automation-configs.migrations.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
import { cloneDeep } from 'lodash';
import { cloneDeep, merge } from 'lodash';
import { AUTOMATION_CONFIGS_DEFAULT, AutomationConfigs } from '../models/automations';
import { info } from 'tauri-plugin-log-api';

const migrations: { [v: number]: (data: any) => any } = {
1: toLatest,
2: toLatest,
1: resetToLatest,
2: resetToLatest,
3: from2to3,
4: from3to4,
5: from4to5,
6: from5to6,
7: from6to7,
8: from7to8,
9: from8to9,
};

export function migrateAutomationConfigs(data: any): AutomationConfigs {
let currentVersion = data.version || 0;
// Reset to latest when the current version is higher than the latest
if (currentVersion > AUTOMATION_CONFIGS_DEFAULT.version) {
data = toLatest(data);
data = resetToLatest(data);
info(
`[automation-configs-migrations] Reset future automation configs version back to version ${
currentVersion + ''
Expand All @@ -34,51 +33,25 @@ export function migrateAutomationConfigs(data: any): AutomationConfigs {
}`
);
}
data = merge({}, AUTOMATION_CONFIGS_DEFAULT, data);
return data as AutomationConfigs;
}

function toLatest(data: any): any {
function resetToLatest(data: any): any {
// Reset to latest
data = cloneDeep(AUTOMATION_CONFIGS_DEFAULT);
return data;
}

function from8to9(data: any): any {
data.version = 9;
data.SLEEP_MODE_ENABLE_FOR_SLEEP_DETECTOR = {
...data.SLEEP_MODE_ENABLE_FOR_SLEEP_DETECTOR,
detectionWindowMinutes:
AUTOMATION_CONFIGS_DEFAULT.SLEEP_MODE_ENABLE_FOR_SLEEP_DETECTOR.detectionWindowMinutes,
};
return data;
}

function from7to8(data: any): any {
data.version = 8;
data.DISPLAY_BRIGHTNESS_ON_SLEEP_MODE_ENABLE = cloneDeep(
AUTOMATION_CONFIGS_DEFAULT.DISPLAY_BRIGHTNESS_ON_SLEEP_MODE_ENABLE
);
data.DISPLAY_BRIGHTNESS_ON_SLEEP_MODE_DISABLE = cloneDeep(
AUTOMATION_CONFIGS_DEFAULT.DISPLAY_BRIGHTNESS_ON_SLEEP_MODE_DISABLE
);
data.RENDER_RESOLUTION_ON_SLEEP_MODE_ENABLE = cloneDeep(
AUTOMATION_CONFIGS_DEFAULT.RENDER_RESOLUTION_ON_SLEEP_MODE_ENABLE
);
data.RENDER_RESOLUTION_ON_SLEEP_MODE_DISABLE = cloneDeep(
AUTOMATION_CONFIGS_DEFAULT.RENDER_RESOLUTION_ON_SLEEP_MODE_DISABLE
);
data.OSC_GENERAL = cloneDeep(AUTOMATION_CONFIGS_DEFAULT.OSC_GENERAL);
// Missing keys are now always added by default
return data;
}

function from6to7(data: any): any {
data.version = 7;
data.SLEEP_MODE_CHANGE_ON_STEAMVR_STATUS = cloneDeep(
AUTOMATION_CONFIGS_DEFAULT.SLEEP_MODE_CHANGE_ON_STEAMVR_STATUS
);
data.SLEEP_MODE_ENABLE_FOR_SLEEP_DETECTOR = cloneDeep(
AUTOMATION_CONFIGS_DEFAULT.SLEEP_MODE_ENABLE_FOR_SLEEP_DETECTOR
);
// Missing keys are now always added by default
return data;
}

Expand All @@ -91,22 +64,18 @@ function from5to6(data: any): any {

function from4to5(data: any): any {
data.version = 5;
data.AUTO_ACCEPT_INVITE_REQUESTS = cloneDeep(
AUTOMATION_CONFIGS_DEFAULT.AUTO_ACCEPT_INVITE_REQUESTS
);
// Missing keys are now always added by default
return data;
}

function from3to4(data: any): any {
data.version = 4;
data.CHANGE_STATUS_BASED_ON_PLAYER_COUNT = cloneDeep(
AUTOMATION_CONFIGS_DEFAULT.CHANGE_STATUS_BASED_ON_PLAYER_COUNT
);
// Missing keys are now always added by default
return data;
}

function from2to3(data: any): any {
data.version = 3;
data.SLEEPING_ANIMATIONS = cloneDeep(AUTOMATION_CONFIGS_DEFAULT.SLEEPING_ANIMATIONS);
// Missing keys are now always added by default
return data;
}
Loading

0 comments on commit 7776f99

Please sign in to comment.