Skip to content

Commit

Permalink
Minimal editor demo
Browse files Browse the repository at this point in the history
  • Loading branch information
ggeoffrey committed Jun 13, 2022
1 parent 00671be commit 0a5f418
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 4 deletions.
52 changes: 52 additions & 0 deletions resources/public/editor.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Hyperfiddle</title>
<link rel="apple-touch-icon" sizes="180x180" href="icons/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="icons/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="icons/favicon-16x16.png">
<link rel="manifest" href="icons/site.webmanifest">
<link rel="mask-icon" href="icons/safari-pinned-tab.svg" color="#5bbad5">
<link rel="shortcut icon" href="icons/favicon.ico">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="msapplication-config" content="/icons/browserconfig.xml">
<meta name="theme-color" content="#ffffff">

<link rel="stylesheet" href="hfql.css" type="text/css" media="screen" />
<link rel="stylesheet" href="browser.css" type="text/css" media="screen" />
<style>
body{
flex-direction: column;
}
#editor-root {
display:grid;
grid-auto-flow: columns;
grid-template-columns: 1fr 1fr;
grid-row:2;
}
.pannel {
width:100%;
min-height: 100vh;
overflow: scroll;
}
</style>
</head>
<body>
<p style="grid-row:1">Compile editor with <code>shadow-cljs compile :editor</code></p>
<div id="editor-root">
<div id="root" class="pannel"></div>
<iframe class="pannel" title="editor" src="output.html"></iframe>
</div>

<script>
window.hyperfiddle_photon_config = {server_url: "ws://"+ location.hostname +":8081/ws"};
</script>

<script type="text/javascript" src="/js/editor/main.js"></script>

<script>
user.start_BANG_(cljs.core.symbol("wip.editor", "main"));
</script>
</body>
</html>
7 changes: 7 additions & 0 deletions shadow-cljs.edn
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@
:output-dir "resources/public/js"
:asset-path "/js"
:modules {:main {:entries [user]}}}
:editor {:target :browser
:devtools {:watch-dir "resources/public" ; live reload CSS
:hud #{:errors :progress}
:ignore-warnings true} ; warnings don't prevent hot-reload
:output-dir "resources/public/js/editor"
:asset-path "/js"
:modules {:main {:entries [user]}}}
:test {:target :node-test
:output-to "out/node-tests.js"
:ns-regexp "^hyperfiddle.(photon-[^dom]|core-async).*$"
Expand Down
12 changes: 8 additions & 4 deletions src-dev/user.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
wip.demo-logical-clock
wip.example-router
wip.hfql-links
wip.editor
))

(defn runtime-resolve [exported-qualified-sym]
Expand All @@ -27,9 +28,12 @@
(defonce user-photon-main `user.demo-healthcheck/main) ; lazy resolve
(defonce reactor nil) ; save for debugging

(defn ^:dev/after-load ^:export start! []
(when user-photon-main
(set! reactor ((runtime-resolve user-photon-main) ; Photon main recompiles every reload, must re-resolve it
(defn set-main [s]
(set! user-photon-main (symbol s)))

(defn ^:dev/after-load ^:export start! [main]
(when (or user-photon-main main)
(set! reactor ((runtime-resolve (or main user-photon-main)) ; Photon main recompiles every reload, must re-resolve it
#(js/console.log "Reactor success:" %)
#(js/console.error "Reactor failure:" %)))))

Expand All @@ -39,4 +43,4 @@

(defn browser-main! [photon-main-sym]
;(println ::received-reload-command photon-main-sym (type photon-main-sym))
(set! user-photon-main photon-main-sym) (stop!) (start!))
(set! user-photon-main photon-main-sym) (stop!) (start! nil))
80 changes: 80 additions & 0 deletions src-docs/wip/editor.cljc
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
(ns wip.editor
(:require [hyperfiddle.photon :as p]
[hyperfiddle.photon-dom3 :as dom]
[missionary.core :as m]
#?(:clj [clojure.java.io :as io]))
(:import (hyperfiddle.photon Pending)
(missionary Cancelled)
#?(:clj (java.nio.file WatchService Paths FileSystems))))

#?(:clj (def ENTRY_MODIFY java.nio.file.StandardWatchEventKinds/ENTRY_MODIFY))

#?(:clj (defn register! [dir watcher]
(let [;; File change notification might take several seconds on macos.
;; Set watch event priority to high to be notfied ASAP.
modifiers (when-let [modifier (try
(let [c (Class/forName "com.sun.nio.file.SensitivityWatchEventModifier")
f (.getField c "HIGH")]
(.get f c))
(catch Exception _ nil))]
(doto (make-array java.nio.file.WatchEvent$Modifier 1)
(aset 0 modifier)))
types (into-array [ENTRY_MODIFY])]
(if modifiers
(.register dir watcher (into-array types) modifiers)
(.register dir watcher (into-array types))))))

#?(:clj (defn watch-dir! [dir-path callback]
(let [dir (Paths/get dir-path (make-array String 0))
watcher (.. FileSystems getDefault newWatchService)]
(register! dir watcher)
(letfn [(watch [watcher keys]
(let [key (.take watcher)]
(doseq [event (.pollEvents key)]
(let [name (->> event .context (.resolve dir) str)]
(callback name)
(.reset key)))
(recur watcher keys)))]
(future (watch watcher keys))
#(.close watcher)))))

(defn file-watcher [file-path]
#?(:clj
(let [dir-path (.getParent (io/file file-path))]
(->> (m/observe (fn [!]
(let [stop (watch-dir! dir-path
(fn [filename]
(prn dir-path filename)
(when (= filename file-path)
(! (slurp filename)))))]
#(stop))))
(m/eduction (dedupe))
(m/reductions {} (slurp file-path))
(m/relieve {})))))

(defn write! [dir-path text]
#?(:clj (spit dir-path text)))

(defn debounce [delay flow]
(m/relieve {} (m/reductions {} nil (m/ap (let [x (m/?< flow)]
(try (m/? (m/sleep delay x))
(catch Cancelled _ (m/amb))))))))

(def main #?(:cljs (p/client
(p/main
(try (binding [dom/parent (dom/by-id "root")]
~@(let [dir-path "src-docs/user/demo_healthcheck.cljc"
content (new (file-watcher dir-path))
edited ~@(dom/div {:style {:width "100vw"}}
(dom/textarea {:rows 25
:style {:width "100%"}}
(dom/text content)
(new (->> (dom/events "input" (map dom/target-value))
(debounce 2000)))))]
(when (and edited (not= edited content))
(write! dir-path edited))))
(catch Pending _))))))

(comment
(user/browser-main! `main)
)

0 comments on commit 0a5f418

Please sign in to comment.