WIP

Antonio Scandurra created

Change summary

Cargo.lock                                  | 10 ++
crates/client2/Cargo.toml                   |  2 
crates/client2/src/user.rs                  | 14 +--
crates/feature_flags2/Cargo.toml            | 12 +++
crates/feature_flags2/src/feature_flags2.rs | 79 +++++++++++++++++++++++
5 files changed, 107 insertions(+), 10 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -1458,7 +1458,7 @@ dependencies = [
  "async-tungstenite",
  "collections",
  "db",
- "feature_flags",
+ "feature_flags2",
  "futures 0.3.28",
  "gpui2",
  "image",
@@ -2676,6 +2676,14 @@ dependencies = [
  "gpui",
 ]
 
+[[package]]
+name = "feature_flags2"
+version = "0.1.0"
+dependencies = [
+ "anyhow",
+ "gpui2",
+]
+
 [[package]]
 name = "feedback"
 version = "0.1.0"

crates/client2/Cargo.toml 🔗

@@ -19,7 +19,7 @@ util = { path = "../util" }
 rpc = { path = "../rpc" }
 text = { path = "../text" }
 settings2 = { path = "../settings2" }
-feature_flags = { path = "../feature_flags" }
+feature_flags2 = { path = "../feature_flags2" }
 sum_tree = { path = "../sum_tree" }
 
 anyhow.workspace = true

crates/client2/src/user.rs 🔗

@@ -193,16 +193,14 @@ impl UserStore {
                         }
                         Status::SignedOut => {
                             current_user_tx.send(None).await.ok();
-                            if let Some(this) = this.upgrade(&cx) {
-                                this.update(&mut cx, |this, cx| {
-                                    cx.notify();
-                                    this.clear_contacts()
-                                })
-                                .await;
-                            }
+                            this.update(&mut cx, |this, cx| {
+                                cx.notify();
+                                this.clear_contacts()
+                            })
+                            .await;
                         }
                         Status::ConnectionLost => {
-                            if let Some(this) = this.upgrade(&cx) {
+                            if let Some(this) = this.upgrade() {
                                 this.update(&mut cx, |this, cx| {
                                     cx.notify();
                                     this.clear_contacts()

crates/feature_flags2/Cargo.toml 🔗

@@ -0,0 +1,12 @@
+[package]
+name = "feature_flags2"
+version = "0.1.0"
+edition = "2021"
+publish = false
+
+[lib]
+path = "src/feature_flags2.rs"
+
+[dependencies]
+gpui2 = { path = "../gpui2" }
+anyhow.workspace = true

crates/feature_flags2/src/feature_flags2.rs 🔗

@@ -0,0 +1,79 @@
+use gpui2::{AppContext, Subscription, ViewContext};
+
+#[derive(Default)]
+struct FeatureFlags {
+    flags: Vec<String>,
+    staff: bool,
+}
+
+impl FeatureFlags {
+    fn has_flag(&self, flag: &str) -> bool {
+        self.staff || self.flags.iter().find(|f| f.as_str() == flag).is_some()
+    }
+}
+
+pub trait FeatureFlag {
+    const NAME: &'static str;
+}
+
+pub enum ChannelsAlpha {}
+
+impl FeatureFlag for ChannelsAlpha {
+    const NAME: &'static str = "channels_alpha";
+}
+
+pub trait FeatureFlagViewExt<V: 'static> {
+    fn observe_flag<T: FeatureFlag, F>(&mut self, callback: F) -> Subscription
+    where
+        F: Fn(bool, &mut V, &mut ViewContext<V>) + 'static;
+}
+
+impl<V: 'static> FeatureFlagViewExt<V> for ViewContext<'_, '_, V> {
+    fn observe_flag<T: FeatureFlag, F>(&mut self, callback: F) -> Subscription
+    where
+        F: Fn(bool, &mut V, &mut ViewContext<V>) + 'static,
+    {
+        self.observe_global::<FeatureFlags, _>(move |v, cx| {
+            let feature_flags = cx.global::<FeatureFlags>();
+            callback(feature_flags.has_flag(<T as FeatureFlag>::NAME), v, cx);
+        })
+    }
+}
+
+pub trait FeatureFlagAppExt {
+    fn update_flags(&mut self, staff: bool, flags: Vec<String>);
+    fn set_staff(&mut self, staff: bool);
+    fn has_flag<T: FeatureFlag>(&self) -> bool;
+    fn is_staff(&self) -> bool;
+}
+
+impl FeatureFlagAppExt for AppContext {
+    fn update_flags(&mut self, staff: bool, flags: Vec<String>) {
+        self.update_default_global::<FeatureFlags, _, _>(|feature_flags, _| {
+            feature_flags.staff = staff;
+            feature_flags.flags = flags;
+        })
+    }
+
+    fn set_staff(&mut self, staff: bool) {
+        self.update_default_global::<FeatureFlags, _, _>(|feature_flags, _| {
+            feature_flags.staff = staff;
+        })
+    }
+
+    fn has_flag<T: FeatureFlag>(&self) -> bool {
+        if self.has_global::<FeatureFlags>() {
+            self.global::<FeatureFlags>().has_flag(T::NAME)
+        } else {
+            false
+        }
+    }
+
+    fn is_staff(&self) -> bool {
+        if self.has_global::<FeatureFlags>() {
+            return self.global::<FeatureFlags>().staff;
+        } else {
+            false
+        }
+    }
+}