0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-17 10:11:22 -05:00

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

This commit is contained in:
Alejandro Alonso 2023-03-24 12:33:14 +01:00
commit 4fad2ab619
59 changed files with 608 additions and 325 deletions

View file

@ -22,6 +22,7 @@
- Allow for absolute positioned elements inside layout [Taiga #4834](https://tree.taiga.io/project/penpot/us/4834)
- Add z-index option for flex layout items [Taiga #2980](https://tree.taiga.io/project/penpot/us/2980)
- Scale content proportionally affects strokes, shadows, blurs and corners [Taiga #1951](https://tree.taiga.io/project/penpot/us/1951)
- Use tabulators to navigate layers [Taiga #5010](https://tree.taiga.io/project/penpot/issue/5010)
### :bug: Bugs fixed
@ -44,6 +45,27 @@
- Fix problem with board titles misplaced [Taiga #4738](https://tree.taiga.io/project/penpot/issue/4738)
- Fix problem with alt getting stuck when alt+tab [Taiga #5013](https://tree.taiga.io/project/penpot/issue/5013)
- Fix problem with z positioning of elements [Taiga #5014](https://tree.taiga.io/project/penpot/issue/5014)
- Fix problem in Firefox with scroll jumping when changin pages [#3052](https://github.com/penpot/penpot/issues/3052)
- Fix nested frame interaction created flow in wrong frame [Taiga #5043](https://tree.taiga.io/project/penpot/issue/5043)
- Font-Kerning does not work on Artboard Export to PNG/JPG/PDF [#3029](https://github.com/penpot/penpot/issues/3029)
- Fix manipulate duplicated project (delete, duplicate, rename, pin/unpin...) [Taiga #5027](https://tree.taiga.io/project/penpot/issue/5027)
- Fix deleted files appear in search results [Taiga #5002](https://tree.taiga.io/project/penpot/issue/5002)
- Fix problem with selected colors and texts [Taiga #5051](https://tree.taiga.io/project/penpot/issue/5051)
- Fix problem when assigning color from palette or assets [Taiga #5050](https://tree.taiga.io/project/penpot/issue/5050)
- Fix shortcuts for alignment [Taiga #5030](https://tree.taiga.io/project/penpot/issue/5030)
- Fix path options not showing when editing rects or ellipses [Taiga #5053](https://tree.taiga.io/project/penpot/issue/5053)
- Fix tooltips for some alignment options are truncated on design tab [Taiga #5040](https://tree.taiga.io/project/penpot/issue/5040)
- Fix horizontal margins drag don't always start from place [Taiga #5020](https://tree.taiga.io/project/penpot/issue/5020)
- Fix multiplayer username sometimes is not displayed correctly [Taiga #4400](https://tree.taiga.io/project/penpot/issue/4400)
- Show warning when trying to invite a user that is already in members [Taiga #4147](https://tree.taiga.io/project/penpot/issue/4147)
- Fix problem with text out of borders when changing from auto-width to fixed [Taiga #4308](https://tree.taiga.io/project/penpot/issue/4308)
- Fix header not showing when exiting fullscreen mode in viewer [Taiga #4244](https://tree.taiga.io/project/penpot/issue/4244)
- Fix visual problem in select options [Taiga #5028](https://tree.taiga.io/project/penpot/issue/5028)
- Forbid empty names for assets [Taiga #5056](https://tree.taiga.io/project/penpot/issue/5056)
- Select children after ungroup action [Taiga #4917](https://tree.taiga.io/project/penpot/issue/4917)
- Fix problem with guides not showing when moving over nested frames [Taiga #4905](https://tree.taiga.io/project/penpot/issue/4905)
- Fix change email and password for users signed in via social login [Taiga #4273](https://tree.taiga.io/project/penpot/issue/4273)
- Fix drag and drop files from browser or file explorer under circumstances [Taiga #5054](https://tree.taiga.io/project/penpot/issue/5054)
### :heart: Community contributions by (Thank you!)
- To @ondrejkonec: for contributing to the code with:

View file

@ -231,12 +231,13 @@
;; Defer all constraints
(db/exec-one! conn ["SET CONSTRAINTS ALL DEFERRED"])
(let [project (db/get-by-id conn :project project-id)
(let [project (-> (db/get-by-id conn :project project-id)
(assoc :is-pinned false))
files (db/query conn :file
{:project-id (:id project)
:deleted-at nil}
{:columns [:id]})
{:project-id (:id project)
:deleted-at nil}
{:columns [:id]})
project (cond-> project
(string? name)

View file

@ -113,7 +113,7 @@
(declare invalidate-profile-session!)
(s/def ::password ::us/not-empty-string)
(s/def ::old-password ::us/not-empty-string)
(s/def ::old-password (s/nilable ::us/string))
(s/def ::update-profile-password
(s/keys :req [::rpc/profile-id]
@ -145,7 +145,8 @@
(defn- validate-password!
[{:keys [::db/conn] :as cfg} {:keys [profile-id old-password] :as params}]
(let [profile (db/get-by-id conn :profile profile-id ::db/for-update? true)]
(when-not (:valid (verify-password cfg old-password (:password profile)))
(when (and (not= (:password profile) "!")
(not (:valid (verify-password cfg old-password (:password profile)))))
(ex/raise :type :validation
:code :old-password-not-match))
profile))

View file

@ -45,6 +45,7 @@
from file as f
inner join projects as pr on (f.project_id = pr.id)
where f.name ilike ('%' || ? || '%')
and (f.deleted_at is null or f.deleted_at > now())
order by f.created_at asc")
(defn search-files

View file

@ -31,7 +31,7 @@
(s/def ::path ::us/string)
(s/def ::profile-id ::us/uuid)
(s/def ::password ::us/not-empty-string)
(s/def ::old-password ::us/not-empty-string)
(s/def ::old-password (s/nilable ::us/string))
(s/def ::theme ::us/string)
;; --- MUTATION: Update Profile (own)

View file

@ -382,10 +382,11 @@
(defn update-group-selrect
[group children]
(let [shape-center (gco/center-shape group)
;; Points for every shape inside the group
(let [;; Points for every shape inside the group
points (->> children (mapcat :points))
shape-center (gco/center-points points)
;; Fixed problem with empty groups. Should not happen (but it does)
points (if (empty? points) (:points group) points)

View file

@ -37,8 +37,10 @@
(= type :frame)))
(defn group-shape?
[{:keys [type]}]
(= type :group))
([objects id]
(group-shape? (get objects id)))
([{:keys [type]}]
(= type :group)))
(defn mask-shape?
[{:keys [type masked-group?]}]
@ -171,6 +173,25 @@
(get objects)
(get-frame objects)))))
(defn get-root-frame
[objects shape-id]
(let [frame-id
(if (frame-shape? objects shape-id)
shape-id
(dm/get-in objects [shape-id :frame-id]))
frame (get objects frame-id)]
(cond
(or (root? frame) (nil? frame))
nil
(root-frame? frame)
frame
:else
(get-root-frame objects (:frame-id frame)))))
(defn valid-frame-target?
[objects parent-id shape-id]
(let [shape (get objects shape-id)]

View file

@ -100,7 +100,8 @@
(def browser-pool-factory
(letfn [(create []
(p/let [browser (.launch pw/chromium)
(p/let [opts #js {:args #js ["--font-render-hinting=none"]}
browser (.launch pw/chromium opts)
id (swap! pool-browser-id inc)]
(l/info :origin "factory" :action "create" :browser-id id)
(unchecked-set browser "__id" id)

View file

@ -1,29 +1,46 @@
/*
MIT License
Copyright (c) 2021 Tobias Buschor
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
// Polyfill for `scrollIntoViewIfNeeded` function not existing in Firefox.
// https://github.com/nuxodin/lazyfill
;(function() {
if (!Element.prototype.scrollIntoViewIfNeeded) {
Element.prototype.scrollIntoViewIfNeeded = function (centerIfNeeded) {
centerIfNeeded = arguments.length === 0 ? true : !!centerIfNeeded;
var parent = this.parentNode;
if (parent) {
var parentComputedStyle = window.getComputedStyle(parent, null),
parentBorderTopWidth = parseInt(parentComputedStyle.getPropertyValue('border-top-width')),
parentBorderLeftWidth = parseInt(parentComputedStyle.getPropertyValue('border-left-width')),
overTop = this.offsetTop - parent.offsetTop < parent.scrollTop,
overBottom = (this.offsetTop - parent.offsetTop + this.clientHeight - parentBorderTopWidth) > (parent.scrollTop + parent.clientHeight),
overLeft = this.offsetLeft - parent.offsetLeft < parent.scrollLeft,
overRight = (this.offsetLeft - parent.offsetLeft + this.clientWidth - parentBorderLeftWidth) > (parent.scrollLeft + parent.clientWidth),
alignWithTop = overTop && !overBottom;
if ((overTop || overBottom) && centerIfNeeded) {
parent.scrollTop = this.offsetTop - parent.offsetTop - parent.clientHeight / 2 - parentBorderTopWidth + this.clientHeight / 2;
Element.prototype.scrollIntoViewIfNeeded = function ( centerIfNeeded = true ) {
const el = this;
new IntersectionObserver( function( [entry] ) {
const ratio = entry.intersectionRatio;
if (ratio < 1) {
let place = ratio <= 0 && centerIfNeeded ? 'center' : 'nearest';
el.scrollIntoView( {
block: place,
inline: place,
} );
}
if ((overLeft || overRight) && centerIfNeeded) {
parent.scrollLeft = this.offsetLeft - parent.offsetLeft - parent.clientWidth / 2 - parentBorderLeftWidth + this.clientWidth / 2;
}
if ((overTop || overBottom || overLeft || overRight) && !centerIfNeeded) {
this.scrollIntoView(alignWithTop);
}
}
this.disconnect();
} ).observe(this);
};
}
})()

View file

@ -97,12 +97,11 @@
fill: $color-gray-20;
}
.error {
background-color: #ffd9e0;
.error,
.warning {
width: 100%;
display: flex;
.icon {
background-color: $color-danger;
text-align: center;
padding: 5px;
svg {
@ -118,6 +117,22 @@
font-size: $fs12;
}
}
.error {
background-color: #ffd9e0;
.icon {
background-color: $color-danger;
}
}
.warning {
background-color: #ffeaca;
.icon {
background-color: $color-warning;
}
}
}
.dashboard-team-members,

View file

@ -270,6 +270,9 @@ textarea {
&.invalid {
border: 1px solid $color-danger;
}
&.caution {
border: 1px solid $color-warning;
}
.text {
display: inline-block;

View file

@ -195,6 +195,10 @@
}
.input-select {
/* This padding is so the text won't overlap the arrow*/
padding-right: 1rem;
overflow: hidden;
text-overflow: ellipsis;
color: $color-gray-10;
&:focus {

View file

@ -279,15 +279,19 @@
(->
(assoc-in (conj path :position) (:position comment-thread))
(assoc-in (conj path :frame-id) (:frame-id comment-thread))))))
(fetched [data state]
(let [state (assoc state :comment-threads (d/index-by :id data))]
(reduce set-comment-threds state data)))]
(fetched [[users comments] state]
(let [state (-> state
(assoc :comment-threads (d/index-by :id comments))
(assoc :current-file-comments-users (d/index-by :id users)))]
(reduce set-comment-threds state comments)))]
(ptk/reify ::retrieve-comment-threads
ptk/WatchEvent
(watch [_ state _]
(let [share-id (-> state :viewer-local :share-id)]
(->> (rp/cmd! :get-comment-threads {:file-id file-id :share-id share-id})
(->> (rx/zip (rp/cmd! :get-team-users {:file-id file-id})
(rp/cmd! :get-comment-threads {:file-id file-id :share-id share-id}))
(rx/take 1)
(rx/map #(partial fetched %))
(rx/catch #(rx/throw {:type :comment-error}))))))))

View file

@ -7,7 +7,7 @@
(ns app.main.data.shortcuts
(:refer-clojure :exclude [meta reset!])
(:require
["mousetrap" :as mousetrap]
["./shortcuts_impl.js$default" :as mousetrap]
[app.common.logging :as log]
[app.common.spec :as us]
[app.config :as cf]
@ -32,6 +32,7 @@
(def up-arrow "\u2191")
(def right-arrow "\u2192")
(def down-arrow "\u2193")
(def tab "tab")
(defn c-mod
"Adds the control/command modifier to a shortcuts depending on the

View file

@ -0,0 +1,27 @@
/**
* 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
*/
"use strict";
import Mousetrap from 'mousetrap'
const target = Mousetrap.prototype || Mousetrap;
target.stopCallback = function(e, element, combo) {
// if the element has the class "mousetrap" then no need to stop
if ((' ' + element.className + ' ').indexOf(' mousetrap ') > -1) {
return false;
}
// stop for input, select, textarea and button
return element.tagName == 'INPUT' ||
element.tagName == 'SELECT' ||
element.tagName == 'TEXTAREA' ||
element.tagName == 'BUTTON' ||
(element.contentEditable && element.contentEditable == 'true');
}
export default Mousetrap;

View file

@ -37,7 +37,7 @@
(s/def ::created-at ::us/inst)
(s/def ::password-1 ::us/string)
(s/def ::password-2 ::us/string)
(s/def ::password-old ::us/string)
(s/def ::password-old (s/nilable ::us/string))
(s/def ::profile
(s/keys :req-un [::id]

View file

@ -300,6 +300,13 @@
(update [_ state]
(update-in state [:viewer-local :fullscreen?] not))))
(defn exit-fullscreen
[]
(ptk/reify ::exit-fullscreen
ptk/UpdateEvent
(update [_ state]
(assoc-in state [:viewer-local :fullscreen?] false))))
(defn set-viewport-size
[{:keys [size]}]
(ptk/reify ::set-viewport-size

View file

@ -2043,6 +2043,8 @@
(dm/export dws/select-all)
(dm/export dws/select-inside-group)
(dm/export dws/select-shape)
(dm/export dws/select-prev-shape)
(dm/export dws/select-next-shape)
(dm/export dws/shift-select-shapes)
;; Highlight

View file

@ -8,6 +8,7 @@
(:require
[app.common.colors :as colors]
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.pages.helpers :as cph]
[app.main.broadcast :as mbc]
[app.main.data.modal :as md]
@ -81,6 +82,8 @@
text-ids (filter is-text? ids)
shape-ids (remove is-text? ids)
undo-id (js/Symbol)
attrs
(cond-> {}
(contains? color :color)
@ -104,8 +107,10 @@
transform-attrs #(transform % attrs)]
(rx/concat
(rx/of (dwu/start-undo-transaction undo-id))
(rx/from (map #(dwt/update-text-with-function % transform-attrs) text-ids))
(rx/of (dch/update-shapes shape-ids transform-attrs)))))
(rx/of (dch/update-shapes shape-ids transform-attrs))
(rx/of (dwu/commit-undo-transaction undo-id)))))
(defn swap-attrs [shape attr index new-index]
(let [first (get-in shape [attr index])
@ -339,7 +344,8 @@
(defn change-text-color
[old-color new-color index node]
(let [fills (map #(dissoc % :fill-color-ref-id :fill-color-ref-file) (:fills node))
parsed-color (d/without-nils (color-att->text old-color))
parsed-color (-> (d/without-nils (color-att->text old-color))
(dissoc :fill-color-ref-id :fill-color-ref-file))
parsed-new-color (d/without-nils (color-att->text new-color))
has-color? (d/index-of fills parsed-color)]
(cond-> node
@ -365,23 +371,33 @@
(rx/of (dwu/commit-undo-transaction undo-id)))))))
(defn apply-color-from-palette
[color is-alt?]
[color stroke?]
(ptk/reify ::apply-color-from-palette
ptk/WatchEvent
(watch [_ state _]
(let [objects (wsh/lookup-page-objects state)
selected (->> (wsh/lookup-selected state)
(cph/clean-loops objects))
selected-obj (keep (d/getf objects) selected)
select-shapes-for-color (fn [shape objects]
(let [shapes (case (:type shape)
:group (cph/get-children objects (:id shape))
[shape])]
(->> shapes
(remove cph/group-shape?)
(map :id))))
ids (mapcat #(select-shapes-for-color % objects) selected-obj)]
(if is-alt?
ids
(loop [pending (seq selected)
result []]
(if (empty? pending)
result
(let [cur (first pending)
;; We treat frames with no fill the same as groups
group? (or (cph/group-shape? objects cur)
(and (cph/frame-shape? objects cur)
(empty? (dm/get-in objects [cur :fills]))))
pending
(if group?
(concat pending (dm/get-in objects [cur :shapes]))
pending)
result (cond-> result (not group?) (conj cur))]
(recur (rest pending) result))))]
(if stroke?
(rx/of (change-stroke ids (merge uc/empty-color color) 0))
(rx/of (change-fill ids (merge uc/empty-color color) 0)))))))

View file

@ -7,6 +7,7 @@
(ns app.main.data.workspace.groups
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.geom.shapes :as gsh]
[app.common.pages.changes-builder :as pcb]
[app.common.pages.helpers :as cph]
@ -195,6 +196,11 @@
(keep :id))
selected)
child-ids
(into (d/ordered-set)
(mapcat #(dm/get-in objects [% :shapes]))
selected)
changes {:redo-changes (vec (mapcat :redo-changes changes-list))
:undo-changes (vec (mapcat :undo-changes changes-list))
:origin it}
@ -203,7 +209,8 @@
(rx/of (dwu/start-undo-transaction undo-id)
(dch/commit-changes changes)
(ptk/data-event :layout/update parents)
(dwu/commit-undo-transaction undo-id))))))
(dwu/commit-undo-transaction undo-id)
(dws/select-shapes child-ids))))))
(def mask-group
(ptk/reify ::mask-group

View file

@ -112,7 +112,7 @@
(watch [_ state _]
(let [page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
frame (cph/get-frame objects shape)
frame (cph/get-root-frame objects (:id shape))
flows (get-in state [:workspace-data
:pages-index
page-id

View file

@ -176,10 +176,11 @@
(ptk/reify ::rename-color
ptk/WatchEvent
(watch [it state _]
(let [data (get state :workspace-data)
object (get-in data [:colors id])
new-object (assoc object :name new-name)]
(do-update-color it state new-object file-id)))))
(when (and (some? new-name) (not= "" new-name))
(let [data (get state :workspace-data)
object (get-in data [:colors id])
new-object (assoc object :name new-name)]
(do-update-color it state new-object file-id))))))
(defn delete-color
[{:keys [id] :as params}]
@ -211,14 +212,15 @@
(ptk/reify ::rename-media
ptk/WatchEvent
(watch [it state _]
(let [data (get state :workspace-data)
[path name] (cph/parse-path-name new-name)
object (get-in data [:media id])
new-object (assoc object :path path :name name)
changes (-> (pcb/empty-changes it)
(pcb/with-library-data data)
(pcb/update-media new-object))]
(rx/of (dch/commit-changes changes))))))
(when (and (some? new-name) (not= "" new-name))
(let [data (get state :workspace-data)
[path name] (cph/parse-path-name new-name)
object (get-in data [:media id])
new-object (assoc object :path path :name name)
changes (-> (pcb/empty-changes it)
(pcb/with-library-data data)
(pcb/update-media new-object))]
(rx/of (dch/commit-changes changes)))))))
(defn delete-media
@ -281,11 +283,12 @@
(ptk/reify ::rename-typography
ptk/WatchEvent
(watch [it state _]
(let [data (get state :workspace-data)
[path name] (cph/parse-path-name new-name)
object (get-in data [:typographies id])
new-object (assoc object :path path :name name)]
(do-update-tipography it state new-object file-id)))))
(when (and (some? new-name) (not= "" new-name))
(let [data (get state :workspace-data)
[path name] (cph/parse-path-name new-name)
object (get-in data [:typographies id])
new-object (assoc object :path path :name name)]
(do-update-tipography it state new-object file-id))))))
(defn delete-typography
[id]
@ -342,27 +345,28 @@
(ptk/reify ::rename-component
ptk/WatchEvent
(watch [it state _]
(let [data (get state :workspace-data)
[path name] (cph/parse-path-name new-name)
(when (and (some? new-name) (not= "" new-name))
(let [data (get state :workspace-data)
[path name] (cph/parse-path-name new-name)
update-fn
(fn [component]
;; NOTE: we need to ensure the component exists,
;; because there are small possibilities of race
;; conditions with component deletion.
(when component
(-> component
(assoc :path path)
(assoc :name name)
(update :objects
;; Give the same name to the root shape
#(assoc-in % [id :name] name)))))
update-fn
(fn [component]
;; NOTE: we need to ensure the component exists,
;; because there are small possibilities of race
;; conditions with component deletion.
(when component
(-> component
(assoc :path path)
(assoc :name name)
(update :objects
;; Give the same name to the root shape
#(assoc-in % [id :name] name)))))
changes (-> (pcb/empty-changes it)
(pcb/with-library-data data)
(pcb/update-component id update-fn))]
changes (-> (pcb/empty-changes it)
(pcb/with-library-data data)
(pcb/update-component id update-fn))]
(rx/of (dch/commit-changes changes))))))
(rx/of (dch/commit-changes changes)))))))
(defn duplicate-component
"Create a new component copied from the one with the given id."

View file

@ -131,6 +131,55 @@
objects (wsh/lookup-page-objects state page-id)]
(rx/of (dwc/expand-all-parents [id] objects)))))))
(defn select-prev-shape
([]
(ptk/reify ::select-prev-shape
ptk/WatchEvent
(watch [_ state _]
(let [selected (wsh/lookup-selected state)
count-selected (count selected)
first-selected (first selected)
page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
current (get objects first-selected)
parent (get objects (:parent-id current))
sibling-ids (:shapes parent)
current-index (d/index-of sibling-ids first-selected)
sibling (if (= (dec (count sibling-ids)) current-index)
(first sibling-ids)
(nth sibling-ids (inc current-index)))]
(cond
(= 1 count-selected)
(rx/of (select-shape sibling))
(> count-selected 1)
(rx/of (select-shape first-selected))))))))
(defn select-next-shape
([]
(ptk/reify ::select-next-shape
ptk/WatchEvent
(watch [_ state _]
(let [selected (wsh/lookup-selected state)
count-selected (count selected)
first-selected (first selected)
page-id (:current-page-id state)
objects (wsh/lookup-page-objects state page-id)
current (get objects first-selected)
parent (get objects (:parent-id current))
sibling-ids (:shapes parent)
current-index (d/index-of sibling-ids first-selected)
sibling (if (= 0 current-index)
(last sibling-ids)
(nth sibling-ids (dec current-index)))]
(cond
(= 1 count-selected)
(rx/of (select-shape sibling))
(> count-selected 1)
(rx/of (select-shape first-selected))))))))
(defn deselect-shape
[id]
(us/verify ::us/uuid id)
@ -140,13 +189,14 @@
(update-in state [:workspace-local :selected] disj id))))
(defn shift-select-shapes
([id] (shift-select-shapes id nil))
([id]
(shift-select-shapes id nil))
([id objects]
(ptk/reify ::shift-select-shapes
ptk/UpdateEvent
(update [_ state]
(let [page-id (:current-page-id state)
objects (or objects (wsh/lookup-page-objects state page-id))
(let [objects (or objects (wsh/lookup-page-objects state))
selection (-> state
wsh/lookup-selected
(conj id))]

View file

@ -67,8 +67,8 @@
:cut {:tooltip (ds/meta "X")
:command (ds/c-mod "x")
:subsections [:edit]
:fn #(emit-when-no-readonly (dw/copy-selected)
(dw/delete-selected))}
:fn #(emit-when-no-readonly (dw/copy-selected)
(dw/delete-selected))}
:paste {:tooltip (ds/meta "V")
:disabled true
@ -110,7 +110,7 @@
;; MODIFY LAYERS
:group {:tooltip (ds/meta "G")
:command (ds/c-mod "g")
@ -222,7 +222,7 @@
:fn #(emit-when-no-readonly (dwsl/toggle-layout-flex))}
;; TOOLS
:draw-frame {:tooltip "B"
:command ["b" "a"]
:subsections [:tools :basics]
@ -247,7 +247,7 @@
:command "t"
:subsections [:tools]
:fn #(emit-when-no-readonly dwtxt/start-edit-if-selected
(dwd/select-for-drawing :text))}
(dwd/select-for-drawing :text))}
:draw-path {:tooltip "P"
:command "p"
@ -300,7 +300,7 @@
:fn #(emit-when-no-readonly (dw/toggle-focus-mode))}
;; ITEM ALIGNMENT
:align-left {:tooltip (ds/alt "A")
:command "alt+a"
:subsections [:alignment]
@ -342,7 +342,7 @@
:fn #(emit-when-no-readonly (dw/distribute-objects :vertical))}
;; MAIN MENU
:toggle-rules {:tooltip (ds/meta-shift "R")
:command (ds/c-mod "shift+r")
:subsections [:main-menu]
@ -387,7 +387,7 @@
:command (ds/c-mod "shift+e")
:subsections [:basics :main-menu]
:fn #(st/emit!
(de/show-workspace-export-dialog))}
(de/show-workspace-export-dialog))}
:toggle-snap-guide {:tooltip (ds/meta-shift "G")
:command (ds/c-mod "shift+g")
@ -400,7 +400,7 @@
:fn #(st/emit! (toggle-layout-flag :shortcuts))}
;; PANELS
:toggle-layers {:tooltip (ds/alt "L")
:command (ds/a-mod "l")
:subsections [:panels]
@ -420,15 +420,15 @@
:command (ds/a-mod "p")
:subsections [:panels]
:fn #(do (r/set-resize-type! :bottom)
(emit-when-no-readonly (dw/remove-layout-flag :textpalette)
(toggle-layout-flag :colorpalette)))}
(emit-when-no-readonly (dw/remove-layout-flag :textpalette)
(toggle-layout-flag :colorpalette)))}
:toggle-textpalette {:tooltip (ds/alt "T")
:command (ds/a-mod "t")
:subsections [:panels]
:fn #(do (r/set-resize-type! :bottom)
(emit-when-no-readonly (dw/remove-layout-flag :colorpalette)
(toggle-layout-flag :textpalette)))}
(emit-when-no-readonly (dw/remove-layout-flag :colorpalette)
(toggle-layout-flag :textpalette)))}
:hide-ui {:tooltip "\\"
:command "\\"
@ -436,7 +436,7 @@
:fn #(st/emit! (toggle-layout-flag :hide-ui))}
;; ZOOM-WORKSPACE
:increase-zoom {:tooltip "+"
:command ["+" "="]
:subsections [:zoom-workspace]
@ -473,7 +473,7 @@
:fn identity}
;; NAVIGATION
:open-viewer {:tooltip "G V"
:command "g v"
@ -495,7 +495,18 @@
:subsections [:navigation-workspace]
:fn #(st/emit! (dw/go-to-dashboard))}
:select-prev {:tooltip (ds/shift "tab")
:command "shift+tab"
:subsections [:navigation-workspace]
:fn #(st/emit! (dw/select-prev-shape))}
:select-next {:tooltip ds/tab
:command "tab"
:subsections [:navigation-workspace]
:fn #(st/emit! (dw/select-next-shape))}
;; SHAPE
:bool-union {:tooltip (ds/meta (ds/alt "U"))
:command (ds/c-mod "alt+u")

View file

@ -202,22 +202,22 @@
(st/emit! (dwu/commit-undo-transaction undo-id)))))
(def shortcuts
{:align-left {:tooltip (ds/meta (ds/alt "l"))
:command (ds/c-mod "alt+l")
:subsections [:text-editor]
:fn #(update-attrs-when-no-readonly {:text-align "left"})}
:align-right {:tooltip (ds/meta (ds/alt "r"))
:command (ds/c-mod "alt+r")
:subsections [:text-editor]
:fn #(update-attrs-when-no-readonly {:text-align "right"})}
:align-center {:tooltip (ds/meta (ds/alt "t"))
:command (ds/c-mod "alt+t")
:subsections [:text-editor]
:fn #(update-attrs-when-no-readonly {:text-align "center"})}
:align-justify {:tooltip (ds/meta (ds/alt "j"))
:command (ds/c-mod "alt+j")
:subsections [:text-editor]
:fn #(update-attrs-when-no-readonly {:text-align "justify"})}
{:text-align-left {:tooltip (ds/meta (ds/alt "l"))
:command (ds/c-mod "alt+l")
:subsections [:text-editor]
:fn #(update-attrs-when-no-readonly {:text-align "left"})}
:text-align-right {:tooltip (ds/meta (ds/alt "r"))
:command (ds/c-mod "alt+r")
:subsections [:text-editor]
:fn #(update-attrs-when-no-readonly {:text-align "right"})}
:text-align-center {:tooltip (ds/meta (ds/alt "t"))
:command (ds/c-mod "alt+t")
:subsections [:text-editor]
:fn #(update-attrs-when-no-readonly {:text-align "center"})}
:text-align-justify {:tooltip (ds/meta (ds/alt "j"))
:command (ds/c-mod "alt+j")
:subsections [:text-editor]
:fn #(update-attrs-when-no-readonly {:text-align "justify"})}
:underline {:tooltip (ds/meta "u")
:command (ds/c-mod "u")

View file

@ -251,7 +251,7 @@
(into [] (distinct) (conj coll item)))
(mf/defc multi-input
[{:keys [form label class name trim valid-item-fn on-submit] :as props}]
[{:keys [form label class name trim valid-item-fn caution-item-fn on-submit] :as props}]
(let [form (or form (mf/use-ctx form-ctx))
input-name (get props :name)
touched? (get-in @form [:touched input-name])
@ -309,7 +309,9 @@
(on-submit form))
(when (not (str/empty? @value))
(reset! value "")
(swap! items conj-dedup {:text val :valid (valid-item-fn val)}))))
(swap! items conj-dedup {:text val
:valid (valid-item-fn val)
:caution (caution-item-fn val)}))))
(and (kbd/backspace? event)
(str/empty? @value))
@ -361,6 +363,7 @@
[:div.selected-item {:key (:text item)
:tab-index "0"
:on-key-down (partial manage-key-down item)}
[:span.around {:class (when-not (:valid item) "invalid")}
[:span.around {:class (dom/classnames "invalid" (not (:valid item))
"caution" (:caution item))}
[:span.text (:text item)]
[:span.icon {:on-click #(remove-item! item)} i/cross]]])])]))

View file

@ -59,7 +59,8 @@
(assert (fn? on-edit) "missing `on-edit` prop")
(assert (fn? on-menu-close) "missing `on-menu-close` prop")
(assert (boolean? navigate?) "missing `navigate?` prop")
(let [is-lib-page? (= :libraries origin)
(let [is-lib-page? (= :libraries origin)
is-search-page? (= :search origin)
top (or top 0)
left (or left 0)
@ -264,28 +265,30 @@
[{:option-name (tr "dashboard.open-in-new-tab")
:id "file-open-new-tab"
:option-handler on-new-tab}
{:option-name (tr "labels.rename")
:id "file-rename"
:option-handler on-edit
:data-test "file-rename"}
{:option-name (tr "dashboard.duplicate")
:id "file-duplicate"
:option-handler on-duplicate
:data-test "file-duplicate"}
(when (and (not is-lib-page?) (or (seq current-projects) (seq other-teams)))
(when (not is-search-page?)
{:option-name (tr "labels.rename")
:id "file-rename"
:option-handler on-edit
:data-test "file-rename"}
{:option-name (tr "dashboard.duplicate")
:id "file-duplicate"
:option-handler on-duplicate
:data-test "file-duplicate"})
(when (and (not is-lib-page?) (not is-search-page?) (or (seq current-projects) (seq other-teams)))
{:option-name (tr "dashboard.move-to")
:id "file-move-to"
:sub-options sub-options
:data-test "file-move-to"})
(if (:is-shared file)
{:option-name (tr "dashboard.unpublish-shared")
:id "file-del-shared"
:option-handler on-del-shared
:data-test "file-del-shared"}
{:option-name (tr "dashboard.add-shared")
:id "file-add-shared"
:option-handler on-add-shared
:data-test "file-add-shared"})
(when (not is-search-page?)
(if (:is-shared file)
{:option-name (tr "dashboard.unpublish-shared")
:id "file-del-shared"
:option-handler on-del-shared
:data-test "file-del-shared"}
{:option-name (tr "dashboard.add-shared")
:id "file-add-shared"
:option-handler on-add-shared
:data-test "file-add-shared"}))
{:option-name :separator}
{:option-name (tr "dashboard.download-binary-file")
:id "file-download-binary"
@ -295,7 +298,7 @@
:id "file-download-standard"
:option-handler on-export-standard-files
:data-test "download-standard-file"}
(when (not is-lib-page?)
(when (and (not is-lib-page?) (not is-search-page?))
{:option-name :separator}
{:option-name (tr "labels.delete")
:id "file-delete"

View file

@ -87,4 +87,5 @@
:else
[:& grid {:files result
:hide-new? true
:origin :search
:limit limit}])]]))

View file

@ -39,7 +39,9 @@
go-webhooks (mf/use-fn #(st/emit! (dd/go-to-team-webhooks)))
invite-member (mf/use-fn
(mf/deps team)
#(st/emit! (modal/show {:type :invite-members :team team :origin :team})))
#(st/emit! (modal/show {:type :invite-members
:team team
:origin :team})))
members-section? (= section :dashboard-team-members)
settings-section? (= section :dashboard-team-settings)
@ -98,7 +100,10 @@
{::mf/register modal/components
::mf/register-as :invite-members}
[{:keys [team origin]}]
(let [perms (:permissions team)
(let [members-map (mf/deref refs/dashboard-team-members)
perms (:permissions team)
roles (mf/use-memo (mf/deps perms) #(get-available-roles perms))
initial (mf/use-memo (constantly {:role "editor" :team-id (:id team)}))
form (fm/use-form :spec ::invite-member-form
@ -111,6 +116,9 @@
(modal/hide)
(dd/fetch-team-invitations)))
current-data-emails (into #{} (dm/get-in @form [:clean-data :emails]))
current-members-emails (into #{} (map (comp :email second)) members-map)
on-error
(fn [{:keys [type code] :as error}]
(cond
@ -148,17 +156,23 @@
[:div.error
[:span.icon i/msg-error]
[:span.text @error-text]])
(when (some current-data-emails current-members-emails)
[:div.warning
[:span.icon i/msg-warning]
[:span.text (tr "modals.invite-member.repeated-invitation")]])
[:div.form-row
[:p.label (tr "onboarding.choice.team-up.roles")]
[:& fm/select {:name :role :options roles}]]
[:div.form-row
[:& fm/multi-input {:type "email"
:name :emails
:auto-focus? true
:trim true
:valid-item-fn us/parse-email
:caution-item-fn current-members-emails
:label (tr "modals.invite-member.emails")
:on-submit on-submit}]]

View file

@ -307,7 +307,7 @@
on-pointer-down
(mf/use-callback
(mf/deps frame-id padding-num)
(mf/deps frame-id rect-data padding-num)
(fn [event]
(dom/capture-pointer event)
(reset! resizing? true)
@ -382,9 +382,9 @@
pill-width (/ flex-display-pill-width zoom)
pill-height (/ flex-display-pill-height zoom)
hover? #(or hover-all?
(and (or (= % :p1) (= % :p3)) hover-v?)
(and (or (= % :p2) (= % :p4)) hover-h?)
(= @hover %))
(and (or (= % :p1) (= % :p3)) hover-v?)
(and (or (= % :p2) (= % :p4)) hover-h?)
(= @hover %))
negate {:p1 (if (:flip-y frame) true false)
:p2 (if (:flip-x frame) true false)
:p3 (if (:flip-y frame) true false)
@ -854,9 +854,9 @@
(mf/defc padding
[{:keys [frame zoom alt? shift?]}]
(when frame
[:g.measurement-gaps {:pointer-events "none"}
[:g.hover-shapes
[:& padding-rects {:frame frame :zoom zoom :alt? alt? :shift? shift?}]]]))
[:g.measurement-gaps {:pointer-events "none"}
[:g.hover-shapes
[:& padding-rects {:frame frame :zoom zoom :alt? alt? :shift? shift?}]]]))
(mf/defc gap
[{:keys [frame zoom]}]

View file

@ -32,7 +32,10 @@
(defn- on-success
[form]
(reset! form nil)
(let [msg (tr "dashboard.notifications.password-saved")]
(let [password-old-node (dom/get-element "password-old")
msg (tr "dashboard.notifications.password-saved")]
(dom/clean-value! password-old-node)
(dom/focus! password-old-node)
(st/emit! (dm/success msg))))
(defn- on-submit
@ -45,7 +48,7 @@
(s/def ::password-1 ::us/not-empty-string)
(s/def ::password-2 ::us/not-empty-string)
(s/def ::password-old ::us/not-empty-string)
(s/def ::password-old (s/nilable ::us/string))
(defn- password-equality
[errors data]
@ -66,9 +69,10 @@
(mf/defc password-form
[{:keys [locale] :as props}]
(let [form (fm/use-form :spec ::password-form
:validators [password-equality]
:initial {})]
(let [initial (mf/use-memo (constantly {:password-old nil}))
form (fm/use-form :spec ::password-form
:validators [password-equality]
:initial initial)]
[:& fm/form {:class "password-form"
:on-submit on-submit
:form form}
@ -77,6 +81,7 @@
[:& fm/input
{:type "password"
:name :password-old
:auto-focus? true
:label (t locale "labels.old-password")}]]
[:div.fields-row

View file

@ -5,6 +5,7 @@
;; Copyright (c) KALEIDOS INC
(ns app.main.ui.viewer
(:import goog.events.EventType)
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
@ -33,6 +34,7 @@
[app.main.ui.viewer.thumbnails :refer [thumbnails-panel]]
[app.util.dom :as dom]
[app.util.dom.normalize-wheel :as nw]
[app.util.globals :as globals]
[app.util.i18n :as i18n :refer [tr]]
[app.util.keyboard :as kbd]
[app.util.webapi :as wapi]
@ -328,7 +330,13 @@
(dom/stop-propagation event)
(if shift?
(dom/set-h-scroll-pos! viewer-section new-scroll-pos)
(dom/set-scroll-pos! viewer-section new-scroll-pos)))))))]
(dom/set-scroll-pos! viewer-section new-scroll-pos)))))))
on-exit-fullscreen
(mf/use-callback
(fn []
(when (not (dom/fullscreen?))
(st/emit! (dv/exit-fullscreen)))))]
(hooks/use-shortcuts ::viewer sc/shortcuts)
(when (nil? page)
@ -346,11 +354,20 @@
(dom/set-html-title (str "\u25b6 " (tr "title.viewer" name))))))
(mf/with-effect []
(let [key1 (events/listen js/window "click" on-click)
key2 (events/listen (mf/ref-val viewer-section-ref) "wheel" on-wheel #js {"passive" false})]
(dom/set-html-theme-color clr/gray-50 "dark")
(let [events
[(events/listen globals/window EventType.CLICK on-click)
(events/listen (mf/ref-val viewer-section-ref) EventType.WHEEL on-wheel #js {"passive" false})]]
(doseq [event dom/fullscreen-events]
(.addEventListener globals/document event on-exit-fullscreen false))
(fn []
(events/unlistenByKey key1)
(events/unlistenByKey key2))))
(doseq [key events]
(events/unlistenByKey key))
(doseq [event dom/fullscreen-events]
(.removeEventListener globals/document event on-exit-fullscreen)))))
(mf/use-effect
(fn []

View file

@ -234,10 +234,11 @@
;; When we have a text with grow-type :auto-height or :auto-height we need to check the correct height
;; otherwise the center alignment will break
tr-shape (when text-modifier (dwt/apply-text-modifier shape text-modifier))
shape (cond-> shape
(and (some? text-modifier) (#{:auto-height :auto-width} (:grow-type shape)))
(assoc :width (:width tr-shape) :height (:height tr-shape)))
shape
(if (some? text-modifier)
(let [{:keys [width height]} (dwt/apply-text-modifier shape text-modifier)]
(assoc shape :width width :height height))
shape)
shape (hooks/use-equal-memo shape)

View file

@ -1173,29 +1173,13 @@
(:color color) (:color color)
:else (:value color))
;; TODO: looks like the first argument is not necessary
;; TODO: this code should be out of this UI component
apply-color
(fn [_ event]
(let [objects (wsh/lookup-page-objects @st/state)
selected (->> (wsh/lookup-selected @st/state)
(cph/clean-loops objects))
selected-obj (keep (d/getf objects) selected)
select-shapes-for-color (fn [shape objects]
(let [shapes (case (:type shape)
:group (cph/get-children objects (:id shape))
[shape])]
(->> shapes
(remove cph/group-shape?)
(map :id))))
ids (mapcat #(select-shapes-for-color % objects) selected-obj)]
(if (kbd/alt? event)
(st/emit! (dc/change-stroke ids (merge uc/empty-color color) 0))
(st/emit! (dc/change-fill ids (merge uc/empty-color color) 0)))))
(fn [event]
(st/emit! (dc/apply-color-from-palette (merge uc/empty-color color) (kbd/alt? event))))
rename-color
(fn [name]
(st/emit! (dwl/update-color (assoc color :name name) file-id)))
(st/emit! (dwl/rename-color file-id (:id color) name)))
edit-color
(fn [new-color]
@ -1300,8 +1284,7 @@
:selected (contains? selected-colors (:id color)))
:on-context-menu on-context-menu
:on-click (when-not (:editing @state)
#(on-asset-click % (:id color)
(partial apply-color (:id color))))
#(on-asset-click % (:id color) apply-color))
:ref item-ref
:draggable (and (not workspace-read-only?) (not (:editing @state)))
:on-drag-start on-color-drag-start

View file

@ -11,6 +11,7 @@
[app.common.uuid :as uuid]
[app.main.data.workspace.changes :as dch]
[app.main.data.workspace.libraries :as dwl]
[app.main.data.workspace.shortcuts :as sc]
[app.main.data.workspace.texts :as dwt]
[app.main.data.workspace.undo :as dwu]
[app.main.fonts :as fonts]
@ -25,8 +26,6 @@
[cuerdas.core :as str]
[rumext.v2 :as mf]))
(mf/defc text-align-options
[{:keys [values on-change on-blur] :as props}]
(let [{:keys [text-align]} values
@ -38,22 +37,22 @@
;; --- Align
[:div.align-icons
[:span.tooltip.tooltip-bottom
{:alt (tr "workspace.options.text-options.align-left")
{:alt (tr "workspace.options.text-options.align-left" (sc/get-tooltip :text-align-left))
:class (dom/classnames :current (= "left" text-align))
:on-click #(handle-change % "left")}
i/text-align-left]
[:span.tooltip.tooltip-bottom
{:alt (tr "workspace.options.text-options.align-center")
{:alt (tr "workspace.options.text-options.align-center" (sc/get-tooltip :text-align-center))
:class (dom/classnames :current (= "center" text-align))
:on-click #(handle-change % "center")}
i/text-align-center]
[:span.tooltip.tooltip-bottom
{:alt (tr "workspace.options.text-options.align-right")
{:alt (tr "workspace.options.text-options.align-right" (sc/get-tooltip :text-align-right))
:class (dom/classnames :current (= "right" text-align))
:on-click #(handle-change % "right")}
i/text-align-right]
[:span.tooltip.tooltip-bottom
{:alt (tr "workspace.options.text-options.align-justify")
{:alt (tr "workspace.options.text-options.align-justify" (sc/get-tooltip :text-align-justify))
:class (dom/classnames :current (= "justify" text-align))
:on-click #(handle-change % "justify")}
i/text-align-justify]]))
@ -149,13 +148,13 @@
i/minus]
[:span.tooltip.tooltip-bottom
{:alt (tr "workspace.options.text-options.underline")
{:alt (tr "workspace.options.text-options.underline" (sc/get-tooltip :underline))
:class (dom/classnames :current (= "underline" text-decoration))
:on-click #(handle-change % "underline")}
i/underline]
[:span.tooltip.tooltip-bottom
{:alt (tr "workspace.options.text-options.strikethrough")
{:alt (tr "workspace.options.text-options.strikethrough" (sc/get-tooltip :line-through))
:class (dom/classnames :current (= "line-through" text-decoration))
:on-click #(handle-change % "line-through")}
i/strikethrough]]))

View file

@ -143,6 +143,8 @@
;; shortcuts.open-color-picker
;; shortcuts.open-comments
;; shortcuts.open-dashboard
;; shortcuts.select-prev
;; shortcuts.select-next
;; shortcuts.open-inspect
;; shortcuts.open-interactions
;; shortcuts.open-viewer

View file

@ -134,12 +134,14 @@
;; STREAMS
move-stream (mf/use-memo #(rx/subject))
frame-parent (mf/use-memo
guide-frame (mf/use-memo
(mf/deps @hover-ids base-objects)
(fn []
(let [parent (get base-objects (last @hover-ids))]
(when (= :frame (:type parent))
parent))))
(let [parent-id
(->> @hover-ids
(d/seek (partial cph/root-frame? base-objects)))]
(when (some? parent-id)
(get base-objects parent-id)))))
zoom (d/check-num zoom 1)
drawing-tool (:tool drawing)
@ -495,7 +497,7 @@
[:& guides/viewport-guides
{:zoom zoom
:vbox vbox
:hover-frame frame-parent
:hover-frame guide-frame
:disabled-guides? disabled-guides?
:modifiers modifiers}])

View file

@ -434,7 +434,15 @@
(:id component)
(gpt/point final-x final-y))))
;; Will trigger when the user drags an image from a browser to the viewport
;; Will trigger when the user drags an image from a browser to the viewport (firefox and chrome do it a bit different depending on the origin)
(dnd/has-type? event "Files")
(let [files (dnd/get-files event)
params {:file-id (:id file)
:position viewport-coord
:blobs (seq files)}]
(st/emit! (dwm/upload-media-workspace params)))
;; Will trigger when the user drags an image from a browser to the viewport (firefox and chrome do it a bit different depending on the origin)
(dnd/has-type? event "text/uri-list")
(let [data (dnd/get-data event "text/uri-list")
lines (str/lines data)

View file

@ -58,7 +58,8 @@
shape (or drawing-obj (-> selected first))]
(when (or (and (= (count selected) 1)
(= (:id shape) edition)
(cph/path-shape? shape))
(and (not (cph/text-shape? shape))
(not (cph/frame-shape? shape))))
(and (some? drawing-obj)
(cph/path-shape? drawing-obj)
(not= :curve (:tool drawing))))

View file

@ -368,12 +368,22 @@
(when (some? node)
(.blur node)))
;; List of dom events for different browsers to detect the exit of fullscreen mode
(def fullscreen-events
["fullscreenchange" "mozfullscreenchange" "MSFullscreenChange" "webkitfullscreenchange"])
(defn fullscreen?
[]
(cond
(obj/in? globals/document "webkitFullscreenElement")
(boolean (.-webkitFullscreenElement globals/document))
(obj/in? globals/document "mozFullScreen")
(boolean (.-mozFullScreen globals/document))
(obj/in? globals/document "msFullscreenElement")
(boolean (.-msFullscreenElement globals/document))
(obj/in? globals/document "fullscreenElement")
(boolean (.-fullscreenElement globals/document))

View file

@ -3623,19 +3623,19 @@ msgstr "Alinea el centre"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-justify"
msgstr "Justifica"
msgstr "Justifica (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-left"
msgstr "Alinea a l'esquerra"
msgstr "Alinea a l'esquerra (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-middle"
msgstr "Alinea al centre"
msgstr "Alinea al centre (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-right"
msgstr "Alinea a la dreta"
msgstr "Alinea a la dreta (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-top"
@ -3679,7 +3679,7 @@ msgstr "Cap"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.strikethrough"
msgstr "Ratllat"
msgstr "Ratllat (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.title"
@ -3699,7 +3699,7 @@ msgstr "Inicials en majúscules"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.underline"
msgstr "Subratllat"
msgstr "Subratllat (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs
msgid "workspace.options.text-options.uppercase"

View file

@ -3688,19 +3688,19 @@ msgstr "Zarovnat doprostřed"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-justify"
msgstr "Zarovnat"
msgstr "Zarovnat (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-left"
msgstr "Zarovnat vlevo"
msgstr "Zarovnat vlevo (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-middle"
msgstr "Zarovnat na střed"
msgstr "Zarovnat na střed (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-right"
msgstr "Zarovnat vpravo"
msgstr "Zarovnat vpravo (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-top"
@ -3744,7 +3744,7 @@ msgstr "Žádné"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.strikethrough"
msgstr "Přeškrtnutí"
msgstr "Přeškrtnutí (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.title"
@ -3764,7 +3764,7 @@ msgstr "První písmeno velké"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.underline"
msgstr "Podtrhnout"
msgstr "Podtrhnout (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs
msgid "workspace.options.text-options.uppercase"

View file

@ -3907,19 +3907,19 @@ msgstr "Zentrieren"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-justify"
msgstr "Ausrichtung in der Breite"
msgstr "Ausrichtung in der Breite (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-left"
msgstr "Linksbündig ausrichten"
msgstr "Linksbündig ausrichten (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-middle"
msgstr "An Mitte ausrichten"
msgstr "An Mitte ausrichten (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-right"
msgstr "Rechtsbündig ausrichten"
msgstr "Rechtsbündig ausrichten (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-top"
@ -3964,7 +3964,7 @@ msgstr "Keine"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.strikethrough"
msgstr "Durchgestrichen"
msgstr "Durchgestrichen (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.title"
@ -3984,7 +3984,7 @@ msgstr "Kapitälchen"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.underline"
msgstr "Unterstrichen"
msgstr "Unterstrichen (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs
msgid "workspace.options.text-options.uppercase"

View file

@ -1797,19 +1797,19 @@ msgstr "Ευθυγράμμιση κέντρο"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-justify"
msgstr "Δικαιολόγηση"
msgstr "Δικαιολόγηση (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-left"
msgstr "Στοίχιση αριστερά"
msgstr "Στοίχιση αριστερά (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-middle"
msgstr "Στοίχιση στο κέντρο"
msgstr "Στοίχιση στο κέντρο (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-right"
msgstr "Για ευθυγράμμιση προς τα δεξιά"
msgstr "Για ευθυγράμμιση προς τα δεξιά (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-top"
@ -1849,7 +1849,7 @@ msgstr "Κανένας"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.strikethrough"
msgstr "Διαγράμμιση"
msgstr "Διαγράμμιση (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.title"
@ -1869,7 +1869,7 @@ msgstr "Τίτλος υπόθεση"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.underline"
msgstr "υπογράμμιση"
msgstr "υπογράμμιση (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs
msgid "workspace.options.text-options.uppercase"

View file

@ -1821,6 +1821,9 @@ msgstr "Send invitation"
msgid "modals.invite-member.emails"
msgstr "Emails, comma separated"
msgid "modals.invite-member.repeated-invitation"
msgstr "Some emails are from current team members. Their invitations will not be sent."
#: src/app/main/ui/dashboard/team.cljs
msgid "modals.invite-team-member.title"
msgstr "Invite members to the team"
@ -2458,6 +2461,12 @@ msgstr "Go to viewer comment section"
msgid "shortcuts.open-dashboard"
msgstr "Go to dashboard"
msgid "shortcuts.select-next"
msgstr "Select next layer"
msgid "shortcuts.select-prev"
msgstr "Select previous layer"
msgid "shortcuts.open-inspect"
msgstr "Go to viewer inspect section"
@ -3998,19 +4007,19 @@ msgstr "Align center"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-justify"
msgstr "Justify"
msgstr "Justify (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-left"
msgstr "Align left"
msgstr "Align left (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-middle"
msgstr "Align middle"
msgstr "Align middle (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-right"
msgstr "Align right"
msgstr "Align right (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-top"
@ -4054,7 +4063,7 @@ msgstr "None"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.strikethrough"
msgstr "Strikethrough"
msgstr "Strikethrough (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.title"
@ -4074,7 +4083,7 @@ msgstr "Title case"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.underline"
msgstr "Underline"
msgstr "Underline (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs
msgid "workspace.options.text-options.uppercase"

View file

@ -1904,6 +1904,9 @@ msgstr "Enviar invitacion"
msgid "modals.invite-member.emails"
msgstr "Emails, separados por coma"
msgid "modals.invite-member.repeated-invitation"
msgstr "Algunas direcciones de correo ya se encuentran entre los miembros. Estas invitaciones no serán enviadas."
#: src/app/main/ui/dashboard/team.cljs
msgid "modals.invite-team-member.title"
msgstr "Invitar a miembros al equipo"
@ -2603,6 +2606,12 @@ msgstr "Comentarios"
msgid "shortcuts.open-dashboard"
msgstr "Ir al dashboard"
msgid "shortcuts.select-next"
msgstr "Seleccionar capa siguiente"
msgid "shortcuts.select-prev"
msgstr "Seleccionar capa anterior"
msgid "shortcuts.open-inspect"
msgstr "Ir al inspector"
@ -4190,19 +4199,19 @@ msgstr "Aliniear al centro"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-justify"
msgstr "Justificar"
msgstr "Justificar (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-left"
msgstr "Alinear a la izquierda"
msgstr "Alinear a la izquierda (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-middle"
msgstr "Alinear al centro"
msgstr "Alinear al centro (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-right"
msgstr "Alinear a la derecha"
msgstr "Alinear a la derecha (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-top"
@ -4247,7 +4256,7 @@ msgstr "Nada"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.strikethrough"
msgstr "Tachado"
msgstr "Tachado (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.title"
@ -4267,7 +4276,7 @@ msgstr "Título"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.underline"
msgstr "Subrayado"
msgstr "Subrayado (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs
msgid "workspace.options.text-options.uppercase"

View file

@ -3800,19 +3800,19 @@ msgstr "Lerrokatu erdian"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-justify"
msgstr "Justifikatu"
msgstr "Justifikatu (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-left"
msgstr "Lerrokatu ezkerrean"
msgstr "Lerrokatu ezkerrean (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-middle"
msgstr "Lerrokatu erdian"
msgstr "Lerrokatu erdian (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-right"
msgstr "Lerrokatu eskuman"
msgstr "Lerrokatu eskuman (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-top"
@ -3856,7 +3856,7 @@ msgstr "Bat ere ez"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.strikethrough"
msgstr "Gaineko marra"
msgstr "Gaineko marra (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.title"
@ -3876,7 +3876,7 @@ msgstr "Izenburuaren mota"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.underline"
msgstr "Azpimarra"
msgstr "Azpimarra (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs
msgid "workspace.options.text-options.uppercase"

View file

@ -2579,15 +2579,15 @@ msgstr "تراز در مرکز"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-left"
msgstr "تراز چپ"
msgstr "تراز چپ (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-middle"
msgstr "تراز وسط"
msgstr "تراز وسط (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-right"
msgstr "تراز راست"
msgstr "تراز راست (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-top"
@ -2644,7 +2644,7 @@ msgstr "متن انتخابی"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.underline"
msgstr "خط‌زیر"
msgstr "خط‌زیر (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs
msgid "workspace.options.text-options.uppercase"

View file

@ -3647,19 +3647,19 @@ msgstr "Aligner au centre"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-justify"
msgstr "Justifier"
msgstr "Justifier (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-left"
msgstr "Aligner à gauche"
msgstr "Aligner à gauche (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-middle"
msgstr "Aligner verticalement au milieu"
msgstr "Aligner verticalement au milieu (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-right"
msgstr "Aligner à droite"
msgstr "Aligner à droite (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-top"
@ -3704,7 +3704,7 @@ msgstr "Aucune"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.strikethrough"
msgstr "Barré"
msgstr "Barré (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.title"
@ -3724,7 +3724,7 @@ msgstr "Premières Lettres en Capitales"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.underline"
msgstr "Soulignage"
msgstr "Soulignage (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs
msgid "workspace.options.text-options.uppercase"

View file

@ -3863,19 +3863,19 @@ msgstr "יישור למרכז"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-justify"
msgstr "יישור לשני הצדדים"
msgstr "יישור לשני הצדדים (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-left"
msgstr "יישור שמאלה"
msgstr "יישור שמאלה (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-middle"
msgstr "יישור לאמצע"
msgstr "יישור לאמצע (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-right"
msgstr "יישור ימינה"
msgstr "יישור ימינה (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-top"
@ -3920,7 +3920,7 @@ msgstr "ללא"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.strikethrough"
msgstr "קו חוצה"
msgstr "קו חוצה (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.title"
@ -3940,7 +3940,7 @@ msgstr "רישיות כותרת"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.underline"
msgstr "קו תחתי"
msgstr "קו תחתי (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs
msgid "workspace.options.text-options.uppercase"

View file

@ -3812,19 +3812,19 @@ msgstr "Poravnaj sredinu"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
#, fuzzy
msgid "workspace.options.text-options.align-justify"
msgstr "Složi u blok"
msgstr "Složi u blok (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-left"
msgstr "Poravnaj lijevo"
msgstr "Poravnaj lijevo (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-middle"
msgstr "Poravnaj sredinu"
msgstr "Poravnaj sredinu (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-right"
msgstr "Poravnaj desno"
msgstr "Poravnaj desno (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-top"
@ -3869,7 +3869,7 @@ msgstr "Nijedan"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.strikethrough"
msgstr "Precrtanko"
msgstr "Precrtanko (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.title"
@ -3889,7 +3889,7 @@ msgstr "Velika i mala slova"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.underline"
msgstr "Podcrtano"
msgstr "Podcrtano (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs
msgid "workspace.options.text-options.uppercase"

View file

@ -3673,19 +3673,19 @@ msgstr "Paskan ke tengah"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-justify"
msgstr "Justify"
msgstr "Justify (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-left"
msgstr "Paskan ke kiri"
msgstr "Paskan ke kiri (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-middle"
msgstr "Paskan ke tengah"
msgstr "Paskan ke tengah (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-right"
msgstr "Paskan ke kanan"
msgstr "Paskan ke kanan (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-top"
@ -3729,7 +3729,7 @@ msgstr "Tidak ada"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.strikethrough"
msgstr "Coret"
msgstr "Coret (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.title"
@ -3749,7 +3749,7 @@ msgstr "Huruf Judul"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.underline"
msgstr "Garis bawah"
msgstr "Garis bawah (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs
msgid "workspace.options.text-options.uppercase"

View file

@ -3572,19 +3572,19 @@ msgstr "Wyrównaj do środka"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-justify"
msgstr "Wyjustuj"
msgstr "Wyjustuj (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-left"
msgstr "Wyrównaj do lewej"
msgstr "Wyrównaj do lewej (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-middle"
msgstr "Wyrównaj do środka"
msgstr "Wyrównaj do środka (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-right"
msgstr "Wyrównaj do prawej"
msgstr "Wyrównaj do prawej (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-top"
@ -3628,7 +3628,7 @@ msgstr "Brak"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.strikethrough"
msgstr "Przekreślenie"
msgstr "Przekreślenie (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.title"
@ -3648,7 +3648,7 @@ msgstr "Nazwy Własne"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.underline"
msgstr "Podkreślenie"
msgstr "Podkreślenie (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs
msgid "workspace.options.text-options.uppercase"

View file

@ -3794,19 +3794,19 @@ msgstr "Alinhar ao centro"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-justify"
msgstr "Justificar"
msgstr "Justificar (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-left"
msgstr "Alinhar à esquerda"
msgstr "Alinhar à esquerda (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-middle"
msgstr "Alinhar no meio"
msgstr "Alinhar no meio (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-right"
msgstr "Alinhar à direita"
msgstr "Alinhar à direita (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-top"
@ -3850,7 +3850,7 @@ msgstr "Nenhum"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.strikethrough"
msgstr "Tachado"
msgstr "Tachado (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.title"
@ -3870,7 +3870,7 @@ msgstr "Capitalização de Título"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.underline"
msgstr "Sublinhado"
msgstr "Sublinhado (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs
msgid "workspace.options.text-options.uppercase"

View file

@ -3797,19 +3797,19 @@ msgstr "Alinhar ao centro"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-justify"
msgstr "Justificar"
msgstr "Justificar (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-left"
msgstr "Alinhar à esquerda"
msgstr "Alinhar à esquerda (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-middle"
msgstr "Alinhar ao meio"
msgstr "Alinhar ao meio (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-right"
msgstr "Alinhar à direita"
msgstr "Alinhar à direita (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-top"
@ -3853,7 +3853,7 @@ msgstr "Nenhum"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.strikethrough"
msgstr "Rasurado"
msgstr "Rasurado (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.title"
@ -3873,7 +3873,7 @@ msgstr "Capitalizar iniciais"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.underline"
msgstr "Sublinhado"
msgstr "Sublinhado (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs
msgid "workspace.options.text-options.uppercase"

View file

@ -3766,19 +3766,19 @@ msgstr "Aliniază centru"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-justify"
msgstr "Justifică"
msgstr "Justifică (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-left"
msgstr "Aliniază la stânga"
msgstr "Aliniază la stânga (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-middle"
msgstr "Aliniază la mijloc"
msgstr "Aliniază la mijloc (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-right"
msgstr "Aliniază la dreapta"
msgstr "Aliniază la dreapta (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-top"
@ -3822,7 +3822,7 @@ msgstr "Nici unul"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.strikethrough"
msgstr "Barat"
msgstr "Barat (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.title"
@ -3842,7 +3842,7 @@ msgstr "Încadrare Titlu"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.underline"
msgstr "Subliniază"
msgstr "Subliniază (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs
msgid "workspace.options.text-options.uppercase"

View file

@ -2688,19 +2688,19 @@ msgstr "Выравнивание по центру"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-justify"
msgstr "Выравнивание по ширине"
msgstr "Выравнивание по ширине (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-left"
msgstr "Выравнивание по левому краю"
msgstr "Выравнивание по левому краю (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-middle"
msgstr "Выравнивание по центру"
msgstr "Выравнивание по центру (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-right"
msgstr "Выравнивание по правому краю"
msgstr "Выравнивание по правому краю (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-top"
@ -2744,7 +2744,7 @@ msgstr "Не задано"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.strikethrough"
msgstr "Перечеркнутый"
msgstr "Перечеркнутый (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.title"
@ -2764,7 +2764,7 @@ msgstr "Каждое слово с заглавной буквы"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.underline"
msgstr "Подчеркнутый"
msgstr "Подчеркнутый (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs
msgid "workspace.options.text-options.uppercase"

View file

@ -3893,19 +3893,19 @@ msgstr "Ortaya hizala"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-justify"
msgstr "İki yana yasla"
msgstr "İki yana yasla (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-left"
msgstr "Sola hizala"
msgstr "Sola hizala (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-middle"
msgstr "Merkeze hizala"
msgstr "Merkeze hizala (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-right"
msgstr "Sağa hizala"
msgstr "Sağa hizala (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-top"
@ -3950,7 +3950,7 @@ msgstr "Hiçbiri"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.strikethrough"
msgstr "Üstü çizili"
msgstr "Üstü çizili (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.title"
@ -3970,7 +3970,7 @@ msgstr "İlk Harfi Büyük"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.underline"
msgstr "Altı Çizili"
msgstr "Altı Çizili (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs
msgid "workspace.options.text-options.uppercase"

View file

@ -3677,19 +3677,19 @@ msgstr "居中对齐"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-justify"
msgstr "整理"
msgstr "整理 (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-left"
msgstr "靠左对齐"
msgstr "靠左对齐 (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-middle"
msgstr "中间对齐"
msgstr "中间对齐 (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-right"
msgstr "靠右对齐"
msgstr "靠右对齐 (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.align-top"
@ -3733,7 +3733,7 @@ msgstr "无"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.strikethrough"
msgstr "删除线"
msgstr "删除线 (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.title"
@ -3753,7 +3753,7 @@ msgstr "首字母大写"
#: src/app/main/ui/workspace/sidebar/options/menus/text.cljs
msgid "workspace.options.text-options.underline"
msgstr "下划线"
msgstr "下划线 (%s)"
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs
msgid "workspace.options.text-options.uppercase"