0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-02-12 18:18:24 -05:00

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

This commit is contained in:
Andrey Antukh 2023-07-28 11:48:50 +02:00
commit f76f4615cf
24 changed files with 177 additions and 56 deletions

View file

@ -99,6 +99,17 @@
- Fix assets right click button for multiple selection [Taiga #5545](https://tree.taiga.io/project/penpot/issue/5545)
- Fix problem with precision in resizes [Taiga #5623](https://tree.taiga.io/project/penpot/issue/5623)
- Fix absolute positioned layouts not showing flex properties [Taiga #5630](https://tree.taiga.io/project/penpot/issue/5630)
- Fix text gradient handlers [Taiga #4047](https://tree.taiga.io/project/penpot/issue/4047)
- Fix when user deletes one file during import it is impossible to finish importing of second file [Taiga #5656](https://tree.taiga.io/project/penpot/issue/5656)
- Fix export multiple images when only one of them has export settings [Taiga #5649](https://tree.taiga.io/project/penpot/issue/5649)
- Fix error when a user different than the thread creator edits a comment [Taiga #5647](https://tree.taiga.io/project/penpot/issue/5647)
- Fix unnecessary button [Taiga #3312](https://tree.taiga.io/project/penpot/issue/3312)
- Fix copy color information in several formats [Taiga #4723](https://tree.taiga.io/project/penpot/issue/4723)
- Fix dropdown width [Taiga #5541](https://tree.taiga.io/project/penpot/issue/5541)
- Fix enable comment mode and insert image keeps on comment mode [Taiga #5678](https://tree.taiga.io/project/penpot/issue/5678)
- Fix enable undo just after using pencil [Taiga #5674](https://tree.taiga.io/project/penpot/issue/5674)
- Fix 400 error when user changes password [Taiga #5643](https://tree.taiga.io/project/penpot/issue/5643)
- Fix cannot undo layer styles [Taiga #5676](https://tree.taiga.io/project/penpot/issue/5676)
### :arrow_up: Deps updates

View file

@ -468,8 +468,8 @@
{::doc/added "1.15"}
[{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id ::rpc/request-at id share-id content] :as params}]
(db/with-atomic [conn pool]
(let [{:keys [thread-id] :as comment} (get-comment conn id ::db/for-update? true)
{:keys [file-id page-id owner-id] :as thread} (get-comment-thread conn thread-id ::db/for-update? true)]
(let [{:keys [thread-id owner-id] :as comment} (get-comment conn id ::db/for-update? true)
{:keys [file-id page-id] :as thread} (get-comment-thread conn thread-id ::db/for-update? true)]
(files/check-comment-permissions! conn profile-id file-id share-id)

View file

@ -133,7 +133,8 @@
(def schema:update-profile-password
[:map {:title "update-profile-password"}
[:password [::sm/word-string {:max 500}]]
[:old-password [::sm/word-string {:max 500}]]])
;; Social registered users don't have old-password
[:old-password {:optional true} [:maybe [::sm/word-string {:max 500}]]]])
(sv/defmethod ::update-profile-password
{:doc/added "1.0"

View file

@ -776,6 +776,12 @@
[key (delay (generator-fn key))]))
keys))
(defn opacity-to-hex [opacity]
(let [opacity (* opacity 255)
value (mth/round opacity)]
(.. value
(toString 16)
(padStart 2 "0"))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; String Functions

View file

@ -316,6 +316,22 @@
&:hover {
border: 1px solid $color-gray-20;
}
&.no-check {
.custom-select-dropdown {
width: 100%;
min-width: unset;
.check-icon {
display: none;
}
li.checked-element {
padding-left: 0.5rem;
&.is-selected {
background-color: $color-primary;
}
}
}
}
}
.opened {
border: 1px solid $color-primary;

View file

@ -416,6 +416,12 @@ span.element-name {
.page-name {
padding: 8px;
margin-top: 8px;
color: #e3e3e3;
font-size: 0.875rem;
max-width: 90%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.icon-search {
margin-top: 8px;

View file

@ -60,6 +60,15 @@
white-space: nowrap;
}
span.pages-title {
color: #e3e3e3;
font-size: 0.875rem;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
span.tool-badge {
border: 1px solid $color-primary;
border-radius: $br2;

View file

@ -322,7 +322,7 @@
(rx/concat
(rx/of (partial fetched-comments comments))
(->> (rx/from (map :file-id comments))
(->> (rx/from (into #{} (map :file-id) comments))
(rx/merge-map #(rp/cmd! :get-profiles-for-file-comments {:file-id %}))
(rx/reduce #(merge %1 (d/index-by :id %2)) {})
(rx/map #(partial fetched-users %))))))

View file

@ -337,7 +337,8 @@
[:map {:closed true}
[:password-1 :string]
[:password-2 :string]
[:password-old :string]])
;; Social registered users don't have old-password
[:password-old {:optional true} [:maybe :string]]])
(defn update-password
[data]

View file

@ -129,7 +129,7 @@
(let [objects (wsh/lookup-page-objects state)
edition (get-in state [:workspace-local :edition])
drawing (get state :workspace-drawing)]
(when-not (and (or (some? edition) (not-empty drawing))
(when-not (and (or (some? edition) (some? (:object drawing)))
(not (ctl/grid-layout? objects edition)))
(let [undo (:workspace-undo state)
items (:items undo)

View file

@ -182,11 +182,19 @@
(rx/of (shapes-changes-persisted-finished))))))
(rx/catch (fn [cause]
(cond
(= :authentication (:type cause))
(rx/throw cause)
(instance? js/TypeError cause)
(->> (rx/timer 2000)
(rx/map (fn [_]
(persist-changes file-id file-revn changes pending-commits))))
:else
(rx/concat
(if (= :authentication (:type cause))
(rx/empty)
(rx/of (rt/assign-exception cause)))
(rx/throw cause)))))))))
(rx/of (rt/assign-exception cause))
(rx/throw cause))))))))))
;; Event to be thrown after the changes have been persisted
(defn shapes-changes-persisted-finished

View file

@ -66,7 +66,8 @@
(defmethod ptk/handle-error :default
[error]
(ts/schedule #(st/emit! (rt/assign-exception (::instance error))))
(when-let [cause (::instance error)]
(ts/schedule #(st/emit! (rt/assign-exception cause))))
(print-group! "Unhandled Error"
(fn []
(print-trace! error)

View file

@ -145,6 +145,7 @@
(mf/with-effect [theme]
(dom/set-html-theme-color theme))
[:& (mf/provider ctx/current-route) {:value route}
[:& (mf/provider ctx/current-profile) {:value profile}
(if edata

View file

@ -214,7 +214,11 @@
:select-on-focus true
:on-change on-change}]
[:div.buttons
[:input.btn-primary {:type "button" :value "Post" :on-click on-submit*}]
[:input.btn-primary {:type "button"
:value "Post"
:on-click on-submit*
:disabled (or (fm/all-spaces? @content)
(str/empty-or-nil? @content))}]
[:input.btn-secondary {:type "button" :value "Cancel" :on-click on-cancel}]]]))
(mf/defc comment-item

View file

@ -481,3 +481,13 @@
(cond-> errors
(all-spaces? (get data field))
(assoc field {:message error-msg}))))
(defn validate-not-all-spaces
[field error-msg]
(fn [errors data]
(let [value (get data field)]
(cond-> errors
(and
(all-spaces? value)
(> (count value) 0))
(assoc field {:message error-msg})))))

View file

@ -22,17 +22,12 @@
(mf/defc comments-section
[{:keys [profile team]}]
(mf/use-effect
(mf/deps team)
(fn []
(st/emit! (dcm/retrieve-unread-comment-threads (:id team)))))
(let [show-dropdown? (mf/use-state false)
show-dropdown (mf/use-fn #(reset! show-dropdown? true))
hide-dropdown (mf/use-fn #(reset! show-dropdown? false))
threads-map (mf/deref refs/comment-threads)
users (mf/deref refs/current-team-comments-users)
team-id (:id team)
tgroups (->> (vals threads-map)
(sort-by :modified-at)
@ -46,6 +41,11 @@
(st/emit! (-> (dwcm/navigate thread)
(with-meta {::ev/origin "dashboard"})))))]
(mf/use-effect
(mf/deps team-id)
(fn []
(st/emit! (dcm/retrieve-unread-comment-threads team-id))))
(mf/use-effect
(mf/deps @show-dropdown?)
(fn []

View file

@ -337,18 +337,18 @@
(st/emit! (modal/hide))
(when on-finish-import (on-finish-import))))
files (->> (:files @state) (filterv (comp not :deleted?)))
num-importing (+
(->> @state :files (filter #(= (:status %) :importing)) count)
(->> files (filter #(= (:status %) :importing)) count)
(:importing-templates @state))
warning-files (->> @state :files (filter #(and (= (:status %) :import-finish) (d/not-empty? (:errors %)))) count)
success-files (->> @state :files (filter #(and (= (:status %) :import-finish) (empty? (:errors %)))) count)
pending-analysis? (> (->> @state :files (filter #(= (:status %) :analyzing)) count) 0)
warning-files (->> files (filter #(and (= (:status %) :import-finish) (d/not-empty? (:errors %)))) count)
success-files (->> files (filter #(and (= (:status %) :import-finish) (empty? (:errors %)))) count)
pending-analysis? (> (->> files (filter #(= (:status %) :analyzing)) count) 0)
pending-import? (> num-importing 0)
files (->> (:files @state) (filterv (comp not :deleted?)))
;; pending-import? (> (->> @state :files (filter #(= (:status %) :importing)) count) 0)
;; files (->> (:files @state) (filterv (comp not :deleted?)))
valid-files? (or (some? template)
(> (+ (->> files (filterv (fn [x] (not= (:status x) :analyze-error))) count)) 0))]
@ -400,7 +400,7 @@
[:div.modal-footer
[:div.action-buttons
(when (or (= :analyzing (:status @state)) pending-import?)
(when (= :analyzing (:status @state))
[:input.cancel-button
{:type "button"
:value (tr "labels.cancel")

View file

@ -71,7 +71,8 @@
[{:keys [locale] :as props}]
(let [initial (mf/use-memo (constantly {:password-old nil}))
form (fm/use-form :spec ::password-form
:validators [(fm/validate-not-empty :password-1 (tr "auth.password-not-empty"))
:validators [(fm/validate-not-all-spaces :password-old (tr "auth.password-not-empty"))
(fm/validate-not-empty :password-1 (tr "auth.password-not-empty"))
(fm/validate-not-empty :password-2 (tr "auth.password-not-empty"))
password-equality]
:initial initial)]

View file

@ -28,19 +28,25 @@
(seq (:fills shape)))))
(mf/defc fill-block
{::mf/wrap-props false}
[{:keys [objects shape]}]
(let [color-format (mf/use-state :hex)
color (shape->color shape)]
(let [format* (mf/use-state :hex)
format (deref format*)
color (shape->color shape)
on-change (mf/use-fn #(reset! format* %))]
[:div.attributes-fill-block
[:& color-row {:color color
:format @color-format
:on-change-format #(reset! color-format %)
[:& color-row
{:color color
:format format
:on-change-format on-change
:copy-data (css/get-shape-properties-css objects {:fills [shape]} properties)}]]))
(mf/defc fill-panel
{::mf/wrap-props false}
[{:keys [shapes]}]
(let [shapes (->> shapes (filter has-fill?))]
(let [shapes (filter has-fill? shapes)]
(when (seq shapes)
[:div.attributes-block
[:div.attributes-block-title

View file

@ -31,7 +31,10 @@
file-id (mf/use-ctx ctx/current-file-id)
on-click
(mf/use-fn #(dom/click (mf/ref-val ref)))
(mf/use-fn
(fn []
(st/emit! :interrupt dw/clear-edition-mode)
(dom/click (mf/ref-val ref))))
on-selected
(mf/use-fn

View file

@ -31,9 +31,11 @@
state (mf/deref refs/export)
in-progress? (:in-progress state)
shapes-with-exports (->> (wsh/lookup-shapes @st/state ids)
(filter #(pos? (count (:exports %)))))
sname (when (seqable? exports)
(let [shapes (wsh/lookup-shapes @st/state ids)
sname (-> shapes first :name)
(let [sname (-> shapes-with-exports first :name)
suffix (-> exports first :suffix)]
(cond-> sname
(and (= 1 (count exports)) (some? suffix))
@ -50,7 +52,22 @@
(fn [event]
(dom/prevent-default event)
(if (= :multiple type)
(st/emit! (de/show-workspace-export-dialog {:selected (reverse ids)}))
;; I can select multiple shapes all of them with no export settings and one of them with only one
;; In that situation we must export it directly
(if (and (= 1 (count shapes-with-exports)) (= 1 (-> shapes-with-exports first :exports count)))
(let [shape (-> shapes-with-exports first)
export (-> shape :exports first)
sname (:name shape)
suffix (:suffix export)
defaults {:page-id page-id
:file-id file-id
:name sname
:object-id (:id (first shapes-with-exports))}]
(cond-> sname
(some? suffix)
(str suffix))
(st/emit! (de/request-simple-export {:export (merge export defaults)})))
(st/emit! (de/show-workspace-export-dialog {:selected (reverse ids)})))
;; In other all cases we only allowed to have a single
;; shape-id because multiple shape-ids are handled
@ -182,4 +199,4 @@
:disabled in-progress?}
(if in-progress?
(tr "workspace.options.exporting-object")
(tr "workspace.options.export-object" (c (count ids))))])]))
(tr "workspace.options.export-object" (c (count shapes-with-exports))))])]))

View file

@ -62,6 +62,7 @@
:selected-blend-mode value
:option-highlighted? false
:preview-complete? true)
(st/emit! (dw/unset-preview-blend-mode ids))
(on-change :blend-mode value)))
handle-blend-mode-enter
@ -152,7 +153,7 @@
[:div.element-set-content
[:div.row-flex
[:& select
{:class "flex-grow"
{:class "flex-grow no-check"
:default-value selected-blend-mode
:options options
:on-change handle-change-blend-mode

View file

@ -269,7 +269,7 @@
[:div#sitemap.tool-window {:ref parent-ref
:style #js {"--height" (str size "px")}}
[:div.tool-window-bar
[:span (tr "workspace.sidebar.sitemap")]
[:span.pages-title (tr "workspace.sidebar.sitemap")]
(if workspace-read-only?
[:div.view-only-mode (tr "labels.view-only")]
[:div.add-page {:on-click create} i/close])

View file

@ -7,6 +7,7 @@
(ns app.util.color
"Color conversion utils."
(:require
[app.common.data :as d]
[app.util.i18n :as i18n :refer [tr]]
[app.util.object :as obj]
[app.util.strings :as ust]
@ -150,6 +151,24 @@
:else "transparent")))
(defn color->format->background [{:keys [color opacity gradient]} format]
(let [opacity (or opacity 1)]
(cond
(and gradient (not= :multiple gradient))
(gradient->css gradient)
(not= color :multiple)
(case format
:rgba (let [[r g b] (hex->rgb color)]
(str/fmt "rgba(%s, %s, %s, %s)" r g b opacity))
:hsla (let [[h s l] (hex->hsl color)]
(str/fmt "hsla(%s, %s, %s, %s)" h (* 100 s) (* 100 l) opacity))
:hex (str color (str/upper (d/opacity-to-hex opacity))))
:else "transparent")))
(defn multiple? [{:keys [id file-id value color gradient]}]
(or (= value :multiple)
(= color :multiple)