Fixed automic orientation would fail in some cases

This commit is contained in:
Spxg
2025-05-17 21:18:28 +08:00
parent 5d528f6320
commit 8931532310
3 changed files with 100 additions and 53 deletions

View File

@@ -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()
}}
</SelectConfig>
@@ -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()
}}
</SelectConfig>

View File

@@ -74,25 +74,27 @@ fn handle_connect_db(state: Store<GlobalState>) {
});
}
fn handle_last_error(state: Store<GlobalState>) {
Effect::new(move || {
if state.last_error().read().is_some() {
change_focus(state, Some(Focus::Status));
}
});
}
fn handle_system_theme(state: Store<GlobalState>) {
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<GlobalState>) {
});
}
};
f(query.clone());
let callback = Closure::<dyn Fn(web_sys::MediaQueryList)>::new(f);
query
.add_event_listener_with_callback("change", callback.as_ref().unchecked_ref())
@@ -111,27 +112,28 @@ fn handle_system_theme(state: Store<GlobalState>) {
}
}
fn handle_last_error(state: Store<GlobalState>) {
fn handle_automic_orientation(state: Store<GlobalState>) {
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<GlobalState>) {
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::<dyn Fn(web_sys::MediaQueryList)>::new(f);
if let Some(query) = Orientation::match_media() {
let callback = Closure::<dyn Fn(web_sys::MediaQueryList)>::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<GlobalState>) {
fn gird_style() -> String {
let state = expect_context::<Store<GlobalState>>();
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::<Store<GlobalState>>();
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::<Store<GlobalState>>();
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());

View File

@@ -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<MediaQueryList> {
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<MediaQueryList> {
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"