mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-26 10:40:54 +00:00
WIP
This commit is contained in:
parent
8f86fa1ccd
commit
b923f65a63
8 changed files with 114 additions and 21 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -5142,6 +5142,15 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e0a10c9a9fb3a5dce8c2239ed670f1a2569fcf42da035f5face1b19860d52b0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.1.1"
|
||||
|
@ -5832,6 +5841,7 @@ dependencies = [
|
|||
"smol",
|
||||
"surf",
|
||||
"tempdir",
|
||||
"time 0.3.2",
|
||||
"tiny_http",
|
||||
"toml 0.5.8",
|
||||
"tree-sitter",
|
||||
|
|
|
@ -48,6 +48,7 @@ smallvec = { version = "1.6", features = ["union"] }
|
|||
smol = "1.2.5"
|
||||
surf = "2.2"
|
||||
tempdir = { version = "0.3.7", optional = true }
|
||||
time = { version = "0.3", features = ["local-offset"] }
|
||||
tiny_http = "0.8"
|
||||
toml = "0.5"
|
||||
tree-sitter = "0.19.5"
|
||||
|
|
|
@ -22,8 +22,14 @@ color = "$text.2"
|
|||
[workspace.active_sidebar_icon]
|
||||
color = "$text.0"
|
||||
|
||||
[chat_panel]
|
||||
padding = { top = 10.0, bottom = 10.0, left = 10.0, right = 10.0 }
|
||||
|
||||
[chat_panel.message]
|
||||
body = "$text.0"
|
||||
sender.margin.right = 10.0
|
||||
sender.text = { color = "#ff0000", weight = "bold", italic = true }
|
||||
timestamp.text = "$text.2"
|
||||
|
||||
[selector]
|
||||
background = "$surface.2"
|
||||
|
|
|
@ -14,6 +14,7 @@ use std::{
|
|||
ops::Range,
|
||||
sync::Arc,
|
||||
};
|
||||
use time::OffsetDateTime;
|
||||
use zrpc::{
|
||||
proto::{self, ChannelMessageSent},
|
||||
TypedEnvelope,
|
||||
|
@ -47,6 +48,7 @@ pub struct Channel {
|
|||
pub struct ChannelMessage {
|
||||
pub id: u64,
|
||||
pub body: String,
|
||||
pub timestamp: OffsetDateTime,
|
||||
pub sender: Arc<User>,
|
||||
}
|
||||
|
||||
|
@ -261,14 +263,17 @@ impl Channel {
|
|||
this.insert_message(
|
||||
ChannelMessage {
|
||||
id: response.message_id,
|
||||
timestamp: OffsetDateTime::from_unix_timestamp(
|
||||
response.timestamp as i64,
|
||||
)?,
|
||||
body,
|
||||
sender,
|
||||
},
|
||||
cx,
|
||||
);
|
||||
}
|
||||
});
|
||||
Ok(())
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
.log_err()
|
||||
})
|
||||
|
@ -363,6 +368,7 @@ impl ChannelMessage {
|
|||
Ok(ChannelMessage {
|
||||
id: message.id,
|
||||
body: message.body,
|
||||
timestamp: OffsetDateTime::from_unix_timestamp(message.timestamp as i64)?,
|
||||
sender,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ use gpui::{
|
|||
Subscription, View, ViewContext, ViewHandle,
|
||||
};
|
||||
use postage::watch;
|
||||
use time::{OffsetDateTime, UtcOffset};
|
||||
|
||||
pub struct ChatPanel {
|
||||
channel_list: ModelHandle<ChannelList>,
|
||||
|
@ -75,12 +76,13 @@ impl ChatPanel {
|
|||
fn set_active_channel(&mut self, channel: ModelHandle<Channel>, cx: &mut ViewContext<Self>) {
|
||||
if self.active_channel.as_ref().map(|e| &e.0) != Some(&channel) {
|
||||
let subscription = cx.subscribe(&channel, Self::channel_did_change);
|
||||
let now = OffsetDateTime::now_utc();
|
||||
self.messages = ListState::new(
|
||||
channel
|
||||
.read(cx)
|
||||
.messages()
|
||||
.cursor::<(), ()>()
|
||||
.map(|m| self.render_message(m))
|
||||
.map(|m| self.render_message(m, now))
|
||||
.collect(),
|
||||
Orientation::Bottom,
|
||||
);
|
||||
|
@ -99,12 +101,13 @@ impl ChatPanel {
|
|||
old_range,
|
||||
new_count,
|
||||
} => {
|
||||
let now = OffsetDateTime::now_utc();
|
||||
self.messages.splice(
|
||||
old_range.clone(),
|
||||
channel
|
||||
.read(cx)
|
||||
.messages_in_range(old_range.start..(old_range.start + new_count))
|
||||
.map(|message| self.render_message(message)),
|
||||
.map(|message| self.render_message(message, now)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -115,15 +118,50 @@ impl ChatPanel {
|
|||
Expanded::new(1., List::new(self.messages.clone()).boxed()).boxed()
|
||||
}
|
||||
|
||||
fn render_message(&self, message: &ChannelMessage) -> ElementBox {
|
||||
fn render_message(&self, message: &ChannelMessage, now: OffsetDateTime) -> ElementBox {
|
||||
let settings = self.settings.borrow();
|
||||
Text::new(
|
||||
message.body.clone(),
|
||||
settings.ui_font_family,
|
||||
settings.ui_font_size,
|
||||
)
|
||||
.with_style(&settings.theme.chat_panel.message.body)
|
||||
.boxed()
|
||||
let theme = &settings.theme.chat_panel.message;
|
||||
Flex::column()
|
||||
.with_child(
|
||||
Flex::row()
|
||||
.with_child(
|
||||
Container::new(
|
||||
Label::new(
|
||||
message.sender.github_login.clone(),
|
||||
settings.ui_font_family,
|
||||
settings.ui_font_size,
|
||||
)
|
||||
.with_style(&theme.sender.label)
|
||||
.boxed(),
|
||||
)
|
||||
.with_style(&theme.sender.container)
|
||||
.boxed(),
|
||||
)
|
||||
.with_child(
|
||||
Container::new(
|
||||
Label::new(
|
||||
format_timestamp(message.timestamp, now),
|
||||
settings.ui_font_family,
|
||||
settings.ui_font_size,
|
||||
)
|
||||
.with_style(&theme.timestamp.label)
|
||||
.boxed(),
|
||||
)
|
||||
.with_style(&theme.timestamp.container)
|
||||
.boxed(),
|
||||
)
|
||||
.boxed(),
|
||||
)
|
||||
.with_child(
|
||||
Text::new(
|
||||
message.body.clone(),
|
||||
settings.ui_font_family,
|
||||
settings.ui_font_size,
|
||||
)
|
||||
.with_style(&theme.body)
|
||||
.boxed(),
|
||||
)
|
||||
.boxed()
|
||||
}
|
||||
|
||||
fn render_input_box(&self) -> ElementBox {
|
||||
|
@ -157,9 +195,36 @@ impl View for ChatPanel {
|
|||
}
|
||||
|
||||
fn render(&self, _: &RenderContext<Self>) -> ElementBox {
|
||||
Flex::column()
|
||||
.with_child(self.render_active_channel_messages())
|
||||
.with_child(self.render_input_box())
|
||||
.boxed()
|
||||
let theme = &self.settings.borrow().theme;
|
||||
Container::new(
|
||||
Flex::column()
|
||||
.with_child(self.render_active_channel_messages())
|
||||
.with_child(self.render_input_box())
|
||||
.boxed(),
|
||||
)
|
||||
.with_style(&theme.chat_panel.container)
|
||||
.boxed()
|
||||
}
|
||||
}
|
||||
|
||||
fn format_timestamp(mut timestamp: OffsetDateTime, mut now: OffsetDateTime) -> String {
|
||||
let local_offset = UtcOffset::current_local_offset().unwrap_or(UtcOffset::UTC);
|
||||
timestamp = timestamp.to_offset(local_offset);
|
||||
now = now.to_offset(local_offset);
|
||||
|
||||
let today = now.date();
|
||||
let date = timestamp.date();
|
||||
let mut hour = timestamp.hour();
|
||||
let mut part = "am";
|
||||
if hour > 12 {
|
||||
hour -= 12;
|
||||
part = "pm";
|
||||
}
|
||||
if date == today {
|
||||
format!("{}:{}{}", hour, timestamp.minute(), part)
|
||||
} else if date.next_day() == Some(today) {
|
||||
format!("yesterday at {}:{}{}", hour, timestamp.minute(), part)
|
||||
} else {
|
||||
format!("{}/{}/{}", date.month(), date.day(), date.year())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,12 +55,16 @@ pub struct SidebarIcon {
|
|||
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
pub struct ChatPanel {
|
||||
#[serde(flatten)]
|
||||
pub container: ContainerStyle,
|
||||
pub message: ChatMessage,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
pub struct ChatMessage {
|
||||
pub body: TextStyle,
|
||||
pub sender: ContainedLabel,
|
||||
pub timestamp: ContainedLabel,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
|
@ -70,12 +74,12 @@ pub struct Selector {
|
|||
#[serde(flatten)]
|
||||
pub label: LabelStyle,
|
||||
|
||||
pub item: SelectorItem,
|
||||
pub active_item: SelectorItem,
|
||||
pub item: ContainedLabel,
|
||||
pub active_item: ContainedLabel,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
pub struct SelectorItem {
|
||||
pub struct ContainedLabel {
|
||||
#[serde(flatten)]
|
||||
pub container: ContainerStyle,
|
||||
#[serde(flatten)]
|
||||
|
|
|
@ -99,6 +99,7 @@ impl ThemeSelector {
|
|||
Ok(theme) => {
|
||||
cx.notify_all();
|
||||
action.0.settings_tx.lock().borrow_mut().theme = theme;
|
||||
log::info!("reloaded theme {}", current_theme_name);
|
||||
}
|
||||
Err(error) => {
|
||||
log::error!("failed to load theme {}: {:?}", current_theme_name, error)
|
||||
|
|
|
@ -958,7 +958,7 @@ impl View for Workspace {
|
|||
if let Some(panel) = self.left_sidebar.active_item() {
|
||||
content.add_child(
|
||||
ConstrainedBox::new(ChildView::new(panel.id()).boxed())
|
||||
.with_width(200.0)
|
||||
.with_width(300.0)
|
||||
.named("left panel"),
|
||||
);
|
||||
}
|
||||
|
@ -966,7 +966,7 @@ impl View for Workspace {
|
|||
if let Some(panel) = self.right_sidebar.active_item() {
|
||||
content.add_child(
|
||||
ConstrainedBox::new(ChildView::new(panel.id()).boxed())
|
||||
.with_width(200.0)
|
||||
.with_width(300.0)
|
||||
.named("right panel"),
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue