Skip to content

Commit

Permalink
pasting blocks actually works
Browse files Browse the repository at this point in the history
  • Loading branch information
tangjeff0 committed Aug 13, 2020
1 parent 1de29df commit 7fd4927
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 27 deletions.
8 changes: 7 additions & 1 deletion src/cljs/athens/db.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,13 @@
[(inc ?o) ?new-o]]
[(dec-after ?p ?at ?ch ?new-o)
(after ?p ?at ?ch ?o)
[(dec ?o) ?new-o]]])
[(dec ?o) ?new-o]]
[(plus-after ?p ?at ?ch ?new-o ?x)
(after ?p ?at ?ch ?o)
[(+ ?o ?x) ?new-o]]
[(minus-after ?p ?at ?ch ?new-o ?x)
(after ?p ?at ?ch ?o)
[(- ?o ?x) ?new-o]]])


(defn sort-block-children
Expand Down
36 changes: 36 additions & 0 deletions src/cljs/athens/events.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,15 @@
@db/dsdb rules eid order)))


(defn plus-after
[eid order x]
(->> (d/q '[:find ?ch ?new-o
:keys db/id block/order
:in $ % ?p ?at ?x
:where (plus-after ?p ?at ?ch ?new-o ?x)]
@db/dsdb rules eid order x)))


(reg-event-fx
:up
(fn [_ [_ uid]]
Expand Down Expand Up @@ -600,6 +609,33 @@
(drop-bullet source-uid target-uid kind)))


;; TODO: convert to tree instead of flat map (handling indentation), write tests for markdown list parsing
(reg-event-fx
:paste
(fn [_ [_ uid text]]
(let [lines (clojure.string/split-lines text)
block (db/get-block [:block/uid uid])
{b-order :block/order} block
parent (db/get-parent [:block/uid uid])
{p-id :db/id} parent
now (now-ts)
new-datoms (map-indexed (fn [i x]
(let [start (subs x 0 2)
s (if (or (= start "- ")
(= start "* "))
(subs x 2)
x)]
{:block/uid (gen-block-uid)
:create/time now
:edit/time now
:block/order (+ 1 i b-order)
:block/string s}))
lines)
reindex (plus-after p-id b-order (count lines))
children (concat new-datoms reindex)]
{:dispatch [:transact [{:db/id p-id :block/children children}]]})))


(defn left-sidebar-drop-above
[s-order t-order]
(let [source-eid (d/q '[:find ?e .
Expand Down
6 changes: 3 additions & 3 deletions src/cljs/athens/keybindings.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -385,9 +385,9 @@
;; XXX: what happens here when we have multi-block selection? In this case we pass in `uids` instead of `uid`
(defn block-key-down
[e uid state]
(let [{:keys [meta ctrl key-code]} (destruct-event e)]
(prn "DOWN" (destruct-event e))
;(swap! state)
(let [d-event (destruct-event e)
{:keys [meta ctrl key-code]} d-event]
(swap! state assoc :last-keydown d-event)
(cond
(arrow-key-direction e) (handle-arrow-key e uid state)
(pair-char? e) (handle-pair-char e uid state)
Expand Down
3 changes: 1 addition & 2 deletions src/cljs/athens/listeners.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,7 @@
(->> blocks
(map (fn [x] [:block/uid x]))
(d/pull-many @dsdb '[:block/string])
(map #(str "- " (:block/string %)))
(clojure.string/join "\r\n")))
(map #(str "- " (:block/string %) "\n"))))


(defn copy
Expand Down
38 changes: 17 additions & 21 deletions src/cljs/athens/views/blocks.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
[komponentit.autosize :as autosize]
[re-frame.core :refer [dispatch subscribe]]
[reagent.core :as r]
[stylefy.core :as stylefy :refer [use-style]])
[stylefy.core :as stylefy :refer [use-style]]
[clojure.string :as string])
(:import
(goog.events
EventType)))
Expand Down Expand Up @@ -450,31 +451,25 @@
:on-click #(athens.keybindings/select-slash-cmd i state)}
[:<> [(r/adapt-react-class icon)] [:span text] (when kbd [:kbd kbd])]])]]))

;; TODO: Count whitespace chars at the front of each line. Each char is one indentation level.

(defn paste
"if user does typical copy and paste, meta+v, and "
[e uid state]
(let [data (.. e -clipboardData (getData "text"))
lines (str/split-lines data)]

(if (= 1 (count lines))
(let [{:keys [head tail]} (destruct-event e)
new-str (str head data tail)]
(swap! state assoc :atom-string new-str))
(let [now (now-ts)
datoms (map (fn [x]
[:db/id [:block/uid (gen-block-uid)]
:create/time now
:edit/time now
:block/order 0 ;; must reindex as well
:block/string x])
lines)]
(dispatch [:transact [datoms]])))))
is-block (re-find #"\r?\n" data)
last-keydown (:last-keydown @state)
{:keys [shift]} last-keydown]
;; if `not shift`, do normal plain-text paste
(when (and is-block (not shift))
(.. e preventDefault)
(dispatch [:paste uid data]))))


(defn block-on-change
[e uid state]
(let [{:keys [value]} (destruct-event e)]
(prn "CHANGE" value)
(swap! state assoc :atom-string value)))
(let []
(swap! state assoc :atom-string (.. e -target -value))))


;; Actual string contents - two elements, one for reading and one for writing
;; seems hacky, but so far no better way to click into the correct position with one conditional element
Expand Down Expand Up @@ -554,7 +549,8 @@
:search/index 0
:dragging false
:drag-target nil
:edit/time (:edit/time block)})]
:edit/time (:edit/time block)
:last-keydown nil})]
(add-watch state :string-listener
(fn [_context _atom old new]
(let [{:keys [atom-string]} new]
Expand Down

0 comments on commit 7fd4927

Please sign in to comment.