mirror of
https://github.com/penpot/penpot.git
synced 2025-05-10 22:56:37 +02:00
Merge remote-tracking branch 'origin/staging' into develop
This commit is contained in:
commit
806dc78d2b
22 changed files with 672 additions and 330 deletions
|
@ -1,94 +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) UXBOX Labs SL
|
||||
|
||||
(ns app.main.data.dashboard.fonts
|
||||
(:require
|
||||
[app.common.exceptions :as ex]
|
||||
[app.common.data :as d]
|
||||
[app.common.media :as cm]
|
||||
[app.common.spec :as us]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.repo :as rp]
|
||||
[app.util.time :as dt]
|
||||
[app.util.timers :as ts]
|
||||
[app.main.data.messages :as dm]
|
||||
[app.util.webapi :as wa]
|
||||
[app.util.object :as obj]
|
||||
[app.util.transit :as t]
|
||||
[beicon.core :as rx]
|
||||
[cljs.spec.alpha :as s]
|
||||
[cuerdas.core :as str]
|
||||
[potok.core :as ptk]))
|
||||
|
||||
(defn fetch-fonts
|
||||
[{:keys [id] :as team}]
|
||||
(ptk/reify ::fetch-fonts
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(->> (rp/query! :team-font-variants {:team-id id})
|
||||
(rx/map (fn [items]
|
||||
#(assoc % :dashboard-fonts (d/index-by :id items))))))))
|
||||
|
||||
(defn add-font
|
||||
[font]
|
||||
(ptk/reify ::add-font
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(update state :dashboard-fonts assoc (:id font) font))))
|
||||
|
||||
|
||||
(defn update-font
|
||||
[{:keys [id font-family] :as font}]
|
||||
(ptk/reify ::update-font
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [font (assoc font :font-id (str "custom-" (str/slug font-family)))]
|
||||
(update state :dashboard-fonts assoc id font)))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [font (get-in state [:dashboard-fonts id])]
|
||||
(->> (rp/mutation! :update-font-variant font)
|
||||
(rx/ignore))))))
|
||||
|
||||
(defn delete-font
|
||||
[{:keys [id] :as font}]
|
||||
(ptk/reify ::delete-font
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(update state :dashboard-fonts dissoc id))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [params (select-keys font [:id :team-id])]
|
||||
(->> (rp/mutation! :delete-font-variant params)
|
||||
(rx/ignore))))))
|
||||
|
||||
;; (defn upload-font
|
||||
;; [{:keys [id] :as font}]
|
||||
;; (ptk/reify ::upload-font
|
||||
;; ptk/WatchEvent
|
||||
;; (watch [_ state stream]
|
||||
;; (let [{:keys [on-success on-error]
|
||||
;; :or {on-success identity
|
||||
;; on-error rx/throw}} (meta params)]
|
||||
;; (->> (rp/mutation! :create-font-variant font)
|
||||
;; (rx/tap on-success)
|
||||
;; (rx/catch on-error))))))
|
||||
|
||||
;; (defn add-font
|
||||
;; "Add fonts to the state in a pending to upload state."
|
||||
;; [font]
|
||||
;; (ptk/reify ::add-font
|
||||
;; ptk/UpdateEvent
|
||||
;; (update [_ state]
|
||||
;; (let [id (uuid/next)
|
||||
;; font (-> font
|
||||
;; (assoc :created-at (dt/now))
|
||||
;; (assoc :id id)
|
||||
;; (assoc :status :draft))]
|
||||
;; (js/console.log (clj->js font))
|
||||
;; (assoc-in state [:dashboard-fonts id] font)))))
|
|
@ -6,42 +6,68 @@
|
|||
|
||||
(ns app.main.data.fonts
|
||||
(:require
|
||||
["opentype.js" :as ot]
|
||||
[app.common.data :as d]
|
||||
[app.common.spec :as us]
|
||||
[app.common.media :as cm]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.fonts :as fonts]
|
||||
[app.main.repo :as rp]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[app.util.logging :as log]
|
||||
[beicon.core :as rx]
|
||||
[cljs.spec.alpha :as s]
|
||||
[app.util.webapi :as wa]
|
||||
[cuerdas.core :as str]
|
||||
[potok.core :as ptk]))
|
||||
|
||||
(defn prepare-font-variant
|
||||
[item]
|
||||
{:id (str (:font-style item) "-" (:font-weight item))
|
||||
:name (str (cm/font-weight->name (:font-weight item)) " "
|
||||
(str/capital (:font-style item)))
|
||||
:style (:font-style item)
|
||||
:weight (str (:font-weight item))
|
||||
::fonts/woff1-file-id (:woff1-file-id item)
|
||||
::fonts/woff2-file-id (:woff2-file-id item)
|
||||
::fonts/ttf-file-id (:ttf-file-id item)
|
||||
::fonts/otf-file-id (:otf-file-id item)})
|
||||
|
||||
(defn prepare-font
|
||||
[[id [item :as items]]]
|
||||
{:id id
|
||||
:name (:font-family item)
|
||||
:family (:font-family item)
|
||||
:variants (mapv prepare-font-variant items)})
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; General purpose events & IMPL
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn team-fonts-loaded
|
||||
[fonts]
|
||||
(ptk/reify ::team-fonts-loaded
|
||||
ptk/EffectEvent
|
||||
(effect [_ state stream]
|
||||
(let [fonts (->> (group-by :font-id fonts)
|
||||
(mapv prepare-font))]
|
||||
(fonts/register! :custom fonts)))))
|
||||
(letfn [;; Prepare font to the internal font database format.
|
||||
(prepare-font [[id [item :as items]]]
|
||||
{:id id
|
||||
:name (:font-family item)
|
||||
:family (:font-family item)
|
||||
:variants (->> items
|
||||
(map prepare-font-variant)
|
||||
(sort-by variant-sort-fn)
|
||||
(vec))})
|
||||
|
||||
(variant-sort-fn [item]
|
||||
[(:weight item)
|
||||
(if (= "normal" (:style item)) 1 2)])
|
||||
|
||||
(prepare-font-variant [item]
|
||||
{:id (str (:font-style item) "-" (:font-weight item))
|
||||
:name (str (cm/font-weight->name (:font-weight item))
|
||||
(when (not= "normal" (:font-style item))
|
||||
(str " " (str/capital (:font-style item)))))
|
||||
:style (:font-style item)
|
||||
:weight (str (:font-weight item))
|
||||
::fonts/woff1-file-id (:woff1-file-id item)
|
||||
::fonts/woff2-file-id (:woff2-file-id item)
|
||||
::fonts/ttf-file-id (:ttf-file-id item)
|
||||
::fonts/otf-file-id (:otf-file-id item)})
|
||||
|
||||
(adapt-font-id [variant]
|
||||
(update variant :font-id #(str "custom-" %)))]
|
||||
|
||||
(ptk/reify ::team-fonts-loaded
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(assoc state :dashboard-fonts (d/index-by :id fonts)))
|
||||
|
||||
ptk/EffectEvent
|
||||
(effect [_ state stream]
|
||||
(let [fonts (->> fonts
|
||||
(map adapt-font-id)
|
||||
(group-by :font-id)
|
||||
(mapv prepare-font))]
|
||||
(fonts/register! :custom fonts))))))
|
||||
|
||||
(defn load-team-fonts
|
||||
[team-id]
|
||||
|
@ -51,7 +77,168 @@
|
|||
(->> (rp/query :team-font-variants {:team-id team-id})
|
||||
(rx/map team-fonts-loaded)))))
|
||||
|
||||
(defn process-upload
|
||||
"Given a seq of blobs and the team id, creates a ready-to-use fonts
|
||||
map with temporal ID's associated to each font entry."
|
||||
[blobs team-id]
|
||||
(letfn [(prepare [{:keys [font type name data] :as params}]
|
||||
(let [family (or (.getEnglishName ^js font "preferredFamily")
|
||||
(.getEnglishName ^js font "fontFamily"))
|
||||
variant (or (.getEnglishName ^js font "preferredSubfamily")
|
||||
(.getEnglishName ^js font "fontSubfamily"))]
|
||||
{:content {:data (js/Uint8Array. data)
|
||||
:name name
|
||||
:type type}
|
||||
:font-family family
|
||||
:font-weight (cm/parse-font-weight variant)
|
||||
:font-style (cm/parse-font-style variant)}))
|
||||
|
||||
(defn get-fonts
|
||||
[backend]
|
||||
(get @fonts/fonts backend []))
|
||||
(join [res {:keys [content] :as font}]
|
||||
(let [key-fn (juxt :font-family :font-weight :font-style)
|
||||
existing (d/seek #(= (key-fn font) (key-fn %)) (vals res))]
|
||||
(if existing
|
||||
(update res
|
||||
(:id existing)
|
||||
(fn [existing]
|
||||
(-> existing
|
||||
(update :data assoc (:type content) (:data content))
|
||||
(update :names conj (:name content)))))
|
||||
(let [tmp-id (uuid/next)]
|
||||
(assoc res tmp-id
|
||||
(-> font
|
||||
(assoc :id tmp-id)
|
||||
(assoc :team-id team-id)
|
||||
(assoc :names #{(:name content)})
|
||||
(assoc :data {(:type content)
|
||||
(:data content)})
|
||||
(dissoc :content)))))))
|
||||
|
||||
(parse-mtype [mtype]
|
||||
(case mtype
|
||||
"application/vnd.oasis.opendocument.formula-template" "font/otf"
|
||||
mtype))
|
||||
|
||||
(parse-font [{:keys [data] :as params}]
|
||||
(try
|
||||
(assoc params :font (ot/parse data))
|
||||
(catch :default e
|
||||
(log/warn :msg (str/fmt "skiping file %s, unsupported format" (:name params)))
|
||||
nil)))
|
||||
|
||||
(read-blob [blob]
|
||||
(->> (wa/read-file-as-array-buffer blob)
|
||||
(rx/map (fn [data]
|
||||
{:data data
|
||||
:name (.-name blob)
|
||||
:type (parse-mtype (.-type blob))}))))]
|
||||
|
||||
(->> (rx/from blobs)
|
||||
(rx/mapcat read-blob)
|
||||
(rx/map parse-font)
|
||||
(rx/filter some?)
|
||||
(rx/map prepare)
|
||||
(rx/reduce join {}))))
|
||||
|
||||
(defn- calculate-family-to-id-mapping
|
||||
[existing]
|
||||
(reduce #(assoc %1 (:font-family %2) (:font-id %2)) {} (vals existing)))
|
||||
|
||||
(defn merge-and-group-fonts
|
||||
"Function responsible to merge (and apropriatelly group) incoming
|
||||
fonts (processed by `process-upload`) into existing fonts
|
||||
in local state, preserving correct font-id references."
|
||||
[current-fonts installed-fonts incoming-fonts]
|
||||
(loop [famdb (-> (merge current-fonts installed-fonts)
|
||||
(calculate-family-to-id-mapping))
|
||||
items (vals incoming-fonts)
|
||||
result current-fonts]
|
||||
(if-let [{:keys [id font-family] :as item} (first items)]
|
||||
(let [font-id (or (get famdb font-family)
|
||||
(uuid/next))
|
||||
font (assoc item :font-id font-id)]
|
||||
(recur (assoc famdb font-family font-id)
|
||||
(rest items)
|
||||
(assoc result id font)))
|
||||
result)))
|
||||
|
||||
(defn rename-and-regroup
|
||||
"Function responsible to rename a font in a local state and properly
|
||||
regroup it to the apropriate `font-id` having in account current
|
||||
fonts and installed fonts."
|
||||
[current-fonts id name installed-fonts]
|
||||
(let [famdb (-> (merge current-fonts installed-fonts)
|
||||
(calculate-family-to-id-mapping))
|
||||
font-id (or (get famdb name)
|
||||
(uuid/next))]
|
||||
(update current-fonts id (fn [font]
|
||||
(-> font
|
||||
(assoc :name name)
|
||||
(assoc :font-id font-id))))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Dashboard related events
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn add-font
|
||||
[font]
|
||||
(ptk/reify ::add-font
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(update state :dashboard-fonts assoc (:id font) font))))
|
||||
|
||||
(defn update-font
|
||||
[{:keys [id name] :as params}]
|
||||
(us/assert ::us/uuid id)
|
||||
(us/assert ::us/not-empty-string name)
|
||||
(ptk/reify ::update-font
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
;; Update all variants that has the same font-id with the new
|
||||
;; name in the local state.
|
||||
(update state :dashboard-fonts
|
||||
(fn [fonts]
|
||||
(d/mapm (fn [_ font]
|
||||
(cond-> font
|
||||
(= id (:font-id font))
|
||||
(assoc :font-family name)))
|
||||
fonts))))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [team-id (:current-team-id state)]
|
||||
(->> (rp/mutation! :update-font {:id id :name name :team-id team-id})
|
||||
(rx/ignore))))))
|
||||
|
||||
(defn delete-font
|
||||
"Delete all variants related to the provided `font-id`."
|
||||
[font-id]
|
||||
(us/assert ::us/uuid font-id)
|
||||
(ptk/reify ::delete-font
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(update state :dashboard-fonts
|
||||
(fn [variants]
|
||||
(d/removem (fn [[id variant]]
|
||||
(= (:font-id variant) font-id)) variants))))
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [team-id (:current-team-id state)]
|
||||
(->> (rp/mutation! :delete-font {:id font-id :team-id team-id})
|
||||
(rx/ignore))))))
|
||||
|
||||
(defn delete-font-variant
|
||||
[id]
|
||||
(us/assert ::us/uuid id)
|
||||
(ptk/reify ::delete-font-variants
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(update state :dashboard-fonts
|
||||
(fn [variants]
|
||||
(d/removem (fn [[_ variant]]
|
||||
(= (:id variant) id))
|
||||
variants))))
|
||||
ptk/WatchEvent
|
||||
(watch [_ state stream]
|
||||
(let [team-id (:current-team-id state)]
|
||||
(->> (rp/mutation! :delete-font-variant {:id id :team-id team-id})
|
||||
(rx/ignore))))))
|
||||
|
|
|
@ -56,10 +56,6 @@
|
|||
(vec)
|
||||
(reset! fonts))))
|
||||
|
||||
(defn- remove-fonts
|
||||
[db backend]
|
||||
(reduce-kv #(cond-> %1 (= backend (:backend %3)) (dissoc %2)) db db))
|
||||
|
||||
(defn register!
|
||||
[backend fonts]
|
||||
(swap! fontsdb
|
||||
|
@ -96,7 +92,6 @@
|
|||
(unchecked-set node "type" "text/css")
|
||||
node))
|
||||
|
||||
|
||||
(defn- create-style-element
|
||||
[css]
|
||||
(let [node (.createElement js/document "style")]
|
||||
|
@ -166,9 +161,9 @@
|
|||
url(%(otf-uri)s) format('otf');
|
||||
}")
|
||||
|
||||
(defn- font-id->uri
|
||||
[font-id]
|
||||
(str (u/join cf/public-uri "assets/by-id/" font-id)))
|
||||
(defn- asset-id->uri
|
||||
[asset-id]
|
||||
(str (u/join cf/public-uri "assets/by-id/" asset-id)))
|
||||
|
||||
(defn generate-custom-font-variant-css
|
||||
[family variant]
|
||||
|
@ -176,10 +171,10 @@
|
|||
{:family family
|
||||
:style (:style variant)
|
||||
:weight (:weight variant)
|
||||
:woff2-uri (font-id->uri (::woff2-file-id variant))
|
||||
:woff1-uri (font-id->uri (::woff1-file-id variant))
|
||||
:ttf-uri (font-id->uri (::ttf-file-id variant))
|
||||
:otf-uri (font-id->uri (::otf-file-id variant))}))
|
||||
:woff2-uri (asset-id->uri (::woff2-file-id variant))
|
||||
:woff1-uri (asset-id->uri (::woff1-file-id variant))
|
||||
:ttf-uri (asset-id->uri (::ttf-file-id variant))
|
||||
:otf-uri (asset-id->uri (::otf-file-id variant))}))
|
||||
|
||||
(defn- generate-custom-font-css
|
||||
[{:keys [family variants] :as font}]
|
||||
|
@ -190,7 +185,7 @@
|
|||
(defmethod load-font :custom
|
||||
[{:keys [id family variants ::on-loaded] :as font}]
|
||||
(when (exists? js/window)
|
||||
(js/console.log "[debug:fonts]: loading google font" id)
|
||||
(js/console.log "[debug:fonts]: loading custom font" id)
|
||||
(let [css (generate-custom-font-css font)]
|
||||
(add-font-css! css))))
|
||||
|
||||
|
|
|
@ -145,7 +145,7 @@
|
|||
:dashboard-team-settings)
|
||||
[:*
|
||||
#_[:div.modal-wrapper
|
||||
[:& app.main.ui.onboarding/release-notes-modal {:version "1.5"}]]
|
||||
[:& app.main.ui.onboarding/release-notes-modal {:version "1.6"}]]
|
||||
[:& dashboard {:route route}]]
|
||||
|
||||
:viewer
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
|
||||
(ns app.main.ui.dashboard.fonts
|
||||
(:require
|
||||
["opentype.js" :as ot]
|
||||
[app.common.data :as d]
|
||||
[app.common.media :as cm]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.dashboard :as dd]
|
||||
[app.main.data.dashboard.fonts :as df]
|
||||
[app.main.data.fonts :as df]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.ui.components.file-uploader :refer [file-uploader]]
|
||||
[app.main.ui.components.context-menu :refer [context-menu]]
|
||||
|
@ -64,56 +64,23 @@
|
|||
[:h1 (tr "labels.fonts")]]
|
||||
[:nav
|
||||
#_[:ul
|
||||
[:li {:class (when (= section :fonts) "active")}
|
||||
[:a {:on-click go-fonts} (tr "labels.custom-fonts")]]
|
||||
[:li {:class (when (= section :providers) "active")}
|
||||
[:a {:on-click go-providers} (tr "labels.font-providers")]]]]
|
||||
[:li {:class (when (= section :fonts) "active")}
|
||||
[:a {:on-click go-fonts} (tr "labels.custom-fonts")]]
|
||||
[:li {:class (when (= section :providers) "active")}
|
||||
[:a {:on-click go-providers} (tr "labels.font-providers")]]]]
|
||||
|
||||
[:div]]))
|
||||
|
||||
(defn- prepare-fonts
|
||||
[blobs]
|
||||
(letfn [(prepare [{:keys [font type name data] :as params}]
|
||||
(let [family (or (.getEnglishName ^js font "preferredFamily")
|
||||
(.getEnglishName ^js font "fontFamily"))
|
||||
variant (or (.getEnglishName ^js font "preferredSubfamily")
|
||||
(.getEnglishName ^js font "fontSubfamily"))]
|
||||
{:content {:data (js/Uint8Array. data)
|
||||
:name name
|
||||
:type type}
|
||||
:font-id (str "custom-" (str/slug family))
|
||||
:font-family family
|
||||
:font-weight (cm/parse-font-weight variant)
|
||||
:font-style (cm/parse-font-style variant)}))
|
||||
|
||||
(parse-mtype [mtype]
|
||||
(case mtype
|
||||
"application/vnd.oasis.opendocument.formula-template" "font/otf"
|
||||
mtype))
|
||||
|
||||
(parse-font [{:keys [data] :as params}]
|
||||
(try
|
||||
(assoc params :font (ot/parse data))
|
||||
(catch :default e
|
||||
(log/warn :msg (str/fmt "skiping file %s, unsupported format" (:name params)))
|
||||
nil)))
|
||||
|
||||
(read-blob [blob]
|
||||
(->> (wa/read-file-as-array-buffer blob)
|
||||
(rx/map (fn [data]
|
||||
{:data data
|
||||
:name (.-name blob)
|
||||
:type (parse-mtype (.-type blob))}))))]
|
||||
|
||||
(->> (rx/from blobs)
|
||||
(rx/mapcat read-blob)
|
||||
(rx/map parse-font)
|
||||
(rx/filter some?)
|
||||
(rx/map prepare))))
|
||||
(mf/defc font-variant-display-name
|
||||
[{:keys [variant]}]
|
||||
[:*
|
||||
[:span (cm/font-weight->name (:font-weight variant))]
|
||||
(when (not= "normal" (:font-style variant))
|
||||
[:span " " (str/capital (:font-style variant))])])
|
||||
|
||||
(mf/defc fonts-upload
|
||||
[{:keys [team] :as props}]
|
||||
(let [fonts (mf/use-state {})
|
||||
[{:keys [team installed-fonts] :as props}]
|
||||
(let [fonts (mf/use-state {})
|
||||
input-ref (mf/use-ref)
|
||||
|
||||
uploading (mf/use-state #{})
|
||||
|
@ -126,19 +93,11 @@
|
|||
|
||||
on-selected
|
||||
(mf/use-callback
|
||||
(mf/deps team)
|
||||
(mf/deps team installed-fonts)
|
||||
(fn [blobs]
|
||||
(->> (prepare-fonts blobs)
|
||||
(rx/subs (fn [{:keys [content] :as font}]
|
||||
(let [key (font-key-fn font)]
|
||||
(swap! fonts update key
|
||||
(fn [val]
|
||||
(-> (or val font)
|
||||
(assoc :team-id (:id team))
|
||||
(update :id #(or % (uuid/next)))
|
||||
(update :data assoc (:type content) (:data content))
|
||||
(update :names (fnil conj #{}) (:name content))
|
||||
(dissoc :content))))))
|
||||
(->> (df/process-upload blobs (:id team))
|
||||
(rx/subs (fn [result]
|
||||
(swap! fonts df/merge-and-group-fonts installed-fonts result))
|
||||
(fn [error]
|
||||
(js/console.error "error" error))))))
|
||||
|
||||
|
@ -146,22 +105,26 @@
|
|||
(mf/use-callback
|
||||
(mf/deps team)
|
||||
(fn [item]
|
||||
(let [key (font-key-fn item)]
|
||||
(swap! uploading conj (:id item))
|
||||
(->> (rp/mutation! :create-font-variant item)
|
||||
(rx/delay-at-least 2000)
|
||||
(rx/subs (fn [font]
|
||||
(swap! fonts dissoc key)
|
||||
(swap! uploading disj (:id item))
|
||||
(st/emit! (df/add-font font)))
|
||||
(fn [error]
|
||||
(js/console.log "error" error)))))))
|
||||
(swap! uploading conj (:id item))
|
||||
(->> (rp/mutation! :create-font-variant item)
|
||||
(rx/delay-at-least 2000)
|
||||
(rx/subs (fn [font]
|
||||
(swap! fonts dissoc (:id item))
|
||||
(swap! uploading disj (:id item))
|
||||
(st/emit! (df/add-font font)))
|
||||
(fn [error]
|
||||
(js/console.log "error" error))))))
|
||||
|
||||
on-blur-name
|
||||
(fn [id event]
|
||||
(let [name (dom/get-target-val event)]
|
||||
(swap! fonts df/rename-and-regroup id name installed-fonts)))
|
||||
|
||||
on-delete
|
||||
(mf/use-callback
|
||||
(mf/deps team)
|
||||
(fn [item]
|
||||
(swap! fonts dissoc (font-key-fn item))))]
|
||||
(fn [{:keys [id] :as item}]
|
||||
(swap! fonts dissoc id)))]
|
||||
|
||||
[:div.dashboard-fonts-upload
|
||||
[:div.dashboard-fonts-hero
|
||||
|
@ -177,7 +140,7 @@
|
|||
|
||||
[:div.btn-primary
|
||||
{:on-click on-click}
|
||||
[:span "Add custom font"]
|
||||
[:span (tr "labels.add-custom-font")]
|
||||
[:& file-uploader {:input-id "font-upload"
|
||||
:accept cm/str-font-types
|
||||
:multi true
|
||||
|
@ -190,11 +153,11 @@
|
|||
[:div.font-item.table-row {:key (:id item)}
|
||||
[:div.table-field.family
|
||||
[:input {:type "text"
|
||||
:on-blur #(on-blur-name (:id item) %)
|
||||
:default-value (:font-family item)}]]
|
||||
[:div.table-field.variant
|
||||
[:span (cm/font-weight->name (:font-weight item))]
|
||||
(when (not= "normal" (:font-style item))
|
||||
[:span " " (str/capital (:font-style item))])]
|
||||
[:div.table-field.variants
|
||||
[:span.label
|
||||
[:& font-variant-display-name {:variant item}]]]
|
||||
[:div.table-field.filenames
|
||||
(for [item (:names item)]
|
||||
[:span item])]
|
||||
|
@ -210,56 +173,67 @@
|
|||
[:span.icon.close {:on-click #(on-delete item)} i/close]]]))]]))
|
||||
|
||||
(mf/defc installed-font
|
||||
[{:keys [font] :as props}]
|
||||
(let [open-menu? (mf/use-state false)
|
||||
[{:keys [font-id variants] :as props}]
|
||||
(let [font (first variants)
|
||||
|
||||
variants (sort-by (fn [item]
|
||||
[(:font-weight item)
|
||||
(if (= "normal" (:font-style item)) 1 2)])
|
||||
variants)
|
||||
|
||||
open-menu? (mf/use-state false)
|
||||
edit? (mf/use-state false)
|
||||
state (mf/use-var (:font-family font))
|
||||
|
||||
on-change
|
||||
(mf/use-callback
|
||||
(mf/deps font)
|
||||
(fn [event]
|
||||
(reset! state (dom/get-target-val event))))
|
||||
(fn [event]
|
||||
(reset! state (dom/get-target-val event)))
|
||||
|
||||
on-save
|
||||
(mf/use-callback
|
||||
(mf/deps font)
|
||||
(fn [event]
|
||||
(let [font (assoc font :font-family @state)]
|
||||
(st/emit! (df/update-font font))
|
||||
(reset! edit? false))))
|
||||
(fn [event]
|
||||
(let [font-family @state]
|
||||
(st/emit! (df/update-font
|
||||
{:id font-id
|
||||
:name font-family}))
|
||||
(reset! edit? false)))
|
||||
|
||||
on-key-down
|
||||
(mf/use-callback
|
||||
(mf/deps font)
|
||||
(fn [event]
|
||||
(when (kbd/enter? event)
|
||||
(on-save event))))
|
||||
(fn [event]
|
||||
(when (kbd/enter? event)
|
||||
(on-save event)))
|
||||
|
||||
on-cancel
|
||||
(mf/use-callback
|
||||
(mf/deps font)
|
||||
(fn [event]
|
||||
(reset! edit? false)
|
||||
(reset! state (:font-family font))))
|
||||
(fn [event]
|
||||
(reset! edit? false)
|
||||
(reset! state (:font-family font)))
|
||||
|
||||
delete-fn
|
||||
(mf/use-callback
|
||||
(mf/deps font)
|
||||
(st/emitf (df/delete-font font)))
|
||||
delete-font-fn
|
||||
(fn [] (st/emit! (df/delete-font font-id)))
|
||||
|
||||
delete-variant-fn
|
||||
(fn [id] (st/emit! (df/delete-font-variant id)))
|
||||
|
||||
on-delete
|
||||
(mf/use-callback
|
||||
(mf/deps font)
|
||||
(st/emitf (modal/show
|
||||
{:type :confirm
|
||||
:title (tr "modals.delete-font.title")
|
||||
:message (tr "modals.delete-font.message")
|
||||
:accept-label (tr "labels.delete")
|
||||
:on-accept delete-fn})))]
|
||||
(fn []
|
||||
(st/emit! (modal/show
|
||||
{:type :confirm
|
||||
:title (tr "modals.delete-font.title")
|
||||
:message (tr "modals.delete-font.message")
|
||||
:accept-label (tr "labels.delete")
|
||||
:on-accept (fn [props]
|
||||
(delete-font-fn))})))
|
||||
|
||||
on-delete-variant
|
||||
(fn [id]
|
||||
(st/emit! (modal/show
|
||||
{:type :confirm
|
||||
:title (tr "modals.delete-font-variant.title")
|
||||
:message (tr "modals.delete-font-variant.message")
|
||||
:accept-label (tr "labels.delete")
|
||||
:on-accept (fn [props]
|
||||
(delete-variant-fn id))})))]
|
||||
|
||||
[:div.font-item.table-row {:key (:id font)}
|
||||
[:div.font-item.table-row
|
||||
[:div.table-field.family
|
||||
(if @edit?
|
||||
[:input {:type "text"
|
||||
|
@ -268,10 +242,14 @@
|
|||
:on-change on-change}]
|
||||
[:span (:font-family font)])]
|
||||
|
||||
[:div.table-field.variant
|
||||
[:span (cm/font-weight->name (:font-weight font))]
|
||||
(when (not= "normal" (:font-style font))
|
||||
[:span " " (str/capital (:font-style font))])]
|
||||
[:div.table-field.variants
|
||||
(for [item variants]
|
||||
[:div.variant
|
||||
[:span.label
|
||||
[:& font-variant-display-name {:variant item}]]
|
||||
[:span.icon.close
|
||||
{:on-click #(on-delete-variant (:id item))}
|
||||
i/plus]])]
|
||||
|
||||
[:div]
|
||||
|
||||
|
@ -281,7 +259,7 @@
|
|||
{:disabled (str/blank? @state)
|
||||
:on-click on-save
|
||||
:class (dom/classnames :btn-disabled (str/blank? @state))}
|
||||
"Save"]
|
||||
(tr "labels.save")]
|
||||
[:span.icon.close {:on-click on-cancel} i/close]]
|
||||
|
||||
[:div.table-field.options
|
||||
|
@ -313,41 +291,45 @@
|
|||
[:h3 (tr "labels.installed-fonts")]
|
||||
[:div.installed-fonts-header
|
||||
[:div.table-field.family (tr "labels.font-family")]
|
||||
[:div.table-field.variant (tr "labels.font-variant")]
|
||||
[:div.table-field.variants (tr "labels.font-variants")]
|
||||
[:div]
|
||||
[:div.table-field.search-input
|
||||
[:input {:placeholder (tr "labels.search-font")
|
||||
:default-value ""
|
||||
:on-change on-change
|
||||
}]]]
|
||||
(for [[font-id fonts] (->> fonts
|
||||
(filter matches?)
|
||||
(group-by :font-id))]
|
||||
[:div.fonts-group
|
||||
(for [font (sort-by (juxt :font-weight :font-style) fonts)]
|
||||
[:& installed-font {:key (:id font) :font font}])])]))
|
||||
|
||||
(cond
|
||||
(seq fonts)
|
||||
(for [[font-id variants] (->> (vals fonts)
|
||||
(filter matches?)
|
||||
(group-by :font-id))]
|
||||
[:& installed-font {:key (str font-id)
|
||||
:font-id font-id
|
||||
:variants variants}])
|
||||
|
||||
(nil? fonts)
|
||||
[:div.fonts-placeholder
|
||||
[:div.icon i/loader]
|
||||
[:div.label (tr "dashboard.loading-fonts")]]
|
||||
|
||||
:else
|
||||
[:div.fonts-placeholder
|
||||
[:div.icon i/text]
|
||||
[:div.label (tr "dashboard.fonts.empty-placeholder")]])]))
|
||||
|
||||
(mf/defc fonts-page
|
||||
[{:keys [team] :as props}]
|
||||
(let [fonts-map (mf/deref refs/dashboard-fonts)
|
||||
fonts (vals fonts-map)]
|
||||
|
||||
(mf/use-effect
|
||||
(mf/deps team)
|
||||
(st/emitf (df/fetch-fonts team)))
|
||||
|
||||
(let [fonts (mf/deref refs/dashboard-fonts)]
|
||||
[:*
|
||||
[:& header {:team team :section :fonts}]
|
||||
[:section.dashboard-container.dashboard-fonts
|
||||
[:& fonts-upload {:team team}]
|
||||
[:& fonts-upload {:team team :installed-fonts fonts}]
|
||||
[:& installed-fonts {:team team :fonts fonts}]]]))
|
||||
|
||||
(when fonts
|
||||
[:& installed-fonts {:team team
|
||||
:fonts fonts}])]]))
|
||||
(mf/defc font-providers-page
|
||||
[{:keys [team] :as props}]
|
||||
[:*
|
||||
[:& header {:team team :section :providers}]
|
||||
[:section.dashboard-container
|
||||
[:span "hello world font providers"]]])
|
||||
[:span "font providers"]]])
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
(mf/defc onboarding-start
|
||||
[{:keys [next] :as props}]
|
||||
[:div.modal-container.onboarding
|
||||
[:div.modal-left
|
||||
[:div.modal-left.welcome
|
||||
[:img {:src "images/login-on.jpg" :border "0" :alt "Penpot"}]]
|
||||
[:div.modal-right
|
||||
[:div.modal-title
|
||||
|
@ -296,7 +296,7 @@
|
|||
|
||||
(defmethod render-release-notes "0.0"
|
||||
[params]
|
||||
(render-release-notes (assoc params :version "1.5")))
|
||||
(render-release-notes (assoc params :version "1.6")))
|
||||
|
||||
(defmethod render-release-notes "1.4"
|
||||
[{:keys [slide klass next finish navigate version]}]
|
||||
|
@ -474,3 +474,101 @@
|
|||
{:slide @slide
|
||||
:navigate navigate
|
||||
:total 3}]]]]]])))
|
||||
|
||||
(defmethod render-release-notes "1.6"
|
||||
[{:keys [slide klass next finish navigate version]}]
|
||||
(mf/html
|
||||
(case @slide
|
||||
:start
|
||||
[:div.modal-overlay
|
||||
[:div.animated {:class @klass}
|
||||
[:div.modal-container.onboarding.feature
|
||||
[:div.modal-left
|
||||
[:img {:src "images/login-on.jpg" :border "0" :alt "What's new Alpha release 1.6.0"}]]
|
||||
[:div.modal-right
|
||||
[:div.modal-title
|
||||
[:h2 "What's new?"]]
|
||||
[:span.release "Alpha version " version]
|
||||
[:div.modal-content
|
||||
[:p "Penpot continues growing with new features that improve performance, user experience and visual design."]
|
||||
[:p "We are happy to show you a sneak peak of the most important stuff that the Alpha 1.6.0 version brings."]]
|
||||
[:div.modal-navigation
|
||||
[:button.btn-secondary {:on-click next} "Continue"]]]
|
||||
[:img.deco {:src "images/deco-left.png" :border "0"}]
|
||||
[:img.deco.right {:src "images/deco-right.png" :border "0"}]]]]
|
||||
|
||||
0
|
||||
[:div.modal-overlay
|
||||
[:div.animated {:class @klass}
|
||||
[:div.modal-container.onboarding.feature
|
||||
[:div.modal-left
|
||||
[:img {:src "images/features/custom-fonts.gif" :border "0" :alt "Upload/use custom fonts"}]]
|
||||
[:div.modal-right
|
||||
[:div.modal-title
|
||||
[:h2 "Upload/use custom fonts"]]
|
||||
[:div.modal-content
|
||||
[:p "From now on you can upload fonts to a Penpot team and use them across its files. This is one of the most requested features since our first release (we listen!)"]
|
||||
[:p "We hope you enjoy having more typography options and our brand new font selector."]]
|
||||
[:div.modal-navigation
|
||||
[:button.btn-secondary {:on-click next} "Continue"]
|
||||
[:& navigation-bullets
|
||||
{:slide @slide
|
||||
:navigate navigate
|
||||
:total 4}]]]]]]
|
||||
|
||||
1
|
||||
[:div.modal-overlay
|
||||
[:div.animated {:class @klass}
|
||||
[:div.modal-container.onboarding.feature
|
||||
[:div.modal-left
|
||||
[:img {:src "images/features/scale-text.gif" :border "0" :alt "Interactively scale text"}]]
|
||||
[:div.modal-right
|
||||
[:div.modal-title
|
||||
[:h2 "Scale text layers at resizing"]]
|
||||
[:div.modal-content
|
||||
[:p "New main menu option “Scale text (K)” to enable scale text mode."]
|
||||
[:p "Disabled by default, this tool is disabled back after being used."]]
|
||||
[:div.modal-navigation
|
||||
[:button.btn-secondary {:on-click next} "Continue"]
|
||||
[:& navigation-bullets
|
||||
{:slide @slide
|
||||
:navigate navigate
|
||||
:total 4}]]]]]]
|
||||
|
||||
2
|
||||
[:div.modal-overlay
|
||||
[:div.animated {:class @klass}
|
||||
[:div.modal-container.onboarding.feature
|
||||
[:div.modal-left
|
||||
[:img {:src "images/features/performance.gif" :border "0" :alt "Performance improvements"}]]
|
||||
[:div.modal-right
|
||||
[:div.modal-title
|
||||
[:h2 "Performance improvements"]]
|
||||
[:div.modal-content
|
||||
[:p "Penpot brings important improvements handling large files. The performance in managing files in the dashboard has also been improved."]
|
||||
[:p "You should have the feeling that files and layers show up a bit faster :)"]]
|
||||
[:div.modal-navigation
|
||||
[:button.btn-secondary {:on-click next} "Continue"]
|
||||
[:& navigation-bullets
|
||||
{:slide @slide
|
||||
:navigate navigate
|
||||
:total 4}]]]]]]
|
||||
|
||||
3
|
||||
[:div.modal-overlay
|
||||
[:div.animated {:class @klass}
|
||||
[:div.modal-container.onboarding.feature
|
||||
[:div.modal-left
|
||||
[:img {:src "images/features/shapes-to-path.gif" :border "0" :alt "Shapes to path"}]]
|
||||
[:div.modal-right
|
||||
[:div.modal-title
|
||||
[:h2 "Shapes to path"]]
|
||||
[:div.modal-content
|
||||
[:p "Now you can edit basic shapes like rectangles, circles and image containers by double clicking."]
|
||||
[:p "An easy way to increase speed by working with vectors!"]]
|
||||
[:div.modal-navigation
|
||||
[:button.btn-secondary {:on-click finish} "Start!"]
|
||||
[:& navigation-bullets
|
||||
{:slide @slide
|
||||
:navigate navigate
|
||||
:total 4}]]]]]])))
|
||||
|
|
|
@ -310,7 +310,16 @@
|
|||
[:div.row-flex
|
||||
[:div.input-select.font-option
|
||||
{:on-click #(reset! open-selector? true)}
|
||||
(:name font)]]
|
||||
(cond
|
||||
(= :multiple font-id)
|
||||
"--"
|
||||
|
||||
(some? font)
|
||||
(:name font)
|
||||
|
||||
:else
|
||||
(tr "dashboard.fonts.deleted-placeholder"))]]
|
||||
|
||||
|
||||
[:div.row-flex
|
||||
(let [size-options [8 9 10 11 12 14 18 24 36 48 72]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue