diff --git a/Cargo.lock b/Cargo.lock index e0922217..5898edfe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -270,6 +270,7 @@ dependencies = [ "gloo-net", "ico", "instant", + "rand", "serde", "serde_json", "settings-schema", diff --git a/alvr/dashboard/Cargo.toml b/alvr/dashboard/Cargo.toml index fe431ff9..d00768b0 100644 --- a/alvr/dashboard/Cargo.toml +++ b/alvr/dashboard/Cargo.toml @@ -19,6 +19,7 @@ chrono = "0.4" eframe = "0.23" env_logger = "0.10" ico = "0.3" +rand = "0.8" serde = { version = "1", features = ["derive"] } serde_json = "1" settings-schema = { git = "https://github.com/alvr-org/settings-schema-rs", rev = "676185f" } diff --git a/alvr/dashboard/src/dashboard/components/notifications.rs b/alvr/dashboard/src/dashboard/components/notifications.rs index eb856909..9ceede7f 100644 --- a/alvr/dashboard/src/dashboard/components/notifications.rs +++ b/alvr/dashboard/src/dashboard/components/notifications.rs @@ -6,6 +6,7 @@ use eframe::{ emath::Align, epaint::{Color32, Stroke}, }; +use rand::seq::SliceRandom; use std::time::Duration; #[cfg(target_arch = "wasm32")] @@ -13,30 +14,77 @@ use instant::Instant; #[cfg(not(target_arch = "wasm32"))] use std::time::Instant; -const NO_NOTIFICATIONS: &str = "No new notifications"; const TIMEOUT: Duration = Duration::from_secs(5); +const NO_NOTIFICATIONS_MESSAGE: &str = "No new notifications"; +const NOTIFICATION_TIPS: &[&str] = &[ + // The following tips are ordered roughtly in the order settings appear + r#"If you started having crashes after changing some settings, reset ALVR by deleting "session.json"."#, + r#"Some settings are hidden by default. Click the "Expand" button next to some settings to expand the submenus."#, + r#"It's highly advisable to keep audio setting as default in ALVR and modify the default audio device in the taskbar tray."#, + r#"Increasing "Maximum buffering" may reduce stutters at the cost of more latency."#, + r#"Turning off "Optimize game render latency" may improve streaming smoothness."#, + r#"Sometimes switching between h264 and HEVC codecs is necessary on certain GPUs to fix crashing or fallback to software encoding."#, + r#"If you're using NVIDIA gpu, best to use high bitrate H264, if you're using AMD gpu, HEVC might look better."#, + r#"If you experience "white snow" flickering, reduce the resolution to "Low" and disable "Foveated encoding"."#, + r#"Increasing "Color correction"->"Sharpness" may improve the perceived image quality."#, + r#"If you have problems syncing external controllers or trackers to ALVR tracking space, add one element to "Extra openvr props", then set a custom "Tracking system name"."#, + r#"To change the visual appearance of controllers, set "Controllers"->"Emulation mode"."#, + r#"ALVR supports custom button bindings! If you need help please ask us in the Discord server."#, + r#"ALVR supports hand tracking gestures. Use thumb-index/middle/ring/pinky to activate different buttons. Joystick is enabled by moving the thumb on a closed fist."#, + r#"If hand tracking gestures are annoying, you can disable them in "Controllers"->"Gestures". Alternatively you can enable "Gestures"->"Only touch"."#, + r#"You can fine-tune the controllers responsiveness with "Controllers"->"Prediction"."#, + r#"If the visual controller/hand models does not match the physical controller, you can tweak the offset in "Controllers"->"Left controller position/rotation offset" (affects both controllers)."#, + r#"When using external trackers or controllers you should set both "Position/Rotation recentering mode" to "Disabled"."#, + r#"You can enable tilt mode. Set "Position recentering mode to "Local" and "Rotation recentering mode" to "Tilted"."#, + r#"If you often experience image glitching, you can trade that with stutter frames using "Avoid video glitching"."#, + r#"You can run custom commands/programs at client connection/disconnection using "On connect/disconnect script"."#, + r#"In case you want to report a bug, to get a log file enable "Log to disk". The log will be inside "session_log.txt"."#, + r#"For hacking purposes, you can enable "Log tracking", "Log button presses", "Log haptics". You can get the data using a websocket at ws://localhost:8082/api/events"#, + r#"In case you want to report a bug and share your log, you should enable "Prefer backtrace"."#, + r#"You can quickly cycle through tips like this one by toggling "Show notification tip"."#, + r#"If you want to use body trackers or other SteamVR drivers together with ALVR, set "Driver launch action" to "Unregister ALVR at shutdown""#, + r#"It's handy to enable "Open and close SteamVR with dashboard"."#, + r#"If you want to share a video recording for reporting a bug, you can enable "Rolling video files" to limit the file size of the upload."#, + // Miscellaneous + r#"If your headset does not appear in the clients list it might be in a different subnet. Try "Add client manually"."#, + r#"For audio setup on Linux, check the wiki at https://github.com/alvr-org/ALVR/wiki/Installation-guide#automatic-audio--microphone-setup"#, + r#"ALVR supports wired connection using USB. Check the wiki at https://github.com/alvr-org/ALVR/wiki/ALVR-wired-setup-(ALVR-over-USB)"#, + r#"You can record a video of the gameplay using "Start recording" in the "Debug" category in the sidebar."#, +]; pub struct NotificationBar { message: String, current_level: LogSeverity, receive_instant: Instant, min_notification_level: LogSeverity, + tip_message: Option, expanded: bool, } impl NotificationBar { pub fn new() -> Self { Self { - message: NO_NOTIFICATIONS.into(), + message: NO_NOTIFICATIONS_MESSAGE.into(), current_level: LogSeverity::Debug, receive_instant: Instant::now(), min_notification_level: LogSeverity::Debug, + tip_message: None, expanded: false, } } pub fn update_settings(&mut self, settings: &Settings) { self.min_notification_level = settings.logging.notification_level; + + if settings.logging.show_notification_tip { + if self.tip_message.is_none() { + self.tip_message = NOTIFICATION_TIPS + .choose(&mut rand::thread_rng()) + .map(|s| format!("Tip: {s}")); + } + } else { + self.tip_message = None; + } } pub fn push_notification(&mut self, event: LogEntry) { @@ -53,7 +101,10 @@ impl NotificationBar { pub fn ui(&mut self, context: &egui::Context) { let now = Instant::now(); if now > self.receive_instant + TIMEOUT { - self.message = NO_NOTIFICATIONS.into(); + self.message = self + .tip_message + .clone() + .unwrap_or_else(|| NO_NOTIFICATIONS_MESSAGE.into()); self.current_level = LogSeverity::Debug; } diff --git a/alvr/session/src/settings.rs b/alvr/session/src/settings.rs index 6d01501c..21fad3d8 100644 --- a/alvr/session/src/settings.rs +++ b/alvr/session/src/settings.rs @@ -975,21 +975,31 @@ pub struct RawEventsConfig { #[schema(collapsible)] pub struct LoggingConfig { pub client_log_report_level: Switch, + #[schema(strings(help = "Write logs into the session_log.txt file."))] pub log_to_disk: bool, + #[schema(flag = "real-time")] pub log_tracking: bool, + #[schema(flag = "real-time")] pub log_button_presses: bool, + #[schema(flag = "real-time")] pub log_haptics: bool, + #[schema(flag = "real-time")] pub notification_level: LogSeverity, + #[schema(flag = "real-time")] pub show_raw_events: Switch, + #[schema(strings(help = "This applies only to certain error or warning messages."))] #[schema(flag = "steamvr-restart")] pub prefer_backtrace: bool, + + #[schema(strings(help = "Notification tips teach you how to use ALVR"))] + pub show_notification_tip: bool, } #[derive(SettingsSchema, Serialize, Deserialize, Clone)] @@ -1506,6 +1516,7 @@ pub fn session_settings_default() -> SettingsDefault { }, }, prefer_backtrace: false, + show_notification_tip: true, }, steamvr_launcher: SteamvrLauncherDefault { gui_collapsed: false,