mirror of
https://github.com/penpot/penpot.git
synced 2025-05-15 21:46:39 +02:00
✨ Add more adaptations to make app run in a prefixed path.
This commit is contained in:
parent
2828ccda7f
commit
55ea84a056
14 changed files with 115 additions and 98 deletions
34
common/app/common/uri.cljc
Normal file
34
common/app/common/uri.cljc
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
;;
|
||||||
|
;; Copyright (c) UXBOX Labs SL
|
||||||
|
|
||||||
|
(ns app.common.uri
|
||||||
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
|
[lambdaisland.uri :as u]
|
||||||
|
[lambdaisland.uri.normalize :as un]))
|
||||||
|
|
||||||
|
(d/export u/uri)
|
||||||
|
(d/export u/join)
|
||||||
|
(d/export un/percent-encode)
|
||||||
|
|
||||||
|
(defn query-string->map
|
||||||
|
[s]
|
||||||
|
(u/query-string->map s))
|
||||||
|
|
||||||
|
(defn default-encode-value
|
||||||
|
[v]
|
||||||
|
(if (keyword? v) (name v) v))
|
||||||
|
|
||||||
|
(defn map->query-string
|
||||||
|
([params] (map->query-string params nil))
|
||||||
|
([params {:keys [value-fn key-fn]
|
||||||
|
:or {value-fn default-encode-value
|
||||||
|
key-fn identity}}]
|
||||||
|
(->> params
|
||||||
|
(into {} (comp
|
||||||
|
(remove #(nil? (second %)))
|
||||||
|
(map (fn [[k v]] [(key-fn k) (value-fn v)]))))
|
||||||
|
(u/map->query-string))))
|
|
@ -68,23 +68,23 @@ function readManifest() {
|
||||||
const content = JSON.parse(fs.readFileSync(path, {encoding: "utf8"}));
|
const content = JSON.parse(fs.readFileSync(path, {encoding: "utf8"}));
|
||||||
|
|
||||||
const index = {
|
const index = {
|
||||||
"config": "/js/config.js?ts=" + Date.now(),
|
"config": "js/config.js?ts=" + Date.now(),
|
||||||
"polyfills": "js/polyfills.js?ts=" + Date.now(),
|
"polyfills": "js/polyfills.js?ts=" + Date.now(),
|
||||||
};
|
};
|
||||||
|
|
||||||
for (let item of content) {
|
for (let item of content) {
|
||||||
index[item.name] = "/js/" + item["output-name"];
|
index[item.name] = "js/" + item["output-name"];
|
||||||
};
|
};
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Error on reading manifest, using default.");
|
console.error("Error on reading manifest, using default.");
|
||||||
return {
|
return {
|
||||||
"config": "/js/config.js",
|
"config": "js/config.js",
|
||||||
"polyfills": "js/polyfills.js",
|
"polyfills": "js/polyfills.js",
|
||||||
"main": "/js/main.js",
|
"main": "js/main.js",
|
||||||
"shared": "/js/shared.js",
|
"shared": "js/shared.js",
|
||||||
"worker": "/js/worker.js"
|
"worker": "js/worker.js"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,10 +15,9 @@
|
||||||
<meta name="twitter:image" content="https://penpot.app/images/workspace-ui.jpg">
|
<meta name="twitter:image" content="https://penpot.app/images/workspace-ui.jpg">
|
||||||
<meta name="twitter:site" content="@penpotapp">
|
<meta name="twitter:site" content="@penpotapp">
|
||||||
<meta name="twitter:creator" content="@penpotapp">
|
<meta name="twitter:creator" content="@penpotapp">
|
||||||
<link id="theme" href="/css/main-{{& th}}.css?ts={{& ts}}"
|
<link id="theme" href="css/main-{{& th}}.css?ts={{& ts}}" rel="stylesheet" type="text/css" />
|
||||||
rel="stylesheet" type="text/css" />
|
|
||||||
|
|
||||||
<link rel="icon" href="/images/favicon.png" />
|
<link rel="icon" href="images/favicon.png" />
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
window.penpotTranslations = JSON.parse({{& translations}});
|
window.penpotTranslations = JSON.parse({{& translations}});
|
||||||
|
|
|
@ -6,14 +6,15 @@
|
||||||
|
|
||||||
(ns app.config
|
(ns app.config
|
||||||
(:require
|
(:require
|
||||||
[clojure.spec.alpha :as s]
|
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
|
[app.common.uri :as u]
|
||||||
[app.common.spec :as us]
|
[app.common.spec :as us]
|
||||||
[app.common.version :as v]
|
[app.common.version :as v]
|
||||||
|
[app.util.avatars :as avatars]
|
||||||
|
[app.util.dom :as dom]
|
||||||
[app.util.globals :refer [global location]]
|
[app.util.globals :refer [global location]]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
[app.util.dom :as dom]
|
[clojure.spec.alpha :as s]
|
||||||
[app.util.avatars :as avatars]
|
|
||||||
[cuerdas.core :as str]))
|
[cuerdas.core :as str]))
|
||||||
|
|
||||||
;; --- Auxiliar Functions
|
;; --- Auxiliar Functions
|
||||||
|
@ -76,16 +77,24 @@
|
||||||
(def translations (obj/get global "penpotTranslations"))
|
(def translations (obj/get global "penpotTranslations"))
|
||||||
(def themes (obj/get global "penpotThemes"))
|
(def themes (obj/get global "penpotThemes"))
|
||||||
|
|
||||||
(def public-uri (or (obj/get global "penpotPublicURI") (.-origin ^js location)))
|
|
||||||
|
|
||||||
(def version (delay (parse-version global)))
|
(def version (delay (parse-version global)))
|
||||||
(def target (delay (parse-target global)))
|
(def target (delay (parse-target global)))
|
||||||
(def browser (delay (parse-browser)))
|
(def browser (delay (parse-browser)))
|
||||||
(def platform (delay (parse-platform)))
|
(def platform (delay (parse-platform)))
|
||||||
|
|
||||||
|
(def public-uri
|
||||||
|
(let [uri (u/uri (or (obj/get global "penpotPublicURI")
|
||||||
|
(str (.-origin ^js location)
|
||||||
|
(.-pathname ^js location))))]
|
||||||
|
;; Ensure that the path always ends with "/"; this ensures that
|
||||||
|
;; all path join operations works as expected.
|
||||||
|
(cond-> uri
|
||||||
|
(not (str/ends-with? (:path uri) "/"))
|
||||||
|
(update :path #(str % "/")))))
|
||||||
|
|
||||||
(when (= :browser @target)
|
(when (= :browser @target)
|
||||||
(js/console.log
|
(js/console.log
|
||||||
(str/format "Welcome to penpot! Version: '%s'." (:full @version))))
|
(str/format "Welcome to penpot! version='%s' base-uri='%s'." (:full @version) (str public-uri))))
|
||||||
|
|
||||||
;; --- Helper Functions
|
;; --- Helper Functions
|
||||||
|
|
||||||
|
@ -101,18 +110,20 @@
|
||||||
[{:keys [photo-id fullname name] :as profile}]
|
[{:keys [photo-id fullname name] :as profile}]
|
||||||
(if (nil? photo-id)
|
(if (nil? photo-id)
|
||||||
(avatars/generate {:name (or fullname name)})
|
(avatars/generate {:name (or fullname name)})
|
||||||
(str public-uri "/assets/by-id/" photo-id)))
|
(str (u/join public-uri "assets/by-id/" photo-id))))
|
||||||
|
|
||||||
(defn resolve-team-photo-url
|
(defn resolve-team-photo-url
|
||||||
[{:keys [photo-id name] :as team}]
|
[{:keys [photo-id name] :as team}]
|
||||||
(if (nil? photo-id)
|
(if (nil? photo-id)
|
||||||
(avatars/generate {:name name})
|
(avatars/generate {:name name})
|
||||||
(str public-uri "/assets/by-id/" photo-id)))
|
(str (u/join public-uri "assets/by-id/" photo-id))))
|
||||||
|
|
||||||
(defn resolve-file-media
|
(defn resolve-file-media
|
||||||
([media]
|
([media]
|
||||||
(resolve-file-media media false))
|
(resolve-file-media media false))
|
||||||
([{:keys [id] :as media} thumnail?]
|
([{:keys [id] :as media} thumnail?]
|
||||||
(str public-uri "/assets/by-file-media-id/" id (when thumnail? "/thumbnail"))))
|
(str (cond-> (u/join public-uri "assets/by-file-media-id/")
|
||||||
|
(true? thumnail?) (u/join (str id "/thumbnail"))
|
||||||
|
(false? thumnail?) (u/join (str id))))))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,21 +7,22 @@
|
||||||
(ns app.main.data.workspace.notifications
|
(ns app.main.data.workspace.notifications
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
|
[app.common.uri :as u]
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.pages :as cp]
|
[app.common.pages :as cp]
|
||||||
[app.common.spec :as us]
|
[app.common.spec :as us]
|
||||||
[app.config :as cfg]
|
[app.config :as cf]
|
||||||
[app.main.data.workspace.common :as dwc]
|
[app.main.data.workspace.common :as dwc]
|
||||||
[app.main.data.workspace.persistence :as dwp]
|
|
||||||
[app.main.data.workspace.libraries :as dwl]
|
[app.main.data.workspace.libraries :as dwl]
|
||||||
|
[app.main.data.workspace.persistence :as dwp]
|
||||||
[app.main.repo :as rp]
|
[app.main.repo :as rp]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.streams :as ms]
|
[app.main.streams :as ms]
|
||||||
[app.util.avatars :as avatars]
|
[app.util.avatars :as avatars]
|
||||||
|
[app.util.i18n :as i18n :refer [tr]]
|
||||||
[app.util.time :as dt]
|
[app.util.time :as dt]
|
||||||
[app.util.transit :as t]
|
[app.util.transit :as t]
|
||||||
[app.util.websockets :as ws]
|
[app.util.websockets :as ws]
|
||||||
[app.util.i18n :as i18n :refer [tr]]
|
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[cljs.spec.alpha :as s]
|
[cljs.spec.alpha :as s]
|
||||||
[clojure.set :as set]
|
[clojure.set :as set]
|
||||||
|
@ -39,14 +40,24 @@
|
||||||
(s/def ::message
|
(s/def ::message
|
||||||
(s/keys :req-un [::type]))
|
(s/keys :req-un [::type]))
|
||||||
|
|
||||||
|
(defn prepare-uri
|
||||||
|
[params]
|
||||||
|
(let [base (-> (u/join cf/public-uri "ws/notifications")
|
||||||
|
(assoc :query (u/map->query-string params)))]
|
||||||
|
(cond-> base
|
||||||
|
(= "https" (:scheme base))
|
||||||
|
(assoc :scheme "wss")
|
||||||
|
|
||||||
|
(= "http" (:scheme base))
|
||||||
|
(assoc :scheme "ws"))))
|
||||||
|
|
||||||
(defn initialize
|
(defn initialize
|
||||||
[file-id]
|
[file-id]
|
||||||
(ptk/reify ::initialize
|
(ptk/reify ::initialize
|
||||||
ptk/UpdateEvent
|
ptk/UpdateEvent
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(let [sid (:session-id state)
|
(let [sid (:session-id state)
|
||||||
uri (ws/uri "/ws/notifications" {:file-id file-id
|
uri (prepare-uri {:file-id file-id :session-id sid})]
|
||||||
:session-id sid})]
|
|
||||||
(assoc-in state [:ws file-id] (ws/open uri))))
|
(assoc-in state [:ws file-id] (ws/open uri))))
|
||||||
|
|
||||||
ptk/WatchEvent
|
ptk/WatchEvent
|
||||||
|
|
|
@ -7,13 +7,13 @@
|
||||||
(ns app.main.repo
|
(ns app.main.repo
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
|
[app.common.uri :as u]
|
||||||
[app.config :as cfg]
|
[app.config :as cfg]
|
||||||
[app.util.http :as http]
|
[app.util.http :as http]
|
||||||
[app.util.time :as dt]
|
[app.util.time :as dt]
|
||||||
[app.util.transit :as t]
|
[app.util.transit :as t]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]))
|
||||||
[lambdaisland.uri :as u]))
|
|
||||||
|
|
||||||
(defn- handle-response
|
(defn- handle-response
|
||||||
[{:keys [status body] :as response}]
|
[{:keys [status body] :as response}]
|
||||||
|
@ -43,7 +43,7 @@
|
||||||
:status status
|
:status status
|
||||||
:data body})))
|
:data body})))
|
||||||
|
|
||||||
(def ^:private base-uri (u/uri cfg/public-uri))
|
(def ^:private base-uri cfg/public-uri)
|
||||||
|
|
||||||
(defn- send-query!
|
(defn- send-query!
|
||||||
"A simple helper for send and receive transit data on the penpot
|
"A simple helper for send and receive transit data on the penpot
|
||||||
|
@ -125,7 +125,7 @@
|
||||||
(defmethod mutation ::multipart-upload
|
(defmethod mutation ::multipart-upload
|
||||||
[id params]
|
[id params]
|
||||||
(->> (http/send! {:method :post
|
(->> (http/send! {:method :post
|
||||||
:uri (u/join base-uri "/api/rpc/mutation/" (name id))
|
:uri (u/join base-uri "api/rpc/mutation/" (name id))
|
||||||
:body (http/form-data params)})
|
:body (http/form-data params)})
|
||||||
(rx/map http/conditional-decode-transit)
|
(rx/map http/conditional-decode-transit)
|
||||||
(rx/mapcat handle-response)))
|
(rx/mapcat handle-response)))
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
(:require
|
(:require
|
||||||
[clojure.java.io :as io]
|
[clojure.java.io :as io]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[lambdaisland.uri.normalize :as uri]))
|
[app.common.uri :as u]))
|
||||||
|
|
||||||
(def cursor-folder "images/cursors")
|
(def cursor-folder "images/cursors")
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
[id rotation x y height]
|
[id rotation x y height]
|
||||||
(let [svg-path (str cursor-folder "/" (name id) ".svg")
|
(let [svg-path (str cursor-folder "/" (name id) ".svg")
|
||||||
data (-> svg-path io/resource slurp parse-svg)
|
data (-> svg-path io/resource slurp parse-svg)
|
||||||
data (uri/percent-encode data)
|
data (u/percent-encode data)
|
||||||
|
|
||||||
data (if rotation
|
data (if rotation
|
||||||
(str/fmt "%3Cg transform='rotate(%s 8,8)'%3E%s%3C/g%3E" rotation data)
|
(str/fmt "%3Cg transform='rotate(%s 8,8)'%3E%s%3C/g%3E" rotation data)
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
[app.util.timers :as ts]
|
[app.util.timers :as ts]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[lambdaisland.uri :as uri]
|
|
||||||
[rumext.alpha :as mf]))
|
[rumext.alpha :as mf]))
|
||||||
|
|
||||||
;; --- Grid Item Thumbnail
|
;; --- Grid Item Thumbnail
|
||||||
|
|
|
@ -67,11 +67,11 @@
|
||||||
:viewer
|
:viewer
|
||||||
(:path-params route)
|
(:path-params route)
|
||||||
{:token token :index "0"})
|
{:token token :index "0"})
|
||||||
link (str cfg/public-uri "/#" link)
|
link (assoc cfg/public-uri :fragment link)
|
||||||
|
|
||||||
copy-link
|
copy-link
|
||||||
(fn [event]
|
(fn [event]
|
||||||
(wapi/write-to-clipboard link)
|
(wapi/write-to-clipboard (str link))
|
||||||
(st/emit! (dm/show {:type :info
|
(st/emit! (dm/show {:type :info
|
||||||
:content "Link copied successfuly!"
|
:content "Link copied successfuly!"
|
||||||
:timeout 3000})))]
|
:timeout 3000})))]
|
||||||
|
@ -89,7 +89,7 @@
|
||||||
[:div.share-link-input
|
[:div.share-link-input
|
||||||
(if (string? token)
|
(if (string? token)
|
||||||
[:*
|
[:*
|
||||||
[:span.link link]
|
[:span.link (str link)]
|
||||||
[:span.link-button {:on-click copy-link}
|
[:span.link-button {:on-click copy-link}
|
||||||
(t locale "viewer.header.share.copy-link")]]
|
(t locale "viewer.header.share.copy-link")]]
|
||||||
[:span.link-placeholder (t locale "viewer.header.share.placeholder")])]
|
[:span.link-placeholder (t locale "viewer.header.share.placeholder")])]
|
||||||
|
|
|
@ -8,13 +8,13 @@
|
||||||
"A http client with rx streams interface."
|
"A http client with rx streams interface."
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
|
[app.common.uri :as u]
|
||||||
[app.config :as cfg]
|
[app.config :as cfg]
|
||||||
[app.util.globals :as globals]
|
[app.util.globals :as globals]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
[app.util.transit :as t]
|
[app.util.transit :as t]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[lambdaisland.uri :as u]
|
|
||||||
[promesa.core :as p]))
|
[promesa.core :as p]))
|
||||||
|
|
||||||
(defprotocol IBodyData
|
(defprotocol IBodyData
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
;;
|
||||||
|
;; Copyright (c) UXBOX Labs SL
|
||||||
|
|
||||||
(ns app.util.logging)
|
(ns app.util.logging)
|
||||||
|
|
||||||
(defn- log-expr [form level keyvals]
|
(defn- log-expr [form level keyvals]
|
||||||
|
|
|
@ -9,37 +9,17 @@
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
[app.common.data :as d]
|
||||||
[app.config :as cfg]
|
[app.config :as cfg]
|
||||||
|
[app.common.uri :as u]
|
||||||
[app.util.browser-history :as bhistory]
|
[app.util.browser-history :as bhistory]
|
||||||
[app.util.timers :as ts]
|
[app.util.timers :as ts]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[goog.events :as e]
|
[goog.events :as e]
|
||||||
[potok.core :as ptk]
|
[potok.core :as ptk]
|
||||||
[reitit.core :as r])
|
[reitit.core :as r]))
|
||||||
(:import
|
|
||||||
goog.Uri
|
|
||||||
goog.Uri.QueryData))
|
|
||||||
|
|
||||||
;; --- Router API
|
;; --- Router API
|
||||||
|
|
||||||
(defn- parse-query-data
|
|
||||||
[^QueryData qdata]
|
|
||||||
(persistent!
|
|
||||||
(reduce (fn [acc key]
|
|
||||||
(let [values (.getValues qdata key)
|
|
||||||
rkey (str/keyword key)]
|
|
||||||
(cond
|
|
||||||
(> (alength values) 1)
|
|
||||||
(assoc! acc rkey (into [] values))
|
|
||||||
|
|
||||||
(= (alength values) 1)
|
|
||||||
(assoc! acc rkey (aget values 0))
|
|
||||||
|
|
||||||
:else
|
|
||||||
acc)))
|
|
||||||
(transient {})
|
|
||||||
(.getKeys qdata))))
|
|
||||||
|
|
||||||
(defn resolve
|
(defn resolve
|
||||||
([router id] (resolve router id {} {}))
|
([router id] (resolve router id {} {}))
|
||||||
([router id params] (resolve router id params {}))
|
([router id params] (resolve router id params {}))
|
||||||
|
@ -47,12 +27,10 @@
|
||||||
(when-let [match (r/match-by-name router id params)]
|
(when-let [match (r/match-by-name router id params)]
|
||||||
(if (empty? qparams)
|
(if (empty? qparams)
|
||||||
(r/match->path match)
|
(r/match->path match)
|
||||||
(let [uri (.parse goog.Uri (r/match->path match))
|
(let [query (u/map->query-string qparams)]
|
||||||
qdt (.createFromMap QueryData (-> qparams
|
(-> (u/uri (r/match->path match))
|
||||||
(d/without-nils)
|
(assoc :query query)
|
||||||
(clj->js)))]
|
(str)))))))
|
||||||
(.setQueryData ^js uri qdt)
|
|
||||||
(.toString ^js uri))))))
|
|
||||||
|
|
||||||
(defn create
|
(defn create
|
||||||
[routes]
|
[routes]
|
||||||
|
@ -65,26 +43,18 @@
|
||||||
(update [_ state]
|
(update [_ state]
|
||||||
(assoc state :router (create routes)))))
|
(assoc state :router (create routes)))))
|
||||||
|
|
||||||
(defn query-params
|
|
||||||
"Given goog.Uri, read query parameters into Clojure map."
|
|
||||||
[^goog.Uri uri]
|
|
||||||
(let [^js q (.getQueryData uri)]
|
|
||||||
(->> q
|
|
||||||
(.getKeys)
|
|
||||||
(map (juxt keyword #(.get q %)))
|
|
||||||
(into {}))))
|
|
||||||
|
|
||||||
(defn match
|
(defn match
|
||||||
"Given routing tree and current path, return match with possibly
|
"Given routing tree and current path, return match with possibly
|
||||||
coerced parameters. Return nil if no match found."
|
coerced parameters. Return nil if no match found."
|
||||||
[router path]
|
[router path]
|
||||||
(let [uri (.parse ^js Uri path)]
|
(let [uri (u/uri path)]
|
||||||
(when-let [match (r/match-by-path router (.getPath ^js uri))]
|
(when-let [match (r/match-by-path router (:path uri))]
|
||||||
(let [qparams (parse-query-data (.getQueryData ^js uri))
|
(let [qparams (u/query-string->map (:query uri))
|
||||||
params {:path (:path-params match) :query qparams}]
|
params {:path (:path-params match)
|
||||||
(assoc match
|
:query qparams}]
|
||||||
:params params
|
(-> match
|
||||||
:query-params qparams)))))
|
(assoc :params params)
|
||||||
|
(assoc :query-params qparams))))))
|
||||||
|
|
||||||
;; --- Navigate (Event)
|
;; --- Navigate (Event)
|
||||||
|
|
||||||
|
@ -119,8 +89,9 @@
|
||||||
(effect [_ state stream]
|
(effect [_ state stream]
|
||||||
(let [router (:router state)
|
(let [router (:router state)
|
||||||
path (resolve router id params qparams)
|
path (resolve router id params qparams)
|
||||||
uri (str cfg/public-uri "/#" path)]
|
uri (-> (u/uri cfg/public-uri)
|
||||||
(js/window.open uri "_blank"))))
|
(assoc :fragment path))]
|
||||||
|
(js/window.open (str uri) "_blank"))))
|
||||||
|
|
||||||
(defn nav-new-window
|
(defn nav-new-window
|
||||||
([id] (nav-new-window id nil nil))
|
([id] (nav-new-window id nil nil))
|
||||||
|
|
|
@ -7,13 +7,13 @@
|
||||||
(ns app.util.websockets
|
(ns app.util.websockets
|
||||||
"A interface to webworkers exposed functionality."
|
"A interface to webworkers exposed functionality."
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.uri :as u]
|
||||||
[app.config :as cfg]
|
[app.config :as cfg]
|
||||||
[app.util.transit :as t]
|
[app.util.transit :as t]
|
||||||
[beicon.core :as rx]
|
[beicon.core :as rx]
|
||||||
[goog.events :as ev]
|
[goog.events :as ev]
|
||||||
[potok.core :as ptk])
|
[potok.core :as ptk])
|
||||||
(:import
|
(:import
|
||||||
goog.Uri
|
|
||||||
goog.net.WebSocket
|
goog.net.WebSocket
|
||||||
goog.net.WebSocket.EventType))
|
goog.net.WebSocket.EventType))
|
||||||
|
|
||||||
|
@ -22,19 +22,6 @@
|
||||||
(-send [_ message] "send a message")
|
(-send [_ message] "send a message")
|
||||||
(-close [_] "close websocket"))
|
(-close [_] "close websocket"))
|
||||||
|
|
||||||
(defn uri
|
|
||||||
([path] (uri path {}))
|
|
||||||
([path params]
|
|
||||||
(let [uri (.parse ^js Uri cfg/public-uri)]
|
|
||||||
(.setPath ^js uri path)
|
|
||||||
(if (= (.getScheme ^js uri) "http")
|
|
||||||
(.setScheme ^js uri "ws")
|
|
||||||
(.setScheme ^js uri "wss"))
|
|
||||||
(run! (fn [[k v]]
|
|
||||||
(.setParameterValue ^js uri (name k) (str v)))
|
|
||||||
params)
|
|
||||||
(.toString uri))))
|
|
||||||
|
|
||||||
(defn open
|
(defn open
|
||||||
[uri]
|
[uri]
|
||||||
(let [sb (rx/subject)
|
(let [sb (rx/subject)
|
||||||
|
@ -45,7 +32,7 @@
|
||||||
#(rx/push! sb {:type :error :payload %}))
|
#(rx/push! sb {:type :error :payload %}))
|
||||||
lk3 (ev/listen ws EventType.OPENED
|
lk3 (ev/listen ws EventType.OPENED
|
||||||
#(rx/push! sb {:type :opened :payload %}))]
|
#(rx/push! sb {:type :opened :payload %}))]
|
||||||
(.open ws uri)
|
(.open ws (str uri))
|
||||||
(reify
|
(reify
|
||||||
cljs.core/IDeref
|
cljs.core/IDeref
|
||||||
(-deref [_] ws)
|
(-deref [_] ws)
|
||||||
|
|
|
@ -19,8 +19,7 @@
|
||||||
[app.worker.snaps]
|
[app.worker.snaps]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
[app.util.transit :as t]
|
[app.util.transit :as t]
|
||||||
[app.util.worker :as w])
|
[app.util.worker :as w]))
|
||||||
(:import goog.Uri))
|
|
||||||
|
|
||||||
;; --- Messages Handling
|
;; --- Messages Handling
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue