feat(home): presence selector as a compact dropdown instead of 3 radios
Replace the three tooltip'd presence radios in the home Friends card with a pick_list dropdown + a one-line explainer for the current choice, mirroring the Settings NetworkMode picker. Add PresenceMode::ALL + a Display impl (descriptive labels) to back the picker. Tightens the Friends card vertically. clippy --all-targets clean, 256 lib tests green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+15
-15
@@ -1453,19 +1453,21 @@ fn friends_panel(state: &AppState) -> Element<'_, AppMessage> {
|
||||
.spacing(0)
|
||||
.width(iced::Length::Fill);
|
||||
|
||||
// Presence posture radios (each with a hover explainer).
|
||||
let presence_radio = |mode: PresenceMode, label: &'static str| -> Element<'_, AppMessage> {
|
||||
tooltip(
|
||||
radio(label, mode, Some(state.config.presence_mode), AppMessage::PresenceModeSelected),
|
||||
container(text(presence_mode_hint(mode)).size(11).color(color_text))
|
||||
.padding(8)
|
||||
.max_width(300.0)
|
||||
.style(c_style(color_crust, color_surface, 6.0)),
|
||||
iced::widget::tooltip::Position::Bottom,
|
||||
// Presence posture: a compact dropdown (mirrors the Settings NetworkMode
|
||||
// picker) with a one-line explainer for the current choice below it.
|
||||
let presence_picker = column![
|
||||
pick_list(
|
||||
&PresenceMode::ALL[..],
|
||||
Some(state.config.presence_mode),
|
||||
AppMessage::PresenceModeSelected,
|
||||
)
|
||||
.gap(8)
|
||||
.into()
|
||||
};
|
||||
.width(iced::Length::Fill),
|
||||
text(presence_mode_hint(state.config.presence_mode))
|
||||
.size(11)
|
||||
.color(color_subtext),
|
||||
]
|
||||
.spacing(4)
|
||||
.width(iced::Length::Fill);
|
||||
|
||||
container(
|
||||
column![
|
||||
@@ -1481,9 +1483,7 @@ fn friends_panel(state: &AppState) -> Element<'_, AppMessage> {
|
||||
add_form,
|
||||
vertical_space(14.0),
|
||||
text("Your presence").size(13).color(color_subtext),
|
||||
presence_radio(PresenceMode::Normal, "Normal — friends only"),
|
||||
presence_radio(PresenceMode::Invisible, "Invisible — appear offline"),
|
||||
presence_radio(PresenceMode::Discoverable, "Discoverable — findable after a move"),
|
||||
presence_picker,
|
||||
]
|
||||
.spacing(6),
|
||||
)
|
||||
|
||||
@@ -35,6 +35,10 @@ pub enum PresenceMode {
|
||||
}
|
||||
|
||||
impl PresenceMode {
|
||||
/// All postures, default first — the option list for the Settings/home picker.
|
||||
pub const ALL: [PresenceMode; 3] =
|
||||
[PresenceMode::Normal, PresenceMode::Invisible, PresenceMode::Discoverable];
|
||||
|
||||
/// Whether this posture publishes to discovery (the only mode that does).
|
||||
pub fn publishes_to_discovery(self) -> bool {
|
||||
matches!(self, PresenceMode::Discoverable)
|
||||
@@ -46,6 +50,17 @@ impl PresenceMode {
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for PresenceMode {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let label = match self {
|
||||
PresenceMode::Normal => "Normal — friends only",
|
||||
PresenceMode::Invisible => "Invisible — appear offline",
|
||||
PresenceMode::Discoverable => "Discoverable — findable after a move",
|
||||
};
|
||||
f.write_str(label)
|
||||
}
|
||||
}
|
||||
|
||||
/// What a peer advertises about the gathering they're currently in. Both fields
|
||||
/// are peer-supplied and therefore untrusted — see [`interpret_pong`], which
|
||||
/// sanitizes the name and validates the ticket before surfacing them.
|
||||
|
||||
Reference in New Issue
Block a user