Files
Ely-GPUI-Components/examples/gallery/pages/shell/status.rs
T

170 lines
5.7 KiB
Rust

use ely_gpui_component::{
buttons::{Button, ButtonVariant},
shell::{
Connectivity, CrashReporter, OfflineIndicator, UpdateBanner, UpdateDialog, UpdateState,
ZoomControl,
},
theme::ActiveTheme,
};
use gpui::{App, IntoElement, ParentElement, Styled, Window, div};
use super::chrome::window_frame;
use crate::{
probe::{Opened, probe},
ui::{native_only, row, section, specimen},
};
fn log_action(name: &'static str) -> impl Fn(&mut Window, &mut App) + 'static {
move |_, _| log::info!("gallery: update {name}")
}
pub fn update_banner(cx: &App) -> impl IntoElement + use<> {
let banner = |id: &'static str, state| {
UpdateBanner::new(id, "0.2.0", state)
.on_download(log_action("download"))
.on_restart(log_action("restart"))
.on_later(log_action("later"))
};
section(
"UpdateBanner",
"Offer, download, restart. One slim bar, three states.",
cx,
)
.child(
window_frame(560.0, 126.0, cx)
.bg(cx.theme().colors.bg)
.child(banner("banner-available", UpdateState::Available))
.child(banner("banner-downloading", UpdateState::Downloading(0.42)))
.child(banner("banner-ready", UpdateState::Ready)),
)
}
fn update_dialog() -> UpdateDialog {
UpdateDialog::new("Ely", "0.1.0", "0.2.0", UpdateState::Available)
.note("Window chrome for macOS, Windows and Linux.")
.note("Docks remember their layout across launches.")
.note("Sticky headers stay inside their scroll area.")
.note("Drawers follow the pointer outside their bounds.")
.on_download(log_action("download"))
.on_later(|window, _| window.remove_window())
}
pub fn update_window(cx: &App) -> impl IntoElement + use<> {
section("UpdateDialog", "What changed, then one clear action.", cx)
.child(specimen(
"Inline",
window_frame(400.0, 380.0, cx)
.bg(cx.theme().colors.bg)
.pt_6()
.child(update_dialog().on_later(log_action("later"))),
cx,
))
.child(native_only(probe(
"update-open",
Button::new("update-open", "Open update window")
.variant(ButtonVariant::Outline)
.on_click(|_, _, cx| match update_dialog().open(cx) {
Ok(handle) => Opened::insert("update", handle.into(), cx),
Err(error) => log::error!("gallery: update window failed: {error:#}"),
}),
)))
}
const REPORT: &str = "Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Crashed Thread: 0 main
0 ely 0x0000000104a1c3f0 layout::dock::restore + 112
1 ely 0x0000000104a1b9d4 workspace::apply + 88
2 ely 0x0000000104a0f2a8 app::open_recent + 404
3 libdyld.dylib 0x000000018f2d4f28 start + 4";
pub fn crash_reporter(cx: &App) -> impl IntoElement + use<> {
let reporter = |details: bool| {
CrashReporter::new(
"Ely",
"The report says where it stopped. Sending it helps fix it.",
REPORT,
)
.details(details)
.on_send(|_, _| log::info!("gallery: crash report sent"))
.on_dismiss(|_, _| log::info!("gallery: crash report dismissed"))
};
section(
"CrashReporter",
"Plain words first. The report waits behind a disclosure.",
cx,
)
.child(specimen(
"Inline, report shown",
window_frame(420.0, 520.0, cx)
.bg(cx.theme().colors.bg)
.pt_6()
.child(reporter(true)),
cx,
))
.child(native_only(probe(
"crash-open",
Button::new("crash-open", "Open crash window")
.variant(ButtonVariant::Outline)
.on_click(move |_, _, cx| match reporter(false).open(cx) {
Ok(handle) => Opened::insert("crash", handle.into(), cx),
Err(error) => log::error!("gallery: crash window failed: {error:#}"),
}),
)))
}
pub fn offline(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
let state = window.use_keyed_state("connectivity", cx, |_, _| Connectivity::Online);
let current = *state.read(cx);
let choices = [
("offline-online", "Online", Connectivity::Online),
("offline-offline", "Offline", Connectivity::Offline),
(
"offline-reconnecting",
"Reconnecting",
Connectivity::Reconnecting,
),
];
section(
"OfflineIndicator",
"Quiet while it matters, gone soon after the network returns.",
cx,
)
.child(row().children(choices.map(|(key, label, choice)| {
let state = state.clone();
probe(
key,
Button::new(key, label)
.size(ely_gpui_component::theme::ControlSize::Sm)
.variant(if current == choice {
ButtonVariant::Subtle
} else {
ButtonVariant::Ghost
})
.on_click(move |_, _, cx| {
state.update(cx, |state, cx| {
*state = choice;
cx.notify();
})
}),
)
})))
.child(
div()
.h(cx
.theme()
.control_height(ely_gpui_component::theme::ControlSize::Lg))
.flex()
.items_center()
.child(OfflineIndicator::new("connectivity-pill", current)),
)
}
pub fn zoom(cx: &App) -> impl IntoElement + use<> {
section(
"ZoomControl",
"Scales the whole window through its rem size. Click the number to reset.",
cx,
)
.child(probe("zoom", ZoomControl::new("zoom-control")))
}