Merge remote-tracking branch 'origin/staging' into develop

This commit is contained in:
Andrey Antukh 2022-09-28 12:16:06 +02:00
commit 7303d311d5
283 changed files with 1548 additions and 1252 deletions

View file

@ -88,7 +88,6 @@
(def worker-uri (obj/get global "penpotWorkerURI" "/js/worker.js"))
(def translations (obj/get global "penpotTranslations"))
(def themes (obj/get global "penpotThemes"))
(def sentry-dsn (obj/get global "penpotSentryDsn"))
(def onboarding-form-id (obj/get global "penpotOnboardingQuestionsFormId"))
(def build-date (parse-build-date global))

View file

@ -13,7 +13,6 @@
[app.main.data.users :as du]
[app.main.data.websocket :as ws]
[app.main.errors]
[app.main.sentry :as sentry]
[app.main.store :as st]
[app.main.ui :as ui]
[app.main.ui.alert]
@ -29,7 +28,7 @@
[debug]
[features]
[potok.core :as ptk]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(log/initialize!)
(log/set-level! :root :warn)
@ -75,7 +74,6 @@
(defn ^:export init
[]
(worker/init!)
(sentry/init!)
(i18n/init! cf/translations)
(theme/init! cf/themes)
(init-ui)

View file

@ -12,7 +12,7 @@
[app.main.store :as st]
[okulary.core :as l]
[potok.core :as ptk]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(log/set-level! :debug)

View file

@ -45,7 +45,7 @@
[beicon.core :as rx]
[clojure.set :as set]
[cuerdas.core :as str]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(def ^:const viewbox-decimal-precision 3)
(def ^:private default-color clr/canvas)

View file

@ -1,60 +0,0 @@
;; 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.sentry
"Sentry integration."
(:require
["@sentry/browser" :as sentry]
[app.common.exceptions :as ex]
[app.common.uuid :as uuid]
[app.config :as cf]
[app.main.refs :as refs]))
(defn- setup-profile!
[profile]
(if (or (= uuid/zero (:id profile))
(nil? profile))
(sentry/setUser nil)
(sentry/setUser #js {:id (str (:id profile))})))
(defn init!
[]
(setup-profile! @refs/profile)
(when cf/sentry-dsn
(sentry/init
#js {:dsn cf/sentry-dsn
:autoSessionTracking false
:attachStacktrace false
:release (str "frontend@" (:base @cf/version))
:maxBreadcrumbs 20
:beforeBreadcrumb (fn [breadcrumb _hint]
(let [category (.-category ^js breadcrumb)]
(if (= category "navigate")
breadcrumb
nil)))
:tracesSampleRate 1.0})
(add-watch refs/profile ::profile
(fn [_ _ _ profile]
(setup-profile! profile)))
(add-watch refs/route ::route
(fn [_ _ _ route]
(sentry/addBreadcrumb
#js {:category "navigate",
:message (str "path: " (:path route))
:level (.-Info ^js sentry/Severity)})))))
(defn capture-exception
[err]
(when cf/sentry-dsn
(when (ex/ex-info? err)
(sentry/setContext "ex-data", (clj->js (ex-data err))))
(sentry/captureException err))
err)

View file

@ -24,7 +24,7 @@
[app.main.ui.viewer :as viewer]
[app.main.ui.workspace :as workspace]
[app.util.router :as rt]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc on-main-error
[{:keys [error] :as props}]

View file

@ -13,7 +13,7 @@
[app.util.i18n :as i18n :refer [tr t]]
[app.util.keyboard :as k]
[goog.events :as events]
[rumext.alpha :as mf])
[rumext.v2 :as mf])
(:import goog.events.EventType))
(mf/defc alert-dialog

View file

@ -14,7 +14,7 @@
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc terms-login
[]

View file

@ -20,7 +20,7 @@
[app.util.router :as rt]
[beicon.core :as rx]
[cljs.spec.alpha :as s]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(def show-alt-login-buttons?
(some (partial contains? @cf/flags)
@ -83,14 +83,24 @@
form (fm/use-form :spec ::login-form :initial initial)
on-error
(fn [_]
(reset! error (tr "errors.wrong-credentials")))
(fn [cause]
(cond
(and (= :restriction (:type cause))
(= :profile-blocked (:code cause)))
(reset! error (tr "errors.profile-blocked"))
(and (= :validation (:type cause))
(= :wrong-credentials (:code cause)))
(reset! error (tr "errors.wrong-credentials"))
:else
(reset! error (tr "errors.generic"))))
on-success-default
(fn [data]
(when-let [token (:invitation-token data)]
(st/emit! (rt/nav :auth-verify-token {} {:token token}))))
on-success
(fn [data]
(if (nil? on-success-callback)

View file

@ -14,7 +14,7 @@
[app.util.i18n :as i18n :refer [tr]]
[app.util.router :as rt]
[cljs.spec.alpha :as s]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(s/def ::password-1 ::us/not-empty-string)
(s/def ::password-2 ::us/not-empty-string)

View file

@ -16,7 +16,7 @@
[app.util.router :as rt]
[beicon.core :as rx]
[cljs.spec.alpha :as s]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(s/def ::email ::us/email)
(s/def ::recovery-request-form (s/keys :req-un [::email]))

View file

@ -20,7 +20,7 @@
[app.util.router :as rt]
[beicon.core :as rx]
[cljs.spec.alpha :as s]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc demo-warning
[_]
@ -48,20 +48,23 @@
:opt-un [::invitation-token]))
(defn- handle-prepare-register-error
[form error]
(case (:code error)
:registration-disabled
[form {:keys [type code] :as cause}]
(condp = [type code]
[:restriction :registration-disabled]
(st/emit! (dm/error (tr "errors.registration-disabled")))
:email-has-permanent-bounces
[:restriction :profile-blocked]
(st/emit! (dm/error (tr "errors.profile-blocked")))
[:validation :email-has-permanent-bounces]
(let [email (get @form [:data :email])]
(st/emit! (dm/error (tr "errors.email-has-permanent-bounces" email))))
:email-already-exists
[:validation :email-already-exists]
(swap! form assoc-in [:errors :email]
{:message "errors.email-already-exists"})
:email-as-password
[:validation :email-as-password]
(swap! form assoc-in [:errors :password]
{:message "errors.email-as-password"})

View file

@ -17,7 +17,7 @@
[app.util.router :as rt]
[app.util.timers :as ts]
[beicon.core :as rx]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defmulti handle-token (fn [token] (:iss token)))
@ -62,33 +62,34 @@
[{:keys [route] :as props}]
(let [token (get-in route [:query-params :token])
bad-token (mf/use-state false)]
(mf/use-effect
(fn []
(dom/set-html-title (tr "title.default"))
(->> (rp/mutation :verify-token {:token token})
(rx/subs
(fn [tdata]
(handle-token tdata))
(fn [{:keys [type code] :as error}]
(cond
(or (= :validation type)
(= :invalid-token code)
(= :token-expired (:reason error)))
(reset! bad-token true)
(= :email-already-exists code)
(let [msg (tr "errors.email-already-exists")]
(ts/schedule 100 #(st/emit! (dm/error msg)))
(st/emit! (rt/nav :auth-login)))
(= :email-already-validated code)
(let [msg (tr "errors.email-already-validated")]
(ts/schedule 100 #(st/emit! (dm/warn msg)))
(st/emit! (rt/nav :auth-login)))
(mf/with-effect []
(dom/set-html-title (tr "title.default"))
(->> (rp/command! :verify-token {:token token})
(rx/subs
(fn [tdata]
(handle-token tdata))
(fn [{:keys [type code] :as error}]
(cond
(or (= :validation type)
(= :invalid-token code)
(= :token-expired (:reason error)))
(reset! bad-token true)
:else
(let [msg (tr "errors.generic")]
(ts/schedule 100 #(st/emit! (dm/error msg)))
(st/emit! (rt/nav :auth-login)))))))))
(= :email-already-exists code)
(let [msg (tr "errors.email-already-exists")]
(ts/schedule 100 #(st/emit! (dm/error msg)))
(st/emit! (rt/nav :auth-login)))
(= :email-already-validated code)
(let [msg (tr "errors.email-already-validated")]
(ts/schedule 100 #(st/emit! (dm/warn msg)))
(st/emit! (rt/nav :auth-login)))
:else
(let [msg (tr "errors.generic")]
(ts/schedule 100 #(st/emit! (dm/error msg)))
(st/emit! (rt/nav :auth-login))))))))
(if @bad-token
[:> static/static-header {}

View file

@ -22,7 +22,7 @@
[app.util.time :as dt]
[cuerdas.core :as str]
[okulary.core :as l]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc resizing-textarea
{::mf/wrap-props false}

View file

@ -7,7 +7,7 @@
(ns app.main.ui.components.code-block
(:require
["highlight.js" :as hljs]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc code-block [{:keys [code type]}]
(let [block-ref (mf/use-ref)]

View file

@ -9,7 +9,7 @@
[app.util.color :as uc]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defn gradient-type->string [type]
(case type

View file

@ -13,7 +13,7 @@
[app.util.keyboard :as kbd]
[app.util.object :as obj]
[goog.events :as events]
[rumext.alpha :as mf])
[rumext.v2 :as mf])
(:import goog.events.EventType))
(defn clean-color

View file

@ -15,7 +15,7 @@
[app.util.i18n :as i18n :refer [tr]]
[app.util.object :as obj]
[goog.object :as gobj]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc context-menu
{::mf/wrap-props false}

View file

@ -10,7 +10,7 @@
[app.util.timers :as timers]
[app.util.webapi :as wapi]
[beicon.core :as rx]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc copy-button [{:keys [data on-copied]}]
(let [just-copied (mf/use-state false)]

View file

@ -12,7 +12,7 @@
[app.util.keyboard :as kbd]
[goog.events :as events]
[goog.object :as gobj]
[rumext.alpha :as mf])
[rumext.v2 :as mf])
(:import goog.events.EventType))
(mf/defc dropdown'

View file

@ -10,7 +10,7 @@
[app.util.dom :as dom]
[app.util.keyboard :as kbd]
[app.util.timers :as timers]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc editable-label
[{:keys [value on-change on-cancel editing? disable-dbl-click? class-name] :as props}]

View file

@ -15,7 +15,7 @@
[app.util.dom :as dom]
[app.util.keyboard :as kbd]
[app.util.timers :as timers]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc editable-select
[{:keys [value type options class on-change placeholder on-blur] :as params}]

View file

@ -8,7 +8,7 @@
(:require
[app.main.store :as st]
[app.util.dom :as dom]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc file-uploader
{::mf/forward-ref true}

View file

@ -17,7 +17,7 @@
[cljs.core :as c]
[clojure.string]
[cuerdas.core :as str]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(def form-ctx (mf/create-context nil))
(def use-form fm/use-form)

View file

@ -16,7 +16,7 @@
[app.util.simple-math :as sm]
[cuerdas.core :as str]
[goog.events :as events]
[rumext.alpha :as mf])
[rumext.v2 :as mf])
(:import goog.events.EventType))
(mf/defc numeric-input

View file

@ -10,7 +10,7 @@
[app.common.uuid :as uuid]
[app.main.ui.components.dropdown :refer [dropdown]]
[app.main.ui.icons :as i]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc select [{:keys [default-value options class on-change]}]
(let [state (mf/use-state {:id (uuid/next)

View file

@ -7,7 +7,7 @@
(ns app.main.ui.components.shape-icon
(:require
[app.main.ui.icons :as i]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc element-icon

View file

@ -8,7 +8,7 @@
(:require
[app.common.data :as d]
[cuerdas.core :as str]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc tab-element
{::mf/wrap-props false}

View file

@ -13,7 +13,7 @@
[app.util.i18n :as i18n :refer [tr t]]
[app.util.keyboard :as k]
[goog.events :as events]
[rumext.alpha :as mf])
[rumext.v2 :as mf])
(:import goog.events.EventType))
(mf/defc confirm-dialog

View file

@ -6,7 +6,7 @@
(ns app.main.ui.context
(:require
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(def render-id (mf/create-context nil))

View file

@ -9,7 +9,7 @@
(:require
[app.util.timers :as ts]
[cuerdas.core :as str]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
;; Static cursors
(def comments (cursor-ref :comments 0 2 20))

View file

@ -37,7 +37,7 @@
[goog.events :as events]
[okulary.core :as l]
[potok.core :as ptk]
[rumext.alpha :as mf])
[rumext.v2 :as mf])
(:import goog.events.EventType))
(defn ^boolean uuid-str?

View file

@ -14,7 +14,7 @@
[app.main.ui.icons :as i]
[app.util.i18n :as i18n :refer [tr]]
[cljs.spec.alpha :as s]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(s/def ::member-id ::us/uuid)
(s/def ::leave-modal-form

View file

@ -17,7 +17,7 @@
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
[potok.core :as ptk]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc comments-section
[{:keys [profile team]}]

View file

@ -15,7 +15,7 @@
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
[beicon.core :as rx]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(def ^:const options [:all :merge :detach])

View file

@ -19,7 +19,7 @@
[app.util.router :as rt]
[beicon.core :as rx]
[potok.core :as ptk]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defn get-project-name
[project]

View file

@ -20,7 +20,7 @@
[app.util.webapi :as wapi]
[beicon.core :as rx]
[cuerdas.core :as str]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc header
[{:keys [project on-create-clicked] :as props}]

View file

@ -20,7 +20,7 @@
[app.util.keyboard :as kbd]
[beicon.core :as rx]
[cuerdas.core :as str]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defn- use-set-page-title
[team section]

View file

@ -6,9 +6,10 @@
(ns app.main.ui.dashboard.grid
(:require
[app.common.data.macros :as dm]
[app.common.logging :as log]
[app.main.data.dashboard :as dd]
[app.main.data.messages :as dm]
[app.main.data.messages :as msg]
[app.main.features :as features]
[app.main.fonts :as fonts]
[app.main.refs :as refs]
@ -19,43 +20,57 @@
[app.main.ui.dashboard.import :refer [use-import-file]]
[app.main.ui.dashboard.inline-edition :refer [inline-edition]]
[app.main.ui.dashboard.placeholder :refer [empty-placeholder loading-placeholder]]
[app.main.ui.hooks :as h]
[app.main.ui.icons :as i]
[app.main.worker :as wrk]
[app.util.dom :as dom]
[app.util.dom.dnd :as dnd]
[app.util.i18n :as i18n :refer [tr]]
[app.util.keyboard :as kbd]
[app.util.perf :as perf]
[app.util.time :as dt]
[app.util.timers :as ts]
[beicon.core :as rx]
[rumext.alpha :as mf]))
[cuerdas.core :as str]
[rumext.v2 :as mf]))
(log/set-level! :warn)
(log/set-level! :info)
;; --- Grid Item Thumbnail
(defn ask-for-thumbnail
"Creates some hooks to handle the files thumbnails cache"
[file]
(let [components-v2 (features/active-feature? :components-v2)]
(wrk/ask! {:cmd :thumbnails/generate
:revn (:revn file)
:file-id (:id file)
:components-v2 components-v2})))
(wrk/ask! {:cmd :thumbnails/generate
:revn (:revn file)
:file-id (:id file)
:file-name (:name file)
:components-v2 (features/active-feature? :components-v2)}))
(mf/defc grid-item-thumbnail
{::mf/wrap [mf/memo]}
[{:keys [file] :as props}]
(let [container (mf/use-ref)]
(mf/with-effect [file]
(->> (ask-for-thumbnail file)
(rx/subs (fn [{:keys [data fonts] :as params}]
(run! fonts/ensure-loaded! fonts)
(when-let [node (mf/ref-val container)]
(dom/set-html! node data))))))
(let [container (mf/use-ref)
bgcolor (dm/get-in file [:data :options :background])
visible? (h/use-visible container :once? true)]
[:div.grid-item-th {:style {:background-color (get-in file [:data :options :background])}
:ref container}
(mf/with-effect [file visible?]
(when visible?
(let [tp (perf/tpoint)]
(->> (ask-for-thumbnail file)
(rx/subscribe-on :af)
(rx/subs (fn [{:keys [data fonts] :as params}]
(run! fonts/ensure-loaded! fonts)
(log/info :hint "loaded thumbnail"
:file-id (dm/str (:id file))
:file-name (:name file)
:elapsed (str/ffmt "%ms" (tp)))
(when-let [node (mf/ref-val container)]
(dom/set-html! node data))))))))
[:div.grid-item-th
{:style {:background-color bgcolor}
:ref container}
i/loader-pencil]))
;; --- Grid Item Library
@ -144,6 +159,7 @@
(mf/defc grid-item-metadata
[{:keys [modified-at]}]
(let [locale (mf/deref i18n/locale)
time (dt/timeago modified-at {:locale locale})]
[:span.date
@ -159,18 +175,19 @@
(mf/defc grid-item
{:wrap [mf/memo]}
[{:keys [file navigate? origin library-view?] :as props}]
(let [file-id (:id file)
local (mf/use-state {:menu-open false
:menu-pos nil
:edition false})
selected-files (mf/deref refs/dashboard-selected-files)
dashboard-local (mf/deref refs/dashboard-local)
item-ref (mf/use-ref)
menu-ref (mf/use-ref)
selected? (contains? selected-files file-id)
(let [file-id (:id file)
local (mf/use-state {:menu-open false
:menu-pos nil
:edition false})
selected-files (mf/deref refs/dashboard-selected-files)
dashboard-local (mf/deref refs/dashboard-local)
node-ref (mf/use-ref)
menu-ref (mf/use-ref)
selected? (contains? selected-files file-id)
on-menu-close
(mf/use-callback
(mf/use-fn
#(swap! local assoc :menu-open false))
on-select
@ -184,7 +201,7 @@
(st/emit! (dd/toggle-file-select file)))))
on-navigate
(mf/use-callback
(mf/use-fn
(mf/deps file)
(fn [event]
(let [menu-icon (mf/ref-val menu-ref)
@ -193,14 +210,14 @@
(st/emit! (dd/go-to-workspace file))))))
on-drag-start
(mf/use-callback
(mf/use-fn
(mf/deps selected-files)
(fn [event]
(let [offset (dom/get-offset-position (.-nativeEvent event))
select-current? (not (contains? selected-files (:id file)))
item-el (mf/ref-val item-ref)
item-el (mf/ref-val node-ref)
counter-el (create-counter-element item-el
(if select-current?
1
@ -221,7 +238,7 @@
(ts/raf #(.removeChild ^js item-el counter-el)))))
on-menu-click
(mf/use-callback
(mf/use-fn
(mf/deps file selected?)
(fn [event]
(dom/prevent-default event)
@ -236,14 +253,14 @@
:menu-pos position))))
edit
(mf/use-callback
(mf/use-fn
(mf/deps file)
(fn [name]
(st/emit! (dd/rename-file (assoc file :name name)))
(swap! local assoc :edition false)))
on-edit
(mf/use-callback
(mf/use-fn
(mf/deps file)
(fn [event]
(dom/stop-propagation event)
@ -251,16 +268,14 @@
:edition true
:menu-open false)))]
(mf/use-effect
(mf/deps selected? local)
(fn []
(when (and (not selected?) (:menu-open @local))
(swap! local assoc :menu-open false))))
(mf/with-effect [selected? local]
(when (and (not selected?) (:menu-open @local))
(swap! local assoc :menu-open false)))
[:div.grid-item.project-th
{:class (dom/classnames :selected selected?
:library library-view?)
:ref item-ref
:ref node-ref
:draggable true
:on-click on-select
:on-double-click on-navigate
@ -296,13 +311,15 @@
:origin origin
:dashboard-local dashboard-local}])]]]))
(mf/defc grid
[{:keys [files project on-create-clicked origin limit library-view?] :as props}]
(let [dragging? (mf/use-state false)
project-id (:id project)
node-ref (mf/use-var nil)
on-finish-import
(mf/use-callback
(mf/use-fn
(fn []
(st/emit! (dd/fetch-files {:project-id project-id})
(dd/fetch-shared-files)
@ -311,7 +328,7 @@
import-files (use-import-file project-id on-finish-import)
on-drag-enter
(mf/use-callback
(mf/use-fn
(fn [e]
(when (or (dnd/has-type? e "Files")
(dnd/has-type? e "application/x-moz-file"))
@ -319,32 +336,34 @@
(reset! dragging? true))))
on-drag-over
(mf/use-callback
(mf/use-fn
(fn [e]
(when (or (dnd/has-type? e "Files")
(dnd/has-type? e "application/x-moz-file"))
(dom/prevent-default e))))
on-drag-leave
(mf/use-callback
(mf/use-fn
(fn [e]
(when-not (dnd/from-child? e)
(reset! dragging? false))))
on-drop
(mf/use-callback
(mf/use-fn
(fn [e]
(when (or (dnd/has-type? e "Files")
(dnd/has-type? e "application/x-moz-file"))
(dom/prevent-default e)
(reset! dragging? false)
(import-files (.-files (.-dataTransfer e))))))]
(import-files (.-files (.-dataTransfer e))))))
]
[:section.dashboard-grid {:on-drag-enter on-drag-enter
:on-drag-over on-drag-over
:on-drag-leave on-drag-leave
:on-drop on-drop}
[:section.dashboard-grid
{:on-drag-enter on-drag-enter
:on-drag-over on-drag-over
:on-drag-leave on-drag-leave
:on-drop on-drop
:ref node-ref}
(cond
(nil? files)
[:& loading-placeholder]
@ -352,8 +371,10 @@
(seq files)
[:div.grid-row
{:style {:grid-template-columns (str "repeat(" limit ", 1fr)")}}
(when @dragging?
[:div.grid-item])
(for [item files]
[:& grid-item
{:file item
@ -361,21 +382,21 @@
:navigate? true
:origin origin
:library-view? library-view?}])]
:else
[:& empty-placeholder {:default? (:is-default project)
:on-create-clicked on-create-clicked
:project project
:limit limit
:origin origin}])]))
[:& empty-placeholder
{:default? (:is-default project)
:on-create-clicked on-create-clicked
:project project
:limit limit
:origin origin}])]))
(mf/defc line-grid-row
[{:keys [files selected-files dragging? limit] :as props}]
(let [limit (if dragging?
(dec limit)
limit)]
(let [limit (if dragging? (dec limit) limit)]
[:div.grid-row.no-wrap
{:style {:grid-template-columns (str "repeat(" limit ", 1fr)")}}
{:style {:grid-template-columns (dm/str "repeat(" limit ", 1fr)")}}
(when dragging?
[:div.grid-item])
(for [item (take limit files)]
@ -396,8 +417,8 @@
selected-project (mf/deref refs/dashboard-selected-project)
on-finish-import
(mf/use-callback
(mf/deps (:id team))
(mf/use-fn
(mf/deps team-id)
(fn []
(st/emit! (dd/fetch-recent-files (:id team))
(dd/clear-selected-files))))
@ -405,7 +426,7 @@
import-files (use-import-file project-id on-finish-import)
on-drag-enter
(mf/use-callback
(mf/use-fn
(mf/deps selected-project)
(fn [e]
(when (dnd/has-type? e "penpot/files")
@ -421,7 +442,7 @@
(reset! dragging? true))))
on-drag-over
(mf/use-callback
(mf/use-fn
(fn [e]
(when (or (dnd/has-type? e "penpot/files")
(dnd/has-type? e "Files")
@ -429,19 +450,19 @@
(dom/prevent-default e))))
on-drag-leave
(mf/use-callback
(mf/use-fn
(fn [e]
(when-not (dnd/from-child? e)
(reset! dragging? false))))
on-drop-success
(fn []
(st/emit! (dm/success (tr "dashboard.success-move-file"))
(st/emit! (msg/success (tr "dashboard.success-move-file"))
(dd/fetch-recent-files (:id team))
(dd/clear-selected-files)))
on-drop
(mf/use-callback
(mf/use-fn
(mf/deps files selected-files)
(fn [e]
(when (or (dnd/has-type? e "Files")

View file

@ -24,7 +24,7 @@
[app.util.webapi :as wapi]
[beicon.core :as rx]
[potok.core :as ptk]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(log/set-level! :debug)

View file

@ -9,7 +9,7 @@
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.keyboard :as kbd]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc inline-edition
[{:keys [content on-end] :as props}]

View file

@ -16,7 +16,7 @@
[app.util.i18n :as i18n :refer [tr]]
[app.util.webapi :as wapi]
[beicon.core :as rx]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc libraries-page
[{:keys [team] :as props}]

View file

@ -8,7 +8,7 @@
(:require
[app.main.ui.icons :as i]
[app.util.i18n :as i18n :refer [tr]]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc empty-placeholder
[{:keys [dragging? on-create-clicked project limit origin] :as props}]

View file

@ -19,7 +19,7 @@
[app.util.i18n :as i18n :refer [tr]]
[app.util.router :as rt]
[cljs.spec.alpha :as s]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(s/def ::project some?)
(s/def ::show? boolean?)

View file

@ -6,10 +6,11 @@
(ns app.main.ui.dashboard.projects
(:require
[app.common.data :as d]
[app.common.math :as mth]
[app.main.data.dashboard :as dd]
[app.main.data.events :as ev]
[app.main.data.messages :as dm]
[app.main.data.messages :as msg]
[app.main.data.modal :as modal]
[app.main.data.users :as du]
[app.main.refs :as refs]
@ -27,7 +28,7 @@
[cuerdas.core :as str]
[okulary.core :as l]
[potok.core :as ptk]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc header
{::mf/wrap [mf/memo]}
@ -43,8 +44,15 @@
(mf/defc team-hero
{::mf/wrap [mf/memo]}
[{:keys [team close-banner] :as props}]
(let [go-members #(st/emit! (dd/go-to-team-members))
invite-member #(st/emit! (modal/show {:type :invite-members :team team :origin :hero}))]
(let [go-members (mf/use-fn #(st/emit! (dd/go-to-team-members)))
invite-member
(mf/use-fn
(mf/deps team)
(fn []
(st/emit! (modal/show {:type :invite-members
:team team
:origin :hero}))))]
[:div.team-hero
[:img {:src "images/deco-team-banner.png" :border "0"}]
[:div.text
@ -52,7 +60,9 @@
[:div.info
[:span (tr "dasboard.team-hero.text")]
[:a {:on-click go-members} (tr "dasboard.team-hero.management")]]]
[:button.btn-primary.invite {:on-click invite-member} (tr "onboarding.choice.team-up.invite-members")]
[:button.btn-primary.invite
{:on-click invite-member}
(tr "onboarding.choice.team-up.invite-members")]
[:button.close {:on-click close-banner}
[:span i/close]]]))
@ -61,46 +71,47 @@
(mf/defc tutorial-project
[{:keys [close-tutorial default-project-id] :as props}]
(let [state (mf/use-state
{:status :waiting
:file nil})
(let [state (mf/use-state {:status :waiting
:file nil})
template (->> (mf/deref builtin-templates)
(filter #(= (:id %) "tutorial-for-beginners"))
first)
templates (mf/deref builtin-templates)
template (d/seek #(= (:id %) "tutorial-for-beginners") templates)
on-template-cloned-success
(mf/use-callback
(mf/use-fn
(mf/deps default-project-id)
(fn [response]
(swap! state #(assoc % :status :success :file (:first response)))
(st/emit! (dd/go-to-workspace {:id (first response) :project-id default-project-id :name "tutorial"})
(du/update-profile-props {:viewed-tutorial? true}))))
on-template-cloned-error
(fn []
(swap! state #(assoc % :status :waiting))
(st/emit!
(dm/error (tr "dashboard.libraries-and-templates.import-error"))))
(mf/use-fn
(fn []
(swap! state #(assoc % :status :waiting))
(st/emit!
(msg/error (tr "dashboard.libraries-and-templates.import-error")))))
download-tutorial
(fn []
(let [mdata {:on-success on-template-cloned-success :on-error on-template-cloned-error}
params {:project-id default-project-id :template-id (:id template)}]
(swap! state #(assoc % :status :importing))
(st/emit! (with-meta (dd/clone-template (with-meta params mdata))
{::ev/origin "get-started-hero-block"}))))]
(mf/use-fn
(mf/deps template default-project-id)
(fn []
(let [mdata {:on-success on-template-cloned-success :on-error on-template-cloned-error}
params {:project-id default-project-id :template-id (:id template)}]
(swap! state #(assoc % :status :importing))
(st/emit! (with-meta (dd/clone-template (with-meta params mdata))
{::ev/origin "get-started-hero-block"})))))]
[:div.tutorial
[:div.img]
[:div.text
[:div.title (tr "dasboard.tutorial-hero.title")]
[:div.info (tr "dasboard.tutorial-hero.info")]
[:button.btn-primary.action {:on-click download-tutorial}
[:button.btn-primary.action {:on-click download-tutorial}
(case (:status @state)
:waiting (tr "dasboard.tutorial-hero.start")
:importing [:span.loader i/loader-pencil]
:success ""
)
]]
:success "")]]
[:button.close
{:on-click close-tutorial}
[:span.icon i/close]]]))
@ -128,32 +139,32 @@
[{:keys [project first? team files] :as props}]
(let [locale (mf/deref i18n/locale)
file-count (or (:count project) 0)
project-id (:id project)
dstate (mf/deref refs/dashboard-local)
edit-id (:project-for-edit dstate)
local
(mf/use-state {:menu-open false
:menu-pos nil
:edition? (= (:id project) edit-id)})
local (mf/use-state {:menu-open false
:menu-pos nil
:edition? (= (:id project) edit-id)})
width (mf/use-state nil)
rowref (mf/use-ref)
itemsize (if (>= @width 1030)
280
230)
ratio (if (some? @width) (/ @width itemsize) 0)
nitems (mth/floor ratio)
limit (min 10 nitems)
limit (max 1 limit)
on-nav
(mf/use-callback
(mf/use-fn
(mf/deps project)
#(st/emit! (rt/nav :dashboard-files {:team-id (:team-id project)
:project-id (:id project)})))
width (mf/use-state nil)
rowref (mf/use-ref)
itemsize (if (>= @width 1030)
280
230)
ratio (if (some? @width) (/ @width itemsize) 0)
nitems (mth/floor ratio)
limit (min 10 nitems)
limit (max 1 limit)
(fn []
(st/emit! (rt/nav :dashboard-files {:team-id (:team-id project)
:project-id project-id}))))
toggle-pin
(mf/use-callback
(mf/deps project)
@ -209,22 +220,24 @@
(dd/fetch-recent-files (:id team))
(dd/clear-selected-files))))]
(mf/use-effect
(fn []
(let [node (mf/ref-val rowref)
mnt? (volatile! true)
sub (->> (wapi/observe-resize node)
(rx/observe-on :af)
(rx/subs (fn [entries]
(let [row (first entries)
row-rect (.-contentRect ^js row)
row-width (.-width ^js row-rect)]
(when @mnt?
(reset! width row-width))))))]
(fn []
(vreset! mnt? false)
(rx/dispose! sub)))))
[:div.dashboard-project-row {:class (when first? "first")}
(mf/with-effect
(let [node (mf/ref-val rowref)
mnt? (volatile! true)
sub (->> (wapi/observe-resize node)
(rx/observe-on :af)
(rx/subs (fn [entries]
(let [row (first entries)
row-rect (.-contentRect ^js row)
row-width (.-width ^js row-rect)]
(when @mnt?
(reset! width row-width))))))]
(fn []
(vreset! mnt? false)
(rx/dispose! sub))))
[:div.dashboard-project-row
{:class (when first? "first")}
[:div.project {:ref rowref}
[:div.project-name-wrapper
(if (:edition? @local)
@ -265,6 +278,7 @@
[:a.btn-secondary.btn-small.tooltip.tooltip-bottom
{:on-click on-menu-click :alt (tr "dashboard.options") :data-test "project-options"}
i/actions]]]
(when (and (> limit 0)
(> file-count limit))
[:div.show-more {:on-click on-nav}
@ -290,53 +304,53 @@
(reverse))
recent-map (mf/deref recent-files-ref)
props (some-> profile (get :props {}))
team-hero? (:team-hero? props true)
team-hero? (and (:team-hero? props true)
(not (:is-default team)))
tutorial-viewed? (:viewed-tutorial? props true)
walkthrough-viewed? (:viewed-walkthrough? props true)
close-banner (fn []
(st/emit!
(du/update-profile-props {:team-hero? false})
(ptk/event ::ev/event {::ev/name "dont-show-team-up-hero"
::ev/origin "dashboard"})))
team-id (:id team)
close-tutorial (fn []
(st/emit!
(du/update-profile-props {:viewed-tutorial? true})
(ptk/event ::ev/event {::ev/name "dont-show"
::ev/origin "get-started-hero-block"
:type "tutorial"
:section "dashboard"})))
close-banner
(mf/use-fn
(fn []
(st/emit! (du/update-profile-props {:team-hero? false})
(ptk/event ::ev/event {::ev/name "dont-show-team-up-hero"
::ev/origin "dashboard"}))))
close-tutorial
(mf/use-fn
(fn []
(st/emit! (du/update-profile-props {:viewed-tutorial? true})
(ptk/event ::ev/event {::ev/name "dont-show"
::ev/origin "get-started-hero-block"
:type "tutorial"
:section "dashboard"}))))
close-walkthrough
(mf/use-fn
(fn []
(st/emit! (du/update-profile-props {:viewed-walkthrough? true})
(ptk/event ::ev/event {::ev/name "dont-show"
::ev/origin "get-started-hero-block"
:type "walkthrough"
:section "dashboard"}))))]
close-walkthrough (fn []
(st/emit!
(du/update-profile-props {:viewed-walkthrough? true})
(ptk/event ::ev/event {::ev/name "dont-show"
::ev/origin "get-started-hero-block"
:type "walkthrough"
:section "dashboard"})))]
(mf/with-effect [team]
(let [tname (if (:is-default team)
(tr "dashboard.your-penpot")
(:name team))]
(dom/set-html-title (tr "title.dashboard.projects" tname))))
(mf/use-effect
(mf/deps team)
(fn []
(let [tname (if (:is-default team)
(tr "dashboard.your-penpot")
(:name team))]
(dom/set-html-title (tr "title.dashboard.projects" tname)))))
(mf/use-effect
(mf/deps (:id team))
(fn []
(st/emit! (dd/fetch-recent-files (:id team))
(dd/clear-selected-files))))
(mf/with-effect [team-id]
(st/emit! (dd/fetch-recent-files team-id)
(dd/clear-selected-files)))
(when (seq projects)
[:*
[:& header]
(when (and team-hero? (not (:is-default team)))
[:& team-hero
{:team team
:close-banner close-banner}])
(when team-hero?
[:& team-hero {:team team :close-banner close-banner}])
(when (or (not tutorial-viewed?) (not walkthrough-viewed?))
[:div.hero-projects
(when (and (not tutorial-viewed?) (:is-default team))
@ -358,5 +372,5 @@
:team team
:files files
:first? (= project (first projects))
:key (:id project)}]))]])))
:key id}]))]])))

View file

@ -16,7 +16,7 @@
[app.util.i18n :as i18n :refer [tr]]
[app.util.webapi :as wapi]
[beicon.core :as rx]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc search-page
[{:keys [team search-term] :as props}]

View file

@ -33,7 +33,7 @@
[cljs.spec.alpha :as s]
[goog.functions :as f]
[potok.core :as ptk]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc sidebar-project
[{:keys [item selected?] :as props}]

View file

@ -27,7 +27,7 @@
[app.util.i18n :as i18n :refer [tr]]
[beicon.core :as rx]
[cljs.spec.alpha :as s]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc header
{::mf/wrap [mf/memo]}

View file

@ -17,7 +17,7 @@
[app.util.router :as rt]
[beicon.core :as rx]
[cljs.spec.alpha :as s]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(s/def ::name ::us/not-empty-string)
(s/def ::team-form

View file

@ -15,7 +15,7 @@
[app.util.i18n :as i18n :refer [tr]]
[app.util.keyboard :as k]
[goog.events :as events]
[rumext.alpha :as mf])
[rumext.v2 :as mf])
(:import goog.events.EventType))
(mf/defc delete-shared-dialog

View file

@ -20,7 +20,7 @@
[app.util.i18n :as i18n :refer [tr c]]
[app.util.strings :as ust]
[cuerdas.core :as str]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc export-multiple-dialog
[{:keys [exports title cmd no-selection]}]

View file

@ -20,7 +20,7 @@
[app.util.timers :as ts]
[beicon.core :as rx]
[goog.functions :as f]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defn use-id
"Get a stable id value across rerenders."
@ -29,7 +29,7 @@
(defn use-rxsub
[ob]
(let [[state reset-state!] (mf/useState @ob)]
(let [[state reset-state!] (mf/useState #(if (satisfies? IDeref ob) @ob nil))]
(mf/useEffect
(fn []
(let [sub (rx/subscribe ob #(reset-state! %))]
@ -313,3 +313,39 @@
(use-stream stream (partial reset! state))
state))
(defonce ^:private intersection-subject (rx/subject))
(defonce ^:private intersection-observer
(delay (js/IntersectionObserver.
(fn [entries _]
(run! (partial rx/push! intersection-subject) (seq entries)))
#js {:rootMargin "0px"
:threshold 1.0})))
(defn use-visible
[ref & {:keys [once?]}]
(let [[state update-state!] (mf/useState false)]
(mf/with-effect [once?]
(let [node (mf/ref-val ref)
stream (->> intersection-subject
(rx/filter (fn [entry]
(let [target (unchecked-get entry "target")]
(identical? target node))))
(rx/map (fn [entry]
(let [ratio (unchecked-get entry "intersectionRatio")
intersecting? (unchecked-get entry "isIntersecting")]
(or intersecting? (> ratio 0.5)))))
(rx/dedupe))
stream (if once?
(->> stream
(rx/filter identity)
(rx/take 1))
stream)
subs (rx/subscribe stream update-state!)]
(.observe ^js @intersection-observer node)
(fn []
(.unobserve ^js @intersection-observer node)
(rx/dispose! subs))))
state))

View file

@ -8,7 +8,7 @@
(:require
[app.common.data :as d]
[app.common.logging :as log]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(log/set-level! :warn)

View file

@ -13,7 +13,7 @@
[app.main.ui.hooks :as hooks]
[app.util.dom :as dom]
[app.util.storage :refer [storage]]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(log/set-level! :warn)

View file

@ -5,13 +5,13 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.icons
(:require [rumext.alpha]))
(:require [rumext.v2]))
(defmacro icon-xref
[id]
(let [href (str "#icon-" (name id))
class (str "icon-" (name id))]
`(rumext.alpha/html
`(rumext.v2/html
[:svg {:width 500 :height 500 :class ~class}
[:use {:href ~href}]])))

View file

@ -7,7 +7,7 @@
(ns app.main.ui.icons
(:refer-clojure :exclude [import mask])
(:require-macros [app.main.ui.icons :refer [icon-xref]])
(:require [rumext.alpha :as mf]))
(:require [rumext.v2 :as mf]))
;; Keep the list of icons sorted

View file

@ -8,7 +8,7 @@
(:require
[app.main.store :as st]
[app.main.ui.icons :as i]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
;; --- Component

View file

@ -13,7 +13,7 @@
[app.common.math :as mth]
[app.common.uuid :as uuid]
[app.main.ui.formats :as fmt]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
;; ------------------------------------------------
;; CONSTANTS

View file

@ -12,7 +12,7 @@
[app.main.store :as st]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc banner
[{:keys [type position status controls content actions on-close data-test] :as props}]

View file

@ -12,7 +12,7 @@
[app.util.keyboard :as k]
[goog.events :as events]
[okulary.core :as l]
[rumext.alpha :as mf])
[rumext.v2 :as mf])
(:import goog.events.EventType))
(defn- on-esc-clicked

View file

@ -18,7 +18,7 @@
[app.util.i18n :as i18n :refer [tr]]
[app.util.timers :as tm]
[potok.core :as ptk]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
;; --- ONBOARDING LIGHTBOX

View file

@ -11,7 +11,7 @@
[app.main.data.users :as du]
[app.main.store :as st]
[app.util.i18n :as i18n :refer [tr]]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc onboarding-newsletter-modal
{::mf/register modal/components

View file

@ -14,7 +14,7 @@
[goog.events :as gev]
[potok.core :as ptk]
[promesa.core :as p]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defn load-arengu-sdk
[container-ref email form-id]

View file

@ -21,7 +21,7 @@
[app.util.timers :as tm]
[cljs.spec.alpha :as s]
[potok.core :as ptk]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(s/def ::name ::us/not-empty-string)
(s/def ::team-form

View file

@ -16,7 +16,7 @@
[app.util.i18n :as i18n :refer [tr]]
[app.util.webapi :as wapi]
[beicon.core :as rx]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc template-item
[{:keys [name path image project-id]}]

View file

@ -24,7 +24,7 @@
[app.main.ui.releases.v1-9]
[app.util.object :as obj]
[app.util.timers :as tm]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
;;; --- RELEASE NOTES MODAL

View file

@ -7,7 +7,7 @@
(ns app.main.ui.releases.common
(:require
[app.util.dom :as dom]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defmulti render-release-notes :version)

View file

@ -7,7 +7,7 @@
(ns app.main.ui.releases.v1-10
(:require
[app.main.ui.releases.common :as c]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defmethod c/render-release-notes "1.10"
[{:keys [klass finish version]}]

View file

@ -7,7 +7,7 @@
(ns app.main.ui.releases.v1-11
(:require
[app.main.ui.releases.common :as c]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defmethod c/render-release-notes "1.11"
[{:keys [slide klass next finish navigate version]}]

View file

@ -7,7 +7,7 @@
(ns app.main.ui.releases.v1-12
(:require
[app.main.ui.releases.common :as c]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defmethod c/render-release-notes "1.12"
[{:keys [slide klass next finish navigate version]}]

View file

@ -7,7 +7,7 @@
(ns app.main.ui.releases.v1-13
(:require
[app.main.ui.releases.common :as c]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defmethod c/render-release-notes "1.13"
[{:keys [slide klass next finish navigate version]}]

View file

@ -7,7 +7,7 @@
(ns app.main.ui.releases.v1-14
(:require
[app.main.ui.releases.common :as c]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defmethod c/render-release-notes "1.14"
[{:keys [slide klass next finish navigate version]}]

View file

@ -7,7 +7,7 @@
(ns app.main.ui.releases.v1-15
(:require
[app.main.ui.releases.common :as c]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defmethod c/render-release-notes "1.15"
[{:keys [slide klass next finish navigate version]}]

View file

@ -7,7 +7,7 @@
(ns app.main.ui.releases.v1-4
(:require
[app.main.ui.releases.common :as c]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defmethod c/render-release-notes "1.4"
[{:keys [slide klass next finish navigate version]}]

View file

@ -7,7 +7,7 @@
(ns app.main.ui.releases.v1-5
(:require
[app.main.ui.releases.common :as c]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defmethod c/render-release-notes "1.5"
[{:keys [slide klass next finish navigate version]}]

View file

@ -7,7 +7,7 @@
(ns app.main.ui.releases.v1-6
(:require
[app.main.ui.releases.common :as c]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defmethod c/render-release-notes "1.6"
[{:keys [slide klass next finish navigate version]}]

View file

@ -7,7 +7,7 @@
(ns app.main.ui.releases.v1-7
(:require
[app.main.ui.releases.common :as c]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defmethod c/render-release-notes "1.7"
[{:keys [slide klass next finish navigate version]}]

View file

@ -7,7 +7,7 @@
(ns app.main.ui.releases.v1-8
(:require
[app.main.ui.releases.common :as c]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defmethod c/render-release-notes "1.8"
[{:keys [slide klass next finish navigate version]}]

View file

@ -7,7 +7,7 @@
(ns app.main.ui.releases.v1-9
(:require
[app.main.ui.releases.common :as c]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defmethod c/render-release-notes "1.9"
[{:keys [slide klass next finish navigate version]}]

View file

@ -17,7 +17,7 @@
[app.main.ui.settings.sidebar :refer [sidebar]]
[app.util.i18n :as i18n :refer [tr]]
[app.util.router :as rt]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc header
{::mf/wrap [mf/memo]}

View file

@ -18,7 +18,7 @@
[app.util.i18n :as i18n :refer [tr]]
[beicon.core :as rx]
[cljs.spec.alpha :as s]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(s/def ::email-1 ::us/email)
(s/def ::email-2 ::us/email)

View file

@ -14,7 +14,7 @@
[app.main.ui.messages :as msgs]
[app.util.i18n :as i18n :refer [tr]]
[beicon.core :as rx]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defn on-error
[{:keys [code] :as error}]

View file

@ -17,7 +17,7 @@
[app.util.i18n :as i18n :refer [tr]]
[beicon.core :as rx]
[cljs.spec.alpha :as s]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(s/def ::content ::us/not-empty-string)
(s/def ::subject ::us/not-empty-string)

View file

@ -15,7 +15,7 @@
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
[cljs.spec.alpha :as s]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(s/def ::lang (s/nilable ::us/string))
(s/def ::theme (s/nilable ::us/not-empty-string))

View file

@ -14,7 +14,7 @@
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [t tr]]
[cljs.spec.alpha :as s]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defn- on-error
[form error]

View file

@ -19,7 +19,7 @@
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
[cljs.spec.alpha :as s]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(s/def ::fullname ::us/not-empty-string)
(s/def ::email ::us/email)

View file

@ -17,7 +17,7 @@
[app.util.keyboard :as kbd]
[app.util.router :as rt]
[potok.core :as ptk]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc sidebar-content
[{:keys [profile section] :as props}]

View file

@ -16,7 +16,7 @@
[app.util.object :as obj]
[app.util.svg :as usvg]
[cuerdas.core :as str]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defn- stroke-type->dasharray
[width style]

View file

@ -13,7 +13,7 @@
[app.main.ui.shapes.export :as use]
[app.main.ui.shapes.path :refer [path-shape]]
[app.util.object :as obj]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defn bool-shape
[shape-wrapper]

View file

@ -10,7 +10,7 @@
[app.main.ui.shapes.attrs :as attrs]
[app.main.ui.shapes.custom-stroke :refer [shape-custom-strokes]]
[app.util.object :as obj]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc circle-shape
{::mf/wrap-props false}

View file

@ -16,7 +16,7 @@
[app.main.ui.shapes.gradients :as grad]
[app.util.object :as obj]
[cuerdas.core :as str]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defn add-props
[props new-props]

View file

@ -9,7 +9,7 @@
[app.main.ui.hooks :as hooks]
[app.util.http :as http]
[beicon.core :as rx]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(def context (mf/create-context false))

View file

@ -16,7 +16,7 @@
[app.util.object :as obj]
[app.util.svg :as usvg]
[cuerdas.core :as str]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(def include-metadata-ctx (mf/create-context false))

View file

@ -14,7 +14,7 @@
[app.main.ui.shapes.embed :as embed]
[app.main.ui.shapes.gradients :as grad]
[app.util.object :as obj]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc fills
{::mf/wrap-props false}

View file

@ -12,7 +12,7 @@
[app.common.uuid :as uuid]
[app.util.color :as color]
[cuerdas.core :as str]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defn get-filter-id []
(str "filter_" (uuid/next)))

View file

@ -13,7 +13,7 @@
[app.main.ui.shapes.custom-stroke :refer [shape-fills shape-strokes]]
[app.util.object :as obj]
[debug :refer [debug?]]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defn frame-clip-id
[shape render-id]

View file

@ -14,7 +14,7 @@
[app.main.ui.context :as muc]
[app.main.ui.shapes.export :as ed]
[app.util.object :as obj]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defn add-metadata [props gradient]
(-> props

View file

@ -10,7 +10,7 @@
[app.main.ui.context :as muc]
[app.main.ui.shapes.mask :refer [mask-url clip-url mask-factory]]
[app.util.object :as obj]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defn group-shape
[shape-wrapper]

View file

@ -10,7 +10,7 @@
[app.main.ui.shapes.attrs :as attrs]
[app.main.ui.shapes.custom-stroke :refer [shape-custom-strokes]]
[app.util.object :as obj]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(mf/defc image-shape
{::mf/wrap-props false}

View file

@ -10,7 +10,7 @@
[app.common.geom.shapes :as gsh]
[app.main.ui.context :as muc]
[cuerdas.core :as str]
[rumext.alpha :as mf]))
[rumext.v2 :as mf]))
(defn mask-id [render-id mask]
(str render-id "-" (:id mask) "-mask"))

Some files were not shown because too many files have changed in this diff Show more