mirror of
https://github.com/penpot/penpot.git
synced 2025-05-31 18:56:11 +02:00
113 lines
4 KiB
Clojure
113 lines
4 KiB
Clojure
;; This Source Code Form is subject to the terms of the Mozilla Public
|
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
;;
|
|
;; Copyright (c) KALEIDOS INC
|
|
|
|
(ns app.main.features
|
|
"A thin, frontend centric abstraction layer and collection of
|
|
helpers for `app.common.features` namespace."
|
|
(:require
|
|
[app.common.data.macros :as dm]
|
|
[app.common.features :as cfeat]
|
|
[app.common.logging :as log]
|
|
[app.config :as cf]
|
|
[app.main.store :as st]
|
|
[app.render-wasm :as wasm]
|
|
[clojure.set :as set]
|
|
[cuerdas.core :as str]
|
|
[okulary.core :as l]
|
|
[potok.v2.core :as ptk]
|
|
[rumext.v2 :as mf]))
|
|
|
|
(log/set-level! :trace)
|
|
|
|
(def global-enabled-features
|
|
(cfeat/get-enabled-features cf/flags))
|
|
|
|
(defn get-enabled-features
|
|
"An explicit lookup of enabled features for the current team"
|
|
[state team-id]
|
|
(let [team (dm/get-in state [:teams team-id])]
|
|
(-> global-enabled-features
|
|
(set/union (get state :features-runtime #{}))
|
|
(set/intersection cfeat/no-migration-features)
|
|
(set/union (get team :features)))))
|
|
|
|
(defn active-feature?
|
|
"Given a state and feature, check if feature is enabled."
|
|
[state feature]
|
|
(assert (contains? cfeat/supported-features feature) "feature not supported")
|
|
(let [runtime-features (get state :features-runtime)
|
|
enabled-features (get state :features)]
|
|
(or (contains? runtime-features feature)
|
|
(if (contains? cfeat/no-migration-features feature)
|
|
(or (contains? global-enabled-features feature)
|
|
(contains? enabled-features feature))
|
|
(contains? enabled-features feature)))))
|
|
|
|
(def ^:private features-ref
|
|
(l/derived (l/key :features) st/state))
|
|
|
|
(defn use-feature
|
|
"A react hook that checks if feature is currently enabled"
|
|
[feature]
|
|
(let [enabled-features (mf/deref features-ref)]
|
|
(contains? enabled-features feature)))
|
|
|
|
(defn toggle-feature
|
|
"An event constructor for runtime feature toggle.
|
|
|
|
Warning: if a feature is active globally or by team, it can't be
|
|
disabled."
|
|
[feature]
|
|
(ptk/reify ::toggle-feature
|
|
ptk/UpdateEvent
|
|
(update [_ state]
|
|
(assert (contains? cfeat/supported-features feature) "not supported feature")
|
|
(-> state
|
|
(update :features-runtime (fn [features]
|
|
(if (contains? features feature)
|
|
(do
|
|
(log/trc :hint "feature disabled" :feature feature)
|
|
(disj features feature))
|
|
(do
|
|
(log/trc :hint "feature enabled" :feature feature)
|
|
(conj features feature)))))
|
|
(update :features-runtime set/intersection cfeat/no-migration-features)))))
|
|
|
|
(defn enable-feature
|
|
[feature]
|
|
(ptk/reify ::enable-feature
|
|
ptk/UpdateEvent
|
|
(update [_ state]
|
|
(assert (contains? cfeat/supported-features feature) "not supported feature")
|
|
(if (active-feature? state feature)
|
|
state
|
|
(do
|
|
(log/trc :hint "feature enabled" :feature feature)
|
|
(-> state
|
|
(update :features-runtime (fnil conj #{}) feature)
|
|
(update :features-runtime set/intersection cfeat/no-migration-features)))))))
|
|
|
|
(defn initialize
|
|
[features]
|
|
(ptk/reify ::initialize
|
|
ptk/UpdateEvent
|
|
(update [_ state]
|
|
(let [features (-> global-enabled-features
|
|
(set/union (get state :features-runtime #{}))
|
|
(set/union features))]
|
|
(assoc state :features features)))
|
|
|
|
ptk/EffectEvent
|
|
(effect [_ state _]
|
|
(let [features (get state :features)]
|
|
(if (contains? features "render-wasm/v1")
|
|
(wasm/initialize true)
|
|
(wasm/initialize false))
|
|
|
|
(log/inf :hint "initialized"
|
|
:enabled (str/join "," features)
|
|
:runtime (str/join "," (:features-runtime state)))))))
|
|
|