Render an offline icon in titlebar when connection is lost
Co-Authored-By: Max Brunsfeld <maxbrunsfeld@gmail.com>
This commit is contained in:
co-authored by
Max Brunsfeld
parent
e212461dfe
commit
99a2dc4880
@@ -209,7 +209,7 @@ impl ChatPanel {
|
||||
Flex::column()
|
||||
.with_child(
|
||||
Container::new(ChildView::new(self.channel_select.id()).boxed())
|
||||
.with_style(&theme.chat_panel.channel_select.container)
|
||||
.with_style(theme.chat_panel.channel_select.container)
|
||||
.boxed(),
|
||||
)
|
||||
.with_child(self.render_active_channel_messages())
|
||||
@@ -243,7 +243,7 @@ impl ChatPanel {
|
||||
)
|
||||
.boxed(),
|
||||
)
|
||||
.with_style(&theme.sender.container)
|
||||
.with_style(theme.sender.container)
|
||||
.boxed(),
|
||||
)
|
||||
.with_child(
|
||||
@@ -254,7 +254,7 @@ impl ChatPanel {
|
||||
)
|
||||
.boxed(),
|
||||
)
|
||||
.with_style(&theme.timestamp.container)
|
||||
.with_style(theme.timestamp.container)
|
||||
.boxed(),
|
||||
)
|
||||
.boxed(),
|
||||
@@ -262,14 +262,14 @@ impl ChatPanel {
|
||||
.with_child(Text::new(message.body.clone(), theme.body.clone()).boxed())
|
||||
.boxed(),
|
||||
)
|
||||
.with_style(&theme.container)
|
||||
.with_style(theme.container)
|
||||
.boxed()
|
||||
}
|
||||
|
||||
fn render_input_box(&self) -> ElementBox {
|
||||
let theme = &self.settings.borrow().theme;
|
||||
Container::new(ChildView::new(self.input_editor.id()).boxed())
|
||||
.with_style(&theme.chat_panel.input_editor.container)
|
||||
.with_style(theme.chat_panel.input_editor.container)
|
||||
.boxed()
|
||||
}
|
||||
|
||||
@@ -293,13 +293,13 @@ impl ChatPanel {
|
||||
Flex::row()
|
||||
.with_child(
|
||||
Container::new(Label::new("#".to_string(), theme.hash.text.clone()).boxed())
|
||||
.with_style(&theme.hash.container)
|
||||
.with_style(theme.hash.container)
|
||||
.boxed(),
|
||||
)
|
||||
.with_child(Label::new(channel.name.clone(), theme.name.clone()).boxed())
|
||||
.boxed(),
|
||||
)
|
||||
.with_style(&theme.container)
|
||||
.with_style(theme.container)
|
||||
.boxed()
|
||||
}
|
||||
|
||||
@@ -387,7 +387,7 @@ impl View for ChatPanel {
|
||||
};
|
||||
ConstrainedBox::new(
|
||||
Container::new(element)
|
||||
.with_style(&theme.chat_panel.container)
|
||||
.with_style(theme.chat_panel.container)
|
||||
.boxed(),
|
||||
)
|
||||
.with_min_width(150.)
|
||||
|
||||
@@ -88,13 +88,13 @@ impl View for FileFinder {
|
||||
Flex::new(Axis::Vertical)
|
||||
.with_child(
|
||||
Container::new(ChildView::new(self.query_editor.id()).boxed())
|
||||
.with_style(&settings.theme.selector.input_editor.container)
|
||||
.with_style(settings.theme.selector.input_editor.container)
|
||||
.boxed(),
|
||||
)
|
||||
.with_child(Flexible::new(1.0, self.render_matches()).boxed())
|
||||
.boxed(),
|
||||
)
|
||||
.with_style(&settings.theme.selector.container)
|
||||
.with_style(settings.theme.selector.container)
|
||||
.boxed(),
|
||||
)
|
||||
.with_max_width(500.0)
|
||||
@@ -127,7 +127,7 @@ impl FileFinder {
|
||||
)
|
||||
.boxed(),
|
||||
)
|
||||
.with_style(&settings.theme.selector.empty.container)
|
||||
.with_style(settings.theme.selector.empty.container)
|
||||
.named("empty matches");
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ impl FileFinder {
|
||||
)
|
||||
.boxed(),
|
||||
)
|
||||
.with_style(&style.container);
|
||||
.with_style(style.container);
|
||||
|
||||
let action = Select(Entry {
|
||||
worktree_id: path_match.tree_id,
|
||||
|
||||
+9
-1
@@ -48,10 +48,18 @@ pub struct Titlebar {
|
||||
pub container: ContainerStyle,
|
||||
pub title: TextStyle,
|
||||
pub avatar_width: f32,
|
||||
pub icon_signed_out: Color,
|
||||
pub offline_icon: OfflineIcon,
|
||||
pub icon_color: Color,
|
||||
pub avatar: ImageStyle,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize)]
|
||||
pub struct OfflineIcon {
|
||||
#[serde(flatten)]
|
||||
pub container: ContainerStyle,
|
||||
pub width: f32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize)]
|
||||
pub struct Tab {
|
||||
#[serde(flatten)]
|
||||
|
||||
@@ -214,7 +214,7 @@ impl ThemeSelector {
|
||||
)
|
||||
.boxed(),
|
||||
)
|
||||
.with_style(&settings.theme.selector.empty.container)
|
||||
.with_style(settings.theme.selector.empty.container)
|
||||
.named("empty matches");
|
||||
}
|
||||
|
||||
@@ -259,9 +259,9 @@ impl ThemeSelector {
|
||||
.boxed(),
|
||||
)
|
||||
.with_style(if index == self.selected_index {
|
||||
&theme.selector.active_item.container
|
||||
theme.selector.active_item.container
|
||||
} else {
|
||||
&theme.selector.item.container
|
||||
theme.selector.item.container
|
||||
});
|
||||
|
||||
container.boxed()
|
||||
@@ -288,7 +288,7 @@ impl View for ThemeSelector {
|
||||
.with_child(Flexible::new(1.0, self.render_matches(cx)).boxed())
|
||||
.boxed(),
|
||||
)
|
||||
.with_style(&settings.theme.selector.container)
|
||||
.with_style(settings.theme.selector.container)
|
||||
.boxed(),
|
||||
)
|
||||
.with_max_width(600.0)
|
||||
|
||||
+45
-7
@@ -31,7 +31,6 @@ pub use pane::*;
|
||||
pub use pane_group::*;
|
||||
use postage::{prelude::Stream, watch};
|
||||
use sidebar::{Side, Sidebar, ToggleSidebarItem};
|
||||
use smol::prelude::*;
|
||||
use std::{
|
||||
collections::{hash_map::Entry, HashMap, HashSet},
|
||||
future::Future,
|
||||
@@ -391,9 +390,14 @@ impl Workspace {
|
||||
right_sidebar.add_item("icons/user-16.svg", cx.add_view(|_| ProjectBrowser).into());
|
||||
|
||||
let mut current_user = app_state.user_store.current_user().clone();
|
||||
let mut connection_status = app_state.rpc.status().clone();
|
||||
let _observe_current_user = cx.spawn_weak(|this, mut cx| async move {
|
||||
current_user.recv().await;
|
||||
while current_user.recv().await.is_some() {
|
||||
connection_status.recv().await;
|
||||
let mut stream =
|
||||
Stream::map(current_user, drop).merge(Stream::map(connection_status, drop));
|
||||
|
||||
while stream.recv().await.is_some() {
|
||||
cx.update(|cx| {
|
||||
if let Some(this) = this.upgrade(&cx) {
|
||||
this.update(cx, |_, cx| cx.notify());
|
||||
@@ -642,7 +646,7 @@ impl Workspace {
|
||||
if let Some(load_result) = watch.borrow().as_ref() {
|
||||
break load_result.clone();
|
||||
}
|
||||
watch.next().await;
|
||||
watch.recv().await;
|
||||
};
|
||||
|
||||
this.update(&mut cx, |this, cx| {
|
||||
@@ -954,7 +958,34 @@ impl Workspace {
|
||||
&self.active_pane
|
||||
}
|
||||
|
||||
fn render_current_user(&self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
fn render_connection_status(&self) -> Option<ElementBox> {
|
||||
let theme = &self.settings.borrow().theme;
|
||||
match dbg!(&*self.rpc.status().borrow()) {
|
||||
rpc::Status::ConnectionError
|
||||
| rpc::Status::ConnectionLost
|
||||
| rpc::Status::Reauthenticating
|
||||
| rpc::Status::Reconnecting { .. }
|
||||
| rpc::Status::ReconnectionError { .. } => Some(
|
||||
Container::new(
|
||||
Align::new(
|
||||
ConstrainedBox::new(
|
||||
Svg::new("icons/offline-14.svg")
|
||||
.with_color(theme.workspace.titlebar.icon_color)
|
||||
.boxed(),
|
||||
)
|
||||
.with_width(theme.workspace.titlebar.offline_icon.width)
|
||||
.boxed(),
|
||||
)
|
||||
.boxed(),
|
||||
)
|
||||
.with_style(theme.workspace.titlebar.offline_icon.container)
|
||||
.boxed(),
|
||||
),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn render_avatar(&self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
let theme = &self.settings.borrow().theme;
|
||||
let avatar = if let Some(avatar) = self
|
||||
.user_store
|
||||
@@ -969,7 +1000,7 @@ impl Workspace {
|
||||
} else {
|
||||
MouseEventHandler::new::<Authenticate, _, _, _>(0, cx, |_, _| {
|
||||
Svg::new("icons/signed-out-12.svg")
|
||||
.with_color(theme.workspace.titlebar.icon_signed_out)
|
||||
.with_color(theme.workspace.titlebar.icon_color)
|
||||
.boxed()
|
||||
})
|
||||
.on_click(|cx| cx.dispatch_action(Authenticate))
|
||||
@@ -1019,11 +1050,18 @@ impl View for Workspace {
|
||||
.boxed(),
|
||||
)
|
||||
.with_child(
|
||||
Align::new(self.render_current_user(cx)).right().boxed(),
|
||||
Align::new(
|
||||
Flex::row()
|
||||
.with_children(self.render_connection_status())
|
||||
.with_child(self.render_avatar(cx))
|
||||
.boxed(),
|
||||
)
|
||||
.right()
|
||||
.boxed(),
|
||||
)
|
||||
.boxed(),
|
||||
)
|
||||
.with_style(&theme.workspace.titlebar.container)
|
||||
.with_style(theme.workspace.titlebar.container)
|
||||
.boxed(),
|
||||
)
|
||||
.with_height(32.)
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
use super::{ItemViewHandle, SplitDirection};
|
||||
use crate::settings::Settings;
|
||||
use gpui::{Border, Entity, MutableAppContext, Quad, RenderContext, View, ViewContext, ViewHandle, action, color::Color, elements::*, geometry::{rect::RectF, vector::vec2f}, keymap::Binding, platform::CursorStyle};
|
||||
use gpui::{
|
||||
action,
|
||||
color::Color,
|
||||
elements::*,
|
||||
geometry::{rect::RectF, vector::vec2f},
|
||||
keymap::Binding,
|
||||
platform::CursorStyle,
|
||||
Border, Entity, MutableAppContext, Quad, RenderContext, View, ViewContext, ViewHandle,
|
||||
};
|
||||
use postage::watch;
|
||||
use std::{cmp, path::Path, sync::Arc};
|
||||
|
||||
@@ -256,7 +264,7 @@ impl Pane {
|
||||
)
|
||||
.boxed(),
|
||||
)
|
||||
.with_style(&ContainerStyle {
|
||||
.with_style(ContainerStyle {
|
||||
margin: Margin {
|
||||
left: style.spacing,
|
||||
right: style.spacing,
|
||||
@@ -283,7 +291,8 @@ impl Pane {
|
||||
icon.with_color(style.icon_close).boxed()
|
||||
}
|
||||
},
|
||||
).with_cursor_style(CursorStyle::PointingHand)
|
||||
)
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.on_click(move |cx| {
|
||||
cx.dispatch_action(CloseItem(item_id))
|
||||
})
|
||||
@@ -298,7 +307,7 @@ impl Pane {
|
||||
)
|
||||
.boxed(),
|
||||
)
|
||||
.with_style(&style.container)
|
||||
.with_style(style.container)
|
||||
.boxed(),
|
||||
)
|
||||
.on_mouse_down(move |cx| {
|
||||
|
||||
@@ -113,7 +113,7 @@ impl Sidebar {
|
||||
}))
|
||||
.boxed(),
|
||||
)
|
||||
.with_style(&theme.container)
|
||||
.with_style(theme.container)
|
||||
.boxed(),
|
||||
)
|
||||
.with_width(theme.width)
|
||||
@@ -165,7 +165,7 @@ impl Sidebar {
|
||||
let side = self.side;
|
||||
MouseEventHandler::new::<Self, _, _, _>(self.side.id(), &mut cx, |_, _| {
|
||||
Container::new(Empty::new().boxed())
|
||||
.with_style(&self.theme(settings).resize_handle)
|
||||
.with_style(self.theme(settings).resize_handle)
|
||||
.boxed()
|
||||
})
|
||||
.with_padding(Padding {
|
||||
|
||||
Reference in New Issue
Block a user