mirror of
https://github.com/penpot/penpot.git
synced 2025-02-01 11:59:17 -05:00
Merge branch 'spelling' of https://github.com/jsoref/penpot into jsoref-spelling
This commit is contained in:
commit
a82a33cecf
121 changed files with 256 additions and 252 deletions
18
CHANGES.md
18
CHANGES.md
|
@ -58,7 +58,7 @@
|
||||||
### :boom: Breaking changes
|
### :boom: Breaking changes
|
||||||
|
|
||||||
- Some stroke-caps can change behaviour.
|
- Some stroke-caps can change behaviour.
|
||||||
- Text display bug fix could potentialy make some texts jump a line.
|
- Text display bug fix could potentially make some texts jump a line.
|
||||||
|
|
||||||
### :sparkles: New features
|
### :sparkles: New features
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@
|
||||||
- Fix bug in firefox when a text box is inside a mask [Taiga #2152](https://tree.taiga.io/project/penpot/issue/2152).
|
- Fix bug in firefox when a text box is inside a mask [Taiga #2152](https://tree.taiga.io/project/penpot/issue/2152).
|
||||||
- Fix problem with stroke inside/outside [Taiga #2186](https://tree.taiga.io/project/penpot/issue/2186)
|
- Fix problem with stroke inside/outside [Taiga #2186](https://tree.taiga.io/project/penpot/issue/2186)
|
||||||
- Fix masks export area [Taiga #2189](https://tree.taiga.io/project/penpot/issue/2189)
|
- Fix masks export area [Taiga #2189](https://tree.taiga.io/project/penpot/issue/2189)
|
||||||
- Fix paste in place in arboards [Taiga #2188](https://tree.taiga.io/project/penpot/issue/2188)
|
- Fix paste in place in artboards [Taiga #2188](https://tree.taiga.io/project/penpot/issue/2188)
|
||||||
- Fix font size input stuck on selection change [Taiga #2184](https://tree.taiga.io/project/penpot/issue/2184)
|
- Fix font size input stuck on selection change [Taiga #2184](https://tree.taiga.io/project/penpot/issue/2184)
|
||||||
- Fix stroke cut on shapes export [Taiga #2171](https://tree.taiga.io/project/penpot/issue/2171)
|
- Fix stroke cut on shapes export [Taiga #2171](https://tree.taiga.io/project/penpot/issue/2171)
|
||||||
- Fix no color when boolean with an SVG [Taiga #2193](https://tree.taiga.io/project/penpot/issue/2193)
|
- Fix no color when boolean with an SVG [Taiga #2193](https://tree.taiga.io/project/penpot/issue/2193)
|
||||||
|
@ -256,7 +256,7 @@
|
||||||
### :bug: Bugs fixed
|
### :bug: Bugs fixed
|
||||||
|
|
||||||
- Process numeric input changes only if the value actually changed.
|
- Process numeric input changes only if the value actually changed.
|
||||||
- Remove unnecesary redirect from history when user goes to workspace from dashboard [Taiga #1820](https://tree.taiga.io/project/penpot/issue/1820).
|
- Remove unnecessary redirect from history when user goes to workspace from dashboard [Taiga #1820](https://tree.taiga.io/project/penpot/issue/1820).
|
||||||
- Detach shapes from deleted assets [Taiga #1850](https://tree.taiga.io/project/penpot/issue/1850).
|
- Detach shapes from deleted assets [Taiga #1850](https://tree.taiga.io/project/penpot/issue/1850).
|
||||||
- Fix tooltip position on view application [Taiga #1819](https://tree.taiga.io/project/penpot/issue/1819).
|
- Fix tooltip position on view application [Taiga #1819](https://tree.taiga.io/project/penpot/issue/1819).
|
||||||
- Fix dashboard navigation on moving file to other team [Taiga #1817](https://tree.taiga.io/project/penpot/issue/1817).
|
- Fix dashboard navigation on moving file to other team [Taiga #1817](https://tree.taiga.io/project/penpot/issue/1817).
|
||||||
|
@ -267,7 +267,7 @@
|
||||||
- Fix negative values in blur [Taiga #1815](https://tree.taiga.io/project/penpot/issue/1815)
|
- Fix negative values in blur [Taiga #1815](https://tree.taiga.io/project/penpot/issue/1815)
|
||||||
- Fix problem when editing color in group [Taiga #1816](https://tree.taiga.io/project/penpot/issue/1816)
|
- Fix problem when editing color in group [Taiga #1816](https://tree.taiga.io/project/penpot/issue/1816)
|
||||||
- Fix resize/rotate with mouse buttons different than left [#1060](https://github.com/penpot/penpot/issues/1060)
|
- Fix resize/rotate with mouse buttons different than left [#1060](https://github.com/penpot/penpot/issues/1060)
|
||||||
- Fix header partialy visible on fullscreen viewer mode [Taiga #1875](https://tree.taiga.io/project/penpot/issue/1875)
|
- Fix header partially visible on fullscreen viewer mode [Taiga #1875](https://tree.taiga.io/project/penpot/issue/1875)
|
||||||
- Fix dynamic alignment enabled with hidden objects [#1063](https://github.com/penpot/penpot/issues/1063)
|
- Fix dynamic alignment enabled with hidden objects [#1063](https://github.com/penpot/penpot/issues/1063)
|
||||||
|
|
||||||
|
|
||||||
|
@ -328,12 +328,12 @@
|
||||||
### :bug: Bugs fixed
|
### :bug: Bugs fixed
|
||||||
|
|
||||||
- Add safety check on reg-objects change impl.
|
- Add safety check on reg-objects change impl.
|
||||||
- Fix custom fonts embbedding issue.
|
- Fix custom fonts embedding issue.
|
||||||
- Fix dashboard ordering issue.
|
- Fix dashboard ordering issue.
|
||||||
- Fix problem when creating a component with empty data.
|
- Fix problem when creating a component with empty data.
|
||||||
- Fix problem with moving shapes into frames.
|
- Fix problem with moving shapes into frames.
|
||||||
- Fix problems with mov-objects.
|
- Fix problems with mov-objects.
|
||||||
- Fix unexpected excetion related to rounding integers.
|
- Fix unexpected exception related to rounding integers.
|
||||||
- Fix wrong type usage on libraries changes.
|
- Fix wrong type usage on libraries changes.
|
||||||
- Improve editor lifecycle management.
|
- Improve editor lifecycle management.
|
||||||
- Make the navigation async by default.
|
- Make the navigation async by default.
|
||||||
|
@ -536,7 +536,7 @@
|
||||||
|
|
||||||
- The LDAP configuration variables interpolation starts using `:`
|
- The LDAP configuration variables interpolation starts using `:`
|
||||||
(example `:username`) instead of `$`. The main reason is avoid
|
(example `:username`) instead of `$`. The main reason is avoid
|
||||||
unnecesary conflict with bash interpolation.
|
unnecessary conflict with bash interpolation.
|
||||||
|
|
||||||
|
|
||||||
### :arrow_up: Deps updates
|
### :arrow_up: Deps updates
|
||||||
|
@ -559,14 +559,14 @@
|
||||||
|
|
||||||
- Add emailcatcher and ldap test containers to devenv. [#506](https://github.com/penpot/penpot/pull/506)
|
- Add emailcatcher and ldap test containers to devenv. [#506](https://github.com/penpot/penpot/pull/506)
|
||||||
- Add major refactor of internal pubsub/redis code; improves scalability and performance [#640](https://github.com/penpot/penpot/pull/640)
|
- Add major refactor of internal pubsub/redis code; improves scalability and performance [#640](https://github.com/penpot/penpot/pull/640)
|
||||||
- Add more chinese transtions [#687](https://github.com/penpot/penpot/pull/687)
|
- Add more chinese translations [#687](https://github.com/penpot/penpot/pull/687)
|
||||||
- Add more presets for artboard [#654](https://github.com/penpot/penpot/pull/654)
|
- Add more presets for artboard [#654](https://github.com/penpot/penpot/pull/654)
|
||||||
- Add optional loki integration [#645](https://github.com/penpot/penpot/pull/645)
|
- Add optional loki integration [#645](https://github.com/penpot/penpot/pull/645)
|
||||||
- Add proper http session lifecycle handling.
|
- Add proper http session lifecycle handling.
|
||||||
- Allow to set border radius of each rect corner individually
|
- Allow to set border radius of each rect corner individually
|
||||||
- Bounce & Complaint handling [#635](https://github.com/penpot/penpot/pull/635)
|
- Bounce & Complaint handling [#635](https://github.com/penpot/penpot/pull/635)
|
||||||
- Disable groups interactions when holding "Ctrl" key (deep selection)
|
- Disable groups interactions when holding "Ctrl" key (deep selection)
|
||||||
- New action in context menu to "edit" some shapes (binded to key "Enter")
|
- New action in context menu to "edit" some shapes (bound to key "Enter")
|
||||||
|
|
||||||
|
|
||||||
### :bug: Bugs fixed
|
### :bug: Bugs fixed
|
||||||
|
|
|
@ -19,7 +19,7 @@ If you found a bug, please report it, as far as possible with:
|
||||||
- a browser and the browser version used
|
- a browser and the browser version used
|
||||||
- a dev tools console exception stack trace (if it is available)
|
- a dev tools console exception stack trace (if it is available)
|
||||||
|
|
||||||
If you found a bug that you consider better discuse in private (for
|
If you found a bug that you consider better discuss in private (for
|
||||||
example: security bugs), consider first send an email to
|
example: security bugs), consider first send an email to
|
||||||
`support@penpot.app`.
|
`support@penpot.app`.
|
||||||
|
|
||||||
|
|
|
@ -70,9 +70,9 @@ You can ask and answer questions, have open-ended conversations, and follow alon
|
||||||
|
|
||||||
✉️ [Mail us](mailto:info@penpot.app)
|
✉️ [Mail us](mailto:info@penpot.app)
|
||||||
|
|
||||||
💬 [Github discussions](https://github.com/penpot/penpot/discussions)
|
💬 [GitHub discussions](https://github.com/penpot/penpot/discussions)
|
||||||
|
|
||||||
🐞 [Github issues](mailto:info@penpot.apphttps://github.com/penpot/penpot/issues)
|
🐞 [GitHub issues](https://github.com/penpot/penpot/issues)
|
||||||
|
|
||||||
✍️️ [Gitter](https://gitter.im/penpot/community)
|
✍️️ [Gitter](https://gitter.im/penpot/community)
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ You can ask and answer questions, have open-ended conversations, and follow alon
|
||||||
You can ask and answer questions, have open-ended conversations, and follow along on decisions affecting the project.
|
You can ask and answer questions, have open-ended conversations, and follow along on decisions affecting the project.
|
||||||
Would you like to know more about Penpot? We recommend you to visit our youtube channel and learn more about the functionalities and possibilities of Penpot with our video tutorials.
|
Would you like to know more about Penpot? We recommend you to visit our youtube channel and learn more about the functionalities and possibilities of Penpot with our video tutorials.
|
||||||
|
|
||||||
🎞️ [Youtube channel](https://www.youtube.com/channel/UCAqS8G72uv9P5HG1IfgnQ9g)
|
🎞️ [YouTube channel](https://www.youtube.com/channel/UCAqS8G72uv9P5HG1IfgnQ9g)
|
||||||
|
|
||||||
## License ##
|
## License ##
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@
|
||||||
;; Copy run script template
|
;; Copy run script template
|
||||||
(-> ($ cp "./scripts/manage.template.sh" "./target/dist/manage.sh") check)
|
(-> ($ cp "./scripts/manage.template.sh" "./target/dist/manage.sh") check)
|
||||||
|
|
||||||
;; Add exec permisions to scripts.
|
;; Add exec permissions to scripts.
|
||||||
(-> ($ chmod +x "./target/dist/run.sh") check)
|
(-> ($ chmod +x "./target/dist/run.sh") check)
|
||||||
(-> ($ chmod +x "./target/dist/manage.sh") check)
|
(-> ($ chmod +x "./target/dist/manage.sh") check)
|
||||||
|
|
||||||
|
|
|
@ -173,14 +173,14 @@
|
||||||
|
|
||||||
(defn- process-report
|
(defn- process-report
|
||||||
[cfg {:keys [type profile-id] :as report}]
|
[cfg {:keys [type profile-id] :as report}]
|
||||||
(l/trace :action "procesing report" :report (pr-str report))
|
(l/trace :action "processing report" :report (pr-str report))
|
||||||
(cond
|
(cond
|
||||||
;; In this case we receive a bounce/complaint notification without
|
;; In this case we receive a bounce/complaint notification without
|
||||||
;; confirmed identity, we just emit a warning but do nothing about
|
;; confirmed identity, we just emit a warning but do nothing about
|
||||||
;; it because this is not a normal case. All notifications should
|
;; it because this is not a normal case. All notifications should
|
||||||
;; come with profile identity.
|
;; come with profile identity.
|
||||||
(nil? profile-id)
|
(nil? profile-id)
|
||||||
(l/warn :msg "a notification without identity recevied from AWS"
|
(l/warn :msg "a notification without identity received from AWS"
|
||||||
:report (pr-str report))
|
:report (pr-str report))
|
||||||
|
|
||||||
(= "bounce" type)
|
(= "bounce" type)
|
||||||
|
|
|
@ -130,7 +130,7 @@
|
||||||
(when-not (set/subset? provider-roles profile-roles)
|
(when-not (set/subset? provider-roles profile-roles)
|
||||||
(ex/raise :type :internal
|
(ex/raise :type :internal
|
||||||
:code :unable-to-auth
|
:code :unable-to-auth
|
||||||
:hint "not enought permissions"))))
|
:hint "not enough permissions"))))
|
||||||
|
|
||||||
(cond-> info
|
(cond-> info
|
||||||
(some? (:invitation-token state))
|
(some? (:invitation-token state))
|
||||||
|
|
|
@ -150,7 +150,7 @@
|
||||||
(defmethod ig/init-key ::collector
|
(defmethod ig/init-key ::collector
|
||||||
[_ cfg]
|
[_ cfg]
|
||||||
(when (contains? cf/flags :audit-log)
|
(when (contains? cf/flags :audit-log)
|
||||||
(l/info :msg "intializing audit log collector")
|
(l/info :msg "initializing audit log collector")
|
||||||
(let [input (a/chan 512 event-xform)
|
(let [input (a/chan 512 event-xform)
|
||||||
buffer (aa/batch input {:max-batch-size 100
|
buffer (aa/batch input {:max-batch-size 100
|
||||||
:max-batch-age (* 10 1000) ; 10s
|
:max-batch-age (* 10 1000) ; 10s
|
||||||
|
@ -159,7 +159,7 @@
|
||||||
(when-let [[_type events] (a/<! buffer)]
|
(when-let [[_type events] (a/<! buffer)]
|
||||||
(let [res (a/<! (persist-events cfg events))]
|
(let [res (a/<! (persist-events cfg events))]
|
||||||
(when (ex/exception? res)
|
(when (ex/exception? res)
|
||||||
(l/error :hint "error on persiting events"
|
(l/error :hint "error on persisting events"
|
||||||
:cause res)))
|
:cause res)))
|
||||||
(recur)))
|
(recur)))
|
||||||
|
|
||||||
|
@ -195,7 +195,7 @@
|
||||||
;; Archive Task
|
;; Archive Task
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
;; This is a task responsible to send the accomulated events to an
|
;; This is a task responsible to send the accumulated events to an
|
||||||
;; external service for archival.
|
;; external service for archival.
|
||||||
|
|
||||||
(declare archive-events)
|
(declare archive-events)
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
(defmethod ig/init-key ::reporter
|
(defmethod ig/init-key ::reporter
|
||||||
[_ {:keys [receiver uri] :as cfg}]
|
[_ {:keys [receiver uri] :as cfg}]
|
||||||
(when uri
|
(when uri
|
||||||
(l/info :msg "intializing loki reporter" :uri uri)
|
(l/info :msg "initializing loki reporter" :uri uri)
|
||||||
(let [input (a/chan (a/dropping-buffer 512))]
|
(let [input (a/chan (a/dropping-buffer 512))]
|
||||||
(receiver :sub input)
|
(receiver :sub input)
|
||||||
(a/go-loop []
|
(a/go-loop []
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
(defmethod ig/init-key ::receiver
|
(defmethod ig/init-key ::receiver
|
||||||
[_ {:keys [endpoint] :as cfg}]
|
[_ {:keys [endpoint] :as cfg}]
|
||||||
(l/info :msg "intializing ZMQ receiver" :bind endpoint)
|
(l/info :msg "initializing ZMQ receiver" :bind endpoint)
|
||||||
(let [buffer (a/chan 1)
|
(let [buffer (a/chan 1)
|
||||||
output (a/chan 1 (comp (filter map?)
|
output (a/chan 1 (comp (filter map?)
|
||||||
(map prepare)))
|
(map prepare)))
|
||||||
|
|
|
@ -202,7 +202,7 @@
|
||||||
:cause error))
|
:cause error))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; --- Fonts Generation
|
;; Fonts Generation
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(defmethod process :generate-fonts
|
(defmethod process :generate-fonts
|
||||||
|
@ -324,7 +324,7 @@
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(defn configure-assets-storage
|
(defn configure-assets-storage
|
||||||
"Given storage map, returns a storage configured with the apropriate
|
"Given storage map, returns a storage configured with the appropriate
|
||||||
backend for assets."
|
backend for assets."
|
||||||
[storage conn]
|
[storage conn]
|
||||||
(-> storage
|
(-> storage
|
||||||
|
|
|
@ -22,7 +22,7 @@ CREATE TABLE storage_data (
|
||||||
CREATE INDEX storage_data__id__idx ON storage_data(id);
|
CREATE INDEX storage_data__id__idx ON storage_data(id);
|
||||||
|
|
||||||
-- Table used for store inflight upload ids, for later recheck and
|
-- Table used for store inflight upload ids, for later recheck and
|
||||||
-- delete possible staled files that exists on the phisical storage
|
-- delete possible staled files that exists on the physical storage
|
||||||
-- but does not exists in the 'storage_object' table.
|
-- but does not exists in the 'storage_object' table.
|
||||||
|
|
||||||
CREATE TABLE storage_pending (
|
CREATE TABLE storage_pending (
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
-- Fix problem with content-type inconherence
|
-- Fix problem with content-type incoherence
|
||||||
|
|
||||||
UPDATE storage_object so
|
UPDATE storage_object so
|
||||||
SET metadata = jsonb_set(metadata, '{~:content-type}', to_jsonb(fmo.mtype))
|
SET metadata = jsonb_set(metadata, '{~:content-type}', to_jsonb(fmo.mtype))
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
--- This is a second migration but it should be applied when manual
|
--- This is a second migration but it should be applied when manual
|
||||||
--- migration intervention is alteady executed.
|
--- migration intervention is already executed.
|
||||||
|
|
||||||
ALTER TABLE file_media_object ALTER COLUMN media_id SET NOT NULL;
|
ALTER TABLE file_media_object ALTER COLUMN media_id SET NOT NULL;
|
||||||
DROP TABLE file_media_thumbnail;
|
DROP TABLE file_media_thumbnail;
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
alter index color_colection__team_id__idx to color_collection__team_id__idx;
|
||||||
|
alter index icon_colection__team_id__idx to icon_collection__team_id__idx;
|
||||||
|
alter index file__modified_at__has_media_trimed__idx to file__modified_at__has_media_trimmed__idx;
|
||||||
|
alter index media_bject__file_id__idx rename to media_object__file_id__idx;
|
|
@ -181,7 +181,7 @@
|
||||||
(reify RedisPubSubListener
|
(reify RedisPubSubListener
|
||||||
(message [it pattern topic message])
|
(message [it pattern topic message])
|
||||||
(message [it topic message]
|
(message [it topic message]
|
||||||
;; There are no back pressure, so we use a slidding
|
;; There are no back pressure, so we use a sliding
|
||||||
;; buffer for cases when the pubsub broker sends
|
;; buffer for cases when the pubsub broker sends
|
||||||
;; more messages that we can process.
|
;; more messages that we can process.
|
||||||
(let [val {:topic topic :message (blob/decode message)}]
|
(let [val {:topic topic :message (blob/decode message)}]
|
||||||
|
@ -243,7 +243,7 @@
|
||||||
(recur))
|
(recur))
|
||||||
(a/close! rcv-ch)))
|
(a/close! rcv-ch)))
|
||||||
|
|
||||||
;; Asyncrhonous message processing loop;x
|
;; Asynchronous message processing loop;x
|
||||||
(a/go-loop []
|
(a/go-loop []
|
||||||
(if-let [{:keys [topic message]} (a/<! rcv-ch)]
|
(if-let [{:keys [topic message]} (a/<! rcv-ch)]
|
||||||
;; This means we receive data from redis and we need to
|
;; This means we receive data from redis and we need to
|
||||||
|
|
|
@ -174,7 +174,7 @@
|
||||||
:content content})]
|
:content content})]
|
||||||
|
|
||||||
;; NOTE: this is done in SQL instead of using db/update!
|
;; NOTE: this is done in SQL instead of using db/update!
|
||||||
;; helper bacause currently the helper does not allow pass raw
|
;; helper because currently the helper does not allow pass raw
|
||||||
;; function call parameters to the underlying prepared
|
;; function call parameters to the underlying prepared
|
||||||
;; statement; in a future when we fix/improve it, this can be
|
;; statement; in a future when we fix/improve it, this can be
|
||||||
;; changed to use the helper.
|
;; changed to use the helper.
|
||||||
|
|
|
@ -181,7 +181,7 @@
|
||||||
:library-file-id library-id}))
|
:library-file-id library-id}))
|
||||||
|
|
||||||
|
|
||||||
;; --- Mutation: Update syncrhonization status of a link
|
;; --- Mutation: Update synchronization status of a link
|
||||||
|
|
||||||
(declare update-sync)
|
(declare update-sync)
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
(= :image (:type form)))
|
(= :image (:type form)))
|
||||||
(update-in [:metadata :id] #(get index % %))))
|
(update-in [:metadata :id] #(get index % %))))
|
||||||
|
|
||||||
;; A function responsible to analize all file data and
|
;; A function responsible to analyze all file data and
|
||||||
;; replace the old :component-file reference with the new
|
;; replace the old :component-file reference with the new
|
||||||
;; ones, using the provided file-index
|
;; ones, using the provided file-index
|
||||||
(relink-shapes [data]
|
(relink-shapes [data]
|
||||||
|
@ -294,7 +294,7 @@
|
||||||
;; move all files to the project
|
;; move all files to the project
|
||||||
(db/exec-one! conn [sql:move-files project-id fids])
|
(db/exec-one! conn [sql:move-files project-id fids])
|
||||||
|
|
||||||
;; delete posible broken relations on moved files
|
;; delete possible broken relations on moved files
|
||||||
(db/exec-one! conn [sql:delete-broken-relations pids])
|
(db/exec-one! conn [sql:delete-broken-relations pids])
|
||||||
|
|
||||||
nil)))
|
nil)))
|
||||||
|
@ -329,7 +329,7 @@
|
||||||
{:team-id team-id}
|
{:team-id team-id}
|
||||||
{:id project-id})
|
{:id project-id})
|
||||||
|
|
||||||
;; delete posible broken relations on moved files
|
;; delete possible broken relations on moved files
|
||||||
(db/exec-one! conn [sql:delete-broken-relations pids])
|
(db/exec-one! conn [sql:delete-broken-relations pids])
|
||||||
|
|
||||||
nil)))
|
nil)))
|
||||||
|
|
|
@ -108,7 +108,7 @@
|
||||||
:code :email-domain-is-not-allowed)))
|
:code :email-domain-is-not-allowed)))
|
||||||
|
|
||||||
;; Don't allow proceed in preparing registration if the profile is
|
;; Don't allow proceed in preparing registration if the profile is
|
||||||
;; already reported as spamer.
|
;; already reported as spammer.
|
||||||
(when (eml/has-bounce-reports? pool (:email params))
|
(when (eml/has-bounce-reports? pool (:email params))
|
||||||
(ex/raise :type :validation
|
(ex/raise :type :validation
|
||||||
:code :email-has-permanent-bounces
|
:code :email-has-permanent-bounces
|
||||||
|
@ -177,7 +177,7 @@
|
||||||
::audit/profile-id (:id profile)}))
|
::audit/profile-id (:id profile)}))
|
||||||
|
|
||||||
;; If auth backend is different from "penpot" means user is
|
;; If auth backend is different from "penpot" means user is
|
||||||
;; registring using third party auth mechanism; in this case
|
;; registering using third party auth mechanism; in this case
|
||||||
;; we need to mark this session as logged.
|
;; we need to mark this session as logged.
|
||||||
(not= "penpot" (:auth-backend profile))
|
(not= "penpot" (:auth-backend profile))
|
||||||
(with-meta (profile/strip-private-attrs profile)
|
(with-meta (profile/strip-private-attrs profile)
|
||||||
|
@ -446,7 +446,7 @@
|
||||||
;; --- MUTATION: Request Email Change
|
;; --- MUTATION: Request Email Change
|
||||||
|
|
||||||
(declare request-email-change)
|
(declare request-email-change)
|
||||||
(declare change-email-inmediatelly)
|
(declare change-email-immediately)
|
||||||
|
|
||||||
(s/def ::request-email-change
|
(s/def ::request-email-change
|
||||||
(s/keys :req-un [::email]))
|
(s/keys :req-un [::email]))
|
||||||
|
@ -462,9 +462,9 @@
|
||||||
(if (or (cf/get :smtp-enabled)
|
(if (or (cf/get :smtp-enabled)
|
||||||
(contains? cf/flags :smtp))
|
(contains? cf/flags :smtp))
|
||||||
(request-email-change cfg params)
|
(request-email-change cfg params)
|
||||||
(change-email-inmediatelly cfg params)))))
|
(change-email-immediately cfg params)))))
|
||||||
|
|
||||||
(defn- change-email-inmediatelly
|
(defn- change-email-immediately
|
||||||
[{:keys [conn]} {:keys [profile email] :as params}]
|
[{:keys [conn]} {:keys [profile email] :as params}]
|
||||||
(when (not= email (:email profile))
|
(when (not= email (:email profile))
|
||||||
(check-profile-existence! conn params))
|
(check-profile-existence! conn params))
|
||||||
|
@ -647,7 +647,7 @@
|
||||||
(let [rows (db/exec! conn [sql:owned-teams profile-id])]
|
(let [rows (db/exec! conn [sql:owned-teams profile-id])]
|
||||||
;; If we found owned teams with more than one profile we don't
|
;; If we found owned teams with more than one profile we don't
|
||||||
;; allow delete profile until the user properly transfer ownership
|
;; allow delete profile until the user properly transfer ownership
|
||||||
;; or explictly removes all participants from the team.
|
;; or explicitly removes all participants from the team.
|
||||||
(when (some #(> (:num-profiles %) 1) rows)
|
(when (some #(> (:num-profiles %) 1) rows)
|
||||||
(ex/raise :type :validation
|
(ex/raise :type :validation
|
||||||
:code :owner-teams-with-people
|
:code :owner-teams-with-people
|
||||||
|
|
|
@ -116,7 +116,7 @@
|
||||||
(when (some :is-owner perms)
|
(when (some :is-owner perms)
|
||||||
(ex/raise :type :validation
|
(ex/raise :type :validation
|
||||||
:code :owner-cant-leave-team
|
:code :owner-cant-leave-team
|
||||||
:hint "reasing owner before leave"))
|
:hint "releasing owner before leave"))
|
||||||
|
|
||||||
(when-not (> (count members) 1)
|
(when-not (> (count members) 1)
|
||||||
(ex/raise :type :validation
|
(ex/raise :type :validation
|
||||||
|
@ -136,7 +136,7 @@
|
||||||
(s/keys :req-un [::profile-id ::id]))
|
(s/keys :req-un [::profile-id ::id]))
|
||||||
|
|
||||||
;; TODO: right now just don't allow delete default team, in future it
|
;; TODO: right now just don't allow delete default team, in future it
|
||||||
;; should raise a speific exception for signal that this acction is
|
;; should raise a specific exception for signal that this action is
|
||||||
;; not allowed.
|
;; not allowed.
|
||||||
|
|
||||||
(sv/defmethod ::delete-team
|
(sv/defmethod ::delete-team
|
||||||
|
@ -175,8 +175,8 @@
|
||||||
|
|
||||||
;; We retrieve all team members instead of query the
|
;; We retrieve all team members instead of query the
|
||||||
;; database for a single member. This is just for
|
;; database for a single member. This is just for
|
||||||
;; convenience, if this bocomes a bottleneck or problematic,
|
;; convenience, if this becomes a bottleneck or problematic,
|
||||||
;; we will change it to more efficient fetch mechanims.
|
;; we will change it to more efficient fetch mechanisms.
|
||||||
members (teams/retrieve-team-members conn team-id)
|
members (teams/retrieve-team-members conn team-id)
|
||||||
member (d/seek #(= member-id (:id %)) members)
|
member (d/seek #(= member-id (:id %)) members)
|
||||||
|
|
||||||
|
|
|
@ -134,7 +134,7 @@
|
||||||
|
|
||||||
;; If the session does not matches the invited member, replace
|
;; If the session does not matches the invited member, replace
|
||||||
;; the session with a new one matching the invited member.
|
;; the session with a new one matching the invited member.
|
||||||
;; This techinique should be considered secure because the
|
;; This technique should be considered secure because the
|
||||||
;; user clicking the link he already has access to the email
|
;; user clicking the link he already has access to the email
|
||||||
;; account.
|
;; account.
|
||||||
(with-meta
|
(with-meta
|
||||||
|
@ -179,7 +179,7 @@
|
||||||
::audit/profile-id member-id}))
|
::audit/profile-id member-id}))
|
||||||
|
|
||||||
;; In this case, we wait until frontend app redirect user to
|
;; In this case, we wait until frontend app redirect user to
|
||||||
;; registeration page, the user is correctly registered and the
|
;; registration page, the user is correctly registered and the
|
||||||
;; register mutation call us again with the same token to finally
|
;; register mutation call us again with the same token to finally
|
||||||
;; create the corresponding team-profile relation from the first
|
;; create the corresponding team-profile relation from the first
|
||||||
;; condition of this if.
|
;; condition of this if.
|
||||||
|
|
|
@ -84,8 +84,8 @@
|
||||||
(let [perms (get-permissions conn profile-id file-id)
|
(let [perms (get-permissions conn profile-id file-id)
|
||||||
ldata (retrieve-share-link conn file-id share-id)]
|
ldata (retrieve-share-link conn file-id share-id)]
|
||||||
|
|
||||||
;; NOTE: in a future when share-link becomes more powerfull and
|
;; NOTE: in a future when share-link becomes more powerful and
|
||||||
;; will allow us specify which parts of the app is availabel, we
|
;; will allow us specify which parts of the app is available, we
|
||||||
;; will probably need to tweak this function in order to expose
|
;; will probably need to tweak this function in order to expose
|
||||||
;; this flags to the frontend.
|
;; this flags to the frontend.
|
||||||
(cond
|
(cond
|
||||||
|
@ -227,7 +227,7 @@
|
||||||
(= frame-id uuid/zero)
|
(= frame-id uuid/zero)
|
||||||
(not (some? (get-in objects [frame-id :thumbnail]))))))
|
(not (some? (get-in objects [frame-id :thumbnail]))))))
|
||||||
|
|
||||||
;; We need to remove from the attribute :shapes its childrens because
|
;; We need to remove from the attribute :shapes its children because
|
||||||
;; they will not be sent in the data
|
;; they will not be sent in the data
|
||||||
remove-frame-children
|
remove-frame-children
|
||||||
(fn [[id shape]]
|
(fn [[id shape]]
|
||||||
|
|
|
@ -111,6 +111,6 @@
|
||||||
;; --- Attrs Helpers
|
;; --- Attrs Helpers
|
||||||
|
|
||||||
(defn strip-private-attrs
|
(defn strip-private-attrs
|
||||||
"Only selects a publicy visible profile attrs."
|
"Only selects a publicly visible profile attrs."
|
||||||
[row]
|
[row]
|
||||||
(dissoc row :password :deleted-at))
|
(dissoc row :password :deleted-at))
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
(ex/raise :type :not-found
|
(ex/raise :type :not-found
|
||||||
:code :object-not-found))
|
:code :object-not-found))
|
||||||
|
|
||||||
;; When we have only profile, we need to check read permissiones
|
;; When we have only profile, we need to check read permissions
|
||||||
;; on file.
|
;; on file.
|
||||||
(when (and profile-id (not slink))
|
(when (and profile-id (not slink))
|
||||||
(files/check-read-permissions! conn profile-id file-id))
|
(files/check-read-permissions! conn profile-id file-id))
|
||||||
|
|
|
@ -70,7 +70,7 @@
|
||||||
|
|
||||||
|
|
||||||
(defn duplicate-file
|
(defn duplicate-file
|
||||||
"This is a raw version of duplication of file just only for forensic analisys"
|
"This is a raw version of duplication of file just only for forensic analysis"
|
||||||
[system file-id email]
|
[system file-id email]
|
||||||
(db/with-atomic [conn (:app.db/pool system)]
|
(db/with-atomic [conn (:app.db/pool system)]
|
||||||
(when-let [profile (some->> (prof/retrieve-profile-data-by-email conn (str/lower email))
|
(when-let [profile (some->> (prof/retrieve-profile-data-by-email conn (str/lower email))
|
||||||
|
|
|
@ -188,7 +188,7 @@
|
||||||
object))
|
object))
|
||||||
|
|
||||||
(defn clone-object
|
(defn clone-object
|
||||||
"Creates a clone of the provided object using backend basded efficient
|
"Creates a clone of the provided object using backend based efficient
|
||||||
method. Always clones objects to the configured default."
|
method. Always clones objects to the configured default."
|
||||||
[{:keys [pool conn] :as storage} object]
|
[{:keys [pool conn] :as storage} object]
|
||||||
(us/assert ::storage storage)
|
(us/assert ::storage storage)
|
||||||
|
@ -323,18 +323,18 @@
|
||||||
returning *;")
|
returning *;")
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; Garbage Collection: Analize touched objects
|
;; Garbage Collection: Analyze touched objects
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
;; This task is part of the garbage collection of storage objects and
|
;; This task is part of the garbage collection of storage objects and
|
||||||
;; is responsible on analizing the touched objects and mark them for deletion
|
;; is responsible on analyzing the touched objects and mark them for deletion
|
||||||
;; if corresponds.
|
;; if corresponds.
|
||||||
;;
|
;;
|
||||||
;; When file_media_object is deleted, the depending storage_object are
|
;; When file_media_object is deleted, the depending storage_object are
|
||||||
;; marked as touched. This means that some files that depend on a
|
;; marked as touched. This means that some files that depend on a
|
||||||
;; concrete storage_object are no longer exists and maybe this
|
;; concrete storage_object are no longer exists and maybe this
|
||||||
;; storage_object is no longer necessary and can be ellegible for
|
;; storage_object is no longer necessary and can be eligible for
|
||||||
;; elimination. This task peridically analizes touched objects and
|
;; elimination. This task periodically analyzes touched objects and
|
||||||
;; mark them as freeze (means that has other references and the object
|
;; mark them as freeze (means that has other references and the object
|
||||||
;; is still valid) or deleted (no more references to this object so is
|
;; is still valid) or deleted (no more references to this object so is
|
||||||
;; ready to be deleted).
|
;; ready to be deleted).
|
||||||
|
@ -408,7 +408,7 @@
|
||||||
;; For this situations we need to write a "log" of inserted files that
|
;; For this situations we need to write a "log" of inserted files that
|
||||||
;; are checked in some time in future. If physical file exists but the
|
;; are checked in some time in future. If physical file exists but the
|
||||||
;; database refence does not exists means that leaked file is found
|
;; database refence does not exists means that leaked file is found
|
||||||
;; and is inmediatelly deleted. The responsability of this task is
|
;; and is immediately deleted. The responsibility of this task is
|
||||||
;; check that write log for possible leaked files.
|
;; check that write log for possible leaked files.
|
||||||
|
|
||||||
(def recheck-min-age (dt/duration {:hours 1}))
|
(def recheck-min-age (dt/duration {:hours 1}))
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
(ns app.tasks.file-media-gc
|
(ns app.tasks.file-media-gc
|
||||||
"A maintenance task that is responsible to purge the unused media
|
"A maintenance task that is responsible to purge the unused media
|
||||||
objects from files. A file is ellegible to be garbage collected
|
objects from files. A file is eligible to be garbage collected
|
||||||
after some period of inactivity (the default threshold is 72h)."
|
after some period of inactivity (the default threshold is 72h)."
|
||||||
(:require
|
(:require
|
||||||
[app.common.logging :as l]
|
[app.common.logging :as l]
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
:thumbnail-id (:thumbnail-id mobj))
|
:thumbnail-id (:thumbnail-id mobj))
|
||||||
|
|
||||||
;; NOTE: deleting the file-media-object in the database
|
;; NOTE: deleting the file-media-object in the database
|
||||||
;; automatically marks as toched the referenced storage
|
;; automatically marks as touched the referenced storage
|
||||||
;; objects. The touch mechanism is needed because many files can
|
;; objects. The touch mechanism is needed because many files can
|
||||||
;; point to the same storage objects and we can't just delete
|
;; point to the same storage objects and we can't just delete
|
||||||
;; them.
|
;; them.
|
||||||
|
|
|
@ -129,7 +129,7 @@
|
||||||
(doseq [{:keys [id] :as profile} profiles]
|
(doseq [{:keys [id] :as profile} profiles]
|
||||||
(l/trace :action "delete object" :table table :id id)
|
(l/trace :action "delete object" :table table :id id)
|
||||||
|
|
||||||
;; Mark the owned teams as deleted; this enables them to be procesed
|
;; Mark the owned teams as deleted; this enables them to be processed
|
||||||
;; in the same transaction in the "team" table step.
|
;; in the same transaction in the "team" table step.
|
||||||
(db/exec-one! conn [sql:mark-owned-teams-deleted id max-age])
|
(db/exec-one! conn [sql:mark-owned-teams-deleted id max-age])
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
;; Copyright (c) UXBOX Labs SL
|
;; Copyright (c) UXBOX Labs SL
|
||||||
|
|
||||||
(ns app.tasks.telemetry
|
(ns app.tasks.telemetry
|
||||||
"A task that is reponsible to collect anonymous statistical
|
"A task that is responsible to collect anonymous statistical
|
||||||
information about the current instance and send it to the telemetry
|
information about the current instance and send it to the telemetry
|
||||||
server."
|
server."
|
||||||
(:require
|
(:require
|
||||||
|
|
|
@ -207,7 +207,7 @@
|
||||||
:content html}]))}))
|
:content html}]))}))
|
||||||
|
|
||||||
(s/def ::priority #{:high :low})
|
(s/def ::priority #{:high :low})
|
||||||
(s/def ::to (s/or :sigle ::us/email
|
(s/def ::to (s/or :single ::us/email
|
||||||
:multi (s/coll-of ::us/email)))
|
:multi (s/coll-of ::us/email)))
|
||||||
(s/def ::from ::us/email)
|
(s/def ::from ::us/email)
|
||||||
(s/def ::reply-to ::us/email)
|
(s/def ::reply-to ::us/email)
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
;; --- Implementation
|
;; --- Implementation
|
||||||
|
|
||||||
(defn- registered?
|
(defn- registered?
|
||||||
"Check if concrete migration is already registred."
|
"Check if concrete migration is already registered."
|
||||||
[pool modname stepname]
|
[pool modname stepname]
|
||||||
(let [sql "select * from migrations where module=? and step=?"
|
(let [sql "select * from migrations where module=? and step=?"
|
||||||
rows (jdbc/execute! pool [sql modname stepname])]
|
rows (jdbc/execute! pool [sql modname stepname])]
|
||||||
|
|
|
@ -470,7 +470,7 @@
|
||||||
:type :summary
|
:type :summary
|
||||||
:quantiles []
|
:quantiles []
|
||||||
:name "tasks_checkout_timing"
|
:name "tasks_checkout_timing"
|
||||||
:help "Latency measured between scheduld_at and execution time."
|
:help "Latency measured between scheduled_at and execution time."
|
||||||
:wrap (fn [rootf mobj]
|
:wrap (fn [rootf mobj]
|
||||||
(let [mdata (meta rootf)
|
(let [mdata (meta rootf)
|
||||||
origf (::original mdata rootf)]
|
origf (::original mdata rootf)]
|
||||||
|
|
|
@ -174,12 +174,12 @@
|
||||||
:type :image
|
:type :image
|
||||||
:metadata {:id (:id fmo1)}}}]})]
|
:metadata {:id (:id fmo1)}}}]})]
|
||||||
|
|
||||||
;; run the task inmediatelly
|
;; run the task immediately
|
||||||
(let [task (:app.tasks.file-media-gc/handler th/*system*)
|
(let [task (:app.tasks.file-media-gc/handler th/*system*)
|
||||||
res (task {})]
|
res (task {})]
|
||||||
(t/is (= 0 (:processed res))))
|
(t/is (= 0 (:processed res))))
|
||||||
|
|
||||||
;; make the file ellegible for GC waiting 300ms (configured
|
;; make the file eligible for GC waiting 300ms (configured
|
||||||
;; timeout for testing)
|
;; timeout for testing)
|
||||||
(th/sleep 300)
|
(th/sleep 300)
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
|
|
||||||
;; (th/print-result! out)
|
;; (th/print-result! out)
|
||||||
|
|
||||||
;; Check tha tresult is correct
|
;; Check that result is correct
|
||||||
(t/is (nil? (:error out)))
|
(t/is (nil? (:error out)))
|
||||||
(let [result (:result out)]
|
(let [result (:result out)]
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@
|
||||||
|
|
||||||
;; (th/print-result! out)
|
;; (th/print-result! out)
|
||||||
|
|
||||||
;; Check tha tresult is correct
|
;; Check that result is correct
|
||||||
(t/is (nil? (:error out)))
|
(t/is (nil? (:error out)))
|
||||||
(let [result (:result out)]
|
(let [result (:result out)]
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@
|
||||||
:name "project 1 (copy)"}
|
:name "project 1 (copy)"}
|
||||||
out (th/mutation! data)]
|
out (th/mutation! data)]
|
||||||
|
|
||||||
;; Check tha tresult is correct
|
;; Check that result is correct
|
||||||
(t/is (nil? (:error out)))
|
(t/is (nil? (:error out)))
|
||||||
|
|
||||||
(let [result (:result out)]
|
(let [result (:result out)]
|
||||||
|
@ -254,7 +254,7 @@
|
||||||
:name "project 1 (copy)"}
|
:name "project 1 (copy)"}
|
||||||
out (th/mutation! data)]
|
out (th/mutation! data)]
|
||||||
|
|
||||||
;; Check tha tresult is correct
|
;; Check that result is correct
|
||||||
(t/is (nil? (:error out)))
|
(t/is (nil? (:error out)))
|
||||||
|
|
||||||
(let [result (:result out)]
|
(let [result (:result out)]
|
||||||
|
|
|
@ -68,7 +68,7 @@
|
||||||
(t/is (true? (sto/del-object storage object)))
|
(t/is (true? (sto/del-object storage object)))
|
||||||
|
|
||||||
;; retrieving the same object should be not nil because the
|
;; retrieving the same object should be not nil because the
|
||||||
;; deletion is not inmediate
|
;; deletion is not immediate
|
||||||
(t/is (some? (sto/get-object-data storage object)))
|
(t/is (some? (sto/get-object-data storage object)))
|
||||||
(t/is (some? (sto/get-object-url storage object)))
|
(t/is (some? (sto/get-object-url storage object)))
|
||||||
(t/is (some? (sto/get-object-path storage object)))
|
(t/is (some? (sto/get-object-path storage object)))
|
||||||
|
@ -248,7 +248,7 @@
|
||||||
(th/sleep 200)
|
(th/sleep 200)
|
||||||
|
|
||||||
;; storage_pending table should have the object
|
;; storage_pending table should have the object
|
||||||
;; registred independently of the aborted transaction.
|
;; registered independently of the aborted transaction.
|
||||||
(let [rows (db/exec! th/*pool* ["select * from storage_pending"])]
|
(let [rows (db/exec! th/*pool* ["select * from storage_pending"])]
|
||||||
(t/is (= 1 (count rows))))
|
(t/is (= 1 (count rows))))
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
;; Extract some attributes of a list of shapes.
|
;; Extract some attributes of a list of shapes.
|
||||||
;; For each attribute, if the value is the same in all shapes,
|
;; For each attribute, if the value is the same in all shapes,
|
||||||
;; wll take this value. If there is any shape that is different,
|
;; will take this value. If there is any shape that is different,
|
||||||
;; the value of the attribute will be the keyword :multiple.
|
;; the value of the attribute will be the keyword :multiple.
|
||||||
;;
|
;;
|
||||||
;; If some shape has the value nil in any attribute, it's
|
;; If some shape has the value nil in any attribute, it's
|
||||||
|
|
|
@ -178,7 +178,7 @@
|
||||||
"Maps a function to each pair of values that can be combined inside the
|
"Maps a function to each pair of values that can be combined inside the
|
||||||
function without repetition.
|
function without repetition.
|
||||||
|
|
||||||
Optional parmeters:
|
Optional parameters:
|
||||||
`pred?` A predicate that if not satisfied won't process the pair
|
`pred?` A predicate that if not satisfied won't process the pair
|
||||||
`target?` A collection that will be used as seed to be stored
|
`target?` A collection that will be used as seed to be stored
|
||||||
|
|
||||||
|
@ -433,8 +433,8 @@
|
||||||
(str maybe-keyword)))))
|
(str maybe-keyword)))))
|
||||||
|
|
||||||
(defn with-next
|
(defn with-next
|
||||||
"Given a collectin will return a new collection where each element
|
"Given a collection will return a new collection where each element
|
||||||
is paried with the next item in the collection
|
is paired with the next item in the collection
|
||||||
(with-next (range 5)) => [[0 1] [1 2] [2 3] [3 4] [4 nil]"
|
(with-next (range 5)) => [[0 1] [1 2] [2 3] [3 4] [4 nil]"
|
||||||
[coll]
|
[coll]
|
||||||
(map vector
|
(map vector
|
||||||
|
@ -442,8 +442,8 @@
|
||||||
(concat [] (rest coll) [nil])))
|
(concat [] (rest coll) [nil])))
|
||||||
|
|
||||||
(defn with-prev
|
(defn with-prev
|
||||||
"Given a collectin will return a new collection where each element
|
"Given a collection will return a new collection where each element
|
||||||
is paried with the previous item in the collection
|
is paired with the previous item in the collection
|
||||||
(with-prev (range 5)) => [[0 nil] [1 0] [2 1] [3 2] [4 3]"
|
(with-prev (range 5)) => [[0 nil] [1 0] [2 1] [3 2] [4 3]"
|
||||||
[coll]
|
[coll]
|
||||||
(map vector
|
(map vector
|
||||||
|
@ -469,7 +469,7 @@
|
||||||
(keyword (str prefix kw))))
|
(keyword (str prefix kw))))
|
||||||
|
|
||||||
(defn tap
|
(defn tap
|
||||||
"Simpilar to the tap in rxjs but for plain collections"
|
"Similar to the tap in rxjs but for plain collections"
|
||||||
[f coll]
|
[f coll]
|
||||||
(f coll)
|
(f coll)
|
||||||
coll)
|
coll)
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
(s/def ::type keyword?)
|
(s/def ::type keyword?)
|
||||||
(s/def ::code keyword?)
|
(s/def ::code keyword?)
|
||||||
(s/def ::mesage string?)
|
(s/def ::message string?)
|
||||||
(s/def ::hint string?)
|
(s/def ::hint string?)
|
||||||
(s/def ::cause #?(:clj #(instance? Throwable %)
|
(s/def ::cause #?(:clj #(instance? Throwable %)
|
||||||
:cljs #(instance? js/Error %)))
|
:cljs #(instance? js/Error %)))
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
(s/keys :req-un [::type]
|
(s/keys :req-un [::type]
|
||||||
:opt-un [::code
|
:opt-un [::code
|
||||||
::hint
|
::hint
|
||||||
::mesage
|
::message
|
||||||
::cause]))
|
::cause]))
|
||||||
|
|
||||||
(defn error
|
(defn error
|
||||||
|
|
|
@ -78,7 +78,7 @@
|
||||||
"Distribute equally the space between shapes in the given axis. If
|
"Distribute equally the space between shapes in the given axis. If
|
||||||
there is no space enough, it does nothing. It takes into account
|
there is no space enough, it does nothing. It takes into account
|
||||||
the form of the shape and the rotation, what is distributed is
|
the form of the shape and the rotation, what is distributed is
|
||||||
the wrapping recangles of the shapes. If any shape is a group,
|
the wrapping rectangles of the shapes. If any shape is a group,
|
||||||
move also all of its recursive children."
|
move also all of its recursive children."
|
||||||
[shapes axis objects]
|
[shapes axis objects]
|
||||||
(let [coord (if (= axis :horizontal) :x :y)
|
(let [coord (if (= axis :horizontal) :x :y)
|
||||||
|
@ -116,7 +116,7 @@
|
||||||
(mapcat #(recursive-move %1 {coord %2 other-coord 0} objects)
|
(mapcat #(recursive-move %1 {coord %2 other-coord 0} objects)
|
||||||
sorted-shapes deltas)))))
|
sorted-shapes deltas)))))
|
||||||
|
|
||||||
;; Adjusto to viewport
|
;; Adjust to viewport
|
||||||
|
|
||||||
(defn adjust-to-viewport
|
(defn adjust-to-viewport
|
||||||
([viewport srect] (adjust-to-viewport viewport srect nil))
|
([viewport srect] (adjust-to-viewport viewport srect nil))
|
||||||
|
|
|
@ -187,14 +187,14 @@
|
||||||
(defn round
|
(defn round
|
||||||
"Change the precision of the point coordinates."
|
"Change the precision of the point coordinates."
|
||||||
([point] (round point 0))
|
([point] (round point 0))
|
||||||
([{:keys [x y] :as p} decimanls]
|
([{:keys [x y] :as p} decimals]
|
||||||
(assert (point? p))
|
(assert (point? p))
|
||||||
(assert (number? decimanls))
|
(assert (number? decimals))
|
||||||
(Point. (mth/precision x decimanls)
|
(Point. (mth/precision x decimals)
|
||||||
(mth/precision y decimanls))))
|
(mth/precision y decimals))))
|
||||||
|
|
||||||
(defn transform
|
(defn transform
|
||||||
"Transform a point applying a matrix transfomation."
|
"Transform a point applying a matrix transformation."
|
||||||
[{:keys [x y] :as p} {:keys [a b c d e f]}]
|
[{:keys [x y] :as p} {:keys [a b c d e f]}]
|
||||||
(assert (point? p))
|
(assert (point? p))
|
||||||
(Point. (+ (* x a) (* y c) e)
|
(Point. (+ (* x a) (* y c) e)
|
||||||
|
|
|
@ -147,7 +147,7 @@
|
||||||
(not= wn 0))))
|
(not= wn 0))))
|
||||||
|
|
||||||
;; A intersects with B
|
;; A intersects with B
|
||||||
;; Three posible cases:
|
;; Three possible cases:
|
||||||
;; 1) A is inside of B
|
;; 1) A is inside of B
|
||||||
;; 2) B is inside of A
|
;; 2) B is inside of A
|
||||||
;; 3) A intersects B
|
;; 3) A intersects B
|
||||||
|
@ -207,11 +207,11 @@
|
||||||
(<= v 1)))
|
(<= v 1)))
|
||||||
|
|
||||||
(defn intersects-line-ellipse?
|
(defn intersects-line-ellipse?
|
||||||
"Checks wether a single line intersects with the given ellipse"
|
"Checks whether a single line intersects with the given ellipse"
|
||||||
[[{x1 :x y1 :y} {x2 :x y2 :y}] {:keys [cx cy rx ry]}]
|
[[{x1 :x y1 :y} {x2 :x y2 :y}] {:keys [cx cy rx ry]}]
|
||||||
|
|
||||||
;; Given the ellipse inequality after inserting the line parametric equations
|
;; Given the ellipse inequality after inserting the line parametric equations
|
||||||
;; we resolve t and gives us a cuadratic formula
|
;; we resolve t and gives us a quadratic formula
|
||||||
;; The result of this quadratic will give us a value of T that needs to be
|
;; The result of this quadratic will give us a value of T that needs to be
|
||||||
;; between 0-1 to be in the segment
|
;; between 0-1 to be in the segment
|
||||||
|
|
||||||
|
@ -284,7 +284,7 @@
|
||||||
(intersects-lines-ellipse? rect-lines ellipse-data))))
|
(intersects-lines-ellipse? rect-lines ellipse-data))))
|
||||||
|
|
||||||
(defn overlaps?
|
(defn overlaps?
|
||||||
"General case to check for overlaping between shapes and a rectangle"
|
"General case to check for overlapping between shapes and a rectangle"
|
||||||
[shape rect]
|
[shape rect]
|
||||||
(let [stroke-width (/ (or (:stroke-width shape) 0) 2)
|
(let [stroke-width (/ (or (:stroke-width shape) 0) 2)
|
||||||
rect (-> rect
|
rect (-> rect
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
(mth/almost-zero? (- a b)))
|
(mth/almost-zero? (- a b)))
|
||||||
|
|
||||||
(defn calculate-opposite-handler
|
(defn calculate-opposite-handler
|
||||||
"Given a point and its handler, gives the symetric handler"
|
"Given a point and its handler, gives the symmetric handler"
|
||||||
[point handler]
|
[point handler]
|
||||||
(let [handler-vector (gpt/to-vec point handler)]
|
(let [handler-vector (gpt/to-vec point handler)]
|
||||||
(gpt/add point (gpt/negate handler-vector))))
|
(gpt/add point (gpt/negate handler-vector))))
|
||||||
|
@ -179,7 +179,7 @@
|
||||||
(and (mth/almost-zero? d) (mth/almost-zero? a))
|
(and (mth/almost-zero? d) (mth/almost-zero? a))
|
||||||
[(/ (- c) b)]
|
[(/ (- c) b)]
|
||||||
|
|
||||||
;; Cuadratic
|
;; Quadratic
|
||||||
(mth/almost-zero? d)
|
(mth/almost-zero? d)
|
||||||
[(/ (+ (- b) sqrt-b2-4ac)
|
[(/ (+ (- b) sqrt-b2-4ac)
|
||||||
(* 2 a))
|
(* 2 a))
|
||||||
|
@ -681,7 +681,7 @@
|
||||||
(defn ray-line-intersect
|
(defn ray-line-intersect
|
||||||
[point [a b :as line]]
|
[point [a b :as line]]
|
||||||
|
|
||||||
;; If the ray is paralell to the line there will be no crossings
|
;; If the ray is parallel to the line there will be no crossings
|
||||||
(let [ray-line [point (gpt/point (inc (:x point)) (:y point))]
|
(let [ray-line [point (gpt/point (inc (:x point)) (:y point))]
|
||||||
;; Rays fail when fall just in a vertex so we move a bit upward
|
;; Rays fail when fall just in a vertex so we move a bit upward
|
||||||
;; because only want to use this for insideness
|
;; because only want to use this for insideness
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
(mapv #(gpt/add % move-vec))))
|
(mapv #(gpt/add % move-vec))))
|
||||||
|
|
||||||
(defn move
|
(defn move
|
||||||
"Move the shape relativelly to its current
|
"Move the shape relatively to its current
|
||||||
position applying the provided delta."
|
position applying the provided delta."
|
||||||
[shape {dx :x dy :y}]
|
[shape {dx :x dy :y}]
|
||||||
(let [dx (d/check-num dx)
|
(let [dx (d/check-num dx)
|
||||||
|
@ -71,7 +71,7 @@
|
||||||
:else scale))
|
:else scale))
|
||||||
|
|
||||||
(defn- calculate-skew-angle
|
(defn- calculate-skew-angle
|
||||||
"Calculates the skew angle of the paralelogram given by the points"
|
"Calculates the skew angle of the parallelogram given by the points"
|
||||||
[[p1 _ p3 p4]]
|
[[p1 _ p3 p4]]
|
||||||
(let [v1 (gpt/to-vec p3 p4)
|
(let [v1 (gpt/to-vec p3 p4)
|
||||||
v2 (gpt/to-vec p4 p1)]
|
v2 (gpt/to-vec p4 p1)]
|
||||||
|
@ -83,13 +83,13 @@
|
||||||
(- 90 (gpt/angle-with-other v1 v2)))))
|
(- 90 (gpt/angle-with-other v1 v2)))))
|
||||||
|
|
||||||
(defn- calculate-height
|
(defn- calculate-height
|
||||||
"Calculates the height of a paralelogram given by the points"
|
"Calculates the height of a parallelogram given by the points"
|
||||||
[[p1 _ _ p4]]
|
[[p1 _ _ p4]]
|
||||||
(-> (gpt/to-vec p4 p1)
|
(-> (gpt/to-vec p4 p1)
|
||||||
(gpt/length)))
|
(gpt/length)))
|
||||||
|
|
||||||
(defn- calculate-width
|
(defn- calculate-width
|
||||||
"Calculates the width of a paralelogram given by the points"
|
"Calculates the width of a parallelogram given by the points"
|
||||||
[[p1 p2 _ _]]
|
[[p1 p2 _ _]]
|
||||||
(-> (gpt/to-vec p1 p2)
|
(-> (gpt/to-vec p1 p2)
|
||||||
(gpt/length)))
|
(gpt/length)))
|
||||||
|
@ -299,7 +299,7 @@
|
||||||
(gpr/rect->points)
|
(gpr/rect->points)
|
||||||
(gco/transform-points shape-center (:transform group (gmt/matrix))))
|
(gco/transform-points shape-center (:transform group (gmt/matrix))))
|
||||||
|
|
||||||
;; Calculte the new selrect
|
;; Calculate the new selrect
|
||||||
new-selrect (gpr/points->selrect base-points)]
|
new-selrect (gpr/points->selrect base-points)]
|
||||||
|
|
||||||
;; Updates the shape and the applytransform-rect will update the other properties
|
;; Updates the shape and the applytransform-rect will update the other properties
|
||||||
|
|
|
@ -291,7 +291,7 @@
|
||||||
(reduce update-parent-id $ shapes)
|
(reduce update-parent-id $ shapes)
|
||||||
|
|
||||||
;; Analyze the old parents and clear the old links
|
;; Analyze the old parents and clear the old links
|
||||||
;; only if the new parrent is different form old
|
;; only if the new parent is different form old
|
||||||
;; parent.
|
;; parent.
|
||||||
(reduce (partial remove-from-old-parent cpindex) $ shapes)
|
(reduce (partial remove-from-old-parent cpindex) $ shapes)
|
||||||
|
|
||||||
|
|
|
@ -256,7 +256,7 @@
|
||||||
|
|
||||||
(defn fix-move-to
|
(defn fix-move-to
|
||||||
[content]
|
[content]
|
||||||
;; Remove the field `:prev` and makes the necesaries `move-to`
|
;; Remove the field `:prev` and makes the necessaries `move-to`
|
||||||
;; then clean the subpaths
|
;; then clean the subpaths
|
||||||
|
|
||||||
(loop [current (first content)
|
(loop [current (first content)
|
||||||
|
|
|
@ -147,7 +147,7 @@
|
||||||
[])))))
|
[])))))
|
||||||
|
|
||||||
(defn opposite-index
|
(defn opposite-index
|
||||||
"Calculate sthe opposite index given a prefix and an index"
|
"Calculates the opposite index given a prefix and an index"
|
||||||
[content index prefix]
|
[content index prefix]
|
||||||
|
|
||||||
(let [point (if (= prefix :c2)
|
(let [point (if (= prefix :c2)
|
||||||
|
|
|
@ -126,7 +126,7 @@
|
||||||
(pt= (:from subpath) (:to subpath)))
|
(pt= (:from subpath) (:to subpath)))
|
||||||
|
|
||||||
(defn close-subpaths
|
(defn close-subpaths
|
||||||
"Searches a path for posible supaths that can create closed loops and merge them"
|
"Searches a path for possible supaths that can create closed loops and merge them"
|
||||||
[content]
|
[content]
|
||||||
(let [subpaths (get-subpaths content)
|
(let [subpaths (get-subpaths content)
|
||||||
closed-subpaths
|
closed-subpaths
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
;; NOTE: don't remove this, causes exception on advanced build
|
;; NOTE: don't remove this, causes exception on advanced build
|
||||||
;; because of some strange interaction with cljs.spec.alpha and
|
;; because of some strange interaction with cljs.spec.alpha and
|
||||||
;; modules spliting.
|
;; modules splitting.
|
||||||
[app.common.exceptions :as ex]
|
[app.common.exceptions :as ex]
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
|
|
|
@ -175,7 +175,7 @@
|
||||||
:x :y :width :height :x1 :y1 :x2 :y2))
|
:x :y :width :height :x1 :y1 :x2 :y2))
|
||||||
:rect :path))
|
:rect :path))
|
||||||
|
|
||||||
(t/testing "Transform shape with invalid selrect fails gracefuly"
|
(t/testing "Transform shape with invalid selrect fails gracefully"
|
||||||
(t/are [type selrect]
|
(t/are [type selrect]
|
||||||
(let [modifiers {:displacement (gmt/matrix)}
|
(let [modifiers {:displacement (gmt/matrix)}
|
||||||
shape-before (-> (create-test-shape type {:modifiers modifiers})
|
shape-before (-> (create-test-shape type {:modifiers modifiers})
|
||||||
|
|
|
@ -71,7 +71,7 @@
|
||||||
:components {}
|
:components {}
|
||||||
:version 7}
|
:version 7}
|
||||||
|
|
||||||
expct (-> data
|
expect (-> data
|
||||||
(update-in [:pages-index page-id :objects] dissoc
|
(update-in [:pages-index page-id :objects] dissoc
|
||||||
(uuid/custom 1 2)
|
(uuid/custom 1 2)
|
||||||
(uuid/custom 1 3)
|
(uuid/custom 1 3)
|
||||||
|
@ -84,8 +84,8 @@
|
||||||
res (cpm/migrate-data data)]
|
res (cpm/migrate-data data)]
|
||||||
|
|
||||||
;; (pprint res)
|
;; (pprint res)
|
||||||
;; (pprint expct)
|
;; (pprint expect)
|
||||||
|
|
||||||
(t/is (= (dissoc expct :version)
|
(t/is (= (dissoc expect :version)
|
||||||
(dissoc res :version)))
|
(dissoc res :version)))
|
||||||
))
|
))
|
||||||
|
|
|
@ -41,7 +41,7 @@ services:
|
||||||
environment:
|
environment:
|
||||||
- EXTERNAL_UID=${CURRENT_USER_ID}
|
- EXTERNAL_UID=${CURRENT_USER_ID}
|
||||||
- PENPOT_SECRET_KEY=super-secret-devenv-key
|
- PENPOT_SECRET_KEY=super-secret-devenv-key
|
||||||
# STMP setup
|
# SMTP setup
|
||||||
- PENPOT_SMTP_ENABLED=true
|
- PENPOT_SMTP_ENABLED=true
|
||||||
- PENPOT_SMTP_DEFAULT_FROM=no-reply@example.com
|
- PENPOT_SMTP_DEFAULT_FROM=no-reply@example.com
|
||||||
- PENPOT_SMTP_DEFAULT_REPLY_TO=no-reply@example.com
|
- PENPOT_SMTP_DEFAULT_REPLY_TO=no-reply@example.com
|
||||||
|
@ -91,7 +91,7 @@ services:
|
||||||
environment:
|
environment:
|
||||||
- EXTERNAL_UID=${CURRENT_USER_ID}
|
- EXTERNAL_UID=${CURRENT_USER_ID}
|
||||||
- PENPOT_SECRET_KEY=super-secret-devenv-key
|
- PENPOT_SECRET_KEY=super-secret-devenv-key
|
||||||
# STMP setup
|
# SMTP setup
|
||||||
- PENPOT_SMTP_ENABLED=true
|
- PENPOT_SMTP_ENABLED=true
|
||||||
- PENPOT_SMTP_DEFAULT_FROM=no-reply@example.com
|
- PENPOT_SMTP_DEFAULT_FROM=no-reply@example.com
|
||||||
- PENPOT_SMTP_DEFAULT_REPLY_TO=no-reply@example.com
|
- PENPOT_SMTP_DEFAULT_REPLY_TO=no-reply@example.com
|
||||||
|
|
|
@ -24,7 +24,7 @@ else
|
||||||
fi
|
fi
|
||||||
|
|
||||||
function command_not_found {
|
function command_not_found {
|
||||||
>&2 echo "Leiningen coundn't find $1 in your \$PATH ($PATH), which is required."
|
>&2 echo "Leiningen couldn't find $1 in your \$PATH ($PATH), which is required."
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ fi
|
||||||
|
|
||||||
if [ ! -x "$JAVA_CMD" ] && ! type -f java >/dev/null
|
if [ ! -x "$JAVA_CMD" ] && ! type -f java >/dev/null
|
||||||
then
|
then
|
||||||
>&2 echo "Leiningen coundn't find 'java' executable, which is required."
|
>&2 echo "Leiningen couldn't find 'java' executable, which is required."
|
||||||
>&2 echo "Please either set JAVA_CMD or put java (>=1.6) in your \$PATH ($PATH)."
|
>&2 echo "Please either set JAVA_CMD or put java (>=1.6) in your \$PATH ($PATH)."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -144,7 +144,7 @@ function ImageTracer(){
|
||||||
// 3. Batch pathscan
|
// 3. Batch pathscan
|
||||||
var bps = _this.batchpathscan( ls, options.pathomit );
|
var bps = _this.batchpathscan( ls, options.pathomit );
|
||||||
|
|
||||||
// 4. Batch interpollation
|
// 4. Batch interpolation
|
||||||
var bis = _this.batchinternodes( bps, options );
|
var bis = _this.batchinternodes( bps, options );
|
||||||
|
|
||||||
// 5. Batch tracing and creating tracedata object
|
// 5. Batch tracing and creating tracedata object
|
||||||
|
@ -240,7 +240,7 @@ function ImageTracer(){
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// 1. Color quantization
|
// 1. Color quantization
|
||||||
// Using a form of k-means clustering repeatead options.colorquantcycles times. http://en.wikipedia.org/wiki/Color_quantization
|
// Using a form of k-means clustering repeated options.colorquantcycles times. http://en.wikipedia.org/wiki/Color_quantization
|
||||||
this.colorquantization = function( imgd, options ){
|
this.colorquantization = function( imgd, options ){
|
||||||
var arr = [], idx=0, cd,cdl,ci, paletteacc = [], pixelnum = imgd.width * imgd.height, i, j, k, cnt, palette;
|
var arr = [], idx=0, cd,cdl,ci, paletteacc = [], pixelnum = imgd.width * imgd.height, i, j, k, cnt, palette;
|
||||||
|
|
||||||
|
@ -300,7 +300,7 @@ function ImageTracer(){
|
||||||
}// End of palette loop
|
}// End of palette loop
|
||||||
}// End of Average colors from the second iteration
|
}// End of Average colors from the second iteration
|
||||||
|
|
||||||
// Reseting palette accumulator for averaging
|
// Resetting palette accumulator for averaging
|
||||||
for( i=0; i < palette.length; i++ ){ paletteacc[i] = { r:0, g:0, b:0, a:0, n:0 }; }
|
for( i=0; i < palette.length; i++ ){ paletteacc[i] = { r:0, g:0, b:0, a:0, n:0 }; }
|
||||||
|
|
||||||
// loop through all pixels
|
// loop through all pixels
|
||||||
|
@ -322,7 +322,7 @@ function ImageTracer(){
|
||||||
|
|
||||||
}// End of palette loop
|
}// End of palette loop
|
||||||
|
|
||||||
// add to palettacc
|
// add to paletteacc
|
||||||
paletteacc[ci].r += imgd.data[idx ];
|
paletteacc[ci].r += imgd.data[idx ];
|
||||||
paletteacc[ci].g += imgd.data[idx+1];
|
paletteacc[ci].g += imgd.data[idx+1];
|
||||||
paletteacc[ci].b += imgd.data[idx+2];
|
paletteacc[ci].b += imgd.data[idx+2];
|
||||||
|
@ -620,7 +620,7 @@ function ImageTracer(){
|
||||||
return bpaths;
|
return bpaths;
|
||||||
},
|
},
|
||||||
|
|
||||||
// 4. interpollating between path points for nodes with 8 directions ( East, SouthEast, S, SW, W, NW, N, NE )
|
// 4. interpolating between path points for nodes with 8 directions ( East, SouthEast, S, SW, W, NW, N, NE )
|
||||||
this.internodes = function( paths, options ){
|
this.internodes = function( paths, options ){
|
||||||
var ins = [], palen=0, nextidx=0, nextidx2=0, previdx=0, previdx2=0, pacnt, pcnt;
|
var ins = [], palen=0, nextidx=0, nextidx2=0, previdx=0, previdx2=0, pacnt, pcnt;
|
||||||
|
|
||||||
|
@ -718,7 +718,7 @@ function ImageTracer(){
|
||||||
return val;
|
return val;
|
||||||
},// End of getdirection()
|
},// End of getdirection()
|
||||||
|
|
||||||
// 4. Batch interpollation
|
// 4. Batch interpolation
|
||||||
this.batchinternodes = function( bpaths, options ){
|
this.batchinternodes = function( bpaths, options ){
|
||||||
var binternodes = [];
|
var binternodes = [];
|
||||||
for (var k in bpaths) {
|
for (var k in bpaths) {
|
||||||
|
|
|
@ -56,8 +56,8 @@
|
||||||
token (.get ^js cookies "auth-token")]
|
token (.get ^js cookies "auth-token")]
|
||||||
(if (seq frame-ids)
|
(if (seq frame-ids)
|
||||||
(p/let [tdpath (sh/create-tmpdir! "pdfexport-")
|
(p/let [tdpath (sh/create-tmpdir! "pdfexport-")
|
||||||
data (-> (reduce (fn [promis frame-id]
|
data (-> (reduce (fn [promise frame-id]
|
||||||
(p/then promis (partial export-frame tdpath file-id page-id token frame-id)))
|
(p/then promise (partial export-frame tdpath file-id page-id token frame-id)))
|
||||||
(p/future [])
|
(p/future [])
|
||||||
(reverse frame-ids))
|
(reverse frame-ids))
|
||||||
(p/then (partial join-files tdpath file-id))
|
(p/then (partial join-files tdpath file-id))
|
||||||
|
|
|
@ -206,7 +206,7 @@
|
||||||
|
|
||||||
;; Now we have the result containing the svgdata of a
|
;; Now we have the result containing the svgdata of a
|
||||||
;; SVG with all text layers. Now we need to transform
|
;; SVG with all text layers. Now we need to transform
|
||||||
;; this SVG to G (Group) and remove unnecesary metada
|
;; this SVG to G (Group) and remove unnecessary metadata
|
||||||
;; objects.
|
;; objects.
|
||||||
(let [vbox (-> (get-in result ["attributes" "viewBox"])
|
(let [vbox (-> (get-in result ["attributes" "viewBox"])
|
||||||
(parse-viewbox))
|
(parse-viewbox))
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
(enable-console-print!)
|
(enable-console-print!)
|
||||||
|
|
||||||
;; --- Index Initialization Bechmark
|
;; --- Index Initialization Benchmark
|
||||||
|
|
||||||
(defn- bench-init-10000
|
(defn- bench-init-10000
|
||||||
[]
|
[]
|
||||||
|
@ -60,9 +60,9 @@
|
||||||
(bench-knn-160000)
|
(bench-knn-160000)
|
||||||
(bench-knn-360000))
|
(bench-knn-360000))
|
||||||
|
|
||||||
;; --- Accuracity tests
|
;; --- Accuracy tests
|
||||||
|
|
||||||
(defn test-accuracity
|
(defn test-accuracy
|
||||||
[]
|
[]
|
||||||
(let [tree (k/create)]
|
(let [tree (k/create)]
|
||||||
(k/setup tree 4000 4000 20 20)
|
(k/setup tree 4000 4000 20 20)
|
||||||
|
@ -101,7 +101,7 @@
|
||||||
(bench-knn)
|
(bench-knn)
|
||||||
|
|
||||||
(= type "kd-test")
|
(= type "kd-test")
|
||||||
(test-accuracity)
|
(test-accuracy)
|
||||||
|
|
||||||
(= type "interval")
|
(= type "interval")
|
||||||
(test-interval)
|
(test-interval)
|
||||||
|
|
|
@ -64,7 +64,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// This mixing allow you to add placeholder colors in all availables browsers
|
/// This mixing allow you to add placeholder colors in all available browsers
|
||||||
/// @group Mixins
|
/// @group Mixins
|
||||||
|
|
||||||
@mixin placeholder {
|
@mixin placeholder {
|
||||||
|
|
|
@ -431,7 +431,7 @@ ul.slider-dots {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.miliseconds {
|
&.milliseconds {
|
||||||
|
|
||||||
&::after {
|
&::after {
|
||||||
content: "ms";
|
content: "ms";
|
||||||
|
|
|
@ -31,7 +31,7 @@ svg#loader-icon {
|
||||||
animation: pen3 2s infinite ease;
|
animation: pen3 2s infinite ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
// btn prncil loader
|
// btn pencil loader
|
||||||
svg#loader-pencil {
|
svg#loader-pencil {
|
||||||
fill: $color-primary-darker;
|
fill: $color-primary-darker;
|
||||||
width: 60px;
|
width: 60px;
|
||||||
|
|
|
@ -85,7 +85,7 @@
|
||||||
(def browser (atom (parse-browser)))
|
(def browser (atom (parse-browser)))
|
||||||
(def platform (atom (parse-platform)))
|
(def platform (atom (parse-platform)))
|
||||||
|
|
||||||
;; mantain for backward compatibility
|
;; maintain for backward compatibility
|
||||||
(let [login-with-ldap (obj/get global "penpotLoginWithLDAP" false)
|
(let [login-with-ldap (obj/get global "penpotLoginWithLDAP" false)
|
||||||
registration (obj/get global "penpotRegistrationEnabled" true)]
|
registration (obj/get global "penpotRegistrationEnabled" true)]
|
||||||
(when login-with-ldap
|
(when login-with-ldap
|
||||||
|
|
|
@ -206,7 +206,7 @@
|
||||||
|
|
||||||
(defn login-from-register
|
(defn login-from-register
|
||||||
"Event used mainly for mark current session as logged-in in after the
|
"Event used mainly for mark current session as logged-in in after the
|
||||||
user sucessfully registred using third party auth provider (in this
|
user successfully registered using third party auth provider (in this
|
||||||
case we dont need to verify the email)."
|
case we dont need to verify the email)."
|
||||||
[]
|
[]
|
||||||
(ptk/reify ::login-from-register
|
(ptk/reify ::login-from-register
|
||||||
|
@ -351,7 +351,7 @@
|
||||||
(defn mark-onboarding-as-viewed
|
(defn mark-onboarding-as-viewed
|
||||||
([] (mark-onboarding-as-viewed nil))
|
([] (mark-onboarding-as-viewed nil))
|
||||||
([{:keys [version]}]
|
([{:keys [version]}]
|
||||||
(ptk/reify ::mark-oboarding-as-viewed
|
(ptk/reify ::mark-onboarding-as-viewed
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ state _]
|
(watch [_ state _]
|
||||||
(let [version (or version (:main @cf/version))
|
(let [version (or version (:main @cf/version))
|
||||||
|
|
|
@ -1645,7 +1645,7 @@
|
||||||
(not= root-file-id (:current-file-id state))
|
(not= root-file-id (:current-file-id state))
|
||||||
(nil? (get-in state [:workspace-libraries root-file-id])))))
|
(nil? (get-in state [:workspace-libraries root-file-id])))))
|
||||||
|
|
||||||
;; Procceed with the standard shape paste procediment.
|
;; Proceed with the standard shape paste process.
|
||||||
(do-paste [it state mouse-pos media]
|
(do-paste [it state mouse-pos media]
|
||||||
(let [page-objects (wsh/lookup-page-objects state)
|
(let [page-objects (wsh/lookup-page-objects state)
|
||||||
media-idx (d/index-by :prev-id media)
|
media-idx (d/index-by :prev-id media)
|
||||||
|
@ -1673,7 +1673,7 @@
|
||||||
|
|
||||||
page-id (:current-page-id state)
|
page-id (:current-page-id state)
|
||||||
unames (-> (wsh/lookup-page-objects state page-id)
|
unames (-> (wsh/lookup-page-objects state page-id)
|
||||||
(dwc/retrieve-used-names)) ;; TODO: move this calculation inside prepare-duplcate-changes?
|
(dwc/retrieve-used-names)) ;; TODO: move this calculation inside prepare-duplicate-changes?
|
||||||
|
|
||||||
rchanges (->> (dws/prepare-duplicate-changes all-objects page-id unames selected delta)
|
rchanges (->> (dws/prepare-duplicate-changes all-objects page-id unames selected delta)
|
||||||
(mapv (partial process-rchange media-idx))
|
(mapv (partial process-rchange media-idx))
|
||||||
|
@ -1799,7 +1799,7 @@
|
||||||
(watch [it state _]
|
(watch [it state _]
|
||||||
(let [page-id (get state :current-page-id)
|
(let [page-id (get state :current-page-id)
|
||||||
options (wsh/lookup-page-options state page-id)
|
options (wsh/lookup-page-options state page-id)
|
||||||
previus-color (:background options)]
|
previous-color (:background options)]
|
||||||
(rx/of (dch/commit-changes
|
(rx/of (dch/commit-changes
|
||||||
{:redo-changes [{:type :set-option
|
{:redo-changes [{:type :set-option
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
|
@ -1808,7 +1808,7 @@
|
||||||
:undo-changes [{:type :set-option
|
:undo-changes [{:type :set-option
|
||||||
:page-id page-id
|
:page-id page-id
|
||||||
:option :background
|
:option :background
|
||||||
:value previus-color}]
|
:value previous-color}]
|
||||||
:origin it}))))))
|
:origin it}))))))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
|
@ -252,7 +252,7 @@
|
||||||
[objects selected attrs]
|
[objects selected attrs]
|
||||||
|
|
||||||
(if (= :frame (:type attrs))
|
(if (= :frame (:type attrs))
|
||||||
;; Frames are alwasy positioned on the root frame
|
;; Frames are always positioned on the root frame
|
||||||
[uuid/zero uuid/zero nil]
|
[uuid/zero uuid/zero nil]
|
||||||
|
|
||||||
;; Calculate the frame over which we're drawing
|
;; Calculate the frame over which we're drawing
|
||||||
|
|
|
@ -104,7 +104,7 @@
|
||||||
:page-id page-id}))
|
:page-id page-id}))
|
||||||
|
|
||||||
;; Look at the `get-empty-groups-after-group-creation`
|
;; Look at the `get-empty-groups-after-group-creation`
|
||||||
;; doctring to understand the real purpuse of this code
|
;; docstring to understand the real purpose of this code
|
||||||
ids-to-delete (get-empty-groups-after-group-creation objects parent-id shapes)
|
ids-to-delete (get-empty-groups-after-group-creation objects parent-id shapes)
|
||||||
|
|
||||||
delete-group
|
delete-group
|
||||||
|
|
|
@ -690,7 +690,7 @@
|
||||||
;; update to finish, before marking this file as synced.
|
;; update to finish, before marking this file as synced.
|
||||||
;; TODO: look for a more precise way of syncing this.
|
;; TODO: look for a more precise way of syncing this.
|
||||||
;; Maybe by using the stream (second argument passed to watch)
|
;; Maybe by using the stream (second argument passed to watch)
|
||||||
;; to wait for the corresponding changes-commited and then proced
|
;; to wait for the corresponding changes-committed and then proceed
|
||||||
;; with the :update-sync mutation.
|
;; with the :update-sync mutation.
|
||||||
(rx/concat (rx/timer 3000)
|
(rx/concat (rx/timer 3000)
|
||||||
(rp/mutation :update-sync
|
(rp/mutation :update-sync
|
||||||
|
|
|
@ -159,7 +159,7 @@
|
||||||
color
|
color
|
||||||
(get-next-color presence)))
|
(get-next-color presence)))
|
||||||
|
|
||||||
(update-sesion [session presence]
|
(update-session [session presence]
|
||||||
(-> session
|
(-> session
|
||||||
(assoc :id session-id)
|
(assoc :id session-id)
|
||||||
(assoc :profile-id profile-id)
|
(assoc :profile-id profile-id)
|
||||||
|
@ -168,7 +168,7 @@
|
||||||
|
|
||||||
(update-presence [presence]
|
(update-presence [presence]
|
||||||
(-> presence
|
(-> presence
|
||||||
(update session-id update-sesion presence)
|
(update session-id update-session presence)
|
||||||
(d/without-nils)))
|
(d/without-nils)))
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -161,7 +161,7 @@
|
||||||
points (upg/content->points content)]
|
points (upg/content->points content)]
|
||||||
|
|
||||||
(rx/concat
|
(rx/concat
|
||||||
;; This stream checks the consecutive mouse positions to do the draging
|
;; This stream checks the consecutive mouse positions to do the dragging
|
||||||
(->> points
|
(->> points
|
||||||
(streams/move-points-stream snap-toggled start-position selected-points)
|
(streams/move-points-stream snap-toggled start-position selected-points)
|
||||||
(rx/take-until stopper)
|
(rx/take-until stopper)
|
||||||
|
|
|
@ -108,7 +108,7 @@
|
||||||
:params position})))
|
:params position})))
|
||||||
|
|
||||||
(defn append-node
|
(defn append-node
|
||||||
"Creates a new node in the path. Usualy used when drawing."
|
"Creates a new node in the path. Usually used when drawing."
|
||||||
[shape position prev-point prev-handler]
|
[shape position prev-point prev-handler]
|
||||||
(let [command (next-node shape position prev-point prev-handler)]
|
(let [command (next-node shape position prev-point prev-handler)]
|
||||||
(-> shape
|
(-> shape
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
ks)))
|
ks)))
|
||||||
|
|
||||||
(defn get-path
|
(defn get-path
|
||||||
"Retrieves the location of the path object and additionaly can pass
|
"Retrieves the location of the path object and additionally can pass
|
||||||
the arguments. This location can be used in get-in, assoc-in... functions"
|
the arguments. This location can be used in get-in, assoc-in... functions"
|
||||||
[state & ks]
|
[state & ks]
|
||||||
(let [path-loc (get-path-location state)
|
(let [path-loc (get-path-location state)
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
[tubax.core :as tubax]))
|
[tubax.core :as tubax]))
|
||||||
|
|
||||||
(declare persist-changes)
|
(declare persist-changes)
|
||||||
(declare persist-sychronous-changes)
|
(declare persist-synchronous-changes)
|
||||||
(declare shapes-changes-persisted)
|
(declare shapes-changes-persisted)
|
||||||
(declare update-persistence-status)
|
(declare update-persistence-status)
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@
|
||||||
(rx/map deref)
|
(rx/map deref)
|
||||||
(rx/filter library-file?)
|
(rx/filter library-file?)
|
||||||
(rx/filter (complement #(empty? (:changes %))))
|
(rx/filter (complement #(empty? (:changes %))))
|
||||||
(rx/map persist-sychronous-changes)
|
(rx/map persist-synchronous-changes)
|
||||||
(rx/take-until (rx/delay 100 stoper)))
|
(rx/take-until (rx/delay 100 stoper)))
|
||||||
(->> stream
|
(->> stream
|
||||||
(rx/filter (ptk/type? ::changes-persisted))
|
(rx/filter (ptk/type? ::changes-persisted))
|
||||||
|
@ -167,7 +167,7 @@
|
||||||
(rx/mapcat handle-response)
|
(rx/mapcat handle-response)
|
||||||
(rx/catch on-error)))))))
|
(rx/catch on-error)))))))
|
||||||
|
|
||||||
(defn persist-sychronous-changes
|
(defn persist-synchronous-changes
|
||||||
[{:keys [file-id changes]}]
|
[{:keys [file-id changes]}]
|
||||||
(us/verify ::us/uuid file-id)
|
(us/verify ::us/uuid file-id)
|
||||||
(ptk/reify ::persist-synchronous-changes
|
(ptk/reify ::persist-synchronous-changes
|
||||||
|
@ -201,7 +201,7 @@
|
||||||
(s/def ::shapes-changes-persisted
|
(s/def ::shapes-changes-persisted
|
||||||
(s/keys :req-un [::revn ::cp/changes]))
|
(s/keys :req-un [::revn ::cp/changes]))
|
||||||
|
|
||||||
(defn shapes-persited-event? [event]
|
(defn shapes-persisted-event? [event]
|
||||||
(= (ptk/type event) ::changes-persisted))
|
(= (ptk/type event) ::changes-persisted))
|
||||||
|
|
||||||
(defn shapes-changes-persisted
|
(defn shapes-changes-persisted
|
||||||
|
@ -376,7 +376,7 @@
|
||||||
(= (:code error) :media-type-not-allowed)
|
(= (:code error) :media-type-not-allowed)
|
||||||
(rx/of (dm/error (tr "errors.media-type-not-allowed")))
|
(rx/of (dm/error (tr "errors.media-type-not-allowed")))
|
||||||
|
|
||||||
(= (:code error) :ubable-to-access-to-url)
|
(= (:code error) :unable-to-access-to-url)
|
||||||
(rx/of (dm/error (tr "errors.media-type-not-allowed")))
|
(rx/of (dm/error (tr "errors.media-type-not-allowed")))
|
||||||
|
|
||||||
(= (:code error) :invalid-image)
|
(= (:code error) :invalid-image)
|
||||||
|
@ -486,7 +486,7 @@
|
||||||
;; Media objects are blob of data to be upload
|
;; Media objects are blob of data to be upload
|
||||||
(process-blobs params))
|
(process-blobs params))
|
||||||
|
|
||||||
;; Every stream has its own sideffect. We need to ignore the result
|
;; Every stream has its own sideeffect. We need to ignore the result
|
||||||
(rx/ignore)
|
(rx/ignore)
|
||||||
(handle-upload-error on-error)
|
(handle-upload-error on-error)
|
||||||
(rx/finalize (st/emitf (dm/hide-tag :media-loading))))))))
|
(rx/finalize (st/emitf (dm/hide-tag :media-loading))))))))
|
||||||
|
@ -566,7 +566,7 @@
|
||||||
(ptk/event ::update-frame-thumbnail {:frame-id frame-id}))
|
(ptk/event ::update-frame-thumbnail {:frame-id frame-id}))
|
||||||
|
|
||||||
(defn- extract-frame-changes
|
(defn- extract-frame-changes
|
||||||
"Process a changes set in a commit to extract the frames that are channging"
|
"Process a changes set in a commit to extract the frames that are changing"
|
||||||
[[event [old-objects new-objects]]]
|
[[event [old-objects new-objects]]]
|
||||||
(let [changes (-> event deref :changes)
|
(let [changes (-> event deref :changes)
|
||||||
|
|
||||||
|
@ -643,7 +643,7 @@
|
||||||
(->> (rx/from no-thumb-frames)
|
(->> (rx/from no-thumb-frames)
|
||||||
(rx/map #(update-frame-thumbnail %)))
|
(rx/map #(update-frame-thumbnail %)))
|
||||||
|
|
||||||
;; We remove the thumbnails inmediately but defer their generation
|
;; We remove the thumbnails immediately but defer their generation
|
||||||
(rx/merge
|
(rx/merge
|
||||||
(->> frame-changes
|
(->> frame-changes
|
||||||
(rx/take-until stopper)
|
(rx/take-until stopper)
|
||||||
|
|
|
@ -307,7 +307,7 @@
|
||||||
chgs))))
|
chgs))))
|
||||||
|
|
||||||
(defn duplicate-changes-update-indices
|
(defn duplicate-changes-update-indices
|
||||||
"Parses the change set when duplicating to set-up the appropiate indices"
|
"Parses the change set when duplicating to set-up the appropriate indices"
|
||||||
[objects ids changes]
|
[objects ids changes]
|
||||||
|
|
||||||
(let [process-id
|
(let [process-id
|
||||||
|
|
|
@ -414,7 +414,7 @@
|
||||||
reducer-fn (partial add-svg-child-changes page-id objects selected frame-id shape-id svg-data)]
|
reducer-fn (partial add-svg-child-changes page-id objects selected frame-id shape-id svg-data)]
|
||||||
(reduce reducer-fn [unames changes] (d/enumerate children)))
|
(reduce reducer-fn [unames changes] (d/enumerate children)))
|
||||||
|
|
||||||
;; Cannot create the data from curren tags
|
;; Cannot create the data from current tags
|
||||||
[unames [rchs uchs]])))
|
[unames [rchs uchs]])))
|
||||||
|
|
||||||
(declare create-svg-shapes)
|
(declare create-svg-shapes)
|
||||||
|
@ -425,7 +425,7 @@
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
(watch [_ _ _]
|
(watch [_ _ _]
|
||||||
;; Once the SVG is uploaded, we need to extract all the bitmap
|
;; Once the SVG is uploaded, we need to extract all the bitmap
|
||||||
;; images and upload them separatelly, then proceed to create
|
;; images and upload them separately, then proceed to create
|
||||||
;; all shapes.
|
;; all shapes.
|
||||||
(->> (rx/from (usvg/collect-images svg-data))
|
(->> (rx/from (usvg/collect-images svg-data))
|
||||||
(rx/map (fn [uri]
|
(rx/map (fn [uri]
|
||||||
|
|
|
@ -300,7 +300,7 @@
|
||||||
;; Stop buffering after time without resizes
|
;; Stop buffering after time without resizes
|
||||||
stop-buffer (->> resize-events (rx/debounce 100))
|
stop-buffer (->> resize-events (rx/debounce 100))
|
||||||
|
|
||||||
;; Agregates the resizes so only send the resize when the sizes are stable
|
;; Aggregates the resizes so only send the resize when the sizes are stable
|
||||||
resize-batch
|
resize-batch
|
||||||
(->> resize-events
|
(->> resize-events
|
||||||
(rx/take-until stop-buffer)
|
(rx/take-until stop-buffer)
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
(ts/schedule
|
(ts/schedule
|
||||||
(st/emitf (rt/assign-exception error))))
|
(st/emitf (rt/assign-exception error))))
|
||||||
|
|
||||||
;; Error that happens on an active bussines model validation does not
|
;; Error that happens on an active business model validation does not
|
||||||
;; passes an validation (example: profile can't leave a team). From
|
;; passes an validation (example: profile can't leave a team). From
|
||||||
;; the user perspective a error flash message should be visualized but
|
;; the user perspective a error flash message should be visualized but
|
||||||
;; user can continue operate on the application.
|
;; user can continue operate on the application.
|
||||||
|
|
|
@ -143,7 +143,7 @@
|
||||||
|
|
||||||
best-snap
|
best-snap
|
||||||
(fn [acc val]
|
(fn [acc val]
|
||||||
;; Using a number is faster than accesing the variable.
|
;; Using a number is faster than accessing the variable.
|
||||||
;; Keep up to date with `snap-distance-accuracy`
|
;; Keep up to date with `snap-distance-accuracy`
|
||||||
(if (and (<= val snap-distance-accuracy) (>= val (- snap-distance-accuracy)))
|
(if (and (<= val snap-distance-accuracy) (>= val (- snap-distance-accuracy)))
|
||||||
(min acc val)
|
(min acc val)
|
||||||
|
|
|
@ -114,8 +114,8 @@
|
||||||
(rx/filter kbd/altKey?)
|
(rx/filter kbd/altKey?)
|
||||||
(rx/map #(= :down (:type %))))
|
(rx/map #(= :down (:type %))))
|
||||||
;; Fix a situation caused by using `ctrl+alt` kind of shortcuts,
|
;; Fix a situation caused by using `ctrl+alt` kind of shortcuts,
|
||||||
;; that makes keyboard-alt stream registring the key pressed but
|
;; that makes keyboard-alt stream registering the key pressed but
|
||||||
;; on bluring the window (unfocus) the key down is never arrived.
|
;; on blurring the window (unfocus) the key down is never arrived.
|
||||||
(->> window-blur
|
(->> window-blur
|
||||||
(rx/map (constantly false))))
|
(rx/map (constantly false))))
|
||||||
(rx/dedupe))]
|
(rx/dedupe))]
|
||||||
|
@ -130,8 +130,8 @@
|
||||||
(rx/filter kbd/ctrlKey?)
|
(rx/filter kbd/ctrlKey?)
|
||||||
(rx/map #(= :down (:type %))))
|
(rx/map #(= :down (:type %))))
|
||||||
;; Fix a situation caused by using `ctrl+alt` kind of shortcuts,
|
;; Fix a situation caused by using `ctrl+alt` kind of shortcuts,
|
||||||
;; that makes keyboard-alt stream registring the key pressed but
|
;; that makes keyboard-alt stream registering the key pressed but
|
||||||
;; on bluring the window (unfocus) the key down is never arrived.
|
;; on blurring the window (unfocus) the key down is never arrived.
|
||||||
(->> window-blur
|
(->> window-blur
|
||||||
(rx/map (constantly false))))
|
(rx/map (constantly false))))
|
||||||
(rx/dedupe))]
|
(rx/dedupe))]
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
(mf/defc on-main-error
|
(mf/defc on-main-error
|
||||||
[{:keys [error] :as props}]
|
[{:keys [error] :as props}]
|
||||||
(mf/use-effect (st/emitf (rt/assign-exception error)))
|
(mf/use-effect (st/emitf (rt/assign-exception error)))
|
||||||
[:span "Internal application errror"])
|
[:span "Internal application error"])
|
||||||
|
|
||||||
(mf/defc main-page
|
(mf/defc main-page
|
||||||
{::mf/wrap [#(mf/catch % {:fallback on-main-error})]}
|
{::mf/wrap [#(mf/catch % {:fallback on-main-error})]}
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
(defn- on-success
|
(defn- on-success
|
||||||
[_]
|
[_]
|
||||||
(st/emit! (dm/info (tr "auth.notifications.password-changed-succesfully"))
|
(st/emit! (dm/info (tr "auth.notifications.password-changed-successfully"))
|
||||||
(rt/nav :auth-login)))
|
(rt/nav :auth-login)))
|
||||||
|
|
||||||
(defn- on-submit
|
(defn- on-submit
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
(wapi/exit-fullscreen)))))))]
|
(wapi/exit-fullscreen)))))))]
|
||||||
|
|
||||||
;; NOTE: the user interaction with F11 keyboard hot-key does not
|
;; NOTE: the user interaction with F11 keyboard hot-key does not
|
||||||
;; emits the `fullscreenchange` event; that event is emmited only
|
;; emits the `fullscreenchange` event; that event is emitted only
|
||||||
;; when API is used. There are no way to detect the F11 behavior
|
;; when API is used. There are no way to detect the F11 behavior
|
||||||
;; in a uniform cross browser way.
|
;; in a uniform cross browser way.
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
(fn []
|
(fn []
|
||||||
(.removeEventListener js/document "fullscreenchange" change))))
|
(.removeEventListener js/document "fullscreenchange" change))))
|
||||||
|
|
||||||
[:div.fulllscreen-wrapper {:ref container :class (dom/classnames :fullscreen @state)}
|
[:div.fullscreen-wrapper {:ref container :class (dom/classnames :fullscreen @state)}
|
||||||
[:& (mf/provider fullscreen-context) {:value manager}
|
[:& (mf/provider fullscreen-context) {:value manager}
|
||||||
children]]))
|
children]]))
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
;; Remove comments
|
;; Remove comments
|
||||||
(str/replace #"<\!\-\-(.*?(?=\-\->))\-\->" "")
|
(str/replace #"<\!\-\-(.*?(?=\-\->))\-\->" "")
|
||||||
|
|
||||||
;; Remofe end of line
|
;; Remove end of line
|
||||||
(str/replace #"\r?\n|\r" " ")
|
(str/replace #"\r?\n|\r" " ")
|
||||||
|
|
||||||
;; Replace double quotes for single
|
;; Replace double quotes for single
|
||||||
|
|
|
@ -113,8 +113,8 @@
|
||||||
;; that the team is a implicit context variable that is
|
;; that the team is a implicit context variable that is
|
||||||
;; available using react context or accessing
|
;; available using react context or accessing
|
||||||
;; the :current-team-id on the state. We set the key to the
|
;; the :current-team-id on the state. We set the key to the
|
||||||
;; team-id becase we want to completly refresh all the
|
;; team-id because we want to completely refresh all the
|
||||||
;; components on team change. Many components assumess that the
|
;; components on team change. Many components assumes that the
|
||||||
;; team is already set so don't put the team into mf/deps.
|
;; team is already set so don't put the team into mf/deps.
|
||||||
(when team
|
(when team
|
||||||
[:section.dashboard-layout {:key (:id team)}
|
[:section.dashboard-layout {:key (:id team)}
|
||||||
|
|
|
@ -100,7 +100,7 @@
|
||||||
(mf/use-effect
|
(mf/use-effect
|
||||||
(fn []
|
(fn []
|
||||||
(when-not has-libraries?
|
(when-not has-libraries?
|
||||||
;; Start download automaticaly
|
;; Start download automatically
|
||||||
(start-export))))
|
(start-export))))
|
||||||
|
|
||||||
[:div.modal-overlay
|
[:div.modal-overlay
|
||||||
|
|
|
@ -234,7 +234,7 @@
|
||||||
(let [form (fm/use-form :spec ::leave-modal-form :initial {})
|
(let [form (fm/use-form :spec ::leave-modal-form :initial {})
|
||||||
members (some->> members (filterv #(not= (:id %) (:id profile))))
|
members (some->> members (filterv #(not= (:id %) (:id profile))))
|
||||||
options (into [{:value ""
|
options (into [{:value ""
|
||||||
:label (tr "modals.leave-and-reassign.select-memeber-to-promote")}]
|
:label (tr "modals.leave-and-reassign.select-member-to-promote")}]
|
||||||
(map #(hash-map :label (:name %) :value (str (:id %))) members))
|
(map #(hash-map :label (:name %) :value (str (:id %))) members))
|
||||||
|
|
||||||
on-cancel (st/emitf (modal/hide))
|
on-cancel (st/emitf (modal/hide))
|
||||||
|
|
|
@ -25,14 +25,14 @@
|
||||||
|
|
||||||
(defn- on-create-success
|
(defn- on-create-success
|
||||||
[_form response]
|
[_form response]
|
||||||
(let [msg "Team created successfuly"]
|
(let [msg "Team created successfully"]
|
||||||
(st/emit! (dm/success msg)
|
(st/emit! (dm/success msg)
|
||||||
(modal/hide)
|
(modal/hide)
|
||||||
(rt/nav :dashboard-projects {:team-id (:id response)}))))
|
(rt/nav :dashboard-projects {:team-id (:id response)}))))
|
||||||
|
|
||||||
(defn- on-update-success
|
(defn- on-update-success
|
||||||
[_form _response]
|
[_form _response]
|
||||||
(let [msg "Team created successfuly"]
|
(let [msg "Team created successfully"]
|
||||||
(st/emit! (dm/success msg)
|
(st/emit! (dm/success msg)
|
||||||
(modal/hide))))
|
(modal/hide))))
|
||||||
|
|
||||||
|
|
|
@ -191,7 +191,7 @@
|
||||||
|
|
||||||
|
|
||||||
(defn use-stream
|
(defn use-stream
|
||||||
"Wraps the subscription to a strem into a `use-effect` call"
|
"Wraps the subscription to a stream into a `use-effect` call"
|
||||||
([stream on-subscribe]
|
([stream on-subscribe]
|
||||||
(use-stream stream (mf/deps) on-subscribe))
|
(use-stream stream (mf/deps) on-subscribe))
|
||||||
([stream deps on-subscribe]
|
([stream deps on-subscribe]
|
||||||
|
|
|
@ -393,7 +393,7 @@
|
||||||
(mf/defc onboarding-templates-modal
|
(mf/defc onboarding-templates-modal
|
||||||
{::mf/register modal/components
|
{::mf/register modal/components
|
||||||
::mf/register-as :onboarding-templates}
|
::mf/register-as :onboarding-templates}
|
||||||
;; NOTE: the project usually comes empty, it only comes fullfilled
|
;; NOTE: the project usually comes empty, it only comes fulfilled
|
||||||
;; when a user creates a new team just after signup.
|
;; when a user creates a new team just after signup.
|
||||||
[{:keys [project-id] :as props}]
|
[{:keys [project-id] :as props}]
|
||||||
(let [close-fn (mf/use-callback #(st/emit! (modal/hide)))
|
(let [close-fn (mf/use-callback #(st/emit! (modal/hide)))
|
||||||
|
|
|
@ -181,7 +181,7 @@
|
||||||
[:& cap-markers {:shape shape
|
[:& cap-markers {:shape shape
|
||||||
:render-id render-id}])))
|
:render-id render-id}])))
|
||||||
|
|
||||||
;; Outer alingmnent: display the shape in two layers. One
|
;; Outer alignment: display the shape in two layers. One
|
||||||
;; without stroke (only fill), and another one only with stroke
|
;; without stroke (only fill), and another one only with stroke
|
||||||
;; at double width (transparent fill) and passed through a mask
|
;; at double width (transparent fill) and passed through a mask
|
||||||
;; that shows the whole shape, but hides the original shape
|
;; that shows the whole shape, but hides the original shape
|
||||||
|
|
|
@ -38,6 +38,6 @@
|
||||||
#(when sub
|
#(when sub
|
||||||
(rx/dispose! sub)))))
|
(rx/dispose! sub)))))
|
||||||
|
|
||||||
;; Use ref so if the urls are cached will return inmediately instead of the
|
;; Use ref so if the urls are cached will return immediately instead of the
|
||||||
;; next render
|
;; next render
|
||||||
(mf/ref-val uri-data)))
|
(mf/ref-val uri-data)))
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
:in2 "SourceGraphic"
|
:in2 "SourceGraphic"
|
||||||
:operator "in"
|
:operator "in"
|
||||||
:result "comp"}]]
|
:result "comp"}]]
|
||||||
;; Clip path is necesary so the elements inside the mask won't affect
|
;; Clip path is necessary so the elements inside the mask won't affect
|
||||||
;; the events outside. Clip hides the elements but mask doesn't (like display vs visibility)
|
;; the events outside. Clip hides the elements but mask doesn't (like display vs visibility)
|
||||||
;; we cannot use clips instead of mask because clips can only be simple shapes
|
;; we cannot use clips instead of mask because clips can only be simple shapes
|
||||||
[:clipPath {:id (clip-id render-id mask)}
|
[:clipPath {:id (clip-id render-id mask)}
|
||||||
|
|
|
@ -208,7 +208,7 @@
|
||||||
:height (if (#{:auto-height :auto-width} grow-type) 100000 height)
|
:height (if (#{:auto-height :auto-width} grow-type) 100000 height)
|
||||||
:style (-> (obj/new) (attrs/add-layer-props shape))
|
:style (-> (obj/new) (attrs/add-layer-props shape))
|
||||||
:ref ref}
|
:ref ref}
|
||||||
;; We use a class here because react has a bug that won't use the appropiate selector for
|
;; We use a class here because react has a bug that won't use the appropriate selector for
|
||||||
;; `background-clip`
|
;; `background-clip`
|
||||||
[:style ".text-node { background-clip: text;
|
[:style ".text-node { background-clip: text;
|
||||||
-webkit-background-clip: text;" ]
|
-webkit-background-clip: text;" ]
|
||||||
|
|
|
@ -166,8 +166,8 @@
|
||||||
(mapv (fn [[style text]] (vector (merge txt/default-text-attrs style) text))))]
|
(mapv (fn [[style text]] (vector (merge txt/default-text-attrs style) text))))]
|
||||||
|
|
||||||
(for [[idx [full-style text]] (map-indexed vector style-text-blocks)]
|
(for [[idx [full-style text]] (map-indexed vector style-text-blocks)]
|
||||||
(let [previus-style (first (nth style-text-blocks (dec idx) nil))
|
(let [previous-style (first (nth style-text-blocks (dec idx) nil))
|
||||||
style (remove-equal-values full-style previus-style)
|
style (remove-equal-values full-style previous-style)
|
||||||
|
|
||||||
;; If the color is set we need to add opacity otherwise the display will not work
|
;; If the color is set we need to add opacity otherwise the display will not work
|
||||||
style (cond-> style
|
style (cond-> style
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
;; :style {:filter "sepia(1)"}
|
;; :style {:filter "sepia(1)"}
|
||||||
}])))
|
}])))
|
||||||
|
|
||||||
;; This custom deffered don't deffer rendering when ghost rendering is
|
;; This custom deferred don't defer rendering when ghost rendering is
|
||||||
;; used.
|
;; used.
|
||||||
(defn custom-deferred
|
(defn custom-deferred
|
||||||
[component]
|
[component]
|
||||||
|
|
|
@ -110,7 +110,7 @@
|
||||||
|
|
||||||
[:> shape-container {:shape shape}
|
[:> shape-container {:shape shape}
|
||||||
;; We keep hidden the shape when we're editing so it keeps track of the size
|
;; We keep hidden the shape when we're editing so it keeps track of the size
|
||||||
;; and updates the selrect acordingly
|
;; and updates the selrect accordingly
|
||||||
[:g.text-shape {:opacity (when edition? 0)
|
[:g.text-shape {:opacity (when edition? 0)
|
||||||
:pointer-events "none"}
|
:pointer-events "none"}
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@
|
||||||
state (get state-map id empty-editor-state)
|
state (get state-map id empty-editor-state)
|
||||||
self-ref (mf/use-ref)
|
self-ref (mf/use-ref)
|
||||||
|
|
||||||
blured (mf/use-var false)
|
blurred (mf/use-var false)
|
||||||
|
|
||||||
on-key-up
|
on-key-up
|
||||||
(fn [event]
|
(fn [event]
|
||||||
|
@ -123,13 +123,13 @@
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(dom/stop-propagation event)
|
(dom/stop-propagation event)
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
(reset! blured true)))
|
(reset! blurred true)))
|
||||||
|
|
||||||
on-focus
|
on-focus
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
(mf/deps shape state)
|
(mf/deps shape state)
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(reset! blured false)))
|
(reset! blurred false)))
|
||||||
|
|
||||||
prev-value (mf/use-ref state)
|
prev-value (mf/use-ref state)
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
(fn [val]
|
(fn [val]
|
||||||
(let [val (handle-change val)
|
(let [val (handle-change val)
|
||||||
val (if (true? @blured)
|
val (if (true? @blurred)
|
||||||
(ted/add-editor-blur-selection val)
|
(ted/add-editor-blur-selection val)
|
||||||
(ted/remove-editor-blur-selection val))]
|
(ted/remove-editor-blur-selection val))]
|
||||||
(st/emit! (dwt/update-editor-state shape val)))))
|
(st/emit! (dwt/update-editor-state shape val)))))
|
||||||
|
|
|
@ -1087,7 +1087,7 @@
|
||||||
|
|
||||||
(mf/defc typographies-group
|
(mf/defc typographies-group
|
||||||
[{:keys [file-id prefix groups open-groups file local? selected-typographies local
|
[{:keys [file-id prefix groups open-groups file local? selected-typographies local
|
||||||
editting-id on-asset-click handle-change apply-typography
|
editing-id on-asset-click handle-change apply-typography
|
||||||
on-rename-group on-ungroup on-context-menu]}]
|
on-rename-group on-ungroup on-context-menu]}]
|
||||||
(let [group-open? (get open-groups prefix true)]
|
(let [group-open? (get open-groups prefix true)]
|
||||||
|
|
||||||
|
@ -1113,7 +1113,7 @@
|
||||||
:selected? (contains? selected-typographies (:id typography))
|
:selected? (contains? selected-typographies (:id typography))
|
||||||
:on-click #(on-asset-click % (:id typography)
|
:on-click #(on-asset-click % (:id typography)
|
||||||
(partial apply-typography typography))
|
(partial apply-typography typography))
|
||||||
:editting? (= editting-id (:id typography))
|
:editing? (= editing-id (:id typography))
|
||||||
:focus-name? (= (:rename-typography local) (:id typography))}])])
|
:focus-name? (= (:rename-typography local) (:id typography))}])])
|
||||||
|
|
||||||
(for [[path-item content] groups]
|
(for [[path-item content] groups]
|
||||||
|
@ -1125,7 +1125,7 @@
|
||||||
:file file
|
:file file
|
||||||
:local? local?
|
:local? local?
|
||||||
:selected-typographies selected-typographies
|
:selected-typographies selected-typographies
|
||||||
:editting-id editting-id
|
:editing-id editing-id
|
||||||
:local local
|
:local local
|
||||||
:on-asset-click on-asset-click
|
:on-asset-click on-asset-click
|
||||||
:handle-change handle-change
|
:handle-change handle-change
|
||||||
|
@ -1272,7 +1272,7 @@
|
||||||
(dwl/sync-file file-id file-id)
|
(dwl/sync-file file-id file-id)
|
||||||
(dwu/commit-undo-transaction)))))
|
(dwu/commit-undo-transaction)))))
|
||||||
|
|
||||||
editting-id (or (:rename-typography local) (:edit-typography local))]
|
editing-id (or (:rename-typography local) (:edit-typography local))]
|
||||||
|
|
||||||
(mf/use-effect
|
(mf/use-effect
|
||||||
(mf/deps local)
|
(mf/deps local)
|
||||||
|
@ -1301,7 +1301,7 @@
|
||||||
:file file
|
:file file
|
||||||
:local? local?
|
:local? local?
|
||||||
:selected-typographies selected-typographies
|
:selected-typographies selected-typographies
|
||||||
:editting-id editting-id
|
:editing-id editing-id
|
||||||
:local local
|
:local local
|
||||||
:on-asset-click (partial on-asset-click groups)
|
:on-asset-click (partial on-asset-click groups)
|
||||||
:handle-change handle-change
|
:handle-change handle-change
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
(l/derived :workspace-undo st/state))
|
(l/derived :workspace-undo st/state))
|
||||||
|
|
||||||
(defn get-object
|
(defn get-object
|
||||||
"Searchs for a shape inside the objects list or inside the undo history"
|
"Searches for a shape inside the objects list or inside the undo history"
|
||||||
[id entries objects]
|
[id entries objects]
|
||||||
(let [search-deleted-shape
|
(let [search-deleted-shape
|
||||||
(fn [id entries]
|
(fn [id entries]
|
||||||
|
@ -144,7 +144,7 @@
|
||||||
maybe-keyword))
|
maybe-keyword))
|
||||||
|
|
||||||
(defn select-entry
|
(defn select-entry
|
||||||
"Selects the entry the user will see inside a list of posible entries.
|
"Selects the entry the user will see inside a list of possible entries.
|
||||||
Sometimes the result will be a combination."
|
Sometimes the result will be a combination."
|
||||||
[candidates]
|
[candidates]
|
||||||
(let [;; Group by id and type
|
(let [;; Group by id and type
|
||||||
|
|
|
@ -249,7 +249,7 @@
|
||||||
[:div.interactions-summary {:on-click #(swap! extended-open? not)}
|
[:div.interactions-summary {:on-click #(swap! extended-open? not)}
|
||||||
[:div.trigger-name (event-type-name interaction)]
|
[:div.trigger-name (event-type-name interaction)]
|
||||||
[:div.action-summary (action-summary interaction destination)]]
|
[:div.action-summary (action-summary interaction destination)]]
|
||||||
[:div.elemen-set-actions {:on-click #(remove-interaction index)}
|
[:div.element-set-actions {:on-click #(remove-interaction index)}
|
||||||
[:div.element-set-actions-button i/minus]]
|
[:div.element-set-actions-button i/minus]]
|
||||||
|
|
||||||
(when @extended-open?
|
(when @extended-open?
|
||||||
|
|
|
@ -269,12 +269,12 @@
|
||||||
|
|
||||||
on-convert-to-typography
|
on-convert-to-typography
|
||||||
(fn [_]
|
(fn [_]
|
||||||
(let [setted-values (-> (d/without-nils values)
|
(let [set-values (-> (d/without-nils values)
|
||||||
(select-keys
|
(select-keys
|
||||||
(d/concat text-font-attrs
|
(d/concat text-font-attrs
|
||||||
text-spacing-attrs
|
text-spacing-attrs
|
||||||
text-transform-attrs)))
|
text-transform-attrs)))
|
||||||
typography (merge txt/default-typography setted-values)
|
typography (merge txt/default-typography set-values)
|
||||||
typography (generate-typography-name typography)
|
typography (generate-typography-name typography)
|
||||||
id (uuid/next)]
|
id (uuid/next)]
|
||||||
(st/emit! (dwl/add-typography (assoc typography :id id) false))
|
(st/emit! (dwl/add-typography (assoc typography :id id) false))
|
||||||
|
|
|
@ -433,8 +433,8 @@
|
||||||
;; In summary, this need to a good UX/UI/IMPL rework.
|
;; In summary, this need to a good UX/UI/IMPL rework.
|
||||||
|
|
||||||
(mf/defc typography-entry
|
(mf/defc typography-entry
|
||||||
[{:keys [typography read-only? selected? on-click on-change on-detach on-context-menu editting? focus-name? file]}]
|
[{:keys [typography read-only? selected? on-click on-change on-detach on-context-menu editing? focus-name? file]}]
|
||||||
(let [open? (mf/use-state editting?)
|
(let [open? (mf/use-state editing?)
|
||||||
hover-detach (mf/use-state false)
|
hover-detach (mf/use-state false)
|
||||||
name-input-ref (mf/use-ref)
|
name-input-ref (mf/use-ref)
|
||||||
|
|
||||||
|
@ -458,10 +458,10 @@
|
||||||
(mf/set-ref-val! name-ref (dom/get-target-val event))))]
|
(mf/set-ref-val! name-ref (dom/get-target-val event))))]
|
||||||
|
|
||||||
(mf/use-effect
|
(mf/use-effect
|
||||||
(mf/deps editting?)
|
(mf/deps editing?)
|
||||||
(fn []
|
(fn []
|
||||||
(when editting?
|
(when editing?
|
||||||
(reset! open? editting?))))
|
(reset! open? editing?))))
|
||||||
|
|
||||||
(mf/use-effect
|
(mf/use-effect
|
||||||
(mf/deps focus-name?)
|
(mf/deps focus-name?)
|
||||||
|
|
|
@ -285,13 +285,13 @@
|
||||||
{:name "Twitter post"
|
{:name "Twitter post"
|
||||||
:width 1024
|
:width 1024
|
||||||
:height 512}
|
:height 512}
|
||||||
{:name "Youtube profile"
|
{:name "YouTube profile"
|
||||||
:width 800
|
:width 800
|
||||||
:height 800}
|
:height 800}
|
||||||
{:name "Youtube banner"
|
{:name "YouTube banner"
|
||||||
:width 2560
|
:width 2560
|
||||||
:height 1440}
|
:height 1440}
|
||||||
{:name "Youtube thumb"
|
{:name "YouTube thumb"
|
||||||
:width 1280
|
:width 1280
|
||||||
:height 720}
|
:height 720}
|
||||||
])
|
])
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue