Add a setting to prevent sharing projects in public channels (#41395)
This PR adds a setting to prevent projects from being shared in public
channels.
This can be enabled by adding the following to the project settings
(`.zed/settings.json`):
```json
{
"prevent_sharing_in_public_channels": true
}
```
This will then disable the "Share" button when not in a private channel:
<img width="380" height="115" alt="Screenshot 2025-10-28 at 2 28 10 PM"
src="https://github.com/user-attachments/assets/6761ac34-c0d5-4451-a443-adf7a1c42bcd"
/>
Release Notes:
- collaboration: Added a `prevent_sharing_in_public_channels` project
setting for preventing projects from being shared in public channels.
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -17439,6 +17439,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"auto_update",
|
||||
"call",
|
||||
"channel",
|
||||
"chrono",
|
||||
"client",
|
||||
"cloud_llm_client",
|
||||
|
||||
@@ -64,6 +64,12 @@ pub struct WorktreeSettingsContent {
|
||||
#[serde(skip_serializing_if = "Maybe::is_unset")]
|
||||
pub project_name: Maybe<String>,
|
||||
|
||||
/// Whether to prevent this project from being shared in public channels.
|
||||
///
|
||||
/// Default: false
|
||||
#[serde(default)]
|
||||
pub prevent_sharing_in_public_channels: bool,
|
||||
|
||||
/// Completely ignore files matching globs from `file_scan_exclusions`. Overrides
|
||||
/// `file_scan_inclusions`.
|
||||
///
|
||||
|
||||
@@ -855,6 +855,7 @@ impl VsCodeSettings {
|
||||
fn worktree_settings_content(&self) -> WorktreeSettingsContent {
|
||||
WorktreeSettingsContent {
|
||||
project_name: crate::Maybe::Unset,
|
||||
prevent_sharing_in_public_channels: false,
|
||||
file_scan_exclusions: self
|
||||
.read_value("files.watcherExclude")
|
||||
.and_then(|v| v.as_array())
|
||||
|
||||
@@ -30,6 +30,7 @@ test-support = [
|
||||
anyhow.workspace = true
|
||||
auto_update.workspace = true
|
||||
call.workspace = true
|
||||
channel.workspace = true
|
||||
chrono.workspace = true
|
||||
client.workspace = true
|
||||
cloud_llm_client.workspace = true
|
||||
|
||||
@@ -2,18 +2,22 @@ use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
use call::{ActiveCall, ParticipantLocation, Room};
|
||||
use channel::ChannelStore;
|
||||
use client::{User, proto::PeerId};
|
||||
use gpui::{
|
||||
AnyElement, Hsla, IntoElement, MouseButton, Path, ScreenCaptureSource, Styled, WeakEntity,
|
||||
canvas, point,
|
||||
};
|
||||
use gpui::{App, Task, Window, actions};
|
||||
use project::WorktreeSettings;
|
||||
use rpc::proto::{self};
|
||||
use settings::{Settings as _, SettingsLocation};
|
||||
use theme::ActiveTheme;
|
||||
use ui::{
|
||||
Avatar, AvatarAudioStatusIndicator, ContextMenu, ContextMenuItem, Divider, DividerColor,
|
||||
Facepile, PopoverMenu, SplitButton, SplitButtonStyle, TintColor, Tooltip, prelude::*,
|
||||
};
|
||||
use util::rel_path::RelPath;
|
||||
use workspace::notifications::DetachAndPromptErr;
|
||||
|
||||
use crate::TitleBar;
|
||||
@@ -347,6 +351,11 @@ impl TitleBar {
|
||||
let can_share_projects = room.can_share_projects();
|
||||
let screen_sharing_supported = cx.is_screen_capture_supported();
|
||||
|
||||
let channel_store = ChannelStore::global(cx);
|
||||
let channel = room
|
||||
.channel_id()
|
||||
.and_then(|channel_id| channel_store.read(cx).channel_for_id(channel_id).cloned());
|
||||
|
||||
let mut children = Vec::new();
|
||||
|
||||
children.push(
|
||||
@@ -368,6 +377,20 @@ impl TitleBar {
|
||||
);
|
||||
|
||||
if is_local && can_share_projects && !is_connecting_to_project {
|
||||
let is_sharing_disabled = channel.is_some_and(|channel| match channel.visibility {
|
||||
proto::ChannelVisibility::Public => project.visible_worktrees(cx).any(|worktree| {
|
||||
let worktree_id = worktree.read(cx).id();
|
||||
|
||||
let settings_location = Some(SettingsLocation {
|
||||
worktree_id,
|
||||
path: RelPath::empty(),
|
||||
});
|
||||
|
||||
WorktreeSettings::get(settings_location, cx).prevent_sharing_in_public_channels
|
||||
}),
|
||||
proto::ChannelVisibility::Members => false,
|
||||
});
|
||||
|
||||
children.push(
|
||||
Button::new(
|
||||
"toggle_sharing",
|
||||
@@ -382,6 +405,11 @@ impl TitleBar {
|
||||
.selected_style(ButtonStyle::Tinted(TintColor::Accent))
|
||||
.toggle_state(is_shared)
|
||||
.label_size(LabelSize::Small)
|
||||
.when(is_sharing_disabled, |parent| {
|
||||
parent.disabled(true).tooltip(Tooltip::text(
|
||||
"This project may not be shared in a public channel.",
|
||||
))
|
||||
})
|
||||
.on_click(cx.listener(move |this, _, window, cx| {
|
||||
if is_shared {
|
||||
this.unshare_project(window, cx);
|
||||
|
||||
@@ -11,6 +11,8 @@ use util::{
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub struct WorktreeSettings {
|
||||
pub project_name: Option<String>,
|
||||
/// Whether to prevent this project from being shared in public channels.
|
||||
pub prevent_sharing_in_public_channels: bool,
|
||||
pub file_scan_inclusions: PathMatcher,
|
||||
pub file_scan_exclusions: PathMatcher,
|
||||
pub private_files: PathMatcher,
|
||||
@@ -51,6 +53,7 @@ impl Settings for WorktreeSettings {
|
||||
|
||||
Self {
|
||||
project_name: worktree.project_name.into_inner(),
|
||||
prevent_sharing_in_public_channels: worktree.prevent_sharing_in_public_channels,
|
||||
file_scan_exclusions: path_matchers(file_scan_exclusions, "file_scan_exclusions")
|
||||
.log_err()
|
||||
.unwrap_or_default(),
|
||||
|
||||
Reference in New Issue
Block a user