channel projects (#8456)
Add plumbing for hosted projects. This will currently show them if they exist but provides no UX to create/rename/delete them. Also changed the `ChannelId` type to not auto-cast to u64; this avoids type confusion if you have multiple id types. Release Notes: - N/A
This commit is contained in:
parent
8cf36ae603
commit
c31626717f
37 changed files with 446 additions and 144 deletions
|
@ -1,9 +1,9 @@
|
|||
use anyhow::Result;
|
||||
use call::report_call_event_for_channel;
|
||||
use channel::{Channel, ChannelBuffer, ChannelBufferEvent, ChannelId, ChannelStore};
|
||||
use channel::{Channel, ChannelBuffer, ChannelBufferEvent, ChannelStore};
|
||||
use client::{
|
||||
proto::{self, PeerId},
|
||||
Collaborator, ParticipantIndex,
|
||||
ChannelId, Collaborator, ParticipantIndex,
|
||||
};
|
||||
use collections::HashMap;
|
||||
use editor::{
|
||||
|
@ -454,7 +454,7 @@ impl FollowableItem for ChannelView {
|
|||
|
||||
Some(proto::view::Variant::ChannelView(
|
||||
proto::view::ChannelView {
|
||||
channel_id: channel_buffer.channel_id,
|
||||
channel_id: channel_buffer.channel_id.0,
|
||||
editor: if let Some(proto::view::Variant::Editor(proto)) =
|
||||
self.editor.read(cx).to_state_proto(cx)
|
||||
{
|
||||
|
@ -480,7 +480,8 @@ impl FollowableItem for ChannelView {
|
|||
unreachable!()
|
||||
};
|
||||
|
||||
let open = ChannelView::open_in_pane(state.channel_id, None, pane, workspace, cx);
|
||||
let open =
|
||||
ChannelView::open_in_pane(ChannelId(state.channel_id), None, pane, workspace, cx);
|
||||
|
||||
Some(cx.spawn(|mut cx| async move {
|
||||
let this = open.await?;
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::{collab_panel, ChatPanelSettings};
|
|||
use anyhow::Result;
|
||||
use call::{room, ActiveCall};
|
||||
use channel::{ChannelChat, ChannelChatEvent, ChannelMessage, ChannelMessageId, ChannelStore};
|
||||
use client::Client;
|
||||
use client::{ChannelId, Client};
|
||||
use collections::HashMap;
|
||||
use db::kvp::KEY_VALUE_STORE;
|
||||
use editor::Editor;
|
||||
|
@ -169,7 +169,7 @@ impl ChatPanel {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn channel_id(&self, cx: &AppContext) -> Option<u64> {
|
||||
pub fn channel_id(&self, cx: &AppContext) -> Option<ChannelId> {
|
||||
self.active_chat
|
||||
.as_ref()
|
||||
.map(|(chat, _)| chat.read(cx).channel_id)
|
||||
|
@ -710,7 +710,7 @@ impl ChatPanel {
|
|||
|
||||
pub fn select_channel(
|
||||
&mut self,
|
||||
selected_channel_id: u64,
|
||||
selected_channel_id: ChannelId,
|
||||
scroll_to_message_id: Option<u64>,
|
||||
cx: &mut ViewContext<ChatPanel>,
|
||||
) -> Task<Result<()>> {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use anyhow::Result;
|
||||
use channel::{ChannelId, ChannelMembership, ChannelStore, MessageParams};
|
||||
use client::UserId;
|
||||
use channel::{ChannelMembership, ChannelStore, MessageParams};
|
||||
use client::{ChannelId, UserId};
|
||||
use collections::{HashMap, HashSet};
|
||||
use editor::{AnchorRangeExt, CompletionProvider, Editor, EditorElement, EditorStyle};
|
||||
use fuzzy::StringMatchCandidate;
|
||||
|
@ -131,7 +131,7 @@ impl MessageEditor {
|
|||
|
||||
pub fn set_channel(
|
||||
&mut self,
|
||||
channel_id: u64,
|
||||
channel_id: ChannelId,
|
||||
channel_name: Option<SharedString>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
|
|
|
@ -7,8 +7,8 @@ use crate::{
|
|||
CollaborationPanelSettings,
|
||||
};
|
||||
use call::ActiveCall;
|
||||
use channel::{Channel, ChannelEvent, ChannelId, ChannelStore};
|
||||
use client::{Client, Contact, User, UserStore};
|
||||
use channel::{Channel, ChannelEvent, ChannelStore, HostedProjectId};
|
||||
use client::{ChannelId, Client, Contact, User, UserStore};
|
||||
use contact_finder::ContactFinder;
|
||||
use db::kvp::KEY_VALUE_STORE;
|
||||
use editor::{Editor, EditorElement, EditorStyle};
|
||||
|
@ -184,6 +184,10 @@ enum ListEntry {
|
|||
ChannelEditor {
|
||||
depth: usize,
|
||||
},
|
||||
HostedProject {
|
||||
id: HostedProjectId,
|
||||
name: SharedString,
|
||||
},
|
||||
Contact {
|
||||
contact: Arc<Contact>,
|
||||
calling: bool,
|
||||
|
@ -326,7 +330,10 @@ impl CollabPanel {
|
|||
panel.width = serialized_panel.width;
|
||||
panel.collapsed_channels = serialized_panel
|
||||
.collapsed_channels
|
||||
.unwrap_or_else(|| Vec::new());
|
||||
.unwrap_or_else(|| Vec::new())
|
||||
.iter()
|
||||
.map(|cid| ChannelId(*cid))
|
||||
.collect();
|
||||
cx.notify();
|
||||
});
|
||||
}
|
||||
|
@ -344,7 +351,9 @@ impl CollabPanel {
|
|||
COLLABORATION_PANEL_KEY.into(),
|
||||
serde_json::to_string(&SerializedCollabPanel {
|
||||
width,
|
||||
collapsed_channels: Some(collapsed_channels),
|
||||
collapsed_channels: Some(
|
||||
collapsed_channels.iter().map(|cid| cid.0).collect(),
|
||||
),
|
||||
})?,
|
||||
)
|
||||
.await?;
|
||||
|
@ -563,6 +572,7 @@ impl CollabPanel {
|
|||
}
|
||||
}
|
||||
|
||||
let hosted_projects = channel_store.projects_for_id(channel.id);
|
||||
let has_children = channel_store
|
||||
.channel_at_index(mat.candidate_id + 1)
|
||||
.map_or(false, |next_channel| {
|
||||
|
@ -596,6 +606,10 @@ impl CollabPanel {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
for (name, id) in hosted_projects {
|
||||
self.entries.push(ListEntry::HostedProject { id, name })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1023,6 +1037,33 @@ impl CollabPanel {
|
|||
.tooltip(move |cx| Tooltip::text("Open Chat", cx))
|
||||
}
|
||||
|
||||
fn render_channel_project(
|
||||
&self,
|
||||
id: HostedProjectId,
|
||||
name: &SharedString,
|
||||
is_selected: bool,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> impl IntoElement {
|
||||
ListItem::new(ElementId::NamedInteger(
|
||||
"channel-project".into(),
|
||||
id.0 as usize,
|
||||
))
|
||||
.indent_level(2)
|
||||
.indent_step_size(px(20.))
|
||||
.selected(is_selected)
|
||||
.on_click(cx.listener(move |_this, _, _cx| {
|
||||
// todo!()
|
||||
}))
|
||||
.start_slot(
|
||||
h_flex()
|
||||
.relative()
|
||||
.gap_1()
|
||||
.child(IconButton::new(0, IconName::FileTree)),
|
||||
)
|
||||
.child(Label::new(name.clone()))
|
||||
.tooltip(move |cx| Tooltip::text("Open Project", cx))
|
||||
}
|
||||
|
||||
fn has_subchannels(&self, ix: usize) -> bool {
|
||||
self.entries.get(ix).map_or(false, |entry| {
|
||||
if let ListEntry::Channel { has_children, .. } = entry {
|
||||
|
@ -1486,6 +1527,12 @@ impl CollabPanel {
|
|||
ListEntry::ChannelChat { channel_id } => {
|
||||
self.join_channel_chat(*channel_id, cx)
|
||||
}
|
||||
ListEntry::HostedProject {
|
||||
id: _id,
|
||||
name: _name,
|
||||
} => {
|
||||
// todo!()
|
||||
}
|
||||
|
||||
ListEntry::OutgoingRequest(_) => {}
|
||||
ListEntry::ChannelEditor { .. } => {}
|
||||
|
@ -1923,7 +1970,7 @@ impl CollabPanel {
|
|||
|
||||
fn respond_to_channel_invite(
|
||||
&mut self,
|
||||
channel_id: u64,
|
||||
channel_id: ChannelId,
|
||||
accept: bool,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
|
@ -1942,7 +1989,7 @@ impl CollabPanel {
|
|||
.detach_and_prompt_err("Call failed", cx, |_, _| None);
|
||||
}
|
||||
|
||||
fn join_channel(&self, channel_id: u64, cx: &mut ViewContext<Self>) {
|
||||
fn join_channel(&self, channel_id: ChannelId, cx: &mut ViewContext<Self>) {
|
||||
let Some(workspace) = self.workspace.upgrade() else {
|
||||
return;
|
||||
};
|
||||
|
@ -2089,6 +2136,10 @@ impl CollabPanel {
|
|||
ListEntry::ChannelChat { channel_id } => self
|
||||
.render_channel_chat(*channel_id, is_selected, cx)
|
||||
.into_any_element(),
|
||||
|
||||
ListEntry::HostedProject { id, name } => self
|
||||
.render_channel_project(*id, name, is_selected, cx)
|
||||
.into_any_element(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2405,7 +2456,7 @@ impl CollabPanel {
|
|||
.tooltip(|cx| Tooltip::text("Accept invite", cx)),
|
||||
];
|
||||
|
||||
ListItem::new(("channel-invite", channel.id as usize))
|
||||
ListItem::new(("channel-invite", channel.id.0 as usize))
|
||||
.selected(is_selected)
|
||||
.child(
|
||||
h_flex()
|
||||
|
@ -2497,7 +2548,7 @@ impl CollabPanel {
|
|||
|
||||
div()
|
||||
.h_6()
|
||||
.id(channel_id as usize)
|
||||
.id(channel_id.0 as usize)
|
||||
.group("")
|
||||
.flex()
|
||||
.w_full()
|
||||
|
@ -2525,7 +2576,7 @@ impl CollabPanel {
|
|||
this.move_channel(dragged_channel.id, channel_id, cx);
|
||||
}))
|
||||
.child(
|
||||
ListItem::new(channel_id as usize)
|
||||
ListItem::new(channel_id.0 as usize)
|
||||
// Add one level of depth for the disclosure arrow.
|
||||
.indent_level(depth + 1)
|
||||
.indent_step_size(px(20.))
|
||||
|
@ -2572,7 +2623,7 @@ impl CollabPanel {
|
|||
)
|
||||
.child(
|
||||
h_flex()
|
||||
.id(channel_id as usize)
|
||||
.id(channel_id.0 as usize)
|
||||
.child(Label::new(channel.name.clone()))
|
||||
.children(face_pile.map(|face_pile| face_pile.p_1())),
|
||||
),
|
||||
|
@ -2826,6 +2877,11 @@ impl PartialEq for ListEntry {
|
|||
return channel_1.id == channel_2.id;
|
||||
}
|
||||
}
|
||||
ListEntry::HostedProject { id, .. } => {
|
||||
if let ListEntry::HostedProject { id: other_id, .. } = other {
|
||||
return id == other_id;
|
||||
}
|
||||
}
|
||||
ListEntry::ChannelNotes { channel_id } => {
|
||||
if let ListEntry::ChannelNotes {
|
||||
channel_id: other_id,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use channel::{ChannelId, ChannelMembership, ChannelStore};
|
||||
use channel::{ChannelMembership, ChannelStore};
|
||||
use client::{
|
||||
proto::{self, ChannelRole, ChannelVisibility},
|
||||
User, UserId, UserStore,
|
||||
ChannelId, User, UserId, UserStore,
|
||||
};
|
||||
use fuzzy::{match_strings, StringMatchCandidate};
|
||||
use gpui::{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::{chat_panel::ChatPanel, NotificationPanelSettings};
|
||||
use anyhow::Result;
|
||||
use channel::ChannelStore;
|
||||
use client::{Client, Notification, User, UserStore};
|
||||
use client::{ChannelId, Client, Notification, User, UserStore};
|
||||
use collections::HashMap;
|
||||
use db::kvp::KEY_VALUE_STORE;
|
||||
use futures::StreamExt;
|
||||
|
@ -357,7 +357,7 @@ impl NotificationPanel {
|
|||
"{} invited you to join the #{channel_name} channel",
|
||||
inviter.github_login
|
||||
),
|
||||
needs_response: channel_store.has_channel_invitation(channel_id),
|
||||
needs_response: channel_store.has_channel_invitation(ChannelId(channel_id)),
|
||||
actor: Some(inviter),
|
||||
can_navigate: false,
|
||||
})
|
||||
|
@ -368,7 +368,7 @@ impl NotificationPanel {
|
|||
message_id,
|
||||
} => {
|
||||
let sender = user_store.get_cached_user(sender_id)?;
|
||||
let channel = channel_store.channel_for_id(channel_id)?;
|
||||
let channel = channel_store.channel_for_id(ChannelId(channel_id))?;
|
||||
let message = self
|
||||
.notification_store
|
||||
.read(cx)
|
||||
|
@ -432,7 +432,7 @@ impl NotificationPanel {
|
|||
if let Some(panel) = workspace.focus_panel::<ChatPanel>(cx) {
|
||||
panel.update(cx, |panel, cx| {
|
||||
panel
|
||||
.select_channel(channel_id, Some(message_id), cx)
|
||||
.select_channel(ChannelId(channel_id), Some(message_id), cx)
|
||||
.detach_and_log_err(cx);
|
||||
});
|
||||
}
|
||||
|
@ -454,7 +454,7 @@ impl NotificationPanel {
|
|||
panel.is_scrolled_to_bottom()
|
||||
&& panel
|
||||
.active_chat()
|
||||
.map_or(false, |chat| chat.read(cx).channel_id == *channel_id)
|
||||
.map_or(false, |chat| chat.read(cx).channel_id.0 == *channel_id)
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue