Panics · P36 Account: handlers in new; gone accounts, workspaces, providers and roles mark none; expiries refuse overflow

This commit is contained in:
ZacharyZhang-NY committed 2026-10-07 05:59:27 -04:00
1 parent ad472490e0
commit e7aec1651e
19 files changed
+476 -518

No files matched your search

+40 -63
View File
@@ -109,7 +109,7 @@ pub struct AccountSwitcher {
id: ElementId,
accounts: Vec<Account>,
current: SharedString,
on_select: Option<OnKey>,
on_select: OnKey,
on_add: Option<Run>,
}
@@ -118,30 +118,19 @@ impl AccountSwitcher {
id: impl Into<ElementId>,
accounts: impl IntoIterator<Item = Account>,
current: impl Into<SharedString>,
on_select: impl Fn(&SharedString, &mut Window, &mut App) + 'static,
) -> Self {
let (accounts, current): (Vec<_>, SharedString) =
(accounts.into_iter().collect(), current.into());
assert!(
accounts.iter().any(|account| account.key == current),
"account switcher: no account {current}"
);
Self {
id: id.into(),
accounts,
current,
on_select: None,
on_select: Rc::new(on_select),
on_add: None,
}
}
pub fn on_select(
mut self,
handler: impl Fn(&SharedString, &mut Window, &mut App) + 'static,
) -> Self {
self.on_select = Some(Rc::new(handler));
self
}
/// Shows "Add account".
pub fn on_add(mut self, handler: impl Fn(&mut Window, &mut App) + 'static) -> Self {
self.on_add = Some(Rc::new(handler));
@@ -152,9 +141,7 @@ impl AccountSwitcher {
impl RenderOnce for AccountSwitcher {
fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement {
let id = self.id;
let on_select = self
.on_select
.unwrap_or_else(|| panic!("account switcher {id:?} has no on_select"));
let on_select = self.on_select;
let items = self.accounts.iter().map(|account| {
let (key, pick) = (account.key.clone(), on_select.clone());
MenuItem::radio(account.email.clone(), account.key == self.current).on_click(
@@ -175,18 +162,22 @@ impl RenderOnce for AccountSwitcher {
let now = self
.accounts
.into_iter()
.find(|account| account.key == self.current)
.expect("the current account");
let mut avatar = Avatar::new((id.clone(), "avatar"), now.name.clone()).size(AvatarSize::Sm);
if let Some(image) = now.image {
.find(|account| account.key == self.current);
if now.is_none() {
log::error!(
"account switcher {id:?}: no account {}; none current",
self.current
);
}
let name = now
.as_ref()
.map_or_else(|| SharedString::from("No account"), |now| now.name.clone());
let mut avatar = Avatar::new((id.clone(), "avatar"), name.clone()).size(AvatarSize::Sm);
if let Some(image) = now.as_ref().and_then(|now| now.image.clone()) {
avatar = avatar.image(image);
}
let trigger = row(
(id.clone(), "trigger"),
avatar,
named(now.name, now.email, cx),
cx,
);
let email = now.map(|now| now.email).unwrap_or_default();
let trigger = row((id.clone(), "trigger"), avatar, named(name, email, cx), cx);
opening(id, &menu, trigger, window, cx)
}
}
@@ -197,7 +188,7 @@ pub struct WorkspaceSwitcher {
id: ElementId,
workspaces: Vec<Workspace>,
current: SharedString,
on_select: Option<OnKey>,
on_select: OnKey,
on_create: Option<Run>,
}
@@ -206,30 +197,19 @@ impl WorkspaceSwitcher {
id: impl Into<ElementId>,
workspaces: impl IntoIterator<Item = Workspace>,
current: impl Into<SharedString>,
on_select: impl Fn(&SharedString, &mut Window, &mut App) + 'static,
) -> Self {
let (workspaces, current): (Vec<_>, SharedString) =
(workspaces.into_iter().collect(), current.into());
assert!(
workspaces.iter().any(|each| each.key == current),
"workspace switcher: no workspace {current}"
);
Self {
id: id.into(),
workspaces,
current,
on_select: None,
on_select: Rc::new(on_select),
on_create: None,
}
}
pub fn on_select(
mut self,
handler: impl Fn(&SharedString, &mut Window, &mut App) + 'static,
) -> Self {
self.on_select = Some(Rc::new(handler));
self
}
/// Shows "Create workspace".
pub fn on_create(mut self, handler: impl Fn(&mut Window, &mut App) + 'static) -> Self {
self.on_create = Some(Rc::new(handler));
@@ -240,9 +220,7 @@ impl WorkspaceSwitcher {
impl RenderOnce for WorkspaceSwitcher {
fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement {
let id = self.id;
let on_select = self
.on_select
.unwrap_or_else(|| panic!("workspace switcher {id:?} has no on_select"));
let on_select = self.on_select;
let items: Vec<_> = self
.workspaces
.iter()
@@ -267,17 +245,22 @@ impl RenderOnce for WorkspaceSwitcher {
let now = self
.workspaces
.into_iter()
.find(|each| each.key == self.current)
.expect("the current workspace");
let mark = Avatar::new((id.clone(), "mark"), now.name.clone())
.find(|each| each.key == self.current);
if now.is_none() {
log::error!(
"workspace switcher {id:?}: no workspace {}; none current",
self.current
);
}
let name = now.as_ref().map_or_else(
|| SharedString::from("No workspace"),
|now| now.name.clone(),
);
let mark = Avatar::new((id.clone(), "mark"), name.clone())
.square()
.size(AvatarSize::Sm);
let trigger = row(
(id.clone(), "trigger"),
mark,
named(now.name, now.detail, cx),
cx,
);
let detail = now.map(|now| now.detail).unwrap_or_default();
let trigger = row((id.clone(), "trigger"), mark, named(name, detail, cx), cx);
opening(id, &menu, trigger, window, cx)
}
}
@@ -291,7 +274,7 @@ pub struct UserMenu {
image: Option<ImageSource>,
presence: Option<Presence>,
items: Vec<MenuItem>,
on_sign_out: Option<Run>,
on_sign_out: Run,
}
impl UserMenu {
@@ -299,6 +282,7 @@ impl UserMenu {
id: impl Into<ElementId>,
name: impl Into<SharedString>,
email: impl Into<SharedString>,
on_sign_out: impl Fn(&mut Window, &mut App) + 'static,
) -> Self {
Self {
id: id.into(),
@@ -307,7 +291,7 @@ impl UserMenu {
image: None,
presence: None,
items: Vec::new(),
on_sign_out: None,
on_sign_out: Rc::new(on_sign_out),
}
}
@@ -326,19 +310,12 @@ impl UserMenu {
self.items.push(item);
self
}
pub fn on_sign_out(mut self, handler: impl Fn(&mut Window, &mut App) + 'static) -> Self {
self.on_sign_out = Some(Rc::new(handler));
self
}
}
impl RenderOnce for UserMenu {
fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement {
let id = self.id;
let sign_out = self
.on_sign_out
.unwrap_or_else(|| panic!("user menu {id:?} has no on_sign_out"));
let sign_out = self.on_sign_out;
let menu =
Menu::new()
.group(format!("Signed in as {}", self.email), self.items)