Make feature resolved on team load

That simplifies features retrieval to simple get
This commit is contained in:
Andrey Antukh 2025-04-01 20:01:21 +02:00
parent f04229d8cb
commit f8ffae75c4
17 changed files with 171 additions and 224 deletions

View file

@ -25,7 +25,6 @@
(let [claims (-> {} (let [claims (-> {}
(into (::session/token-claims request)) (into (::session/token-claims request))
(into (::actoken/token-claims request)))] (into (::actoken/token-claims request)))]
{:request/path (:path request) {:request/path (:path request)
:request/method (:method request) :request/method (:method request)
:request/params (:params request) :request/params (:params request)

View file

@ -15,7 +15,6 @@
[app.main.data.profile :as dp] [app.main.data.profile :as dp]
[app.main.data.websocket :as ws] [app.main.data.websocket :as ws]
[app.main.errors] [app.main.errors]
[app.main.features :as feat]
[app.main.rasterizer :as thr] [app.main.rasterizer :as thr]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui :as ui] [app.main.ui :as ui]
@ -67,7 +66,6 @@
(watch [_ _ stream] (watch [_ _ stream]
(rx/merge (rx/merge
(rx/of (ev/initialize) (rx/of (ev/initialize)
(feat/initialize)
(dp/refresh-profile)) (dp/refresh-profile))
;; Watch for profile deletion events ;; Watch for profile deletion events

View file

@ -13,7 +13,6 @@
[app.common.types.shape-tree :as ctst] [app.common.types.shape-tree :as ctst]
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[app.main.data.helpers :as dsh] [app.main.data.helpers :as dsh]
[app.main.features :as features]
[app.main.worker :as uw] [app.main.worker :as uw]
[app.util.time :as dt] [app.util.time :as dt]
[beicon.v2.core :as rx] [beicon.v2.core :as rx]
@ -182,8 +181,8 @@
(let [file-id (or file-id (:current-file-id state)) (let [file-id (or file-id (:current-file-id state))
uchg (vec undo-changes) uchg (vec undo-changes)
rchg (vec redo-changes) rchg (vec redo-changes)
features (features/get-team-enabled-features state) features (get state :features)
permissions (:permissions state)] permissions (get state :permissions)]
;; Prevent commit changes by a viewer team member (it really should never happen) ;; Prevent commit changes by a viewer team member (it really should never happen)
(when (:can-edit permissions) (when (:can-edit permissions)

View file

@ -16,7 +16,6 @@
[app.main.data.modal :as modal] [app.main.data.modal :as modal]
[app.main.data.notifications :as ntf] [app.main.data.notifications :as ntf]
[app.main.data.persistence :as-alias dps] [app.main.data.persistence :as-alias dps]
[app.main.features :as features]
[app.main.repo :as rp] [app.main.repo :as rp]
[app.main.router :as rt] [app.main.router :as rt]
[app.main.store :as st] [app.main.store :as st]
@ -112,7 +111,7 @@
(ptk/reify ::show-shared-dialog (ptk/reify ::show-shared-dialog
ptk/WatchEvent ptk/WatchEvent
(watch [_ state _] (watch [_ state _]
(let [features (features/get-team-enabled-features state) (let [features (get state :features)
file (dsh/lookup-file state) file (dsh/lookup-file state)
data (get file :data)] data (get file :data)]
@ -169,8 +168,8 @@
(ptk/reify ::export-files (ptk/reify ::export-files
ptk/WatchEvent ptk/WatchEvent
(watch [_ state _] (watch [_ state _]
(let [features (features/get-team-enabled-features state) (let [features (get state :features)
team-id (:current-team-id state)] team-id (get state :current-team-id)]
(->> (rx/from files) (->> (rx/from files)
(rx/mapcat (rx/mapcat
(fn [file] (fn [file]

View file

@ -19,7 +19,6 @@
[app.main.data.helpers :as dsh] [app.main.data.helpers :as dsh]
[app.main.data.modal :as modal] [app.main.data.modal :as modal]
[app.main.data.websocket :as dws] [app.main.data.websocket :as dws]
[app.main.features :as features]
[app.main.repo :as rp] [app.main.repo :as rp]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[app.util.sse :as sse] [app.util.sse :as sse]
@ -497,7 +496,7 @@
base-name (tr "dashboard.new-file-prefix") base-name (tr "dashboard.new-file-prefix")
name (or name name (or name
(cfh/generate-unique-name base-name unames :immediate-suffix? true)) (cfh/generate-unique-name base-name unames :immediate-suffix? true))
features (-> (features/get-team-enabled-features state) features (-> (get state :features)
(set/difference cfeat/frontend-only-features)) (set/difference cfeat/frontend-only-features))
params (-> params params (-> params
(assoc :name name) (assoc :name name)

View file

@ -12,7 +12,6 @@
[app.common.schema :as sm] [app.common.schema :as sm]
[app.main.data.event :as ev] [app.main.data.event :as ev]
[app.main.data.modal :as modal] [app.main.data.modal :as modal]
[app.main.features :as features]
[app.main.repo :as rp] [app.main.repo :as rp]
[beicon.v2.core :as rx] [beicon.v2.core :as rx]
[potok.v2.core :as ptk])) [potok.v2.core :as ptk]))
@ -47,7 +46,7 @@
(ptk/reify ::export-files (ptk/reify ::export-files
ptk/WatchEvent ptk/WatchEvent
(watch [_ state _] (watch [_ state _]
(let [features (features/get-team-enabled-features state) (let [features (get state :features)
team-id (:current-team-id state) team-id (:current-team-id state)
evname (if (= format :legacy-zip) evname (if (= format :legacy-zip)
"export-standard-files" "export-standard-files"

View file

@ -101,7 +101,7 @@
(let [permissions (get team :permissions) (let [permissions (get team :permissions)
features (get team :features)] features (get team :features)]
(rx/of #(assoc % :permissions permissions) (rx/of #(assoc % :permissions permissions)
(features/initialize (or features #{})) (features/initialize features)
(fetch-members team-id)))))) (fetch-members team-id))))))
ptk/EffectEvent ptk/EffectEvent
@ -255,11 +255,11 @@
(dm/assert! (string? name)) (dm/assert! (string? name))
(ptk/reify ::create-team (ptk/reify ::create-team
ptk/WatchEvent ptk/WatchEvent
(watch [it state _] (watch [it _ _]
(let [{:keys [on-success on-error] (let [{:keys [on-success on-error]
:or {on-success identity :or {on-success identity
on-error rx/throw}} (meta params) on-error rx/throw}} (meta params)
features (features/get-enabled-features state) features features/global-enabled-features
params {:name name :features features}] params {:name name :features features}]
(->> (rp/cmd! :create-team (with-meta params (meta it))) (->> (rp/cmd! :create-team (with-meta params (meta it)))
(rx/tap on-success) (rx/tap on-success)
@ -272,11 +272,11 @@
[{:keys [name emails role] :as params}] [{:keys [name emails role] :as params}]
(ptk/reify ::create-team-with-invitations (ptk/reify ::create-team-with-invitations
ptk/WatchEvent ptk/WatchEvent
(watch [it state _] (watch [it _ _]
(let [{:keys [on-success on-error] (let [{:keys [on-success on-error]
:or {on-success identity :or {on-success identity
on-error rx/throw}} (meta params) on-error rx/throw}} (meta params)
features (features/get-enabled-features state) features features/global-enabled-features
params {:name name params {:name name
:emails emails :emails emails
:role role :role role

View file

@ -184,7 +184,7 @@
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(let [team-id (:id team) (let [team-id (:id team)
team {:members users}] team (assoc team :members users)]
(-> state (-> state
(assoc :share-links share-links) (assoc :share-links share-links)
(assoc :current-team-id team-id) (assoc :current-team-id team-id)

View file

@ -80,7 +80,6 @@
[app.main.data.workspace.viewport :as dwv] [app.main.data.workspace.viewport :as dwv]
[app.main.data.workspace.zoom :as dwz] [app.main.data.workspace.zoom :as dwz]
[app.main.errors] [app.main.errors]
[app.main.features :as features]
[app.main.features.pointer-map :as fpmap] [app.main.features.pointer-map :as fpmap]
[app.main.repo :as rp] [app.main.repo :as rp]
[app.main.router :as rt] [app.main.router :as rt]
@ -208,11 +207,10 @@
(d/index-by :id)))))) (d/index-by :id))))))
(defn- fetch-libraries (defn- fetch-libraries
[file-id] [file-id features]
(ptk/reify ::fetch-libries (ptk/reify ::fetch-libries
ptk/WatchEvent ptk/WatchEvent
(watch [_ state _] (watch [_ _ _]
(let [features (features/get-team-enabled-features state)]
(->> (rp/cmd! :get-file-libraries {:file-id file-id}) (->> (rp/cmd! :get-file-libraries {:file-id file-id})
(rx/mapcat (rx/mapcat
(fn [libraries] (fn [libraries]
@ -231,7 +229,7 @@
(rx/mapcat (fn [file-id] (rx/mapcat (fn [file-id]
(rp/cmd! :get-file-object-thumbnails {:file-id file-id :tag "component"}))) (rp/cmd! :get-file-object-thumbnails {:file-id file-id :tag "component"})))
(rx/map dwl/library-thumbnails-fetched))) (rx/map dwl/library-thumbnails-fetched)))
(rx/of (check-libraries-synchronozation file-id libraries)))))))))) (rx/of (check-libraries-synchronozation file-id libraries)))))))))
(defn- workspace-initialized (defn- workspace-initialized
[file-id] [file-id]
@ -249,28 +247,16 @@
(fbs/fix-broken-shapes))))) (fbs/fix-broken-shapes)))))
(defn- bundle-fetched (defn- bundle-fetched
[{:keys [features file thumbnails]}] [{:keys [file file-id thumbnails] :as bundle}]
(ptk/reify ::bundle-fetched (ptk/reify ::bundle-fetched
IDeref IDeref
(-deref [_] (-deref [_] bundle)
{:features features
:file file
:thumbnails thumbnails})
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(let [file-id (:id file)]
(-> state (-> state
(assoc :thumbnails thumbnails) (assoc :thumbnails thumbnails)
(update :files assoc file-id file)))) (update :files assoc file-id file)))))
ptk/WatchEvent
(watch [_ state _]
(let [team-id (:current-team-id state)
file-id (:id file)]
(rx/of (dwn/initialize team-id file-id)
(dwsl/initialize-shape-layout)
(fetch-libraries file-id))))))
(defn zoom-to-frame (defn zoom-to-frame
[] []
@ -299,30 +285,11 @@
(defn- fetch-bundle (defn- fetch-bundle
"Multi-stage file bundle fetch coordinator" "Multi-stage file bundle fetch coordinator"
[file-id] [file-id features]
(ptk/reify ::fetch-bundle (ptk/reify ::fetch-bundle
ptk/WatchEvent ptk/WatchEvent
(watch [_ state stream] (watch [_ _ stream]
(let [features (features/get-team-enabled-features state) (let [stopper-s (rx/filter (ptk/type? ::finalize-workspace) stream)]
render-wasm? (contains? features "render-wasm/v1")
stopper-s (rx/filter (ptk/type? ::finalize-workspace) stream)
team-id (:current-team-id state)]
(->> (rx/concat
;; Firstly load wasm module if it is enabled and fonts
(rx/merge
(if ^boolean render-wasm?
(->> (rx/from @wasm/module)
(rx/ignore))
(rx/empty))
(->> stream
(rx/filter (ptk/type? ::df/fonts-loaded))
(rx/take 1)
(rx/ignore))
(rx/of (df/fetch-fonts team-id)))
;; Then fetch file and thumbnails
(->> (rx/zip (rp/cmd! :get-file {:id file-id :features features}) (->> (rx/zip (rp/cmd! :get-file {:id file-id :features features})
(get-file-object-thumbnails file-id)) (get-file-object-thumbnails file-id))
(rx/take 1) (rx/take 1)
@ -331,14 +298,16 @@
(->> (resolve-file file) (->> (resolve-file file)
(rx/map (fn [file] (rx/map (fn [file]
{:file file {:file file
:file-id file-id
:features features :features features
:thumbnails thumbnails}))))) :thumbnails thumbnails})))))
(rx/map bundle-fetched))) (rx/map bundle-fetched)
(rx/take-until stopper-s)))))) (rx/take-until stopper-s))))))
(defn initialize-workspace (defn initialize-workspace
[file-id] [file-id]
(assert (uuid? file-id) "expected valud uuid for `file-id`") (assert (uuid? file-id) "expected valud uuid for `file-id`")
(ptk/reify ::initialize-workspace (ptk/reify ::initialize-workspace
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
@ -350,26 +319,52 @@
ptk/WatchEvent ptk/WatchEvent
(watch [_ state stream] (watch [_ state stream]
(log/debug :hint "initialize-workspace" :file-id (dm/str file-id))
(let [stoper-s (rx/filter (ptk/type? ::finalize-workspace) stream) (let [stoper-s (rx/filter (ptk/type? ::finalize-workspace) stream)
rparams (rt/get-params state) rparams (rt/get-params state)
features (features/get-team-enabled-features state) team-id (get state :current-team-id)
features (get state :features)
render-wasm? (contains? features "render-wasm/v1")] render-wasm? (contains? features "render-wasm/v1")]
(log/debug :hint "initialize-workspace"
:team-id (dm/str team-id)
:file-id (dm/str file-id))
(->> (rx/merge (->> (rx/merge
(rx/concat
;; Fetch all essential data that should be loaded before the file
(rx/merge
(if ^boolean render-wasm?
(->> (rx/from @wasm/module)
(rx/ignore))
(rx/empty))
(->> stream
(rx/filter (ptk/type? ::df/fonts-loaded))
(rx/take 1)
(rx/ignore))
(rx/of (ntf/hide) (rx/of (ntf/hide)
(dcmt/retrieve-comment-threads file-id) (dcmt/retrieve-comment-threads file-id)
(dcmt/fetch-profiles) (dcmt/fetch-profiles)
(fetch-bundle file-id)) (df/fetch-fonts team-id)))
;; Once the essential data is fetched, lets proceed to
;; fetch teh file bunldle
(rx/of (fetch-bundle file-id features)))
(->> stream (->> stream
(rx/filter (ptk/type? ::bundle-fetched)) (rx/filter (ptk/type? ::bundle-fetched))
(rx/take 1) (rx/take 1)
(rx/map deref) (rx/map deref)
(rx/mapcat (fn [{:keys [file]}] (rx/mapcat
(fn [{:keys [file]}]
(rx/of (dpj/initialize-project (:project-id file)) (rx/of (dpj/initialize-project (:project-id file))
(dwn/initialize team-id file-id)
(dwsl/initialize-shape-layout)
(fetch-libraries file-id features)
(-> (workspace-initialized file-id) (-> (workspace-initialized file-id)
(with-meta {:file-id file-id})))))) (with-meta {:team-id team-id
:file-id file-id}))))))
(->> stream (->> stream
(rx/filter (ptk/type? ::dps/persistence-notification)) (rx/filter (ptk/type? ::dps/persistence-notification))
@ -442,7 +437,6 @@
ptk/WatchEvent ptk/WatchEvent
(watch [_ state _] (watch [_ state _]
(let [project-id (:current-project-id state)] (let [project-id (:current-project-id state)]
(rx/of (dwn/finalize file-id) (rx/of (dwn/finalize file-id)
(dpj/finalize-project project-id) (dpj/finalize-project project-id)
(dwsl/finalize-shape-layout) (dwsl/finalize-shape-layout)
@ -462,8 +456,6 @@
;; Make this event callable through dynamic resolution ;; Make this event callable through dynamic resolution
(defmethod ptk/resolve ::reload-current-file [_ _] (reload-current-file)) (defmethod ptk/resolve ::reload-current-file [_ _] (reload-current-file))
(def ^:private xf:collect-file-media (def ^:private xf:collect-file-media
"Resolve and collect all file media on page objects" "Resolve and collect all file media on page objects"
(comp (map second) (comp (map second)
@ -1435,7 +1427,7 @@
(let [objects (dsh/lookup-page-objects state) (let [objects (dsh/lookup-page-objects state)
selected (->> (dsh/lookup-selected state) selected (->> (dsh/lookup-selected state)
(cfh/clean-loops objects)) (cfh/clean-loops objects))
features (-> (features/get-team-enabled-features state) features (-> (get state :features)
(set/difference cfeat/frontend-only-features)) (set/difference cfeat/frontend-only-features))
file-id (:current-file-id state) file-id (:current-file-id state)
@ -1673,9 +1665,10 @@
objects (dsh/lookup-page-objects state)] objects (dsh/lookup-page-objects state)]
(when-let [shape (get objects selected)] (when-let [shape (get objects selected)]
(let [props (cts/extract-props shape) (let [props (cts/extract-props shape)
features (-> (features/get-team-enabled-features state) features (-> (get state :features)
(set/difference cfeat/frontend-only-features)) (set/difference cfeat/frontend-only-features))
version (-> (dsh/lookup-file state) :version) version (-> (dsh/lookup-file state)
(get :version))
copy-data {:type :copied-props copy-data {:type :copied-props
:features features :features features
@ -1810,7 +1803,7 @@
ptk/WatchEvent ptk/WatchEvent
(watch [_ state _] (watch [_ state _]
(let [file-id (:current-file-id state) (let [file-id (:current-file-id state)
features (features/get-team-enabled-features state)] features (get state :features)]
(when-not (paste-data-valid? pdata) (when-not (paste-data-valid? pdata)
(ex/raise :type :validation (ex/raise :type :validation
@ -1881,7 +1874,7 @@
(ptk/reify ::paste-transit-props (ptk/reify ::paste-transit-props
ptk/WatchEvent ptk/WatchEvent
(watch [_ state _] (watch [_ state _]
(let [features (features/get-team-enabled-features state) (let [features (get state :features)
selected (dsh/lookup-selected state)] selected (dsh/lookup-selected state)]
(when (paste-data-valid? pdata) (when (paste-data-valid? pdata)

View file

@ -1398,7 +1398,7 @@
ptk/WatchEvent ptk/WatchEvent
(watch [_ state _] (watch [_ state _]
(let [features (features/get-team-enabled-features state)] (let [features (get state :features)]
(rx/concat (rx/concat
(rx/merge (rx/merge
(->> (rp/cmd! :link-file-to-library {:file-id file-id :library-id library-id}) (->> (rp/cmd! :link-file-to-library {:file-id file-id :library-id library-id})

View file

@ -13,7 +13,6 @@
[app.config :as cf] [app.config :as cf]
[app.main.store :as st] [app.main.store :as st]
[app.render-wasm :as wasm] [app.render-wasm :as wasm]
[beicon.v2.core :as rx]
[clojure.set :as set] [clojure.set :as set]
[cuerdas.core :as str] [cuerdas.core :as str]
[okulary.core :as l] [okulary.core :as l]
@ -25,39 +24,24 @@
(def global-enabled-features (def global-enabled-features
(cfeat/get-enabled-features cf/flags)) (cfeat/get-enabled-features cf/flags))
(defn get-enabled-features
[state]
(-> (get state :features-runtime #{})
(set/intersection cfeat/no-migration-features)
(set/union global-enabled-features)))
(defn get-team-enabled-features
[state]
(let [runtime-features (:features-runtime state #{})
team-features (->> (:features-team state #{})
(into #{} cfeat/xf-remove-ephimeral))]
(-> global-enabled-features
(set/union runtime-features)
(set/intersection cfeat/no-migration-features)
(set/union team-features))))
(def features-ref
(l/derived get-team-enabled-features st/state =))
(defn active-feature? (defn active-feature?
"Given a state and feature, check if feature is enabled" "Given a state and feature, check if feature is enabled."
[state feature] [state feature]
(assert (contains? cfeat/supported-features feature) "not supported feature") (assert (contains? cfeat/supported-features feature) "feature not supported")
(or (contains? (get state :features-runtime) feature) (let [runtime-features (get state :features-runtime)
enabled-features (get state :features)]
(or (contains? runtime-features feature)
(if (contains? cfeat/no-migration-features feature) (if (contains? cfeat/no-migration-features feature)
(or (contains? global-enabled-features feature) (or (contains? global-enabled-features feature)
(contains? (get state :features-team) feature)) (contains? enabled-features feature))
(contains? (get state :features-team state) feature)))) (contains? enabled-features feature)))))
(def ^:private features-ref
(l/derived (l/key :features) st/state))
(defn use-feature (defn use-feature
"A react hook that checks if feature is currently enabled" "A react hook that checks if feature is currently enabled"
[feature] [feature]
(assert (contains? cfeat/supported-features feature) "Not supported feature")
(let [enabled-features (mf/deref features-ref)] (let [enabled-features (mf/deref features-ref)]
(contains? enabled-features feature))) (contains? enabled-features feature)))
@ -71,14 +55,16 @@
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(assert (contains? cfeat/supported-features feature) "not supported feature") (assert (contains? cfeat/supported-features feature) "not supported feature")
(update state :features-runtime (fn [features] (-> state
(update :features-runtime (fn [features]
(if (contains? features feature) (if (contains? features feature)
(do (do
(log/trc :hint "feature disabled" :feature feature) (log/trc :hint "feature disabled" :feature feature)
(disj features feature)) (disj features feature))
(do (do
(log/trc :hint "feature enabled" :feature feature) (log/trc :hint "feature enabled" :feature feature)
(conj features feature)))))))) (conj features feature)))))
(update :features-runtime set/intersection cfeat/no-migration-features)))))
(defn enable-feature (defn enable-feature
[feature] [feature]
@ -90,46 +76,28 @@
state state
(do (do
(log/trc :hint "feature enabled" :feature feature) (log/trc :hint "feature enabled" :feature feature)
(update state :features-runtime (fnil conj #{}) feature)))))) (-> state
(update :features-runtime (fnil conj #{}) feature)
(update :features-runtime set/intersection cfeat/no-migration-features)))))))
(defn initialize (defn initialize
([] (initialize #{})) [features]
([team-features]
(assert (set? team-features) "expected a set of features")
(assert (every? string? team-features) "expected a set of strings")
(ptk/reify ::initialize (ptk/reify ::initialize
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(let [runtime-features (get state :features/runtime #{}) (let [features (-> global-enabled-features
team-features (into #{} (set/union (get state :features-runtime #{}))
cfeat/xf-supported-features (set/union features))]
team-features)] (assoc state :features features)))
(-> state
(assoc :features-runtime runtime-features)
(assoc :features-team team-features))))
ptk/WatchEvent
(watch [_ _ _]
(when *assert*
(->> (rx/from cfeat/no-migration-features)
;; text editor v2 isn't enabled by default even in devenv
;; wasm render v1 isn't enabled by default even in devenv
(rx/filter #(not (or (contains? cfeat/backend-only-features %)
(= "text-editor/v2" %)
(= "render-wasm/v1" %)
(= "design-tokens/v1" %))))
(rx/observe-on :async)
(rx/map enable-feature))))
ptk/EffectEvent ptk/EffectEvent
(effect [_ state _] (effect [_ state _]
(let [features (get-team-enabled-features state)] (let [features (get state :features)]
(if (contains? features "render-wasm/v1") (if (contains? features "render-wasm/v1")
(wasm/initialize true) (wasm/initialize true)
(wasm/initialize false)) (wasm/initialize false))
(log/inf :hint "initialized" (log/inf :hint "initialized"
:enabled (str/join "," features) :enabled (str/join "," features)
:runtime (str/join "," (:features-runtime state)))))))) :runtime (str/join "," (:features-runtime state)))))))

View file

@ -17,7 +17,6 @@
[app.main.data.notifications :as ntf] [app.main.data.notifications :as ntf]
[app.main.data.project :as dpj] [app.main.data.project :as dpj]
[app.main.data.team :as dtm] [app.main.data.team :as dtm]
[app.main.features :as features]
[app.main.fonts :as fonts] [app.main.fonts :as fonts]
[app.main.rasterizer :as thr] [app.main.rasterizer :as thr]
[app.main.refs :as refs] [app.main.refs :as refs]
@ -60,7 +59,7 @@
(->> (wrk/ask! {:cmd :thumbnails/generate-for-file (->> (wrk/ask! {:cmd :thumbnails/generate-for-file
:revn revn :revn revn
:file-id file-id :file-id file-id
:features (features/get-team-enabled-features @st/state)}) :features (get @st/state :features)})
(rx/mapcat (fn [{:keys [fonts] :as result}] (rx/mapcat (fn [{:keys [fonts] :as result}]
(->> (fonts/render-font-styles fonts) (->> (fonts/render-font-styles fonts)
(rx/map (fn [styles] (rx/map (fn [styles]

View file

@ -15,7 +15,6 @@
[app.main.data.modal :as modal] [app.main.data.modal :as modal]
[app.main.data.notifications :as ntf] [app.main.data.notifications :as ntf]
[app.main.errors :as errors] [app.main.errors :as errors]
[app.main.features :as features]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.components.file-uploader :refer [file-uploader]] [app.main.ui.components.file-uploader :refer [file-uploader]]
[app.main.ui.ds.product.loader :refer [loader*]] [app.main.ui.ds.product.loader :refer [loader*]]
@ -162,29 +161,32 @@
(defn- analyze-entries (defn- analyze-entries
[state entries] [state entries]
(let [features (get @st/state :features)]
(->> (uw/ask-many! (->> (uw/ask-many!
{:cmd :analyze-import {:cmd :analyze-import
:files entries :files entries
:features @features/features-ref}) :features features})
(rx/mapcat #(rx/delay emit-delay (rx/of %))) (rx/mapcat #(rx/delay emit-delay (rx/of %)))
(rx/filter some?) (rx/filter some?)
(rx/subs! (rx/subs!
(fn [message] (fn [message]
(swap! state update-with-analyze-result message))))) (swap! state update-with-analyze-result message))))))
(defn- import-files (defn- import-files
[state project-id entries] [state project-id entries]
(st/emit! (ptk/data-event ::ev/event {::ev/name "import-files" (st/emit! (ptk/data-event ::ev/event {::ev/name "import-files"
:num-files (count entries)})) :num-files (count entries)}))
(let [features (get @st/state :features)]
(->> (uw/ask-many! (->> (uw/ask-many!
{:cmd :import-files {:cmd :import-files
:project-id project-id :project-id project-id
:files entries :files entries
:features @features/features-ref}) :features features})
(rx/filter (comp uuid? :file-id)) (rx/filter (comp uuid? :file-id))
(rx/subs! (rx/subs!
(fn [message] (fn [message]
(swap! state update-entry-status message))))) (swap! state update-entry-status message))))))
(mf/defc import-entry* (mf/defc import-entry*
{::mf/props :obj {::mf/props :obj

View file

@ -13,7 +13,6 @@
[app.main.data.exports.files :as exports.files] [app.main.data.exports.files :as exports.files]
[app.main.data.workspace :as dw] [app.main.data.workspace :as dw]
[app.main.data.workspace.versions :as dwv] [app.main.data.workspace.versions :as dwv]
[app.main.features :as features]
[app.main.repo :as rp] [app.main.repo :as rp]
[app.main.store :as st] [app.main.store :as st]
[app.main.worker :as uw] [app.main.worker :as uw]
@ -237,7 +236,7 @@
:else :else
(let [file (u/locate-file id) (let [file (u/locate-file id)
features (features/get-team-enabled-features @st/state) features (:features @st/state)
team-id (:current-team-id @st/state) team-id (:current-team-id @st/state)
format (case format format (case format
"zip" :legacy-zip "zip" :legacy-zip

View file

@ -41,7 +41,7 @@
ptk/WatchEvent ptk/WatchEvent
(watch [_ _ _] (watch [_ _ _]
(rx/of (features/initialize (or features #{})))))) (rx/of (features/initialize features)))))
(defn- fetch-team (defn- fetch-team
[& {:keys [file-id]}] [& {:keys [file-id]}]
@ -98,7 +98,7 @@
(ptk/reify ::fetch-objects-bundle (ptk/reify ::fetch-objects-bundle
ptk/WatchEvent ptk/WatchEvent
(watch [_ state _] (watch [_ state _]
(let [features (features/get-team-enabled-features state)] (let [features (get state :features)]
(->> (rx/zip (->> (rx/zip
(repo/cmd! :get-font-variants {:file-id file-id :share-id share-id}) (repo/cmd! :get-font-variants {:file-id file-id :share-id share-id})
(repo/cmd! :get-page {:file-id file-id (repo/cmd! :get-page {:file-id file-id
@ -237,7 +237,7 @@
(ptk/reify ::fetch-components-bundle (ptk/reify ::fetch-components-bundle
ptk/WatchEvent ptk/WatchEvent
(watch [_ state _] (watch [_ state _]
(let [features (features/get-team-enabled-features state)] (let [features (get state :features)]
(->> (repo/cmd! :get-file {:id file-id :features features}) (->> (repo/cmd! :get-file {:id file-id :features features})
(rx/map (fn [file] #(assoc % :file file)))))))) (rx/map (fn [file] #(assoc % :file file))))))))
@ -309,7 +309,6 @@
(defn ^:export init (defn ^:export init
[] []
(st/emit! (features/initialize))
(init-ui)) (init-ui))
(defn reinit (defn reinit

View file

@ -27,7 +27,6 @@
[app.main.data.workspace.selection :as dws] [app.main.data.workspace.selection :as dws]
[app.main.data.workspace.shortcuts] [app.main.data.workspace.shortcuts]
[app.main.errors :as errors] [app.main.errors :as errors]
[app.main.features :as features]
[app.main.repo :as rp] [app.main.repo :as rp]
[app.main.store :as st] [app.main.store :as st]
[app.util.debug :as dbg] [app.util.debug :as dbg]
@ -393,7 +392,7 @@
(ptk/reify ::repair-current-file (ptk/reify ::repair-current-file
ptk/EffectEvent ptk/EffectEvent
(effect [_ state _] (effect [_ state _]
(let [features (features/get-team-enabled-features state) (let [features (:features state)
sid (:session-id state) sid (:session-id state)
file (dsh/lookup-file state) file (dsh/lookup-file state)
@ -430,7 +429,3 @@
(defn ^:export set-shape-ref (defn ^:export set-shape-ref
[id shape-ref] [id shape-ref]
(st/emit! (dw/set-shape-ref id shape-ref))) (st/emit! (dw/set-shape-ref id shape-ref)))
(defn ^:export enable-text-v2
[]
(st/emit! (features/enable-feature "text-editor/v2")))

View file

@ -20,13 +20,12 @@
nil) nil)
(defn ^:export get-enabled [] (defn ^:export get-enabled []
(clj->js (features/get-enabled-features @st/state))) (clj->js features/global-enabled-features))
(defn ^:export get-team-enabled [] (defn ^:export get-team-enabled []
(clj->js (features/get-team-enabled-features @st/state))) (clj->js (get @st/state :features)))
(defn ^:export plugins [] (defn ^:export plugins []
(st/emit! (features/enable-feature "plugins/runtime")) (st/emit! (features/enable-feature "plugins/runtime"))
(plugins/init-plugins-runtime!) (plugins/init-plugins-runtime!)
nil) nil)