Wire through public access toggle
This commit is contained in:
parent
f8fd77b83e
commit
f6f9b5c8cb
13 changed files with 209 additions and 38 deletions
|
@ -9,7 +9,7 @@ use db::RELEASE_CHANNEL;
|
||||||
use futures::{channel::mpsc, future::Shared, Future, FutureExt, StreamExt};
|
use futures::{channel::mpsc, future::Shared, Future, FutureExt, StreamExt};
|
||||||
use gpui::{AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle, Task, WeakModelHandle};
|
use gpui::{AppContext, AsyncAppContext, Entity, ModelContext, ModelHandle, Task, WeakModelHandle};
|
||||||
use rpc::{
|
use rpc::{
|
||||||
proto::{self, ChannelEdge, ChannelPermission, ChannelRole},
|
proto::{self, ChannelEdge, ChannelPermission, ChannelRole, ChannelVisibility},
|
||||||
TypedEnvelope,
|
TypedEnvelope,
|
||||||
};
|
};
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
@ -49,6 +49,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 visibility: proto::ChannelVisibility,
|
||||||
pub unseen_note_version: Option<(u64, clock::Global)>,
|
pub unseen_note_version: Option<(u64, clock::Global)>,
|
||||||
pub unseen_message_id: Option<u64>,
|
pub unseen_message_id: Option<u64>,
|
||||||
}
|
}
|
||||||
|
@ -508,6 +509,25 @@ impl ChannelStore {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_channel_visibility(
|
||||||
|
&mut self,
|
||||||
|
channel_id: ChannelId,
|
||||||
|
visibility: ChannelVisibility,
|
||||||
|
cx: &mut ModelContext<Self>,
|
||||||
|
) -> Task<Result<()>> {
|
||||||
|
let client = self.client.clone();
|
||||||
|
cx.spawn(|_, _| async move {
|
||||||
|
let _ = client
|
||||||
|
.request(proto::SetChannelVisibility {
|
||||||
|
channel_id,
|
||||||
|
visibility: visibility.into(),
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn invite_member(
|
pub fn invite_member(
|
||||||
&mut self,
|
&mut self,
|
||||||
channel_id: ChannelId,
|
channel_id: ChannelId,
|
||||||
|
@ -869,6 +889,7 @@ impl ChannelStore {
|
||||||
ix,
|
ix,
|
||||||
Arc::new(Channel {
|
Arc::new(Channel {
|
||||||
id: channel.id,
|
id: channel.id,
|
||||||
|
visibility: channel.visibility(),
|
||||||
name: channel.name,
|
name: channel.name,
|
||||||
unseen_note_version: None,
|
unseen_note_version: None,
|
||||||
unseen_message_id: None,
|
unseen_message_id: None,
|
||||||
|
|
|
@ -123,12 +123,14 @@ impl<'a> ChannelPathsInsertGuard<'a> {
|
||||||
|
|
||||||
pub fn insert(&mut self, channel_proto: proto::Channel) {
|
pub fn insert(&mut self, channel_proto: proto::Channel) {
|
||||||
if let Some(existing_channel) = self.channels_by_id.get_mut(&channel_proto.id) {
|
if let Some(existing_channel) = self.channels_by_id.get_mut(&channel_proto.id) {
|
||||||
|
Arc::make_mut(existing_channel).visibility = channel_proto.visibility();
|
||||||
Arc::make_mut(existing_channel).name = channel_proto.name;
|
Arc::make_mut(existing_channel).name = channel_proto.name;
|
||||||
} else {
|
} else {
|
||||||
self.channels_by_id.insert(
|
self.channels_by_id.insert(
|
||||||
channel_proto.id,
|
channel_proto.id,
|
||||||
Arc::new(Channel {
|
Arc::new(Channel {
|
||||||
id: channel_proto.id,
|
id: channel_proto.id,
|
||||||
|
visibility: channel_proto.visibility(),
|
||||||
name: channel_proto.name,
|
name: channel_proto.name,
|
||||||
unseen_note_version: None,
|
unseen_note_version: None,
|
||||||
unseen_message_id: None,
|
unseen_message_id: None,
|
||||||
|
|
|
@ -432,6 +432,7 @@ pub struct NewUserResult {
|
||||||
pub struct Channel {
|
pub struct Channel {
|
||||||
pub id: ChannelId,
|
pub id: ChannelId,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
pub visibility: ChannelVisibility,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
|
|
|
@ -137,7 +137,7 @@ impl Into<i32> for ChannelRole {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Copy, Clone, Debug, EnumIter, DeriveActiveEnum, Default)]
|
#[derive(Eq, PartialEq, Copy, Clone, Debug, EnumIter, DeriveActiveEnum, Default, Hash)]
|
||||||
#[sea_orm(rs_type = "String", db_type = "String(None)")]
|
#[sea_orm(rs_type = "String", db_type = "String(None)")]
|
||||||
pub enum ChannelVisibility {
|
pub enum ChannelVisibility {
|
||||||
#[sea_orm(string_value = "public")]
|
#[sea_orm(string_value = "public")]
|
||||||
|
@ -151,7 +151,7 @@ impl From<proto::ChannelVisibility> for ChannelVisibility {
|
||||||
fn from(value: proto::ChannelVisibility) -> Self {
|
fn from(value: proto::ChannelVisibility) -> Self {
|
||||||
match value {
|
match value {
|
||||||
proto::ChannelVisibility::Public => ChannelVisibility::Public,
|
proto::ChannelVisibility::Public => ChannelVisibility::Public,
|
||||||
proto::ChannelVisibility::ChannelMembers => ChannelVisibility::Members,
|
proto::ChannelVisibility::Members => ChannelVisibility::Members,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,7 @@ impl Into<proto::ChannelVisibility> for ChannelVisibility {
|
||||||
fn into(self) -> proto::ChannelVisibility {
|
fn into(self) -> proto::ChannelVisibility {
|
||||||
match self {
|
match self {
|
||||||
ChannelVisibility::Public => proto::ChannelVisibility::Public,
|
ChannelVisibility::Public => proto::ChannelVisibility::Public,
|
||||||
ChannelVisibility::Members => proto::ChannelVisibility::ChannelMembers,
|
ChannelVisibility::Members => proto::ChannelVisibility::Members,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,12 +93,12 @@ impl Database {
|
||||||
channel_id: ChannelId,
|
channel_id: ChannelId,
|
||||||
visibility: ChannelVisibility,
|
visibility: ChannelVisibility,
|
||||||
user_id: UserId,
|
user_id: UserId,
|
||||||
) -> Result<()> {
|
) -> Result<channel::Model> {
|
||||||
self.transaction(move |tx| async move {
|
self.transaction(move |tx| async move {
|
||||||
self.check_user_is_channel_admin(channel_id, user_id, &*tx)
|
self.check_user_is_channel_admin(channel_id, user_id, &*tx)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
channel::ActiveModel {
|
let channel = channel::ActiveModel {
|
||||||
id: ActiveValue::Unchanged(channel_id),
|
id: ActiveValue::Unchanged(channel_id),
|
||||||
visibility: ActiveValue::Set(visibility),
|
visibility: ActiveValue::Set(visibility),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
@ -106,7 +106,7 @@ impl Database {
|
||||||
.update(&*tx)
|
.update(&*tx)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(channel)
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
@ -219,14 +219,14 @@ impl Database {
|
||||||
channel_id: ChannelId,
|
channel_id: ChannelId,
|
||||||
user_id: UserId,
|
user_id: UserId,
|
||||||
new_name: &str,
|
new_name: &str,
|
||||||
) -> Result<String> {
|
) -> Result<Channel> {
|
||||||
self.transaction(move |tx| async move {
|
self.transaction(move |tx| async move {
|
||||||
let new_name = Self::sanitize_channel_name(new_name)?.to_string();
|
let new_name = Self::sanitize_channel_name(new_name)?.to_string();
|
||||||
|
|
||||||
self.check_user_is_channel_admin(channel_id, user_id, &*tx)
|
self.check_user_is_channel_admin(channel_id, user_id, &*tx)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
channel::ActiveModel {
|
let channel = channel::ActiveModel {
|
||||||
id: ActiveValue::Unchanged(channel_id),
|
id: ActiveValue::Unchanged(channel_id),
|
||||||
name: ActiveValue::Set(new_name.clone()),
|
name: ActiveValue::Set(new_name.clone()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
@ -234,7 +234,11 @@ impl Database {
|
||||||
.update(&*tx)
|
.update(&*tx)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(new_name)
|
Ok(Channel {
|
||||||
|
id: channel.id,
|
||||||
|
name: channel.name,
|
||||||
|
visibility: channel.visibility,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
@ -336,6 +340,7 @@ impl Database {
|
||||||
.map(|channel| Channel {
|
.map(|channel| Channel {
|
||||||
id: channel.id,
|
id: channel.id,
|
||||||
name: channel.name,
|
name: channel.name,
|
||||||
|
visibility: channel.visibility,
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
@ -443,6 +448,7 @@ impl Database {
|
||||||
channels.push(Channel {
|
channels.push(Channel {
|
||||||
id: channel.id,
|
id: channel.id,
|
||||||
name: channel.name,
|
name: channel.name,
|
||||||
|
visibility: channel.visibility,
|
||||||
});
|
});
|
||||||
|
|
||||||
if role == ChannelRole::Admin {
|
if role == ChannelRole::Admin {
|
||||||
|
@ -963,6 +969,7 @@ impl Database {
|
||||||
Ok(Some((
|
Ok(Some((
|
||||||
Channel {
|
Channel {
|
||||||
id: channel.id,
|
id: channel.id,
|
||||||
|
visibility: channel.visibility,
|
||||||
name: channel.name,
|
name: channel.name,
|
||||||
},
|
},
|
||||||
is_accepted,
|
is_accepted,
|
||||||
|
|
|
@ -159,6 +159,7 @@ fn graph(channels: &[(ChannelId, &'static str)], edges: &[(ChannelId, ChannelId)
|
||||||
graph.channels.push(Channel {
|
graph.channels.push(Channel {
|
||||||
id: *id,
|
id: *id,
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
|
visibility: ChannelVisibility::Members,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,8 @@ mod connection_pool;
|
||||||
use crate::{
|
use crate::{
|
||||||
auth,
|
auth,
|
||||||
db::{
|
db::{
|
||||||
self, BufferId, ChannelId, ChannelsForUser, Database, MessageId, ProjectId, RoomId,
|
self, BufferId, ChannelId, ChannelVisibility, ChannelsForUser, Database, MessageId,
|
||||||
ServerId, User, UserId,
|
ProjectId, RoomId, ServerId, User, UserId,
|
||||||
},
|
},
|
||||||
executor::Executor,
|
executor::Executor,
|
||||||
AppState, Result,
|
AppState, Result,
|
||||||
|
@ -38,8 +38,8 @@ use lazy_static::lazy_static;
|
||||||
use prometheus::{register_int_gauge, IntGauge};
|
use prometheus::{register_int_gauge, IntGauge};
|
||||||
use rpc::{
|
use rpc::{
|
||||||
proto::{
|
proto::{
|
||||||
self, Ack, AnyTypedEnvelope, ChannelEdge, ChannelVisibility, EntityMessage,
|
self, Ack, AnyTypedEnvelope, ChannelEdge, EntityMessage, EnvelopedMessage,
|
||||||
EnvelopedMessage, LiveKitConnectionInfo, RequestMessage, UpdateChannelBufferCollaborators,
|
LiveKitConnectionInfo, RequestMessage, UpdateChannelBufferCollaborators,
|
||||||
},
|
},
|
||||||
Connection, ConnectionId, Peer, Receipt, TypedEnvelope,
|
Connection, ConnectionId, Peer, Receipt, TypedEnvelope,
|
||||||
};
|
};
|
||||||
|
@ -255,6 +255,7 @@ impl Server {
|
||||||
.add_request_handler(invite_channel_member)
|
.add_request_handler(invite_channel_member)
|
||||||
.add_request_handler(remove_channel_member)
|
.add_request_handler(remove_channel_member)
|
||||||
.add_request_handler(set_channel_member_role)
|
.add_request_handler(set_channel_member_role)
|
||||||
|
.add_request_handler(set_channel_visibility)
|
||||||
.add_request_handler(rename_channel)
|
.add_request_handler(rename_channel)
|
||||||
.add_request_handler(join_channel_buffer)
|
.add_request_handler(join_channel_buffer)
|
||||||
.add_request_handler(leave_channel_buffer)
|
.add_request_handler(leave_channel_buffer)
|
||||||
|
@ -2210,8 +2211,7 @@ async fn create_channel(
|
||||||
let channel = proto::Channel {
|
let channel = proto::Channel {
|
||||||
id: id.to_proto(),
|
id: id.to_proto(),
|
||||||
name: request.name,
|
name: request.name,
|
||||||
// TODO: Visibility
|
visibility: proto::ChannelVisibility::Members as i32,
|
||||||
visibility: proto::ChannelVisibility::ChannelMembers as i32,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
response.send(proto::CreateChannelResponse {
|
response.send(proto::CreateChannelResponse {
|
||||||
|
@ -2300,9 +2300,8 @@ async fn invite_channel_member(
|
||||||
let mut update = proto::UpdateChannels::default();
|
let mut update = proto::UpdateChannels::default();
|
||||||
update.channel_invitations.push(proto::Channel {
|
update.channel_invitations.push(proto::Channel {
|
||||||
id: channel.id.to_proto(),
|
id: channel.id.to_proto(),
|
||||||
|
visibility: channel.visibility.into(),
|
||||||
name: channel.name,
|
name: channel.name,
|
||||||
// TODO: Visibility
|
|
||||||
visibility: proto::ChannelVisibility::ChannelMembers as i32,
|
|
||||||
});
|
});
|
||||||
for connection_id in session
|
for connection_id in session
|
||||||
.connection_pool()
|
.connection_pool()
|
||||||
|
@ -2343,6 +2342,39 @@ async fn remove_channel_member(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn set_channel_visibility(
|
||||||
|
request: proto::SetChannelVisibility,
|
||||||
|
response: Response<proto::SetChannelVisibility>,
|
||||||
|
session: Session,
|
||||||
|
) -> Result<()> {
|
||||||
|
let db = session.db().await;
|
||||||
|
let channel_id = ChannelId::from_proto(request.channel_id);
|
||||||
|
let visibility = request.visibility().into();
|
||||||
|
|
||||||
|
let channel = db
|
||||||
|
.set_channel_visibility(channel_id, visibility, session.user_id)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let mut update = proto::UpdateChannels::default();
|
||||||
|
update.channels.push(proto::Channel {
|
||||||
|
id: channel.id.to_proto(),
|
||||||
|
name: channel.name,
|
||||||
|
visibility: channel.visibility.into(),
|
||||||
|
});
|
||||||
|
|
||||||
|
let member_ids = db.get_channel_members(channel_id).await?;
|
||||||
|
|
||||||
|
let connection_pool = session.connection_pool().await;
|
||||||
|
for member_id in member_ids {
|
||||||
|
for connection_id in connection_pool.user_connection_ids(member_id) {
|
||||||
|
session.peer.send(connection_id, update.clone())?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
response.send(proto::Ack {})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
async fn set_channel_member_role(
|
async fn set_channel_member_role(
|
||||||
request: proto::SetChannelMemberRole,
|
request: proto::SetChannelMemberRole,
|
||||||
response: Response<proto::SetChannelMemberRole>,
|
response: Response<proto::SetChannelMemberRole>,
|
||||||
|
@ -2391,15 +2423,14 @@ async fn rename_channel(
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let db = session.db().await;
|
let db = session.db().await;
|
||||||
let channel_id = ChannelId::from_proto(request.channel_id);
|
let channel_id = ChannelId::from_proto(request.channel_id);
|
||||||
let new_name = db
|
let channel = db
|
||||||
.rename_channel(channel_id, session.user_id, &request.name)
|
.rename_channel(channel_id, session.user_id, &request.name)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let channel = proto::Channel {
|
let channel = proto::Channel {
|
||||||
id: request.channel_id,
|
id: channel.id.to_proto(),
|
||||||
name: new_name,
|
name: channel.name,
|
||||||
// TODO: Visibility
|
visibility: channel.visibility.into(),
|
||||||
visibility: proto::ChannelVisibility::ChannelMembers as i32,
|
|
||||||
};
|
};
|
||||||
response.send(proto::RenameChannelResponse {
|
response.send(proto::RenameChannelResponse {
|
||||||
channel: Some(channel.clone()),
|
channel: Some(channel.clone()),
|
||||||
|
@ -2437,9 +2468,8 @@ async fn link_channel(
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|channel| proto::Channel {
|
.map(|channel| proto::Channel {
|
||||||
id: channel.id.to_proto(),
|
id: channel.id.to_proto(),
|
||||||
|
visibility: channel.visibility.into(),
|
||||||
name: channel.name,
|
name: channel.name,
|
||||||
// TODO: Visibility
|
|
||||||
visibility: proto::ChannelVisibility::ChannelMembers as i32,
|
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
insert_edge: channels_to_send.edges,
|
insert_edge: channels_to_send.edges,
|
||||||
|
@ -2530,9 +2560,8 @@ async fn move_channel(
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|channel| proto::Channel {
|
.map(|channel| proto::Channel {
|
||||||
id: channel.id.to_proto(),
|
id: channel.id.to_proto(),
|
||||||
|
visibility: channel.visibility.into(),
|
||||||
name: channel.name,
|
name: channel.name,
|
||||||
// TODO: Visibility
|
|
||||||
visibility: proto::ChannelVisibility::ChannelMembers as i32,
|
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
insert_edge: channels_to_send.edges,
|
insert_edge: channels_to_send.edges,
|
||||||
|
@ -2588,9 +2617,8 @@ async fn respond_to_channel_invite(
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|channel| proto::Channel {
|
.map(|channel| proto::Channel {
|
||||||
id: channel.id.to_proto(),
|
id: channel.id.to_proto(),
|
||||||
|
visibility: channel.visibility.into(),
|
||||||
name: channel.name,
|
name: channel.name,
|
||||||
// TODO: Visibility
|
|
||||||
visibility: ChannelVisibility::ChannelMembers.into(),
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
update.unseen_channel_messages = result.channel_messages;
|
update.unseen_channel_messages = result.channel_messages;
|
||||||
|
@ -3094,8 +3122,7 @@ fn build_initial_channels_update(
|
||||||
update.channels.push(proto::Channel {
|
update.channels.push(proto::Channel {
|
||||||
id: channel.id.to_proto(),
|
id: channel.id.to_proto(),
|
||||||
name: channel.name,
|
name: channel.name,
|
||||||
// TODO: Visibility
|
visibility: channel.visibility.into(),
|
||||||
visibility: ChannelVisibility::Public.into(),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,10 @@ use collections::HashMap;
|
||||||
use editor::{Anchor, Editor, ToOffset};
|
use editor::{Anchor, Editor, ToOffset};
|
||||||
use futures::future;
|
use futures::future;
|
||||||
use gpui::{executor::Deterministic, ModelHandle, TestAppContext, ViewContext};
|
use gpui::{executor::Deterministic, ModelHandle, TestAppContext, ViewContext};
|
||||||
use rpc::{proto::PeerId, RECEIVE_TIMEOUT};
|
use rpc::{
|
||||||
|
proto::{self, PeerId},
|
||||||
|
RECEIVE_TIMEOUT,
|
||||||
|
};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use std::{ops::Range, sync::Arc};
|
use std::{ops::Range, sync::Arc};
|
||||||
|
|
||||||
|
@ -445,6 +448,7 @@ fn channel(id: u64, name: &'static str) -> Channel {
|
||||||
Channel {
|
Channel {
|
||||||
id,
|
id,
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
|
visibility: proto::ChannelVisibility::Members,
|
||||||
unseen_note_version: None,
|
unseen_note_version: None,
|
||||||
unseen_message_id: None,
|
unseen_message_id: None,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use channel::{ChannelId, ChannelMembership, ChannelStore};
|
use channel::{Channel, ChannelId, ChannelMembership, ChannelStore};
|
||||||
use client::{
|
use client::{
|
||||||
proto::{self, ChannelRole},
|
proto::{self, ChannelRole, ChannelVisibility},
|
||||||
User, UserId, UserStore,
|
User, UserId, UserStore,
|
||||||
};
|
};
|
||||||
use context_menu::{ContextMenu, ContextMenuItem};
|
use context_menu::{ContextMenu, ContextMenuItem};
|
||||||
|
@ -9,7 +9,8 @@ use gpui::{
|
||||||
actions,
|
actions,
|
||||||
elements::*,
|
elements::*,
|
||||||
platform::{CursorStyle, MouseButton},
|
platform::{CursorStyle, MouseButton},
|
||||||
AppContext, Entity, ModelHandle, MouseState, Task, View, ViewContext, ViewHandle,
|
AppContext, ClipboardItem, Entity, ModelHandle, MouseState, Task, View, ViewContext,
|
||||||
|
ViewHandle,
|
||||||
};
|
};
|
||||||
use picker::{Picker, PickerDelegate, PickerEvent};
|
use picker::{Picker, PickerDelegate, PickerEvent};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -185,6 +186,81 @@ impl View for ChannelModal {
|
||||||
.into_any()
|
.into_any()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render_visibility(
|
||||||
|
channel_id: ChannelId,
|
||||||
|
visibility: ChannelVisibility,
|
||||||
|
theme: &theme::TabbedModal,
|
||||||
|
cx: &mut ViewContext<ChannelModal>,
|
||||||
|
) -> AnyElement<ChannelModal> {
|
||||||
|
enum TogglePublic {}
|
||||||
|
|
||||||
|
if visibility == ChannelVisibility::Members {
|
||||||
|
return Flex::row()
|
||||||
|
.with_child(
|
||||||
|
MouseEventHandler::new::<TogglePublic, _>(0, cx, move |state, _| {
|
||||||
|
let style = theme.visibility_toggle.style_for(state);
|
||||||
|
Label::new(format!("{}", "Public access: OFF"), style.text.clone())
|
||||||
|
.contained()
|
||||||
|
.with_style(style.container.clone())
|
||||||
|
})
|
||||||
|
.on_click(MouseButton::Left, move |_, this, cx| {
|
||||||
|
this.channel_store
|
||||||
|
.update(cx, |channel_store, cx| {
|
||||||
|
channel_store.set_channel_visibility(
|
||||||
|
channel_id,
|
||||||
|
ChannelVisibility::Public,
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.detach_and_log_err(cx);
|
||||||
|
})
|
||||||
|
.with_cursor_style(CursorStyle::PointingHand),
|
||||||
|
)
|
||||||
|
.into_any();
|
||||||
|
}
|
||||||
|
|
||||||
|
Flex::row()
|
||||||
|
.with_child(
|
||||||
|
MouseEventHandler::new::<TogglePublic, _>(0, cx, move |state, _| {
|
||||||
|
let style = theme.visibility_toggle.style_for(state);
|
||||||
|
Label::new(format!("{}", "Public access: ON"), style.text.clone())
|
||||||
|
.contained()
|
||||||
|
.with_style(style.container.clone())
|
||||||
|
})
|
||||||
|
.on_click(MouseButton::Left, move |_, this, cx| {
|
||||||
|
this.channel_store
|
||||||
|
.update(cx, |channel_store, cx| {
|
||||||
|
channel_store.set_channel_visibility(
|
||||||
|
channel_id,
|
||||||
|
ChannelVisibility::Members,
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.detach_and_log_err(cx);
|
||||||
|
})
|
||||||
|
.with_cursor_style(CursorStyle::PointingHand),
|
||||||
|
)
|
||||||
|
.with_spacing(14.0)
|
||||||
|
.with_child(
|
||||||
|
MouseEventHandler::new::<TogglePublic, _>(1, cx, move |state, _| {
|
||||||
|
let style = theme.channel_link.style_for(state);
|
||||||
|
Label::new(format!("{}", "copy link"), style.text.clone())
|
||||||
|
.contained()
|
||||||
|
.with_style(style.container.clone())
|
||||||
|
})
|
||||||
|
.on_click(MouseButton::Left, move |_, this, cx| {
|
||||||
|
if let Some(channel) =
|
||||||
|
this.channel_store.read(cx).channel_for_id(channel_id)
|
||||||
|
{
|
||||||
|
let item = ClipboardItem::new(channel.link());
|
||||||
|
cx.write_to_clipboard(item);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.with_cursor_style(CursorStyle::PointingHand),
|
||||||
|
)
|
||||||
|
.into_any()
|
||||||
|
}
|
||||||
|
|
||||||
Flex::column()
|
Flex::column()
|
||||||
.with_child(
|
.with_child(
|
||||||
Flex::column()
|
Flex::column()
|
||||||
|
@ -193,6 +269,7 @@ impl View for ChannelModal {
|
||||||
.contained()
|
.contained()
|
||||||
.with_style(theme.title.container.clone()),
|
.with_style(theme.title.container.clone()),
|
||||||
)
|
)
|
||||||
|
.with_child(render_visibility(channel.id, channel.visibility, theme, cx))
|
||||||
.with_child(Flex::row().with_children([
|
.with_child(Flex::row().with_children([
|
||||||
render_mode_button::<InviteMembers>(
|
render_mode_button::<InviteMembers>(
|
||||||
Mode::InviteMembers,
|
Mode::InviteMembers,
|
||||||
|
|
|
@ -170,7 +170,8 @@ message Envelope {
|
||||||
|
|
||||||
LinkChannel link_channel = 140;
|
LinkChannel link_channel = 140;
|
||||||
UnlinkChannel unlink_channel = 141;
|
UnlinkChannel unlink_channel = 141;
|
||||||
MoveChannel move_channel = 142; // current max: 145
|
MoveChannel move_channel = 142;
|
||||||
|
SetChannelVisibility set_channel_visibility = 146; // current max: 146
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1049,6 +1050,11 @@ message SetChannelMemberRole {
|
||||||
ChannelRole role = 3;
|
ChannelRole role = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message SetChannelVisibility {
|
||||||
|
uint64 channel_id = 1;
|
||||||
|
ChannelVisibility visibility = 2;
|
||||||
|
}
|
||||||
|
|
||||||
message RenameChannel {
|
message RenameChannel {
|
||||||
uint64 channel_id = 1;
|
uint64 channel_id = 1;
|
||||||
string name = 2;
|
string name = 2;
|
||||||
|
@ -1542,7 +1548,7 @@ message Nonce {
|
||||||
|
|
||||||
enum ChannelVisibility {
|
enum ChannelVisibility {
|
||||||
Public = 0;
|
Public = 0;
|
||||||
ChannelMembers = 1;
|
Members = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Channel {
|
message Channel {
|
||||||
|
|
|
@ -231,6 +231,7 @@ messages!(
|
||||||
(RenameChannel, Foreground),
|
(RenameChannel, Foreground),
|
||||||
(RenameChannelResponse, Foreground),
|
(RenameChannelResponse, Foreground),
|
||||||
(SetChannelMemberRole, Foreground),
|
(SetChannelMemberRole, Foreground),
|
||||||
|
(SetChannelVisibility, Foreground),
|
||||||
(SearchProject, Background),
|
(SearchProject, Background),
|
||||||
(SearchProjectResponse, Background),
|
(SearchProjectResponse, Background),
|
||||||
(ShareProject, Foreground),
|
(ShareProject, Foreground),
|
||||||
|
@ -327,6 +328,7 @@ request_messages!(
|
||||||
(RespondToContactRequest, Ack),
|
(RespondToContactRequest, Ack),
|
||||||
(RespondToChannelInvite, Ack),
|
(RespondToChannelInvite, Ack),
|
||||||
(SetChannelMemberRole, Ack),
|
(SetChannelMemberRole, Ack),
|
||||||
|
(SetChannelVisibility, Ack),
|
||||||
(SendChannelMessage, SendChannelMessageResponse),
|
(SendChannelMessage, SendChannelMessageResponse),
|
||||||
(GetChannelMessages, GetChannelMessagesResponse),
|
(GetChannelMessages, GetChannelMessagesResponse),
|
||||||
(GetChannelMembers, GetChannelMembersResponse),
|
(GetChannelMembers, GetChannelMembersResponse),
|
||||||
|
|
|
@ -286,6 +286,8 @@ pub struct TabbedModal {
|
||||||
pub header: ContainerStyle,
|
pub header: ContainerStyle,
|
||||||
pub body: ContainerStyle,
|
pub body: ContainerStyle,
|
||||||
pub title: ContainedText,
|
pub title: ContainedText,
|
||||||
|
pub visibility_toggle: Interactive<ContainedText>,
|
||||||
|
pub channel_link: Interactive<ContainedText>,
|
||||||
pub picker: Picker,
|
pub picker: Picker,
|
||||||
pub max_height: f32,
|
pub max_height: f32,
|
||||||
pub max_width: f32,
|
pub max_width: f32,
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { useTheme } from "../theme"
|
import { StyleSet, StyleSets, Styles, useTheme } from "../theme"
|
||||||
import { background, border, foreground, text } from "./components"
|
import { background, border, foreground, text } from "./components"
|
||||||
import picker from "./picker"
|
import picker from "./picker"
|
||||||
import { input } from "../component/input"
|
import { input } from "../component/input"
|
||||||
import contact_finder from "./contact_finder"
|
import contact_finder from "./contact_finder"
|
||||||
import { tab } from "../component/tab"
|
import { tab } from "../component/tab"
|
||||||
import { icon_button } from "../component/icon_button"
|
import { icon_button } from "../component/icon_button"
|
||||||
|
import { interactive } from "../element/interactive"
|
||||||
|
|
||||||
export default function channel_modal(): any {
|
export default function channel_modal(): any {
|
||||||
const theme = useTheme()
|
const theme = useTheme()
|
||||||
|
@ -27,6 +28,24 @@ export default function channel_modal(): any {
|
||||||
|
|
||||||
const picker_input = input()
|
const picker_input = input()
|
||||||
|
|
||||||
|
const interactive_text = (styleset: StyleSets) =>
|
||||||
|
interactive({
|
||||||
|
base: {
|
||||||
|
padding: {
|
||||||
|
left: 8,
|
||||||
|
top: 8
|
||||||
|
},
|
||||||
|
...text(theme.middle, "sans", styleset, "default"),
|
||||||
|
}, state: {
|
||||||
|
hovered: {
|
||||||
|
...text(theme.middle, "sans", styleset, "hovered"),
|
||||||
|
},
|
||||||
|
clicked: {
|
||||||
|
...text(theme.middle, "sans", styleset, "active"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const member_icon_style = icon_button({
|
const member_icon_style = icon_button({
|
||||||
variant: "ghost",
|
variant: "ghost",
|
||||||
size: "sm",
|
size: "sm",
|
||||||
|
@ -88,6 +107,8 @@ export default function channel_modal(): any {
|
||||||
left: BUTTON_OFFSET,
|
left: BUTTON_OFFSET,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
visibility_toggle: interactive_text("base"),
|
||||||
|
channel_link: interactive_text("accent"),
|
||||||
picker: {
|
picker: {
|
||||||
empty_container: {},
|
empty_container: {},
|
||||||
item: {
|
item: {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue