From 8931532310fc41975ad46123833de1c5960e0f98 Mon Sep 17 00:00:00 2001 From: Spxg Date: Sat, 17 May 2025 21:18:28 +0800 Subject: [PATCH] Fixed automic orientation would fail in some cases --- src/app/config_menu.rs | 8 ++-- src/app/playground.rs | 89 ++++++++++++++++++++++-------------------- src/app/state.rs | 56 +++++++++++++++++++++++--- 3 files changed, 100 insertions(+), 53 deletions(-) diff --git a/src/app/config_menu.rs b/src/app/config_menu.rs index 512f97c..d672e49 100644 --- a/src/app/config_menu.rs +++ b/src/app/config_menu.rs @@ -65,7 +65,7 @@ pub fn ConfigMenu() -> impl IntoView { let theme_change = move |event: Event| { if let Some(target) = event.target() { let select = HtmlSelectElement::from(JsValue::from(target)); - state.theme().set(Theme::from_value(&select.value())); + state.theme().set(Theme::from_select(&select.value())); } }; @@ -74,7 +74,7 @@ pub fn ConfigMenu() -> impl IntoView { let select = HtmlSelectElement::from(JsValue::from(target)); state .orientation() - .set(Orientation::from_value(&select.value())); + .set(Orientation::from_select(&select.value())); } }; @@ -103,7 +103,7 @@ pub fn ConfigMenu() -> impl IntoView { {move || { ["System", "Light", "Dark"] .into_iter() - .map(|s| selecet_view(s, &state.theme().read().to_value())) + .map(|s| selecet_view(s, &state.theme().read().select())) .collect_view() }} @@ -111,7 +111,7 @@ pub fn ConfigMenu() -> impl IntoView { {move || { ["Automatic", "Horizontal", "Vertical"] .into_iter() - .map(|s| selecet_view(s, &state.orientation().read().to_value())) + .map(|s| selecet_view(s, &state.orientation().read().select())) .collect_view() }} diff --git a/src/app/playground.rs b/src/app/playground.rs index 1104a79..61f3e5e 100644 --- a/src/app/playground.rs +++ b/src/app/playground.rs @@ -74,25 +74,27 @@ fn handle_connect_db(state: Store) { }); } +fn handle_last_error(state: Store) { + Effect::new(move || { + if state.last_error().read().is_some() { + change_focus(state, Some(Focus::Status)); + } + }); +} + fn handle_system_theme(state: Store) { Effect::new(move || { - let theme = match *state.theme().read() { - Theme::System => { - if let Ok(Some(query)) = window().match_media("(prefers-color-scheme: dark)") { - if query.matches() { "dark" } else { "light" } - } else { - "light" - } - } + let theme = match state.theme().read().value() { Theme::SystemLight | Theme::Light => "light", Theme::SystemDark | Theme::Dark => "dark", + Theme::System => unreachable!(), }; if let Some(element) = document().document_element() { element.set_attribute("data-theme", theme).unwrap() } }); - if let Ok(Some(query)) = window().match_media("(prefers-color-scheme: dark)") { + if let Some(query) = Theme::match_media() { let f = move |query: web_sys::MediaQueryList| { if state.theme().get_untracked().is_system() { state.theme().set(if query.matches() { @@ -102,7 +104,6 @@ fn handle_system_theme(state: Store) { }); } }; - f(query.clone()); let callback = Closure::::new(f); query .add_event_listener_with_callback("change", callback.as_ref().unchecked_ref()) @@ -111,27 +112,28 @@ fn handle_system_theme(state: Store) { } } -fn handle_last_error(state: Store) { +fn handle_automic_orientation(state: Store) { + let auto_change = move |query: web_sys::MediaQueryList| { + if state.orientation().read().is_auto() { + let value = if query.matches() { + Orientation::AutoHorizontal + } else { + Orientation::AutoVertical + }; + state + .orientation() + .maybe_update(|orientation| std::mem::replace(orientation, value) != value); + } + }; + Effect::new(move || { - if state.last_error().read().is_some() { - change_focus(state, Some(Focus::Status)); + if let Some(query) = Orientation::match_media() { + auto_change(query); } }); -} -fn handle_automic_orientation(state: Store) { - if let Ok(Some(query)) = window().match_media("(max-width: 1600px)") { - let f = move |query: web_sys::MediaQueryList| { - if state.orientation().get_untracked().is_auto() { - state.orientation().set(if query.matches() { - Orientation::AutoHorizontal - } else { - Orientation::AutoVertical - }); - } - }; - f(query.clone()); - let callback = Closure::::new(f); + if let Some(query) = Orientation::match_media() { + let callback = Closure::::new(auto_change); query .add_event_listener_with_callback("change", callback.as_ref().unchecked_ref()) .unwrap(); @@ -142,15 +144,16 @@ fn handle_automic_orientation(state: Store) { fn gird_style() -> String { let state = expect_context::>(); - let (focused_grid_style, unfocused_grid_style) = match *state.orientation().read() { + let (focused_grid_style, unfocused_grid_style) = match state.orientation().read().value() { Orientation::Horizontal | Orientation::AutoHorizontal => ( styles::resizeableAreaRowOutputFocused.to_string(), styles::resizeableAreaRowOutputUnfocused.to_string(), ), - Orientation::Automatic | Orientation::Vertical | Orientation::AutoVertical => ( + Orientation::Vertical | Orientation::AutoVertical => ( styles::resizeableAreaColumnOutputFocused.to_string(), styles::resizeableAreaColumnOutputUnfocused.to_string(), ), + Orientation::Automatic => unreachable!(), }; if state.read().is_focus() { @@ -163,24 +166,24 @@ fn gird_style() -> String { fn handle_outer_style() -> String { let state = expect_context::>(); - match *state.orientation().read() { + match state.orientation().read().value() { Orientation::Horizontal | Orientation::AutoHorizontal => { styles::splitRowsGutter.to_string() } - Orientation::Automatic | Orientation::Vertical | Orientation::AutoVertical => { - styles::splitColumnsGutter.to_string() - } + Orientation::Vertical | Orientation::AutoVertical => styles::splitColumnsGutter.to_string(), + Orientation::Automatic => unreachable!(), } } fn handle_inner_style() -> String { let state = expect_context::>(); - match *state.orientation().read() { + match state.orientation().read().value() { Orientation::Horizontal | Orientation::AutoHorizontal => { styles::splitRowsGutterHandle.to_string() } - Orientation::Automatic | Orientation::Vertical | Orientation::AutoVertical => String::new(), + Orientation::Vertical | Orientation::AutoVertical => String::new(), + Orientation::Automatic => unreachable!(), } } @@ -211,19 +214,19 @@ fn ResizableArea() -> impl IntoView { JsValue::null() }; - let options = match *state.orientation().read() { + let options = match state.orientation().read().value() { Orientation::Horizontal | Orientation::AutoHorizontal => SplitOptions { min_size: 100, row_gutters: Some(vec![Gutter { track: 1, element }]), column_gutters: None, }, - Orientation::Automatic | Orientation::Vertical | Orientation::AutoVertical => { - SplitOptions { - min_size: 100, - row_gutters: None, - column_gutters: Some(vec![Gutter { track: 1, element }]), - } - } + Orientation::Vertical | Orientation::AutoVertical => SplitOptions { + min_size: 100, + row_gutters: None, + column_gutters: Some(vec![Gutter { track: 1, element }]), + }, + + Orientation::Automatic => unreachable!(), }; let grid = split_grid::split(&options.into()); on_cleanup(move || grid.destroy()); diff --git a/src/app/state.rs b/src/app/state.rs index c0f7f6c..8e6ee38 100644 --- a/src/app/state.rs +++ b/src/app/state.rs @@ -4,6 +4,7 @@ use aceditor::Editor; use leptos::tachys::dom::window; use reactive_stores::Store; use serde::{Deserialize, Serialize}; +use web_sys::MediaQueryList; use crate::{FragileComfirmed, SQLightError, SQLiteStatementResult, WorkerHandle}; @@ -122,7 +123,7 @@ pub enum Focus { Status, } -#[derive(Clone, Copy, Serialize, Deserialize)] +#[derive(Clone, Copy, Serialize, Deserialize, PartialEq, Eq)] pub enum Theme { System, SystemLight, @@ -136,7 +137,7 @@ impl Theme { matches!(self, Theme::System | Theme::SystemLight | Theme::SystemDark) } - pub fn from_value(s: &str) -> Self { + pub fn from_select(s: &str) -> Self { match s { "System" => Self::System, "Light" => Self::Light, @@ -145,7 +146,30 @@ impl Theme { } } - pub fn to_value(&self) -> String { + pub fn match_media() -> Option { + window() + .match_media("(prefers-color-scheme: dark)") + .ok() + .flatten() + } + + pub fn value(&self) -> Self { + if *self == Theme::System { + Self::match_media() + .map(|query| { + if query.matches() { + Theme::SystemDark + } else { + Theme::SystemLight + } + }) + .unwrap_or_else(|| Theme::SystemDark) + } else { + *self + } + } + + pub fn select(&self) -> String { match self { Theme::System | Theme::SystemLight | Theme::SystemDark => "System", Theme::Light => "Light", @@ -155,7 +179,7 @@ impl Theme { } } -#[derive(Clone, Copy, Serialize, Deserialize)] +#[derive(Clone, Copy, Serialize, Deserialize, PartialEq, Eq)] pub enum Orientation { Automatic, AutoHorizontal, @@ -172,7 +196,7 @@ impl Orientation { ) } - pub fn from_value(s: &str) -> Self { + pub fn from_select(s: &str) -> Self { match s { "Automatic" => Self::Automatic, "Horizontal" => Self::Horizontal, @@ -181,7 +205,27 @@ impl Orientation { } } - pub fn to_value(&self) -> String { + pub fn match_media() -> Option { + window().match_media("(max-width: 1600px)").ok().flatten() + } + + pub fn value(&self) -> Self { + if *self == Orientation::Automatic { + Self::match_media() + .map(|query| { + if query.matches() { + Orientation::AutoHorizontal + } else { + Orientation::AutoVertical + } + }) + .unwrap_or_else(|| Orientation::AutoVertical) + } else { + *self + } + } + + pub fn select(&self) -> String { match self { Orientation::Automatic | Orientation::AutoVertical | Orientation::AutoHorizontal => { "Automatic"