Krolyxon
Commit 6e8f058

Branches

Refs →

budctlcratesbudctl-guisrcearbuds.rs

92 lines · 3.1 KB · Rust

1//! The Earbud settings page: dual connection, find the buds, and what they run.
2
3use iced::Element;
4use iced::widget::{column, text};
5
6use crate::buds::Buds;
7use crate::icons::Icon;
8use crate::theme::Look;
9use crate::ui;
10use crate::{Item, Marks, Message};
11
12/// The switch for dual connection, by its key.
13pub const DUAL: &str = "dual";
14
15/// What the keyboard cursor can rest on, top to bottom.
16pub fn items(buds: &Buds) -> Vec<Item> {
17 let dual = buds.status.switches.iter().any(|s| s.key == DUAL);
18 dual.then_some(Item::Switch(DUAL))
19 .into_iter()
20 .chain([Item::Find])
21 .collect()
22}
23
24/// `ringing`: the buds were told to ring and not yet to stop.
25pub fn view<'a>(look: Look, buds: &'a Buds, ringing: bool, marks: Marks) -> Element<'a, Message> {
26 let p = look.p;
27 let dual = buds.status.switches.iter().find(|s| s.key == DUAL).map(|dual| {
28 let about = if marks.pending.contains(&Item::Switch(DUAL)) {
29 "Saving…"
30 } else if dual.on {
31 "Your buds stay connected to two devices at once, like your phone and this computer"
32 } else {
33 "Your buds connect to one device at a time"
34 };
35 let row = ui::setting(
36 look,
37 Icon::Dual,
38 "Dual connection",
39 Some(about.to_owned()),
40 ui::switch(look, dual.on),
41 Some(Message::Switch(DUAL, !dual.on)),
42 marks.focus == Some(Item::Switch(DUAL)),
43 );
44 column![ui::heading(look, "Connection"), ui::card(look, vec![row])].spacing(10)
45 });
46 let about = match (marks.pending.contains(&Item::Find), ringing) {
47 (true, false) => "Starting…",
48 (true, true) => "Stopping…",
49 (false, true) => "Ringing: stop it once you have found them",
50 (false, false) => "Plays a loud sound from both buds",
51 };
52 let find = ui::setting(
53 look,
54 Icon::Find,
55 "Find my earbuds",
56 Some(about.to_owned()),
57 ui::pill(look, if ringing { "Stop" } else { "Ring" }, ringing, Message::Find),
58 None,
59 marks.focus == Some(Item::Find),
60 );
61 let value = |value: Option<&'a str>| -> Element<'a, Message> {
62 text(value.unwrap_or("Unknown")).size(14).color(p.dim).into()
63 };
64 let status = &buds.status;
65 let facts = vec![
66 ui::setting(look, Icon::Earbud, "Name", None, value(Some(&buds.name)), None, false),
67 ui::setting(
68 look,
69 Icon::Chip,
70 "Firmware",
71 None,
72 value(status.firmware.as_deref()),
73 None,
74 false,
75 ),
76 ui::setting(
77 look,
78 Icon::Info,
79 "Audio codec",
80 None,
81 value(status.codec.as_deref()),
82 None,
83 false,
84 ),
85 ];
86 column![ui::title(look, "Earbud settings")]
87 .push(dual)
88 .push(column![ui::heading(look, "Find my earbuds"), ui::card(look, vec![find])].spacing(10))
89 .push(column![ui::heading(look, "About these buds"), ui::card(look, facts)].spacing(10))
90 .spacing(18)
91 .into()
92}