use gpui::{ AnyElement, App, AppContext, Context, Entity, EventEmitter, FocusHandle, Focusable, IntoElement, ParentElement, Render, SharedString, Styled, Window, div, svg, }; use state::NostrRegistry; use theme::ActiveTheme; use ui::button::{Button, ButtonVariants}; use ui::dock::{DockPlacement, Panel, PanelEvent}; use ui::{Icon, IconName, Sizable, StyledExt, h_flex, v_flex}; use crate::panels::profile; use crate::workspace::Workspace; pub fn init(window: &mut Window, cx: &mut App) -> Entity { cx.new(|cx| GreeterPanel::new(window, cx)) } pub struct GreeterPanel { name: SharedString, focus_handle: FocusHandle, } impl GreeterPanel { fn new(_window: &mut Window, cx: &mut App) -> Self { Self { name: "Onboarding".into(), focus_handle: cx.focus_handle(), } } fn add_profile_panel(&mut self, window: &mut Window, cx: &mut Context) { let nostr = NostrRegistry::global(cx); let signer = nostr.read(cx).signer(); if let Some(public_key) = signer.public_key() { cx.spawn_in(window, async move |_this, cx| { cx.update(|window, cx| { Workspace::add_panel( profile::init(public_key, window, cx), DockPlacement::Right, window, cx, ); }) .ok(); }) .detach(); } } } impl Panel for GreeterPanel { fn panel_id(&self) -> SharedString { self.name.clone() } fn title(&self, cx: &App) -> AnyElement { div() .child( svg() .path("brand/coop.svg") .size_4() .text_color(cx.theme().text_muted), ) .into_any_element() } } impl EventEmitter for GreeterPanel {} impl Focusable for GreeterPanel { fn focus_handle(&self, _: &App) -> gpui::FocusHandle { self.focus_handle.clone() } } impl Render for GreeterPanel { fn render(&mut self, _window: &mut Window, cx: &mut Context) -> impl IntoElement { const TITLE: &str = "Welcome to Coop!"; const DESCRIPTION: &str = "Chat Freely, Stay Private on Nostr."; h_flex() .size_full() .items_center() .justify_center() .p_2() .child( v_flex() .h_full() .w_112() .gap_6() .items_center() .justify_center() .child( h_flex() .mb_4() .gap_2() .w_full() .child( svg() .path("brand/coop.svg") .size_12() .text_color(cx.theme().icon_muted), ) .child( v_flex() .child( div() .font_semibold() .text_color(cx.theme().text) .child(SharedString::from(TITLE)), ) .child( div() .text_xs() .text_color(cx.theme().text_muted) .child(SharedString::from(DESCRIPTION)), ), ), ) .child( v_flex() .gap_2() .w_full() .child( h_flex() .gap_2() .w_full() .text_xs() .font_semibold() .text_color(cx.theme().text_muted) .child(SharedString::from("Get Started")) .child(div().flex_1().h_px().bg(cx.theme().border)), ) .child( v_flex() .gap_2() .w_full() .child( Button::new("profile") .icon(Icon::new(IconName::Profile)) .label("Update profile") .ghost() .small() .justify_start() .on_click(cx.listener(move |this, _ev, window, cx| { this.add_profile_panel(window, cx) })), ) .child( Button::new("invite") .icon(Icon::new(IconName::Invite)) .label("Invite friends") .ghost() .small() .justify_start(), ), ), ), ) } }