Skip to content

Commit

Permalink
Factor out undo-demo into its own namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
holmsand committed Feb 3, 2014
1 parent 581cbf8 commit 28c2acc
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 85 deletions.
87 changes: 2 additions & 85 deletions demo/reagentdemo/news.cljs
Original file line number Diff line number Diff line change
@@ -1,95 +1,12 @@
(ns reagentdemo.news
(:require [reagent.core :as reagent :refer [atom]]
[reagent.debug :refer-macros [dbg println]]
[reagentdemo.syntax :refer-macros [get-source]]
[reagentdemo.page :refer [title link page-map]]
[reagentdemo.common :as common :refer [demo-component]]
[reagentdemo.news.async :as async]
[todomvc :as todomvc]))

(def funmap (-> "reagentdemo/news.cljs" get-source common/fun-map))
(def src-for (partial common/src-for funmap))

(def state todomvc/todos)

(def undo-list (atom nil))

(defn undo []
(let [undos @undo-list]
(when-let [old (first undos)]
(reset! state old)
(reset! undo-list (rest undos)))))

(defn undo-button []
(let [n (count @undo-list)]
[:input {:type "button" :on-click undo
:disabled (zero? n)
:value (str "Undo (" n ")")}]))

(defn todomvc-with-undo []
(add-watch state ::undo-watcher
(fn [_ _ old-state _]
(swap! undo-list conj old-state)))
[:div
[undo-button]
[todomvc/todo-app]])

(defn undo-demo []
[demo-component {:comp todomvc-with-undo
:src (src-for [:state :undo-list :undo :save-state
:undo-button :todomvc-with-undo])}])

(def undo-demo-cleanup
(with-meta undo-demo {:component-will-unmount
(fn []
(reset! undo-list nil)
(remove-watch state ::undo-watcher))}))

(defn undo-example [{:keys [summary]}]
(let [head "Cloact becomes Reagent: Undo is trivial"]
[:div.reagent-demo
[:h1 [link {:href undo-example} head]]
[title head]
[:div.demo-text
[:h2 "(reset! cloact-name \"Reagent\")"]

[:p "It turns out that ”Cloact” was a really, really bad
name. It made some people think about birds’ behinds, in
possibly unhealthy ways, which even Google suggested they
should."]

[:p "The new name is " [:strong "Reagent"] ", which hopefully
doesn’t bring with it the same disgusting connotations."]

[:p "The API is otherwise unchanged, so a simple
search-and-replace should suffice."]

(if summary
[link {:href undo-example
:class 'news-read-more} "Read more"]
[:div.demo-text

[:h2 "Undo the easy way"]

[:p "To celebrate the undoing of the apparently disgusting
name, here is an example of how easy it is to add undo
functionality to Reagent components."]

[:p "It simply saves the old state whenever it changes, and
restores it when the button is clicked."]

[:p "The really nice thing about ClojureScript is that not
only is this easy and safe to do, courtesy of immutable data
structures, it is also efficient. ClojureScript figures out
how to represent ”changes” to maps and vectors efficiently,
so that you won’t have to."]

[undo-demo-cleanup]])]]))
[reagentdemo.news.undo-demo :as undo-demo]))

(defn main []
[:div
[async/main {:summary true}]
[undo-example {:summary true}]])

(swap! page-map assoc
"news/cloact-reagent-undo-demo.html" undo-example)
[undo-demo/main {:summary true}]])
89 changes: 89 additions & 0 deletions demo/reagentdemo/news/undo-demo.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
(ns reagentdemo.news.undo-demo
(:require [reagent.core :as reagent :refer [atom]]
[reagent.debug :refer-macros [dbg println]]
[reagentdemo.syntax :refer-macros [get-source]]
[reagentdemo.page :refer [title link page-map]]
[reagentdemo.common :as common :refer [demo-component]]
[todomvc :as todomvc]))

(def funmap (-> "reagentdemo/news/undo-demo.cljs" get-source common/fun-map))
(def src-for (partial common/src-for funmap))

(def state todomvc/todos)

(def undo-list (atom nil))

(defn undo []
(let [undos @undo-list]
(when-let [old (first undos)]
(reset! state old)
(reset! undo-list (rest undos)))))

(defn undo-button []
(let [n (count @undo-list)]
[:input {:type "button" :on-click undo
:disabled (zero? n)
:value (str "Undo (" n ")")}]))

(defn todomvc-with-undo []
(add-watch state ::undo-watcher
(fn [_ _ old-state _]
(swap! undo-list conj old-state)))
[:div
[undo-button]
[todomvc/todo-app]])

(defn undo-demo []
[demo-component {:comp todomvc-with-undo
:src (src-for [:state :undo-list :undo :save-state
:undo-button :todomvc-with-undo])}])

(def undo-demo-cleanup
(with-meta undo-demo {:component-will-unmount
(fn []
(reset! undo-list nil)
(remove-watch state ::undo-watcher))}))

(defn main [{:keys [summary]}]
(let [head "Cloact becomes Reagent: Undo is trivial"]
[:div.reagent-demo
[:h1 [link {:href main} head]]
[title head]
[:div.demo-text
[:h2 "(reset! cloact-name \"Reagent\")"]

[:p "It turns out that ”Cloact” was a really, really bad
name. It made some people think about birds’ behinds, in
possibly unhealthy ways, which even Google suggested they
should."]

[:p "The new name is " [:strong "Reagent"] ", which hopefully
doesn’t bring with it the same disgusting connotations."]

[:p "The API is otherwise unchanged, so a simple
search-and-replace should suffice."]

(if summary
[link {:href main
:class 'news-read-more} "Read more"]
[:div.demo-text

[:h2 "Undo the easy way"]

[:p "To celebrate the undoing of the apparently disgusting
name, here is an example of how easy it is to add undo
functionality to Reagent components."]

[:p "It simply saves the old state whenever it changes, and
restores it when the button is clicked."]

[:p "The really nice thing about ClojureScript is that not
only is this easy and safe to do, courtesy of immutable data
structures, it is also efficient. ClojureScript figures out
how to represent ”changes” to maps and vectors efficiently,
so that you won’t have to."]

[undo-demo-cleanup]])]]))

(swap! page-map assoc
"news/cloact-reagent-undo-demo.html" main)

0 comments on commit 28c2acc

Please sign in to comment.