From 1ed3f9eb42b37f8cb141d6d04813e6bad4ed2ab9 Mon Sep 17 00:00:00 2001 From: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Date: Wed, 16 Jul 2025 01:48:01 -0300 Subject: [PATCH] Add user handle and plan chip to the user menu (#34522) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A nicer way to visualize in which plan you're in and a bit of personalization by adding the GitHub handle you're signed with in the user menu, as a complement to the avatar photo itself. Taking advantage of the newly added Chip component. CleanShot 2025-07-16 at 1  33 08@2x Release Notes: - N/A --- crates/title_bar/src/title_bar.rs | 60 ++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/crates/title_bar/src/title_bar.rs b/crates/title_bar/src/title_bar.rs index 5c91625412..4b8902d14e 100644 --- a/crates/title_bar/src/title_bar.rs +++ b/crates/title_bar/src/title_bar.rs @@ -34,7 +34,7 @@ use std::sync::Arc; use theme::ActiveTheme; use title_bar_settings::TitleBarSettings; use ui::{ - Avatar, Button, ButtonLike, ButtonStyle, ContextMenu, Icon, IconName, IconSize, + Avatar, Button, ButtonLike, ButtonStyle, Chip, ContextMenu, Icon, IconName, IconSize, IconWithIndicator, Indicator, PopoverMenu, Tooltip, h_flex, prelude::*, }; use util::ResultExt; @@ -631,21 +631,55 @@ impl TitleBar { // Since the user might be on the legacy free plan we filter based on whether we have a subscription period. has_subscription_period }); + + let user_avatar = user.avatar_uri.clone(); + let free_chip_bg = cx + .theme() + .colors() + .editor_background + .opacity(0.5) + .blend(cx.theme().colors().text_accent.opacity(0.05)); + + let pro_chip_bg = cx + .theme() + .colors() + .editor_background + .opacity(0.5) + .blend(cx.theme().colors().text_accent.opacity(0.2)); + PopoverMenu::new("user-menu") .anchor(Corner::TopRight) .menu(move |window, cx| { ContextMenu::build(window, cx, |menu, _, _cx| { - menu.link( - format!( - "Current Plan: {}", - match plan { - None => "None", - Some(proto::Plan::Free) => "Zed Free", - Some(proto::Plan::ZedPro) => "Zed Pro", - Some(proto::Plan::ZedProTrial) => "Zed Pro (Trial)", - } - ), - zed_actions::OpenAccountSettings.boxed_clone(), + let user_login = user.github_login.clone(); + + let (plan_name, label_color, bg_color) = match plan { + None => ("None", Color::Default, free_chip_bg), + Some(proto::Plan::Free) => ("Free", Color::Default, free_chip_bg), + Some(proto::Plan::ZedProTrial) => { + ("Pro Trial", Color::Accent, pro_chip_bg) + } + Some(proto::Plan::ZedPro) => ("Pro", Color::Accent, pro_chip_bg), + }; + + menu.custom_entry( + move |_window, _cx| { + let user_login = user_login.clone(); + + h_flex() + .w_full() + .justify_between() + .child(Label::new(user_login)) + .child( + Chip::new(plan_name.to_string()) + .bg_color(bg_color) + .label_color(label_color), + ) + .into_any_element() + }, + move |_, cx| { + cx.open_url("https://zed.dev/account"); + }, ) .separator() .action("Settings", zed_actions::OpenSettings.boxed_clone()) @@ -675,7 +709,7 @@ impl TitleBar { .children( TitleBarSettings::get_global(cx) .show_user_picture - .then(|| Avatar::new(user.avatar_uri.clone())), + .then(|| Avatar::new(user_avatar)), ) .child( Icon::new(IconName::ChevronDown)