Add channel note indicator and clear changed status
This commit is contained in:
parent
9ba975d6ad
commit
e0ff7ba180
6 changed files with 119 additions and 11 deletions
|
@ -43,7 +43,7 @@ pub type ChannelData = (Channel, ChannelPath);
|
||||||
pub struct Channel {
|
pub struct Channel {
|
||||||
pub id: ChannelId,
|
pub id: ChannelId,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub has_changed: bool,
|
pub has_note_changed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Serialize, Deserialize)]
|
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Serialize, Deserialize)]
|
||||||
|
@ -200,19 +200,27 @@ impl ChannelStore {
|
||||||
) -> Task<Result<ModelHandle<ChannelBuffer>>> {
|
) -> Task<Result<ModelHandle<ChannelBuffer>>> {
|
||||||
let client = self.client.clone();
|
let client = self.client.clone();
|
||||||
let user_store = self.user_store.clone();
|
let user_store = self.user_store.clone();
|
||||||
self.open_channel_resource(
|
let open_channel_buffer = self.open_channel_resource(
|
||||||
channel_id,
|
channel_id,
|
||||||
|this| &mut this.opened_buffers,
|
|this| &mut this.opened_buffers,
|
||||||
|channel, cx| ChannelBuffer::new(channel, client, user_store, cx),
|
|channel, cx| ChannelBuffer::new(channel, client, user_store, cx),
|
||||||
cx,
|
cx,
|
||||||
)
|
);
|
||||||
|
cx.spawn(|this, mut cx| async move {
|
||||||
|
let buffer = open_channel_buffer.await?;
|
||||||
|
this.update(&mut cx, |this, cx| {
|
||||||
|
this.channel_index.clear_note_changed(channel_id);
|
||||||
|
cx.notify();
|
||||||
|
});
|
||||||
|
Ok(buffer)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_channel_buffer_changed(&self, channel_id: ChannelId) -> Option<bool> {
|
pub fn has_channel_buffer_changed(&self, channel_id: ChannelId) -> Option<bool> {
|
||||||
self.channel_index
|
self.channel_index
|
||||||
.by_id()
|
.by_id()
|
||||||
.get(&channel_id)
|
.get(&channel_id)
|
||||||
.map(|channel| channel.has_changed)
|
.map(|channel| channel.has_note_changed)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_channel_chat(
|
pub fn open_channel_chat(
|
||||||
|
@ -787,7 +795,7 @@ impl ChannelStore {
|
||||||
Arc::new(Channel {
|
Arc::new(Channel {
|
||||||
id: channel.id,
|
id: channel.id,
|
||||||
name: channel.name,
|
name: channel.name,
|
||||||
has_changed: false,
|
has_note_changed: false,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
@ -825,7 +833,7 @@ impl ChannelStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
for id_changed in payload.notes_changed {
|
for id_changed in payload.notes_changed {
|
||||||
index.has_changed(id_changed);
|
index.note_changed(id_changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
for edge in payload.insert_edge {
|
for edge in payload.insert_edge {
|
||||||
|
|
|
@ -38,6 +38,12 @@ impl ChannelIndex {
|
||||||
channels_by_id: &mut self.channels_by_id,
|
channels_by_id: &mut self.channels_by_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn clear_note_changed(&mut self, channel_id: ChannelId) {
|
||||||
|
if let Some(channel) = self.channels_by_id.get_mut(&channel_id) {
|
||||||
|
Arc::make_mut(channel).has_note_changed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for ChannelIndex {
|
impl Deref for ChannelIndex {
|
||||||
|
@ -76,9 +82,9 @@ impl<'a> ChannelPathsInsertGuard<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_changed(&mut self, channel_id: ChannelId) {
|
pub fn note_changed(&mut self, channel_id: ChannelId) {
|
||||||
if let Some(channel) = self.channels_by_id.get_mut(&channel_id) {
|
if let Some(channel) = self.channels_by_id.get_mut(&channel_id) {
|
||||||
Arc::make_mut(channel).has_changed = true;
|
Arc::make_mut(channel).has_note_changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +97,7 @@ impl<'a> ChannelPathsInsertGuard<'a> {
|
||||||
Arc::new(Channel {
|
Arc::new(Channel {
|
||||||
id: channel_proto.id,
|
id: channel_proto.id,
|
||||||
name: channel_proto.name,
|
name: channel_proto.name,
|
||||||
has_changed: false,
|
has_note_changed: false,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
self.insert_root(channel_proto.id);
|
self.insert_root(channel_proto.id);
|
||||||
|
|
|
@ -445,7 +445,7 @@ fn channel(id: u64, name: &'static str) -> Channel {
|
||||||
Channel {
|
Channel {
|
||||||
id,
|
id,
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
has_changed: false,
|
has_note_changed: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -786,6 +786,7 @@ async fn test_channel_buffer_changes(
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
// Client A makes an edit, and client B should see that the note has changed.
|
||||||
channel_buffer_a.update(cx_a, |buffer, cx| {
|
channel_buffer_a.update(cx_a, |buffer, cx| {
|
||||||
buffer.buffer().update(cx, |buffer, cx| {
|
buffer.buffer().update(cx, |buffer, cx| {
|
||||||
buffer.edit([(0..0, "1")], None, cx);
|
buffer.edit([(0..0, "1")], None, cx);
|
||||||
|
@ -802,6 +803,66 @@ async fn test_channel_buffer_changes(
|
||||||
});
|
});
|
||||||
|
|
||||||
assert!(has_buffer_changed);
|
assert!(has_buffer_changed);
|
||||||
|
|
||||||
|
// Opening the buffer should clear the changed flag.
|
||||||
|
let channel_buffer_b = client_b
|
||||||
|
.channel_store()
|
||||||
|
.update(cx_b, |store, cx| store.open_channel_buffer(channel_id, cx))
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
deterministic.run_until_parked();
|
||||||
|
|
||||||
|
let has_buffer_changed = cx_b.read(|cx| {
|
||||||
|
client_b
|
||||||
|
.channel_store()
|
||||||
|
.read(cx)
|
||||||
|
.has_channel_buffer_changed(channel_id)
|
||||||
|
.unwrap()
|
||||||
|
});
|
||||||
|
|
||||||
|
assert!(!has_buffer_changed);
|
||||||
|
|
||||||
|
// Editing the channel while the buffer is open shuold not show that the buffer has changed.
|
||||||
|
channel_buffer_a.update(cx_a, |buffer, cx| {
|
||||||
|
buffer.buffer().update(cx, |buffer, cx| {
|
||||||
|
buffer.edit([(0..0, "2")], None, cx);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
deterministic.run_until_parked();
|
||||||
|
|
||||||
|
let has_buffer_changed = cx_b.read(|cx| {
|
||||||
|
client_b
|
||||||
|
.channel_store()
|
||||||
|
.read(cx)
|
||||||
|
.has_channel_buffer_changed(channel_id)
|
||||||
|
.unwrap()
|
||||||
|
});
|
||||||
|
|
||||||
|
assert!(!has_buffer_changed);
|
||||||
|
|
||||||
|
// Closing the buffer should re-enable change tracking
|
||||||
|
cx_b.update(|_| {
|
||||||
|
drop(channel_buffer_b);
|
||||||
|
});
|
||||||
|
|
||||||
|
deterministic.run_until_parked();
|
||||||
|
|
||||||
|
channel_buffer_a.update(cx_a, |buffer, cx| {
|
||||||
|
buffer.buffer().update(cx, |buffer, cx| {
|
||||||
|
buffer.edit([(0..0, "3")], None, cx);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
deterministic.run_until_parked();
|
||||||
|
|
||||||
|
let has_buffer_changed = cx_b.read(|cx| {
|
||||||
|
client_b
|
||||||
|
.channel_store()
|
||||||
|
.read(cx)
|
||||||
|
.has_channel_buffer_changed(channel_id)
|
||||||
|
.unwrap()
|
||||||
|
});
|
||||||
|
|
||||||
|
assert!(has_buffer_changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
|
|
|
@ -1774,6 +1774,7 @@ impl CollabPanel {
|
||||||
const FACEPILE_LIMIT: usize = 3;
|
const FACEPILE_LIMIT: usize = 3;
|
||||||
|
|
||||||
enum ChannelCall {}
|
enum ChannelCall {}
|
||||||
|
enum ChannelNote {}
|
||||||
|
|
||||||
let mut is_dragged_over = false;
|
let mut is_dragged_over = false;
|
||||||
if cx
|
if cx
|
||||||
|
@ -1820,7 +1821,7 @@ impl CollabPanel {
|
||||||
channel.name.clone(),
|
channel.name.clone(),
|
||||||
theme
|
theme
|
||||||
.channel_name
|
.channel_name
|
||||||
.in_state(channel.has_changed)
|
.in_state(channel.has_note_changed)
|
||||||
.text
|
.text
|
||||||
.clone(),
|
.clone(),
|
||||||
)
|
)
|
||||||
|
@ -1863,6 +1864,8 @@ impl CollabPanel {
|
||||||
.with_color(theme.channel_hash.color)
|
.with_color(theme.channel_hash.color)
|
||||||
.constrained()
|
.constrained()
|
||||||
.with_width(theme.channel_hash.width)
|
.with_width(theme.channel_hash.width)
|
||||||
|
.contained()
|
||||||
|
.with_margin_right(theme.channel_hash.container.margin.left)
|
||||||
.into_any()
|
.into_any()
|
||||||
} else {
|
} else {
|
||||||
Empty::new().into_any()
|
Empty::new().into_any()
|
||||||
|
@ -1872,6 +1875,34 @@ impl CollabPanel {
|
||||||
this.join_channel_call(channel_id, cx);
|
this.join_channel_call(channel_id, cx);
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
.with_child(
|
||||||
|
MouseEventHandler::new::<ChannelNote, _>(ix, cx, move |_, cx| {
|
||||||
|
let participants =
|
||||||
|
self.channel_store.read(cx).channel_participants(channel_id);
|
||||||
|
if participants.is_empty() {
|
||||||
|
if channel.has_note_changed {
|
||||||
|
Svg::new("icons/terminal.svg")
|
||||||
|
.with_color(theme.channel_note_active_color)
|
||||||
|
.constrained()
|
||||||
|
.with_width(theme.channel_hash.width)
|
||||||
|
.into_any()
|
||||||
|
} else if row_hovered {
|
||||||
|
Svg::new("icons/terminal.svg")
|
||||||
|
.with_color(theme.channel_hash.color)
|
||||||
|
.constrained()
|
||||||
|
.with_width(theme.channel_hash.width)
|
||||||
|
.into_any()
|
||||||
|
} else {
|
||||||
|
Empty::new().into_any()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Empty::new().into_any()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.on_click(MouseButton::Left, move |_, this, cx| {
|
||||||
|
this.open_channel_notes(&OpenChannelNotes { channel_id }, cx);
|
||||||
|
}),
|
||||||
|
)
|
||||||
.align_children_center()
|
.align_children_center()
|
||||||
.styleable_component()
|
.styleable_component()
|
||||||
.disclosable(
|
.disclosable(
|
||||||
|
|
|
@ -238,6 +238,7 @@ pub struct CollabPanel {
|
||||||
pub log_in_button: Interactive<ContainedText>,
|
pub log_in_button: Interactive<ContainedText>,
|
||||||
pub channel_editor: ContainerStyle,
|
pub channel_editor: ContainerStyle,
|
||||||
pub channel_hash: Icon,
|
pub channel_hash: Icon,
|
||||||
|
pub channel_note_active_color: Color,
|
||||||
pub tabbed_modal: TabbedModal,
|
pub tabbed_modal: TabbedModal,
|
||||||
pub contact_finder: ContactFinder,
|
pub contact_finder: ContactFinder,
|
||||||
pub channel_modal: ChannelModal,
|
pub channel_modal: ChannelModal,
|
||||||
|
|
|
@ -194,6 +194,7 @@ export default function contacts_panel(): any {
|
||||||
},
|
},
|
||||||
user_query_editor: filter_input,
|
user_query_editor: filter_input,
|
||||||
channel_hash: icon_style,
|
channel_hash: icon_style,
|
||||||
|
channel_note_active_color: foreground(layer, "active"),
|
||||||
user_query_editor_height: 33,
|
user_query_editor_height: 33,
|
||||||
add_contact_button: header_icon_button,
|
add_contact_button: header_icon_button,
|
||||||
add_channel_button: header_icon_button,
|
add_channel_button: header_icon_button,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue