Detailed changes
@@ -2,102 +2,12 @@ mod channels_panel;
mod channels_panel_settings;
pub use channels_panel::*;
-use gpui::{AppContext, Entity};
+use gpui::{AppContext};
use std::sync::Arc;
use client::Client;
pub fn init(client: Arc<Client>, cx: &mut AppContext) {
- let channels = cx.add_model(|cx| Channels::new(client, cx));
- cx.set_global(channels);
channels_panel::init(cx);
}
-
-#[derive(Debug, Clone)]
-struct Channel {
- id: u64,
- name: String,
- sub_channels: Vec<Channel>,
- _room: Option<()>,
-}
-
-impl Channel {
- fn new(id: u64, name: impl AsRef<str>, members: Vec<Channel>) -> Channel {
- Channel {
- name: name.as_ref().to_string(),
- id,
- sub_channels: members,
- _room: None,
- }
- }
-
- fn members(&self) -> &[Channel] {
- &self.sub_channels
- }
-
- fn name(&self) -> &str {
- &self.name
- }
-}
-
-struct Channels {
- channels: Vec<Channel>,
-}
-
-impl Channels {
- fn channels(&self) -> Vec<Channel> {
- self.channels.clone()
- }
-}
-
-enum ChannelEvents {}
-
-impl Entity for Channels {
- type Event = ChannelEvents;
-}
-
-impl Channels {
- fn new(_client: Arc<Client>, _cx: &mut AppContext) -> Self {
- //TODO: Subscribe to channel updates from the server
- Channels {
- channels: vec![Channel::new(
- 0,
- "Zed Industries",
- vec![
- Channel::new(1, "#general", Vec::new()),
- Channel::new(2, "#admiral", Vec::new()),
- Channel::new(3, "#livestreaming", vec![]),
- Channel::new(4, "#crdb", Vec::new()),
- Channel::new(5, "#crdb-1", Vec::new()),
- Channel::new(6, "#crdb-2", Vec::new()),
- Channel::new(7, "#crdb-3", vec![]),
- Channel::new(8, "#crdb-4", Vec::new()),
- Channel::new(9, "#crdb-1", Vec::new()),
- Channel::new(10, "#crdb-1", Vec::new()),
- Channel::new(11, "#crdb-1", Vec::new()),
- Channel::new(12, "#crdb-1", vec![]),
- Channel::new(13, "#crdb-1", Vec::new()),
- Channel::new(14, "#crdb-1", Vec::new()),
- Channel::new(15, "#crdb-1", Vec::new()),
- Channel::new(16, "#crdb-1", Vec::new()),
- Channel::new(17, "#crdb", vec![]),
- ],
- ),
- Channel::new(
- 18,
- "CRDB Consulting",
- vec![
- Channel::new(19, "#crdb 😭", Vec::new()),
- Channel::new(20, "#crdb 😌", Vec::new()),
- Channel::new(21, "#crdb 🦀", vec![]),
- Channel::new(22, "#crdb 😤", Vec::new()),
- Channel::new(23, "#crdb 😤", Vec::new()),
- Channel::new(24, "#crdb 😤", Vec::new()),
- Channel::new(25, "#crdb 😤", vec![]),
- Channel::new(26, "#crdb 😤", Vec::new()),
- ],
- )],
- }
- }
-}
@@ -1,23 +1,19 @@
use std::sync::Arc;
-use crate::{
- channels_panel_settings::{ChannelsPanelDockPosition, ChannelsPanelSettings},
- Channel, Channels,
-};
+use crate::channels_panel_settings::{ChannelsPanelDockPosition, ChannelsPanelSettings};
use anyhow::Result;
use collections::HashMap;
use context_menu::ContextMenu;
use db::kvp::KEY_VALUE_STORE;
use gpui::{
actions,
- elements::{ChildView, Empty, Flex, Label, MouseEventHandler, ParentElement, Stack},
- serde_json, AnyElement, AppContext, AsyncAppContext, Element, Entity, ModelHandle, Task, View,
- ViewContext, ViewHandle, WeakViewHandle,
+ elements::{ChildView, Flex, Label, ParentElement, Stack},
+ serde_json, AppContext, AsyncAppContext, Element, Entity, Task, View, ViewContext,
+ ViewHandle, WeakViewHandle,
};
use project::Fs;
use serde_derive::{Deserialize, Serialize};
use settings::SettingsStore;
-use theme::ChannelTreeStyle;
use util::{ResultExt, TryFutureExt};
use workspace::{
dock::{DockPosition, Panel},
@@ -37,7 +33,6 @@ pub struct ChannelsPanel {
fs: Arc<dyn Fs>,
has_focus: bool,
pending_serialization: Task<Option<()>>,
- channels: ModelHandle<Channels>,
context_menu: ViewHandle<ContextMenu>,
collapsed_channels: HashMap<u64, bool>,
}
@@ -67,7 +62,6 @@ impl ChannelsPanel {
has_focus: false,
fs: workspace.app_state().fs.clone(),
pending_serialization: Task::ready(None),
- channels: cx.global::<ModelHandle<Channels>>().clone(),
context_menu: cx.add_view(|cx| ContextMenu::new(view_id, cx)),
collapsed_channels: HashMap::default(),
};
@@ -138,101 +132,6 @@ impl ChannelsPanel {
.log_err(),
);
}
-
- fn render_channel(
- &mut self,
- depth: usize,
- channel: &Channel,
- style: &ChannelTreeStyle,
- root: bool,
- cx: &mut ViewContext<Self>,
- ) -> AnyElement<Self> {
- let has_chilren = !channel.members().is_empty();
-
- let sub_channel_details = has_chilren.then(|| {
- let mut sub_channels = Flex::column();
- let collapsed = self
- .collapsed_channels
- .get(&channel.id)
- .copied()
- .unwrap_or_default();
- if !collapsed {
- for sub_channel in channel.members() {
- sub_channels = sub_channels.with_child(self.render_channel(
- depth + 1,
- sub_channel,
- style,
- false,
- cx,
- ));
- }
- }
- (sub_channels, collapsed)
- });
-
- let channel_id = channel.id;
-
- enum ChannelCollapser {}
- Flex::row()
- .with_child(
- Empty::new()
- .constrained()
- .with_width(depth as f32 * style.channel_indent),
- )
- .with_child(
- Flex::column()
- .with_child(
- Flex::row()
- .with_child(
- sub_channel_details
- .as_ref()
- .map(|(_, expanded)| {
- MouseEventHandler::<ChannelCollapser, _>::new(
- channel.id as usize,
- cx,
- |state, _cx| {
- let icon =
- style.channel_icon.style_for(!*expanded, state);
- theme::ui::icon(icon)
- },
- )
- .on_click(
- gpui::platform::MouseButton::Left,
- move |_, v, cx| {
- let entry = v
- .collapsed_channels
- .entry(channel_id)
- .or_default();
- *entry = !*entry;
- v.serialize(cx);
- cx.notify();
- },
- )
- .into_any()
- })
- .unwrap_or_else(|| {
- Empty::new()
- .constrained()
- .with_width(style.channel_icon.default_style().width())
- .into_any()
- }),
- )
- .with_child(
- Label::new(
- channel.name().to_string(),
- if root {
- style.root_name.clone()
- } else {
- style.channel_name.clone()
- },
- )
- .into_any(),
- ),
- )
- .with_children(sub_channel_details.map(|(elements, _)| elements)),
- )
- .into_any()
- }
}
impl View for ChannelsPanel {
@@ -254,42 +153,11 @@ impl View for ChannelsPanel {
fn render(&mut self, cx: &mut gpui::ViewContext<'_, '_, Self>) -> gpui::AnyElement<Self> {
let theme = theme::current(cx).clone();
- let mut channels_column = Flex::column();
- for channel in self.channels.read(cx).channels() {
- channels_column = channels_column.with_child(self.render_channel(
- 0,
- &channel,
- &theme.channels_panel.channel_tree,
- true,
- cx,
- ));
- }
-
- let spacing = theme.channels_panel.spacing;
-
enum ChannelsPanelScrollTag {}
Stack::new()
.with_child(
// Full panel column
Flex::column()
- .with_spacing(spacing)
- .with_child(
- // Channels section column
- Flex::column()
- .with_child(
- Flex::row().with_child(
- Label::new(
- "Active Channels",
- theme.editor.invalid_information_diagnostic.message.clone(),
- )
- .into_any(),
- ),
- )
- // Channels list column
- .with_child(channels_column),
- )
- // TODO: Replace with spacing implementation
- .with_child(Empty::new().constrained().with_height(spacing))
.with_child(
Flex::column().with_child(
Flex::row().with_child(
@@ -22,7 +22,6 @@ pub struct Flex<V: View> {
children: Vec<AnyElement<V>>,
scroll_state: Option<(ElementStateHandle<Rc<ScrollState>>, usize)>,
child_alignment: f32,
- spacing: f32,
}
impl<V: View> Flex<V> {
@@ -32,7 +31,6 @@ impl<V: View> Flex<V> {
children: Default::default(),
scroll_state: None,
child_alignment: -1.,
- spacing: 0.,
}
}
@@ -44,11 +42,6 @@ impl<V: View> Flex<V> {
Self::new(Axis::Vertical)
}
- pub fn with_spacing(mut self, spacing: f32) -> Self {
- self.spacing = spacing;
- self
- }
-
/// Render children centered relative to the cross-axis of the parent flex.
///
/// If this is a flex row, children will be centered vertically. If this is a
@@ -1068,61 +1068,9 @@ pub struct FlexStyle {
item_spacing: f32,
}
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct ChannelProjectStyle {
- // TODO: Implement Contained Flex
- // ContainerStyle + Spacing between elements
- // Negative spacing overlaps elements instead of spacing them out
- pub container: Contained<FlexStyle>,
- pub host: ImageStyle,
- pub title: ContainedText,
- pub members: Contained<FlexStyle>,
- pub member: ImageStyle
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct ChanneltemStyle {
- pub icon: IconStyle,
- pub title: TextStyle,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct ChannelListStyle {
- pub section_title: ContainedText,
- pub channel: Toggleable<Contained<ChanneltemStyle>>,
- pub project: ChannelProjectStyle
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct ContactItemStyle {
- pub container: Contained<FlexStyle>,
- pub avatar: IconStyle,
- pub name: TextStyle,
-}
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct ContactsListStyle {
- pub section_title: ContainedText,
- pub contact: ContactItemStyle,
-}
-
-
-#[derive(Clone, Deserialize, Default, JsonSchema)]
-pub struct ChannelTreeStyle {
- pub channel_indent: f32,
- pub channel_name: TextStyle,
- pub root_name: TextStyle,
- pub channel_icon: Toggleable<Interactive<IconStyle>>,
-}
-
#[derive(Clone, Deserialize, Default, JsonSchema)]
pub struct ChanelsPanelStyle {
- pub channel_tree: ChannelTreeStyle,
- pub spacing: f32,
- // TODO: Uncomment:
- // pub container: ContainerStyle,
- // pub channel_list: ChannelListStyle,
- // pub contacts_list: ContactsListStyle
+ pub contacts_header: TextStyle,
}
#[derive(Clone, Deserialize, Default, JsonSchema)]
@@ -1,68 +1,12 @@
-// import { with_opacity } from "../theme/color"
import {
- // Border,
- // TextStyle,
- // background,
- // border,
- foreground,
text,
} from "./components"
-import { interactive, toggleable } from "../element"
-// import merge from "ts-deepmerge"
import { useTheme } from "../theme"
export default function channels_panel(): any {
const theme = useTheme()
- // const { is_light } = theme
return {
- spacing: 10,
- channel_tree: {
- channel_indent: 10,
- channel_name: text(theme.middle, "sans", "variant", { size: "md" }),
- root_name: text(theme.middle, "sans", "variant", { size: "lg", weight: "bold" }),
- channel_icon: (() => {
- const base_icon = (asset: any, color: any) => {
- return {
- icon: {
- color,
- asset,
- dimensions: {
- width: 12,
- height: 12,
- }
- },
- container: {
- corner_radius: 4,
- padding: {
- top: 4, bottom: 4, left: 4, right: 4
- },
- margin: {
- right: 4,
- },
- }
- }
- }
-
- return toggleable({
- state: {
- inactive: interactive({
- state: {
- default: base_icon("icons/chevron_right_8.svg", foreground(theme.middle, "variant")),
- hovered: base_icon("icons/chevron_right_8.svg", foreground(theme.middle, "hovered")),
- clicked: base_icon("icons/chevron_right_8.svg", foreground(theme.middle, "active")),
- },
- }),
- active: interactive({
- state: {
- default: base_icon("icons/chevron_down_8.svg", foreground(theme.highest, "variant")),
- hovered: base_icon("icons/chevron_down_8.svg", foreground(theme.highest, "hovered")),
- clicked: base_icon("icons/chevron_down_8.svg", foreground(theme.highest, "active")),
- },
- }),
- },
- })
- })(),
- }
+ contacts_header: text(theme.middle, "sans", "variant", { size: "lg" }),
}
}