0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-28 23:51:29 -05:00

🐛 Fix several bugs in comments (#5716)

* ♻️ Remove obsolete CSS code

* 🐛 Fix post a comment with keyboard

* 🐛 Fix show comments cursor on view mode

* 🐛 Fix avoid comment bubbles to appear on top of sidebars

* 🐛 Fix cancel native browser zoom when comment threads are visible
This commit is contained in:
luisδμ 2025-01-30 10:35:47 +01:00 committed by GitHub
parent 6be3285b52
commit 45059d73da
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 94 additions and 75 deletions

View file

@ -602,10 +602,42 @@
[:span {:class (stl/css :replies-unread)} (str unread-replies " " (tr "labels.reply.new"))] [:span {:class (stl/css :replies-unread)} (str unread-replies " " (tr "labels.reply.new"))]
[:span {:class (stl/css :replies-unread)} (str unread-replies " " (tr "labels.replies.new"))]))])]]) [:span {:class (stl/css :replies-unread)} (str unread-replies " " (tr "labels.replies.new"))]))])]])
(mf/defc comment-form-buttons*
{::mf/props :obj
::mf/private true}
[{:keys [on-submit on-cancel is-disabled]}]
(let [handle-cancel
(mf/use-fn
(mf/deps on-cancel)
(fn [event]
(when (kbd/enter? event)
(on-cancel))))
handle-submit
(mf/use-fn
(mf/deps on-submit)
(fn [event]
(when (kbd/enter? event)
(on-submit))))]
[:div {:class (stl/css :form-buttons-wrapper)}
[:> mentions-button*]
[:> button* {:variant "ghost"
:type "button"
:on-key-down handle-cancel
:on-click on-cancel}
(tr "ds.confirm-cancel")]
[:> button* {:variant "primary"
:type "button"
:on-key-down handle-submit
:on-click on-submit
:disabled is-disabled}
(tr "labels.post")]]))
(mf/defc comment-reply-form* (mf/defc comment-reply-form*
{::mf/props :obj {::mf/props :obj
::mf/private true} ::mf/private true}
[{:keys [thread]}] [{:keys [on-submit]}]
(let [show-buttons? (mf/use-state false) (let [show-buttons? (mf/use-state false)
content (mf/use-state "") content (mf/use-state "")
@ -628,11 +660,11 @@
#(do (reset! content "") #(do (reset! content "")
(reset! show-buttons? false))) (reset! show-buttons? false)))
on-submit on-submit*
(mf/use-fn (mf/use-fn
(mf/deps thread @content) (mf/deps @content)
(fn [] (fn []
(st/emit! (dcm/add-comment thread @content)) (on-submit @content)
(on-cancel)))] (on-cancel)))]
[:div {:class (stl/css :form)} [:div {:class (stl/css :form)}
@ -642,24 +674,20 @@
:autofocus true :autofocus true
:on-blur on-blur :on-blur on-blur
:on-focus on-focus :on-focus on-focus
:on-ctrl-enter on-submit :on-ctrl-enter on-submit*
:on-change on-change :on-change on-change
:max-length 750}] :max-length 750}]
(when (or @show-buttons? (seq @content)) (when (or @show-buttons? (seq @content))
[:div {:class (stl/css :form-buttons-wrapper)} [:> comment-form-buttons* {:on-submit on-submit*
[:> mentions-button*] :on-cancel on-cancel
[:> button* {:variant "ghost" :is-disabled disabled?}])]))
:on-click on-cancel}
(tr "ds.confirm-cancel")]
[:> button* {:variant "primary"
:on-click on-submit
:disabled disabled?}
(tr "labels.post")]])]))
(mf/defc comment-edit-form* (mf/defc comment-edit-form*
{::mf/private true} {::mf/private true}
[{:keys [content on-submit on-cancel]}] [{:keys [content on-submit on-cancel]}]
(let [content (mf/use-state content) (let [content (mf/use-state content)
disabled? (blank-content? @content)
on-change on-change
(mf/use-fn (mf/use-fn
@ -668,9 +696,7 @@
on-submit* on-submit*
(mf/use-fn (mf/use-fn
(mf/deps @content) (mf/deps @content)
(fn [] (on-submit @content))) (fn [] (on-submit @content)))]
disabled? (blank-content? @content)]
[:div {:class (stl/css :form)} [:div {:class (stl/css :form)}
[:> comment-input* [:> comment-input*
@ -679,15 +705,9 @@
:on-ctrl-enter on-submit* :on-ctrl-enter on-submit*
:on-change on-change :on-change on-change
:max-length 750}] :max-length 750}]
[:div {:class (stl/css :form-buttons-wrapper)} [:> comment-form-buttons* {:on-submit on-submit*
[:> mentions-button*] :on-cancel on-cancel
[:> button* {:variant "ghost" :is-disabled disabled?}]]))
:on-click on-cancel}
(tr "ds.confirm-cancel")]
[:> button* {:variant "primary"
:on-click on-submit*
:disabled disabled?}
(tr "labels.post")]]]))
(mf/defc comment-floating-thread-draft* (mf/defc comment-floating-thread-draft*
[{:keys [draft zoom on-cancel on-submit position-modifier]}] [{:keys [draft zoom on-cancel on-submit position-modifier]}]
@ -720,10 +740,11 @@
(fn [content] (fn [content]
(st/emit! (dcm/update-draft-thread {:content content})))) (st/emit! (dcm/update-draft-thread {:content content}))))
on-submit on-submit*
(mf/use-fn (mf/use-fn
(mf/deps draft) (mf/deps draft)
(partial on-submit draft))] (fn []
(on-submit draft)))]
[:> (mf/provider mentions-context) {:value mentions-s} [:> (mf/provider mentions-context) {:value mentions-s}
[:div [:div
@ -734,7 +755,7 @@
:on-click dom/stop-propagation} :on-click dom/stop-propagation}
[:> comment-avatar* {:class (stl/css :avatar-lg) [:> comment-avatar* {:class (stl/css :avatar-lg)
:image (cfg/resolve-profile-photo-url profile)}]] :image (cfg/resolve-profile-photo-url profile)}]]
[:div {:class (stl/css :floating-thread-wrapper) [:div {:class (stl/css :floating-thread-wrapper :cursor-auto)
:style {:top (str (- pos-y 24) "px") :style {:top (str (- pos-y 24) "px")
:left (str (+ pos-x 28) "px")} :left (str (+ pos-x 28) "px")}
:on-click dom/stop-propagation} :on-click dom/stop-propagation}
@ -745,19 +766,11 @@
:autofocus true :autofocus true
:on-esc on-esc :on-esc on-esc
:on-change on-change :on-change on-change
:on-ctrl-enter on-submit :on-ctrl-enter on-submit*
:max-length 750}] :max-length 750}]
[:> comment-form-buttons* {:on-submit on-submit*
[:div {:class (stl/css :form-buttons-wrapper)} :on-cancel on-esc
[:> mentions-button*] :is-disabled disabled?}]]
[:> button* {:variant "ghost"
:on-click on-esc}
(tr "ds.confirm-cancel")]
[:> button* {:variant "primary"
:on-click on-submit
:disabled disabled?}
(tr "labels.post")]]]
[:> mentions-panel*]]])) [:> mentions-panel*]]]))
(mf/defc comment-floating-thread-header* (mf/defc comment-floating-thread-header*
@ -935,7 +948,7 @@
{::mf/wrap [mf/memo]} {::mf/wrap [mf/memo]}
[{:keys [thread zoom origin position-modifier viewport]}] [{:keys [thread zoom origin position-modifier viewport]}]
(let [ref (mf/use-ref) (let [ref (mf/use-ref)
mentions-s (mf/use-memo #(rx/subject)) mentions-s (mf/use-memo #(rx/subject))
thread-id (:id thread) thread-id (:id thread)
thread-pos (:position thread) thread-pos (:position thread)
@ -962,7 +975,13 @@
(->> (vals comments-map) (->> (vals comments-map)
(sort-by :created-at))) (sort-by :created-at)))
first-comment (first comments)] first-comment (first comments)
on-submit
(mf/use-fn
(mf/deps thread)
(fn [content]
(st/emit! (dcm/add-comment thread content))))]
(mf/with-effect [thread-id] (mf/with-effect [thread-id]
(st/emit! (dcm/retrieve-comments thread-id))) (st/emit! (dcm/retrieve-comments thread-id)))
@ -977,6 +996,7 @@
[:> (mf/provider mentions-context) {:value mentions-s} [:> (mf/provider mentions-context) {:value mentions-s}
(when (some? first-comment) (when (some? first-comment)
[:div {:class (stl/css-case :floating-thread-wrapper true [:div {:class (stl/css-case :floating-thread-wrapper true
:cursor-auto true
:left (= (:h-dir pos) :left) :left (= (:h-dir pos) :left)
:top (= (:v-dir pos) :top)) :top (= (:v-dir pos) :top))
:id (str "thread-" thread-id) :id (str "thread-" thread-id)
@ -996,7 +1016,7 @@
[:* {:key (dm/str (:id item))} [:* {:key (dm/str (:id item))}
[:> comment-floating-thread-item* {:comment item}]])] [:> comment-floating-thread-item* {:comment item}]])]
[:> comment-reply-form* {:thread thread}] [:> comment-reply-form* {:on-submit on-submit}]
[:> mentions-panel*]])])) [:> mentions-panel*]])]))
@ -1112,11 +1132,13 @@
:on-pointer-leave on-pointer-leave :on-pointer-leave on-pointer-leave
:on-click on-click* :on-click on-click*
:class (stl/css-case :floating-preview-wrapper true :class (stl/css-case :floating-preview-wrapper true
:floating-preview-bubble (false? (:is-hover @state)) :floating-preview-bubble (false? (:is-hover @state)))}
:grabbing (true? (:is-grabbing @state)))}
(if (:is-hover @state) (if (:is-hover @state)
[:div {:class (stl/css :floating-thread-wrapper :floating-preview-displacement)} [:div {:class (stl/css-case :floating-thread-wrapper true
:floating-preview-displacement true
:cursor-pointer (false? (:is-grabbing @state))
:cursor-grabbing (true? (:is-grabbing @state)))}
[:div {:class (stl/css :floating-thread-item-wrapper)} [:div {:class (stl/css :floating-thread-item-wrapper)}
[:div {:class (stl/css :floating-thread-item)} [:div {:class (stl/css :floating-thread-item)}
[:> comment-info* {:item thread [:> comment-info* {:item thread

View file

@ -6,6 +6,18 @@
@import "refactor/common-refactor.scss"; @import "refactor/common-refactor.scss";
.cursor-grabbing {
cursor: grabbing;
}
.cursor-pointer {
cursor: pointer;
}
.cursor-auto {
cursor: auto;
}
.grayed-text { .grayed-text {
color: var(--comment-subtitle-color); color: var(--comment-subtitle-color);
} }
@ -137,10 +149,6 @@
margin-top: calc(-1 * ($s-8 + $s-2)); margin-top: calc(-1 * ($s-8 + $s-2));
} }
.grabbing {
cursor: grabbing;
}
.floating-thread-wrapper { .floating-thread-wrapper {
position: absolute; position: absolute;
display: flex; display: flex;
@ -231,23 +239,6 @@
flex-direction: column; flex-direction: column;
gap: $s-8; gap: $s-8;
max-height: calc(var(--comment-height) - $s-132); max-height: calc(var(--comment-height) - $s-132);
textarea {
@extend .input-element;
@include bodySmallTypography;
line-height: 1.45;
height: 100%;
width: 100%;
max-width: $s-260;
padding: $s-8;
margin-top: $s-4;
color: var(--input-foreground-color-active);
resize: vertical;
&:focus {
border: $s-1 solid var(--input-border-color-active);
outline: none;
}
}
} }
.form-buttons-wrapper { .form-buttons-wrapper {

View file

@ -21,6 +21,7 @@
[app.main.ui.components.dropdown :refer [dropdown]] [app.main.ui.components.dropdown :refer [dropdown]]
[app.main.ui.icons :as i] [app.main.ui.icons :as i]
[app.main.ui.workspace.comments :as wc] [app.main.ui.workspace.comments :as wc]
[app.main.ui.workspace.viewport.utils :as utils]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[okulary.core :as l] [okulary.core :as l]
@ -131,6 +132,8 @@
(let [profile (mf/deref refs/profile) (let [profile (mf/deref refs/profile)
local (mf/deref refs/comments-local) local (mf/deref refs/comments-local)
cursor (utils/get-cursor :comments)
open-thread-id (:open local) open-thread-id (:open local)
page-id (:id page) page-id (:id page)
file-id (:id file) file-id (:id file)
@ -203,7 +206,7 @@
[:div {:class (stl/css :comments-section) [:div {:class (stl/css :comments-section)
:on-click on-click} :on-click on-click}
[:div {:class (stl/css :viewer-comments-container)} [:div {:class (dm/str cursor " " (stl/css :viewer-comments-container))}
[:div {:class (stl/css :threads)} [:div {:class (stl/css :threads)}
(for [item threads] (for [item threads]
[:> cmt/comment-floating-bubble* [:> cmt/comment-floating-bubble*

View file

@ -24,6 +24,7 @@ $width-settings-bar-max: $s-500;
background-color: var(--panel-background-color); background-color: var(--panel-background-color);
height: 100vh; height: 100vh;
max-height: 100vh; max-height: 100vh;
z-index: $z-index-1;
.resize-area { .resize-area {
grid-area: resize; grid-area: resize;
@ -65,7 +66,7 @@ $width-settings-bar-max: $s-500;
height: 100vh; height: 100vh;
width: $width-settings-bar; width: $width-settings-bar;
background-color: var(--panel-background-color); background-color: var(--panel-background-color);
z-index: 0; z-index: $z-index-1;
&.not-expand { &.not-expand {
max-width: $width-settings-bar; max-width: $width-settings-bar;
} }

View file

@ -35,5 +35,5 @@
left: 0; left: 0;
bottom: 0; bottom: 0;
right: 0; right: 0;
z-index: 10; z-index: $z-index-1;
} }

View file

@ -376,9 +376,10 @@
(let [event (.getBrowserEvent ^js event) (let [event (.getBrowserEvent ^js event)
target (dom/get-target event) target (dom/get-target event)
mod? (kbd/mod? event) mod? (kbd/mod? event)
picking-color? (= "pixel-overlay" (.-id target))] picking-color? (= "pixel-overlay" (.-id target))
on-comments-layer? (dom/is-child? (dom/get-element "comments") target)]
(when (or (uwvv/inside-viewport? target) picking-color?) (when (or (uwvv/inside-viewport? target) picking-color? on-comments-layer?)
(dom/prevent-default event) (dom/prevent-default event)
(dom/stop-propagation event) (dom/stop-propagation event)
(let [raw-pt (dom/get-client-position event) (let [raw-pt (dom/get-client-position event)

View file

@ -77,7 +77,8 @@
[:div {:class (stl/css :comments-section)} [:div {:class (stl/css :comments-section)}
[:div [:div
{:class (stl/css :workspace-comments-container) {:id "comments"
:class (stl/css :workspace-comments-container)
:style {:width (dm/str vport-w "px") :style {:width (dm/str vport-w "px")
:height (dm/str vport-h "px")}} :height (dm/str vport-h "px")}}
[:div {:class (stl/css :threads) [:div {:class (stl/css :threads)