mirror of
https://github.com/penpot/penpot.git
synced 2026-09-08 13:09:22 +00:00
Merge remote-tracking branch 'origin/staging' into develop
This commit is contained in:
commit
37f1d3f0fd
@ -241,6 +241,18 @@
|
|||||||
(some-> (db/get cfg :file-data {:file-id file-id :id fragment-id :type "fragment"})
|
(some-> (db/get cfg :file-data {:file-id file-id :id fragment-id :type "fragment"})
|
||||||
(update :data blob/decode)))
|
(update :data blob/decode)))
|
||||||
|
|
||||||
|
(defn- check-fragment-scope!
|
||||||
|
"Checks that the fragment is reachable from the pages authorized by
|
||||||
|
the share-link. Raises a :not-found exception if the fragment is not reachable."
|
||||||
|
[cfg file-id fragment-id pages]
|
||||||
|
(let [fdata (-> (bfc/get-file cfg file-id :read-only? true)
|
||||||
|
(get :data)
|
||||||
|
(update :pages-index select-keys pages))]
|
||||||
|
(when-not (contains? (feat.fdata/get-used-pointer-ids fdata) fragment-id)
|
||||||
|
(ex/raise :type :not-found
|
||||||
|
:code :object-not-found
|
||||||
|
:hint "object not found"))))
|
||||||
|
|
||||||
(sv/defmethod ::get-file-fragment
|
(sv/defmethod ::get-file-fragment
|
||||||
"Retrieve a file fragment by its ID. Only authenticated users."
|
"Retrieve a file fragment by its ID. Only authenticated users."
|
||||||
{::doc/added "1.17"
|
{::doc/added "1.17"
|
||||||
@ -250,11 +262,9 @@
|
|||||||
[cfg {:keys [::rpc/profile-id file-id fragment-id share-id]}]
|
[cfg {:keys [::rpc/profile-id file-id fragment-id share-id]}]
|
||||||
(db/run! cfg (fn [cfg]
|
(db/run! cfg (fn [cfg]
|
||||||
(let [perms (perms/get-file-read-permissions cfg profile-id file-id share-id)]
|
(let [perms (perms/get-file-read-permissions cfg profile-id file-id share-id)]
|
||||||
(when (= :share-link (:type perms))
|
|
||||||
(ex/raise :type :not-found
|
|
||||||
:code :object-not-found
|
|
||||||
:hint "object not found"))
|
|
||||||
(check-read-permissions! perms)
|
(check-read-permissions! perms)
|
||||||
|
(when (= :share-link (:type perms))
|
||||||
|
(check-fragment-scope! cfg file-id fragment-id (:pages perms)))
|
||||||
(-> (get-file-fragment cfg file-id fragment-id)
|
(-> (get-file-fragment cfg file-id fragment-id)
|
||||||
(rph/with-http-cache long-cache-duration))))))
|
(rph/with-http-cache long-cache-duration))))))
|
||||||
|
|
||||||
|
|||||||
@ -326,11 +326,12 @@
|
|||||||
(filter #(= page-id (:page-id %)))
|
(filter #(= page-id (:page-id %)))
|
||||||
(d/index-by :id)
|
(d/index-by :id)
|
||||||
(assoc state :comment-threads)))
|
(assoc state :comment-threads)))
|
||||||
(on-error [{:keys [type] :as err}]
|
(on-error [cause]
|
||||||
(if (or (= :authentication type)
|
(let [{:keys [type]} (ex-data cause)]
|
||||||
(= :not-found type))
|
(if (or (= :authentication type)
|
||||||
(rx/empty)
|
(= :not-found type))
|
||||||
(rx/throw err)))]
|
(rx/empty)
|
||||||
|
(rx/throw cause))))]
|
||||||
|
|
||||||
(ptk/reify ::fetch-comment-threads
|
(ptk/reify ::fetch-comment-threads
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
|
|||||||
@ -114,6 +114,7 @@
|
|||||||
(str "<ul>" items "</ul>"))]
|
(str "<ul>" items "</ul>"))]
|
||||||
(st/emit! (ntf/show {:content (tr "errors.weak-password")
|
(st/emit! (ntf/show {:content (tr "errors.weak-password")
|
||||||
:detail detail
|
:detail detail
|
||||||
|
:is-html true
|
||||||
:type :toast
|
:type :toast
|
||||||
:level :error})))
|
:level :error})))
|
||||||
|
|
||||||
|
|||||||
@ -120,7 +120,7 @@
|
|||||||
[:div
|
[:div
|
||||||
(tr "nitrate.code-activation.footer-after") " "
|
(tr "nitrate.code-activation.footer-after") " "
|
||||||
[:a {:class (stl/css :link)
|
[:a {:class (stl/css :link)
|
||||||
:href "mailto:sales@nitrate.com"}
|
:href "mailto:sales@penpot.app"}
|
||||||
"sales@nitrate.com"]
|
"sales@penpot.app"]
|
||||||
" "
|
" "
|
||||||
(tr "nitrate.code-activation.footer-before")]]]]]))
|
(tr "nitrate.code-activation.footer-before")]]]]]))
|
||||||
|
|||||||
@ -118,8 +118,8 @@
|
|||||||
(tr "nitrate.form.contact-upgrade")
|
(tr "nitrate.form.contact-upgrade")
|
||||||
(tr "nitrate.form.contact-trial"))]
|
(tr "nitrate.form.contact-trial"))]
|
||||||
[:p {:class (stl/css :modal-text-large)}
|
[:p {:class (stl/css :modal-text-large)}
|
||||||
[:a {:class (stl/css :link) :href "mailto:sales@penpot.app"}
|
[:a {:class (stl/css :link) :href "mailto:sales@penpot.net"}
|
||||||
"sales@penpot.app"]]
|
"sales@penpot.net"]]
|
||||||
[:div {:class (stl/css :activation-code)}
|
[:div {:class (stl/css :activation-code)}
|
||||||
[:p {:class (stl/css :modal-text-large)}
|
[:p {:class (stl/css :modal-text-large)}
|
||||||
[:a {:class (stl/css :link)
|
[:a {:class (stl/css :link)
|
||||||
|
|||||||
@ -745,7 +745,6 @@
|
|||||||
:cta-link (if (and (contains? cf/flags :admin-console) nitrate?) #(open-contact-sales-modal subscription-type "Unlimited") #(open-subscription-modal "unlimited" subscription))
|
:cta-link (if (and (contains? cf/flags :admin-console) nitrate?) #(open-contact-sales-modal subscription-type "Unlimited") #(open-subscription-modal "unlimited" subscription))
|
||||||
:cta-text-with-icon (tr "subscription.settings.more-information")
|
:cta-text-with-icon (tr "subscription.settings.more-information")
|
||||||
:cta-link-with-icon go-to-pricing-page
|
:cta-link-with-icon go-to-pricing-page
|
||||||
:recommended (= subscription-type "professional")
|
|
||||||
:show-button-cta (= subscription-type "professional")
|
:show-button-cta (= subscription-type "professional")
|
||||||
:current-plan false}])
|
:current-plan false}])
|
||||||
|
|
||||||
@ -783,6 +782,7 @@
|
|||||||
:cta-text-with-icon (tr "subscription.settings.more-information")
|
:cta-text-with-icon (tr "subscription.settings.more-information")
|
||||||
:cta-link-with-icon go-to-pricing-page
|
:cta-link-with-icon go-to-pricing-page
|
||||||
:code-action :activate
|
:code-action :activate
|
||||||
|
:recommended (= subscription-type "professional")
|
||||||
:show-button-cta (not nitrate-license)
|
:show-button-cta (not nitrate-license)
|
||||||
:current-plan false
|
:current-plan false
|
||||||
:inline-error nitrate-start-error-message}])]]]))
|
:inline-error nitrate-start-error-message}])]]]))
|
||||||
@ -848,8 +848,8 @@
|
|||||||
[:div {:class (stl/css :modal-text)}
|
[:div {:class (stl/css :modal-text)}
|
||||||
(tr "nitrate.form.enterprise-intro" ".") " " (if nitrate-license (tr "nitrate.form.contact-us-upgrade") (tr "nitrate.form.contact-us-free-trial"))]
|
(tr "nitrate.form.enterprise-intro" ".") " " (if nitrate-license (tr "nitrate.form.contact-us-upgrade") (tr "nitrate.form.contact-us-free-trial"))]
|
||||||
[:div {:class (stl/css :modal-text)}
|
[:div {:class (stl/css :modal-text)}
|
||||||
[:a {:class (stl/css :cta-button) :href "mailto:sales@penpot.app"}
|
[:a {:class (stl/css :cta-button) :href "mailto:sales@penpot.net"}
|
||||||
"sales@penpot.app"]]])]]))
|
"sales@penpot.net"]]])]]))
|
||||||
|
|
||||||
(mf/defc nitrate-contact-sales-dialog
|
(mf/defc nitrate-contact-sales-dialog
|
||||||
{::mf/register modal/components
|
{::mf/register modal/components
|
||||||
@ -898,7 +898,7 @@
|
|||||||
:on-click handle-close-dialog} (tr "ds.confirm-cancel")]
|
:on-click handle-close-dialog} (tr "ds.confirm-cancel")]
|
||||||
[:> button* {:variant "primary"
|
[:> button* {:variant "primary"
|
||||||
:type "button"
|
:type "button"
|
||||||
:on-click #(dom/open-new-window (dm/str "mailto:sales@penpot.app?subject=Switch%20to%20the%20" subscription-type "%20plan"))} (tr "nitrate.contact-sales.button")]]])]]]))
|
:on-click #(dom/open-new-window (dm/str "mailto:sales@penpot.net?subject=Switch%20to%20the%20" subscription-type "%20plan"))} (tr "nitrate.contact-sales.button")]]])]]]))
|
||||||
|
|
||||||
(mf/defc nitrate-cancel-contact-sales-dialog
|
(mf/defc nitrate-cancel-contact-sales-dialog
|
||||||
{::mf/register modal/components
|
{::mf/register modal/components
|
||||||
|
|||||||
@ -164,11 +164,13 @@
|
|||||||
|
|
||||||
(defn- sample-container-style
|
(defn- sample-container-style
|
||||||
"Inline style that applies the typography font to the (clipped, fixed-height)
|
"Inline style that applies the typography font to the (clipped, fixed-height)
|
||||||
sample container."
|
sample container. Must be a real JS object (`#js`), not a ClojureScript map:
|
||||||
|
the `:style` value here is a runtime expression, not a literal recognized by
|
||||||
|
the hiccup macro, so it reaches React unconverted."
|
||||||
[typography]
|
[typography]
|
||||||
{:font-family (:font-family typography)
|
#js {:fontFamily (:font-family typography)
|
||||||
:font-weight (:font-weight typography)
|
:fontWeight (:font-weight typography)
|
||||||
:font-style (:font-style typography)})
|
:fontStyle (:font-style typography)})
|
||||||
|
|
||||||
(defn- sample-text-style
|
(defn- sample-text-style
|
||||||
"Inline style that optically centers the sample glyphs. Must be applied to
|
"Inline style that optically centers the sample glyphs. Must be applied to
|
||||||
@ -177,7 +179,7 @@
|
|||||||
would shift the whole box relative to the row instead of the glyphs inside it."
|
would shift the whole box relative to the row instead of the glyphs inside it."
|
||||||
[em]
|
[em]
|
||||||
(when-not (zero? em)
|
(when-not (zero? em)
|
||||||
{:transform (dm/str "translateY(" em "em)")}))
|
#js {:transform (dm/str "translateY(" em "em)")}))
|
||||||
|
|
||||||
;; --- FONT SELECTOR --------------------------------------------------------
|
;; --- FONT SELECTOR --------------------------------------------------------
|
||||||
|
|
||||||
@ -219,6 +221,7 @@
|
|||||||
:role "img"
|
:role "img"
|
||||||
:aria-label (:name font)}
|
:aria-label (:name font)}
|
||||||
[:use {:href (dm/str "#" fonts/preview-sprite-prefix font-id)}]]
|
[:use {:href (dm/str "#" fonts/preview-sprite-prefix font-id)}]]
|
||||||
|
<<<<<<< HEAD
|
||||||
[:span {:class (stl/css :font-item-label)
|
[:span {:class (stl/css :font-item-label)
|
||||||
:style (cond-> {}
|
:style (cond-> {}
|
||||||
loaded?
|
loaded?
|
||||||
@ -226,6 +229,20 @@
|
|||||||
(not (zero? label-offset))
|
(not (zero? label-offset))
|
||||||
(assoc :transform (dm/str "translateY(" label-offset "em)")))}
|
(assoc :transform (dm/str "translateY(" label-offset "em)")))}
|
||||||
(:name font)])))
|
(:name font)])))
|
||||||
|
=======
|
||||||
|
;; The vertical correction goes on an INNER span, not on `.font-item-label`
|
||||||
|
;; itself: that class carries its own `overflow: hidden` (from the
|
||||||
|
;; text-ellipsis mixin, needed to truncate long font names), and a
|
||||||
|
;; transform applied to a self-clipping element moves its clip region
|
||||||
|
;; along with it — a no-op. The inner span has no overflow of its own, so
|
||||||
|
;; the shift actually moves the ink within the outer's fixed clip area.
|
||||||
|
[:span {:class (stl/css :font-item-label)}
|
||||||
|
[:span {:style #js {:fontFamily (when loaded?
|
||||||
|
(dm/str "\"" (:family font) "\", sans-serif"))
|
||||||
|
:transform (when-not (zero? label-offset)
|
||||||
|
(dm/str "translateY(" label-offset "em)"))}}
|
||||||
|
(:name font)]])))
|
||||||
|
>>>>>>> origin/staging
|
||||||
|
|
||||||
(mf/defc font-item*
|
(mf/defc font-item*
|
||||||
{::mf/wrap [mf/memo]}
|
{::mf/wrap [mf/memo]}
|
||||||
|
|||||||
@ -101,7 +101,7 @@ $font-preview-box-height: 28px;
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
background-color: var(--font-name-wrapper-background-color);
|
background-color: var(--font-name-wrapper-background-color);
|
||||||
margin-block-end: var(--sp-s);
|
margin-block-end: var(--sp-s);
|
||||||
padding: var(--sp-s) 0 var(--sp-s) var(--sp-m);
|
padding-inline-start: var(--sp-m);
|
||||||
|
|
||||||
&:focus-within {
|
&:focus-within {
|
||||||
--font-name-wrapper-border-color: var(--color-accent-primary);
|
--font-name-wrapper-border-color: var(--color-accent-primary);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user