Compare commits

...

24 Commits

Author SHA1 Message Date
Alejandro
04b7d8e1e2 Merge pull request #3094 from penpot/hotfix-1.17
🐛 Fix problem with invalid geometry
2023-03-31 14:10:36 +02:00
alonso.torres
745cf1c79d 🐛 Fix problem with invalid geometry 2023-03-31 12:05:59 +02:00
Alejandro Alonso
9e35229ebd 🐛 Fix components texts not displayed in assets panel 2023-03-07 15:22:24 +01:00
Alejandro
e8027d3316 Merge pull request #3010 from penpot/niwinz-docker-frontend-2
🐳 Add backend and exporter uri env vars to frontend docker image
2023-03-07 13:08:59 +01:00
Andrey Antukh
ad34ebff89 🐳 Add backend and exporter uri env vars to frontend docker image 2023-03-07 13:08:38 +01:00
Alejandro Alonso
f733497f0f 🐛 Fix some typos on english translation 2023-03-07 10:57:37 +01:00
Alejandro Alonso
ed917fa194 🐛 Fix font translations not detected as markdown 2023-03-07 10:57:37 +01:00
Alejandro Alonso
313df74202 🐛 Fix handle correctly slashes in emails 2023-03-07 10:51:31 +01:00
Alejandro Alonso
91c12ca34f 🐛 Fix change colors from selected colors 2023-03-07 10:42:58 +01:00
Alejandro Alonso
9f66e8e5d1 🐛 Fix search field shared styles 2023-03-07 10:37:11 +01:00
Alejandro
82e402c271 Merge pull request #3012 from penpot/alotor-bug-redo
🐛 Fix problem with redo shortcut
2023-03-06 14:37:28 +01:00
alonso.torres
827ce6c42a 🐛 Fix problem with redo shortcut 2023-03-06 14:23:26 +01:00
Alejandro Alonso
dec854a012 🐛 Fix full screen not clickable on inspect mode after user entered full screen 2023-03-03 10:31:04 +01:00
Alejandro
03d4e97ad7 Merge pull request #2997 from penpot/alotor-fix-shadow-multi-selection
🐛 Fix problem withs shadows and blur on multiple selection
2023-03-02 16:35:24 +01:00
alonso.torres
e061ba8123 🐛 Fix problem with shadows and blur on multiple selection 2023-03-02 16:32:21 +01:00
Alejandro Alonso
9a272f69c7 🐛 Fix height 100% cropped 2023-03-01 14:19:48 +01:00
Alejandro Alonso
fc1f2b2a9f 🐛 Fix some layout tooltips cropped 2023-03-01 14:19:48 +01:00
Alejandro Alonso
89fbe28ed1 🐛 Fix wrap and nowrap spelling issues 2023-03-01 14:19:48 +01:00
Alejandro Alonso
216d101e56 🐛 Fix flex layout min height bigger than board when height is 100% 2023-03-01 14:19:48 +01:00
Alejandro Alonso
ccf91a129c 🐛 Fix custom fonts not rendered correctly 2023-02-28 10:43:59 +01:00
Alejandro
1f3f6ce1e9 Merge pull request #2980 from penpot/eva-fix-paste-nested-boards
🐛 Fix copy paste a very nested boards inside itself
2023-02-28 09:51:21 +01:00
Eva
8f2e3d5fe4 🐛 Fix copy paste a very nested boards inside itself 2023-02-28 09:51:12 +01:00
Alejandro
47481986a1 Merge pull request #2987 from penpot/alotor-fix-layout-from-selected
🐛 Fix problem when creating layout from selection
2023-02-28 09:40:18 +01:00
alonso.torres
9af0e6ca44 🐛 Fix problem when creating layout from selection 2023-02-27 16:43:59 +01:00
31 changed files with 226 additions and 131 deletions

View File

@@ -1,4 +1,21 @@
# CHANGELOG
## 1.17.3
### :bug: Bugs fixed
- Fix copy and paste very nested inside itself [Taiga #4848](https://tree.taiga.io/project/penpot/issue/4848)
- Fix custom fonts not rendered correctly [Taiga #4874](https://tree.taiga.io/project/penpot/issue/4874)
- Fix problem with shadows and blur on multiple selection
- Fix problem with redo shortcut
- Fix Component texts not displayed in assets panel [Taiga #4907](https://tree.taiga.io/project/penpot/issue/4907)
- Fix search field has implemented shared styles for "close icon" and "search icon" [Taiga #4927](https://tree.taiga.io/project/penpot/issue/4927)
- Fix Handling correctly slashes "/" in emails [Taiga #4906](https://tree.taiga.io/project/penpot/issue/4906)
- Fix Change text color from selected colors [Taiga #4933](https://tree.taiga.io/project/penpot/issue/4933)
### :sparkles: Enhancements
- Adds environment variables for specifying the export and backend URI for the frontend docker image, thanks to @Supernova3339 for the initial PR and suggestion [Github #2984](https://github.com/penpot/penpot/issues/2984)
## 1.17.2
### :bug: Bugs fixed
@@ -8,10 +25,6 @@
- Fix correct behaviour for space-around and added space-evenly option
- Fix duplicate with alt and undo only undo one step [Taiga #4746](https://tree.taiga.io/project/penpot/issue/4746)
- Fix problem creating frames inside layout [Taiga #4844](https://tree.taiga.io/project/penpot/issue/4844)
## 1.17.2
### :bug: Bugs fixed
- Fix paste board inside itself [Taiga #4775](https://tree.taiga.io/project/penpot/issue/4775)
- Fix middle button panning can drag guides [Taiga #4266](https://tree.taiga.io/project/penpot/issue/4266)

View File

@@ -318,8 +318,10 @@
(defn unit
[p1]
(let [p-length (length p1)]
(Point. (/ (dm/get-prop p1 :x) p-length)
(/ (dm/get-prop p1 :y) p-length))))
(if (mth/almost-zero? p-length)
(Point. 0 0)
(Point. (/ (dm/get-prop p1 :x) p-length)
(/ (dm/get-prop p1 :y) p-length)))))
(defn perpendicular
[pt]

View File

@@ -9,7 +9,8 @@
[app.common.data :as d]
[app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt]
[app.common.geom.shapes.rect :as gpr]))
[app.common.geom.shapes.rect :as gpr]
[app.common.math :as mth]))
(defn center-rect
[{:keys [x y width height]}]
@@ -71,3 +72,15 @@
[{:keys [x1 y1 x2 y2] :as sr} matrix]
(let [[c1 c2] (transform-points [(gpt/point x1 y1) (gpt/point x2 y2)] matrix)]
(gpr/corners->selrect c1 c2)))
(defn invalid-geometry?
[{:keys [points selrect]}]
(or (mth/nan? (:x selrect))
(mth/nan? (:y selrect))
(mth/nan? (:width selrect))
(mth/nan? (:height selrect))
(some (fn [p]
(or (mth/nan? (:x p))
(mth/nan? (:y p))))
points)))

View File

@@ -10,6 +10,7 @@
[app.common.geom.shapes.flex-layout.positions :as fpo]
[app.common.geom.shapes.points :as gpo]
[app.common.geom.shapes.transforms :as gtr]
[app.common.math :as mth]
[app.common.types.modifiers :as ctm]
[app.common.types.shape.layout :as ctl]))
@@ -33,7 +34,7 @@
(let [line-width (min line-width (or to-bound-width line-width))
target-width (max (- line-width (ctl/child-width-margin child)) 0.01)
max-width (max (ctl/child-max-width child) 0.01)
target-width (min max-width target-width)
target-width (mth/clamp target-width (ctl/child-min-width child) max-width)
fill-scale (/ target-width child-width)]
{:width target-width
:modifiers (ctm/resize-modifiers (gpt/point fill-scale 1) child-origin transform transform-inverse)})))
@@ -57,7 +58,7 @@
(let [line-height (min line-height (or to-bound-height line-height))
target-height (max (- line-height (ctl/child-height-margin child)) 0.01)
max-height (max (ctl/child-max-height child) 0.01)
target-height (min max-height target-height)
target-height (mth/clamp target-height (ctl/child-min-height child) max-height)
fill-scale (/ target-height child-height)]
{:height target-height
:modifiers (ctm/resize-modifiers (gpt/point 1 fill-scale) child-origin transform transform-inverse)})))

View File

@@ -9,6 +9,7 @@
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.geom.point :as gpt]
[app.common.geom.shapes.common :as gco]
[app.common.geom.shapes.constraints :as gct]
[app.common.geom.shapes.flex-layout :as gcl]
[app.common.geom.shapes.pixel-precision :as gpp]
@@ -175,6 +176,7 @@
(let [children (->> (cph/get-immediate-children objects (:id parent))
(remove :hidden)
(remove gco/invalid-geometry?)
(map apply-modifiers))
layout-data (gcl/calc-layout-data parent children @transformed-parent-bounds)
children (into [] (cond-> children (not (:reverse? layout-data)) reverse))
@@ -215,7 +217,8 @@
(ctm/resize-parent (gpt/point 1 scale-height) origin (:transform parent) (:transform-inverse parent)))))
children (->> (cph/get-immediate-children objects parent-id)
(remove :hidden))
(remove :hidden)
(remove gco/invalid-geometry?))
content-bounds
(when (and (d/not-empty? children) (or (ctl/auto-height? parent) (ctl/auto-width? parent)))

View File

@@ -123,6 +123,10 @@
:blocked
:hidden
:shadow
:blur
:fills
:fill-color
:fill-opacity

View File

@@ -112,7 +112,7 @@
;; --- SPEC: email
(def email-re #"[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+")
(def email-re #"[a-zA-Z0-9_.+-\\\\]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+")
(defn parse-email
[s]

View File

@@ -8,7 +8,7 @@ RUN set -ex; \
ADD ./bundle-frontend/ /var/www/app/
ADD ./files/config.js /var/www/app/js/config.js
ADD ./files/nginx.conf /etc/nginx/nginx.conf
ADD ./files/nginx.conf /etc/nginx/nginx.conf.template
ADD ./files/nginx-entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]

View File

@@ -1,9 +1,5 @@
#!/usr/bin/env bash
log() {
echo "[$(date +%Y-%m-%dT%H:%M:%S%:z)] $*"
}
#########################################
## App Frontend config
#########################################
@@ -17,4 +13,15 @@ update_flags() {
}
update_flags /var/www/app/js/config.js
#########################################
## Nginx Config
#########################################
export PENPOT_BACKEND_URI=${PENPOT_BACKEND_URI:-http://penpot-backend:6060};
export PENPOT_EXPORTER_URI=${PENPOT_EXPORTER_URI:-http://penpot-exporter};
envsubst "\$PENPOT_BACKEND_URI,\$PENPOT_EXPORTER_URI" < /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf
exec "$@";

View File

@@ -82,7 +82,7 @@ http {
}
location /assets {
proxy_pass http://penpot-backend:6060/assets;
proxy_pass $PENPOT_BACKEND_URI/assets;
recursive_error_pages on;
proxy_intercept_errors on;
error_page 301 302 307 = @handle_redirect;
@@ -95,21 +95,17 @@ http {
}
location /api/export {
proxy_pass http://penpot-exporter:6061;
proxy_pass $PENPOT_EXPORTER_URI;
}
location /api {
proxy_pass http://penpot-backend:6060/api;
proxy_pass $PENPOT_BACKEND_URI/api;
}
# location /admin {
# proxy_pass http://penpot-admin:6065/admin;
# }
location /ws/notifications {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_pass http://penpot-backend:6060/ws/notifications;
proxy_pass $PENPOT_BACKEND_URI/ws/notifications;
}
location / {

View File

@@ -28,7 +28,7 @@ $width-settings-bar: 256px;
top: 0;
transition: top 400ms ease 300ms;
margin-bottom: 0;
z-index: 2;
z-index: 10;
}
& .viewer-bottom {
@@ -46,7 +46,7 @@ $width-settings-bar: 256px;
top: -48px;
left: 0;
transition: top 400ms ease 300ms;
z-index: 2;
z-index: 10;
margin-bottom: 48px;
&::after {

View File

@@ -337,15 +337,15 @@
fill: $color-gray-30;
height: 15px;
width: 15px;
&:hover {
fill: $color-danger;
}
}
}
.clear-search svg {
transform: rotate(45deg);
&:hover {
fill: $color-danger;
}
}
}

View File

@@ -54,6 +54,7 @@
display: flex;
justify-content: flex-end;
position: relative;
z-index: 10;
> * {
margin-left: $size-5;

View File

@@ -177,56 +177,64 @@
(watch [_ _ stream]
(let [team-id (:team-id project)
stoper (rx/filter (ptk/type? ::bundle-fetched) stream)]
(->> (rx/merge
;; Initialize notifications & load team fonts
(->> (rx/concat
;; Initialize notifications
(rx/of (dwn/initialize team-id id)
(dwsl/initialize)
(df/load-team-fonts team-id))
(dwsl/initialize))
;; Load all pages, independently if they are pointers or already
;; resolved values.
(->> (rx/from (seq (:pages-index data)))
(rx/merge-map
(fn [[_ page :as kp]]
(if (t/pointer? page)
(resolve-pointer id kp)
(rx/of kp))))
(rx/merge-map
(fn [[id page]]
(let [page (update page :objects ctst/start-page-index)]
(->> (uw/ask! {:cmd :initialize-page-index :page page})
(rx/map (constantly [id page]))))))
(rx/reduce conj {})
(rx/map (fn [pages-index]
(-> data
(assoc :pages-index pages-index)
(workspace-data-loaded)))))
;; Load team fonts. We must ensure custom fonts are fully loadad before starting the workspace load
(rx/merge
(->> stream
(rx/filter (ptk/type? :app.main.data.fonts/team-fonts-loaded))
(rx/take 1)
(rx/ignore))
(rx/of (df/load-team-fonts team-id)))
;; Once workspace data is loaded, proceed asynchronously load
;; the local library and all referenced libraries, without
;; blocking the main workspace load process.
(->> stream
(rx/filter (ptk/type? ::workspace-data-loaded))
(rx/take 1)
(rx/merge-map
(fn [_]
(rx/merge
(rx/of (workspace-initialized))
(rx/merge
;; Load all pages, independently if they are pointers or already
;; resolved values.
(->> (rx/from (seq (:pages-index data)))
(rx/merge-map
(fn [[_ page :as kp]]
(if (t/pointer? page)
(resolve-pointer id kp)
(rx/of kp))))
(rx/merge-map
(fn [[id page]]
(let [page (update page :objects ctst/start-page-index)]
(->> (uw/ask! {:cmd :initialize-page-index :page page})
(rx/map (constantly [id page]))))))
(rx/reduce conj {})
(rx/map (fn [pages-index]
(-> data
(assoc :pages-index pages-index)
(workspace-data-loaded)))))
(->> data
(filter (comp t/pointer? val))
(resolve-pointers id)
(rx/map workspace-data-pointers-loaded))
;; Once workspace data is loaded, proceed asynchronously load
;; the local library and all referenced libraries, without
;; blocking the main workspace load process.
(->> stream
(rx/filter (ptk/type? ::workspace-data-loaded))
(rx/take 1)
(rx/merge-map
(fn [_]
(rx/merge
(rx/of (workspace-initialized))
(->> (rp/cmd! :get-file-libraries {:file-id id :features features})
(rx/mapcat identity)
(rx/mapcat
(fn [{:keys [id data] :as file}]
(->> (filter (comp t/pointer? val) data)
(resolve-pointers id)
(rx/map #(update file :data merge %)))))
(rx/reduce conj [])
(rx/map libraries-fetched)))))))
(->> data
(filter (comp t/pointer? val))
(resolve-pointers id)
(rx/map workspace-data-pointers-loaded))
(->> (rp/cmd! :get-file-libraries {:file-id id :features features})
(rx/mapcat identity)
(rx/mapcat
(fn [{:keys [id data] :as file}]
(->> (filter (comp t/pointer? val) data)
(resolve-pointers id)
(rx/map #(update file :data merge %)))))
(rx/reduce conj [])
(rx/map libraries-fetched))))))))
(rx/take-until stoper)))))))
@@ -429,7 +437,7 @@
name (cp/generate-unique-name unames (:name page))
no_thumbnails_objects (->> (:objects page)
(d/mapm (fn [_ val] (dissoc val :use-for-thumbnail?))))
(d/mapm (fn [_ val] (dissoc val :use-for-thumbnail?))))
page (-> page (assoc :name name :id id :objects no_thumbnails_objects))
@@ -1099,13 +1107,13 @@
qparams {:page-id page-id}]
;; qparams {:page-id page-id :layout :assets}]
(rx/merge
(rx/of (rt/nav :workspace pparams qparams))
(->> stream
(rx/filter (ptk/type? ::dwv/initialize-viewport))
(rx/take 1)
(rx/mapcat #(do
(on-page-selected)
(rx/of (dws/select-shapes (lks/set shape-id)))))))))))))
(rx/of (rt/nav :workspace pparams qparams))
(->> stream
(rx/filter (ptk/type? ::dwv/initialize-viewport))
(rx/take 1)
(rx/mapcat #(do
(on-page-selected)
(rx/of (dws/select-shapes (lks/set shape-id)))))))))))))
(defn go-to-component
[component-id]
@@ -1440,9 +1448,17 @@
(and (= 1 (count selected))
(= :frame (get-in objects [(first selected) :type])))))
(defn same-frame-from-selected? [state frame-id]
(let [selected (wsh/lookup-selected state)]
(contains? frame-id (first selected))))
(defn get-tree-root-shapes [tree]
;; This fn gets a map of shapes and finds what shapes are parent of the rest
(let [shapes-in-tree (vals tree)
shape-ids (keys tree)
parent-ids (set (map #(:parent-id %) shapes-in-tree))]
(->> shape-ids
(filter #(contains? parent-ids %)))))
(defn any-same-frame-from-selected? [state frame-ids]
(let [selected (first (wsh/lookup-selected state))]
(< 0 (count (filter #(= % selected) frame-ids)))))
(defn frame-same-size?
[paste-obj frame-obj]
@@ -1491,22 +1507,27 @@
item))
(calculate-paste-position [state mouse-pos in-viewport?]
(let [page-objects (wsh/lookup-page-objects state)
selected-objs (map #(get paste-objects %) selected)
first-selected-obj (first selected-objs)
page-selected (wsh/lookup-selected state)
wrapper (gsh/selection-rect selected-objs)
orig-pos (gpt/point (:x1 wrapper) (:y1 wrapper))
frame-id (first page-selected)
frame-object (get page-objects frame-id)
base (cph/get-base-shape page-objects page-selected)
index (cph/get-position-on-parent page-objects (:id base))]
(let [page-objects (wsh/lookup-page-objects state)
selected-objs (map #(get paste-objects %) selected)
first-selected-obj (first selected-objs)
page-selected (wsh/lookup-selected state)
wrapper (gsh/selection-rect selected-objs)
orig-pos (gpt/point (:x1 wrapper) (:y1 wrapper))
frame-id (first page-selected)
frame-object (get page-objects frame-id)
base (cph/get-base-shape page-objects page-selected)
index (cph/get-position-on-parent page-objects (:id base))
tree-root (get-tree-root-shapes paste-objects)
only-one-root-shape? (and
(< 1 (count paste-objects))
(= 1 (count tree-root)))]
(cond
(selected-frame? state)
(if (or (same-frame-from-selected? state (first (vals paste-objects)))
(frame-same-size? paste-objects frame-object))
(if (or (any-same-frame-from-selected? state (keys paste-objects))
(and only-one-root-shape?
(frame-same-size? paste-objects (first tree-root))))
;; Paste next to selected frame, if selected is itself or of the same size as the copied
(let [selected-frame-obj (get page-objects (first page-selected))
parent-id (:parent-id base)
@@ -1544,7 +1565,7 @@
;; - Respect the distance of the object to the right and bottom in the original frame
(gpt/point paste-x paste-y))]
[frame-id frame-id delta]))
(empty? page-selected)
(let [frame-id (ctst/top-nested-frame page-objects mouse-pos)
delta (gpt/subtract mouse-pos orig-pos)]
@@ -1837,8 +1858,8 @@
(dwm/create-shapes-img pos media-obj))]
(->> (rx/concat
(rx/of (update-remove-graphics index))
(rx/map process-shapes shapes))
(rx/of (update-remove-graphics index))
(rx/map process-shapes shapes))
(rx/catch #(do
(log/error :msg (str "Error removing " (:name media-obj))
:hint (ex-message %)
@@ -1872,15 +1893,15 @@
(ctst/generate-shape-grid media-points start-pos grid-gap)]
(rx/concat
(rx/of (modal/show {:type :remove-graphics-dialog :file-name file-name})
(initialize-remove-graphics (count media)))
(when new-page?
(rx/of (dch/commit-changes (-> (pcb/empty-changes it)
(pcb/set-save-undo? false)
(pcb/add-page (:id page) page)))))
(rx/mapcat (partial remove-graphic it file-data' page)
(rx/from (d/enumerate (d/zip media shape-grid))))
(rx/of (complete-remove-graphics)))))))
(rx/of (modal/show {:type :remove-graphics-dialog :file-name file-name})
(initialize-remove-graphics (count media)))
(when new-page?
(rx/of (dch/commit-changes (-> (pcb/empty-changes it)
(pcb/set-save-undo? false)
(pcb/add-page (:id page) page)))))
(rx/mapcat (partial remove-graphic it file-data' page)
(rx/from (d/enumerate (d/zip media shape-grid))))
(rx/of (complete-remove-graphics)))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Read only

View File

@@ -337,7 +337,7 @@
(defn change-text-color
[old-color new-color index node]
(let [fills (:fills 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-new-color (d/without-nils (color-att->text new-color))
has-color? (d/index-of fills parsed-color)]

View File

@@ -87,7 +87,7 @@
(watch [it state _]
(let [edition (get-in state [:workspace-local :edition])
drawing (get state :workspace-drawing)]
(when (and (nil? edition) (or (empty drawing) (= :curve (:tool drawing))))
(when (and (nil? edition) (or (empty? drawing) (= :curve (:tool drawing))))
(let [undo (:workspace-undo state)
items (:items undo)
index (or (:index undo) (dec (count items)))]

View File

@@ -183,6 +183,13 @@
(-> shape
(assoc :layout-item-h-sizing :auto
:layout-item-v-sizing :auto))))
;; Set the children to fixed to remove strange interactions
(dwc/update-shapes
selected
(fn [shape]
(-> shape
(assoc :layout-item-h-sizing :fix
:layout-item-v-sizing :fix))))
(ptk/data-event :layout/update [new-shape-id])
(dws/delete-shapes page-id selected)
@@ -204,6 +211,13 @@
(merge flex-params)
(assoc :layout-item-h-sizing :auto
:layout-item-v-sizing :auto))))
;; Set the children to fixed to remove strange interactions
(dwc/update-shapes
selected
(fn [shape]
(-> shape
(assoc :layout-item-h-sizing :fix
:layout-item-v-sizing :fix))))
(ptk/data-event :layout/update [new-shape-id])
(dwu/commit-undo-transaction undo-id))))))))

View File

@@ -287,7 +287,6 @@
:fill "none"}
[:& shape-wrapper {:shape frame}]]]))
;; Component for rendering a thumbnail of a single componenent. Mainly
;; used to render thumbnails on assets panel.
(mf/defc component-svg
@@ -334,7 +333,8 @@
:fill "none"}
[:> shape-container {:shape root-shape}
[:& root-shape-wrapper {:shape root-shape :view-box vbox}]]]))
[:& (mf/provider muc/is-component?) {:value true}
[:& root-shape-wrapper {:shape root-shape :view-box vbox}]]]]))
(mf/defc object-svg
{::mf/wrap [mf/memo]}
@@ -468,7 +468,7 @@
(let [texts (->> objects
(vals)
(filterv #(= (:type %) :text))
(mapv :content)) ]
(mapv :content))]
(->> (rx/from texts)
(rx/map fonts/get-content-fonts)

View File

@@ -27,3 +27,4 @@
(def current-zoom (mf/create-context nil))
(def workspace-read-only? (mf/create-context nil))
(def is-component? (mf/create-context false))

View File

@@ -8,6 +8,8 @@
(:require
[app.common.text :as txt]
[app.main.fonts :as fonts]
[app.main.ui.context :as ctx]
[app.main.ui.shapes.text.fo-text :as fo]
[app.main.ui.shapes.text.svg-text :as svg]
[app.util.object :as obj]
[rumext.v2 :as mf]))
@@ -22,10 +24,13 @@
(mf/defc text-shape
{::mf/wrap-props false}
[props]
(let [{:keys [position-data content] :as shape} (obj/get props "shape")]
(let [{:keys [position-data content] :as shape} (obj/get props "shape")
is-component? (mf/use-ctx ctx/is-component?)]
(mf/with-memo [content]
(load-fonts! content))
(when (some? position-data)
[:> svg/text-shape props])))
;; Old components can have texts without position data that must be rendered via foreign key
(cond
(some? position-data) [:> svg/text-shape props]
is-component? [:> fo/text-shape props])))

View File

@@ -118,13 +118,13 @@
[:*
[:button.tooltip.tooltip-bottom
{:class (dom/classnames :active (= wrap-type :nowrap))
:alt "Nowrap"
:alt "No wrap"
:on-click #(set-wrap :nowrap)
:style {:padding 0}}
[:span.no-wrap i/minus]]
[:button.wrap.tooltip.tooltip-bottom
{:class (dom/classnames :active (= wrap-type :wrap))
:alt "wrap"
:alt "Wrap"
:on-click #(set-wrap :wrap)}
i/auto-wrap]])
@@ -159,8 +159,8 @@
(for [align [:space-between :space-around :space-evenly]]
[:button.align-content.tooltip
{:class (dom/classnames :active (= align-content align)
:tooltip-bottom-left (not= align :start)
:tooltip-bottom (= align :start))
:tooltip-bottom-left (not= align :space-between)
:tooltip-bottom (= align :space-between))
:alt (dm/str "Align content " (d/name align))
:on-click #(set-align-content align)
:key (dm/str "align-content" (d/name align))}
@@ -183,8 +183,8 @@
(for [justify [:space-between :space-around :space-evenly]]
[:button.justify.tooltip
{:class (dom/classnames :active (= justify-content justify)
:tooltip-bottom-left (not= justify :space-around)
:tooltip-bottom (= justify :space-around))
:tooltip-bottom-left (not= justify :space-between)
:tooltip-bottom (= justify :space-between))
:alt (dm/str "Justify content " (d/name justify))
:on-click #(set-justify justify)
:key (dm/str "justify-content" (d/name justify))}

View File

@@ -112,7 +112,7 @@
{:alt "Width 100%"
:class (dom/classnames :active (= layout-item-h-sizing :fill))
:on-click #(on-change-behavior :h :fill)}
i/auto-fill])
i/auto-fill])
(when auto?
[:button.behavior-btn.tooltip.tooltip-bottom
{:alt "Fit content"
@@ -125,9 +125,9 @@
{:alt "Fix height"
:class (dom/classnames :active (= layout-item-v-sizing :fix))
:on-click #(on-change-behavior :v :fix)}
i/auto-fix-layout]
i/auto-fix-layout]
(when fill?
[:button.behavior-btn.tooltip.tooltip-bottom
[:button.behavior-btn.tooltip.tooltip-bottom-left
{:alt "Height 100%"
:class (dom/classnames :active (= layout-item-v-sizing :fill))
:on-click #(on-change-behavior :v :fill)}
@@ -207,7 +207,7 @@
:layout-item-v-sizing (or (:layout-item-v-sizing values) :fix)
:layout-item-h-sizing (or (:layout-item-h-sizing values) :fix)
:on-change-behavior on-change-behavior}]]
(when is-layout-child?
[:div.layout-row
[:div.row-title "Align"]

View File

@@ -40,8 +40,8 @@
:layer :shape
:constraint :shape
:fill :shape
:shadow :children
:blur :children
:shadow :shape
:blur :shape
:stroke :shape
:text :children
:exports :shape

View File

@@ -400,6 +400,7 @@ msgstr[3] "عدد قليل من الخطوط المضافة"
msgstr[4] "تمت إضافة العديد من الخطوط"
msgstr[5] ""
#, markdown
msgid "dashboard.fonts.hero-text1"
msgstr ""
"ستتم إضافة أي خط ويب تقوم بتحميله هنا إلى قائمة عائلة الخطوط المتوفرة في "
@@ -407,6 +408,7 @@ msgstr ""
"عائلة الخطوط على أنها ** عائلة خط واحدة **. يمكنك تحميل الخطوط بالتنسيقات "
"التالية: ** TTF و OTF و WOFF ** (ستحتاج إلى تنسيق واحد فقط)."
#, markdown
msgid "dashboard.fonts.hero-text2"
msgstr ""
"يجب عليك فقط تحميل الخطوط التي تمتلكها أو لديك ترخيص لاستخدامها في Penpot. "

View File

@@ -409,6 +409,7 @@ msgid_plural "dashboard.fonts.fonts-added"
msgstr[0] "1 Schriftart hinzugefügt"
msgstr[1] "%s Schriftarten hinzugefügt"
#, markdown
msgid "dashboard.fonts.hero-text1"
msgstr ""
"Jede Webschriftart, die Sie hier hochladen, wird der Liste der Schriftarten "
@@ -418,6 +419,7 @@ msgstr ""
"den folgenden Formaten hochladen: **TTF, OTF und WOFF** (nur eine wird "
"benötigt)."
#, markdown
msgid "dashboard.fonts.hero-text2"
msgstr ""
"Sie sollten nur Schriftarten hochladen, die Sie besitzen oder für die Sie "

View File

@@ -831,7 +831,7 @@ msgstr "The email «%s» has been reported as spam or permanently bounce."
#: src/app/main/errors.cljs
msgid "errors.feature-mismatch"
msgstr ""
"Looks like you are opening a file that has the feature '%s' enabled bug "
"Looks like you are opening a file that has the feature '%s' enabled but "
"your penpot frontend does not supports it or has it disabled."
#: src/app/main/errors.cljs

View File

@@ -407,6 +407,7 @@ msgid_plural "dashboard.fonts.fonts-added"
msgstr[0] "1 fuente añadida"
msgstr[1] "%s fuentes añadidas"
#, markdown
msgid "dashboard.fonts.hero-text1"
msgstr ""
"Cualquier fuente personalizada añadida aquí aparecerá en la lista de "
@@ -415,6 +416,7 @@ msgstr ""
"como una **única familia de fuentes**. Se pueden cargar fuentes con los "
"siguientes formatos: **TTF, OTF and WOFF** (con uno es suficiente)."
#, markdown
msgid "dashboard.fonts.hero-text2"
msgstr ""
"Sólo deberías cargar fuentes que te pertenecen o de las que tienes una "

View File

@@ -411,6 +411,7 @@ msgid_plural "dashboard.fonts.fonts-added"
msgstr[0] "1 police ajoutée"
msgstr[1] "%s polices ajoutées"
#, markdown
msgid "dashboard.fonts.hero-text1"
msgstr ""
"Toute police Web que vous téléchargez sera ajoutée à la liste de polices de "
@@ -419,6 +420,7 @@ msgstr ""
"**une seule famille de polices**. Vous pouvez télécharger les polices au "
"formats suivants : **TTF, OTF et WOFF** (un seul format est nécessaire)."
#, markdown
msgid "dashboard.fonts.hero-text2"
msgstr ""
"Ne téléchargez que des polices que vous possédez ou dont la license vous "

View File

@@ -401,6 +401,7 @@ msgid_plural "dashboard.fonts.fonts-added"
msgstr[0] "Engadiuse 1 fonte"
msgstr[1] "Engadíronse % fontes"
#, markdown
msgid "dashboard.fonts.hero-text1"
msgstr ""
"Calquera fonte que cargues aquí engadirase na listaxe de familias de fontes "
@@ -409,6 +410,7 @@ msgstr ""
"Podes cargar fontes cos seguintes formatos: **TTF, OFT e WOFF** (só se "
"precisa un)."
#, markdown
msgid "dashboard.fonts.hero-text2"
msgstr ""
"Só debes cargar fontes da túa propiedade ou das que teñas licenza para usar "

View File

@@ -390,6 +390,7 @@ msgstr[1] "נוספו 2 גופנים"
msgstr[2] "נוספו %s גופנים"
msgstr[3] "נוספו %s גופנים"
#, markdown
msgid "dashboard.fonts.hero-text1"
msgstr ""
"כל גופן דפדפן שיועלה כאן יתווסף לרשימת משפחת הגופנים שזמין במאפייני הטקסט "
@@ -397,6 +398,7 @@ msgstr ""
"גופנים יחידה**. ניתן להעלות גופנים מהסוגים הבאים: **TTF, OTF ו־WOFF** (אחד "
"הסוגים יספיק)."
#, markdown
msgid "dashboard.fonts.hero-text2"
msgstr ""
"עליך להעלות גופנים בבעלותך או שיש לך רישיון להשתמש בהם ב־Penpot. ניתן למצוא "

View File

@@ -398,6 +398,7 @@ msgid_plural "dashboard.fonts.fonts-added"
msgstr[0] "1 font aggiunto"
msgstr[1] "%s font aggiunti"
#, markdown
msgid "dashboard.fonts.hero-text1"
msgstr ""
"Qualsiasi font web caricato qui verrà aggiunto alla lista dei font family "
@@ -406,6 +407,7 @@ msgstr ""
"**singolo font family**. È possibile caricare font con i seguenti "
"formati:**TTF, OTF e WOFF**(uno solo di questi è necessario)."
#, markdown
msgid "dashboard.fonts.hero-text2"
msgstr ""
"È consigliabile caricare unicamente font di cui si è proprietari o dei "