Merge pull request #24 from drapanjanas/support-om-next
Support om next fixes #15
This commit is contained in:
commit
055e123476
10
README.md
10
README.md
|
@ -7,7 +7,8 @@ Artur Girenko, MIT License
|
||||||
|
|
||||||
This project is a fork of [dmotz/natal](https://github.com/dmotz/natal) by Dan Motzenbecker with
|
This project is a fork of [dmotz/natal](https://github.com/dmotz/natal) by Dan Motzenbecker with
|
||||||
the goal of generating skeleton of native app for iOS and Android based on
|
the goal of generating skeleton of native app for iOS and Android based on
|
||||||
[Reagent](https://github.com/reagent-project/reagent) and [re-frame](https://github.com/Day8/re-frame).
|
[Reagent](https://github.com/reagent-project/reagent) and [re-frame](https://github.com/Day8/re-frame)
|
||||||
|
or [Om.Next](https://github.com/omcljs/om/wiki/Quick-Start-(om.next)).
|
||||||
|
|
||||||
The support of Figwheel is based on brilliant solution developed by Will Decker [decker405/figwheel-react-native](https://github.com/decker405/figwheel-react-native)
|
The support of Figwheel is based on brilliant solution developed by Will Decker [decker405/figwheel-react-native](https://github.com/decker405/figwheel-react-native)
|
||||||
which works in both platforms.
|
which works in both platforms.
|
||||||
|
@ -54,12 +55,15 @@ To bootstrap a new app, run `re-natal init` with your app's name as an argument:
|
||||||
```
|
```
|
||||||
$ re-natal init FutureApp
|
$ re-natal init FutureApp
|
||||||
```
|
```
|
||||||
|
Or, for Om.Next project:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ re-natal init FutureApp -i om-next
|
||||||
|
```
|
||||||
|
|
||||||
If your app's name is more than a single word, be sure to type it in CamelCase.
|
If your app's name is more than a single word, be sure to type it in CamelCase.
|
||||||
A corresponding hyphenated Clojure namespace will be created.
|
A corresponding hyphenated Clojure namespace will be created.
|
||||||
|
|
||||||
Re-Natal will create a simple skeleton based on the current
|
|
||||||
version of [Reagent](https://github.com/reagent-project/reagent) and [Day8/re-frame](https://github.com/Day8/re-frame).
|
|
||||||
If all goes well you should see printed out basic instructions how to run in iOS simulator.
|
If all goes well you should see printed out basic instructions how to run in iOS simulator.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -37,11 +37,26 @@ interfaceConf =
|
||||||
ios: ["core.cljs"]
|
ios: ["core.cljs"]
|
||||||
android: ["core.cljs"]
|
android: ["core.cljs"]
|
||||||
common: ["handlers.cljs", "subs.cljs", "db.cljs"]
|
common: ["handlers.cljs", "subs.cljs", "db.cljs"]
|
||||||
|
other: []
|
||||||
deps: ['[reagent "0.5.1" :exclusions [cljsjs/react]]'
|
deps: ['[reagent "0.5.1" :exclusions [cljsjs/react]]'
|
||||||
'[re-frame "0.6.0"]'
|
'[re-frame "0.6.0"]'
|
||||||
'[prismatic/schema "1.0.4"]']
|
'[prismatic/schema "1.0.4"]']
|
||||||
shims: ["cljsjs.react"]
|
shims: ["cljsjs.react"]
|
||||||
|
sampleCommandNs: '(in-ns \'$PROJECT_NAME_HYPHENATED$.ios.core)'
|
||||||
sampleCommand: '(dispatch [:set-greeting "Hello Native World!"])'
|
sampleCommand: '(dispatch [:set-greeting "Hello Native World!"])'
|
||||||
|
'om-next':
|
||||||
|
cljsDir: "cljs-om-next"
|
||||||
|
sources:
|
||||||
|
ios: ["core.cljs"]
|
||||||
|
android: ["core.cljs"]
|
||||||
|
common: ["state.cljs"]
|
||||||
|
other: [["support.cljs","re_natal/support.cljs"]]
|
||||||
|
deps: ['[org.omcljs/om "1.0.0-alpha28" :exclusions [cljsjs/react cljsjs/react-dom]]'
|
||||||
|
'[natal-shell "0.1.6"]']
|
||||||
|
shims: ["cljsjs.react", "cljsjs.react.dom"]
|
||||||
|
sampleCommandNs: '(in-ns \'$PROJECT_NAME_HYPHENATED$.state)'
|
||||||
|
sampleCommand: '(swap! app-state assoc :app/msg "Hello Native World!")'
|
||||||
|
interfaceNames = Object.keys interfaceConf
|
||||||
|
|
||||||
log = (s, color = 'green') ->
|
log = (s, color = 'green') ->
|
||||||
console.log chalk[color] s
|
console.log chalk[color] s
|
||||||
|
@ -246,6 +261,7 @@ shimCljsNamespace = (ns) ->
|
||||||
|
|
||||||
copySrcFiles = (interfaceName, projName, projNameUs, projNameHyph) ->
|
copySrcFiles = (interfaceName, projName, projNameUs, projNameHyph) ->
|
||||||
cljsDir = interfaceConf[interfaceName].cljsDir
|
cljsDir = interfaceConf[interfaceName].cljsDir
|
||||||
|
|
||||||
fileNames = interfaceConf[interfaceName].sources.common;
|
fileNames = interfaceConf[interfaceName].sources.common;
|
||||||
for fileName in fileNames
|
for fileName in fileNames
|
||||||
path = "src/#{projNameUs}/#{fileName}"
|
path = "src/#{projNameUs}/#{fileName}"
|
||||||
|
@ -261,6 +277,12 @@ copySrcFiles = (interfaceName, projName, projNameUs, projNameHyph) ->
|
||||||
fs.copySync("#{resources}/#{cljsDir}/#{fileName}", path)
|
fs.copySync("#{resources}/#{cljsDir}/#{fileName}", path)
|
||||||
edit path, [[projNameHyphRx, projNameHyph], [projNameRx, projName], [platformRx, platform]]
|
edit path, [[projNameHyphRx, projNameHyph], [projNameRx, projName], [platformRx, platform]]
|
||||||
|
|
||||||
|
otherFiles = interfaceConf[interfaceName].sources.other;
|
||||||
|
for cpFile in otherFiles
|
||||||
|
from = "#{resources}/#{cljsDir}/#{cpFile[0]}"
|
||||||
|
to = "src/#{cpFile[1]}"
|
||||||
|
fs.copySync(from, to)
|
||||||
|
|
||||||
shims = fileNames = interfaceConf[interfaceName].shims;
|
shims = fileNames = interfaceConf[interfaceName].shims;
|
||||||
for namespace in shims
|
for namespace in shims
|
||||||
shimCljsNamespace(namespace)
|
shimCljsNamespace(namespace)
|
||||||
|
@ -348,7 +370,7 @@ init = (interfaceName, projName) ->
|
||||||
log 'Reload the app in simulator'
|
log 'Reload the app in simulator'
|
||||||
log ''
|
log ''
|
||||||
log 'At the REPL prompt type this:', 'yellow'
|
log 'At the REPL prompt type this:', 'yellow'
|
||||||
log "(in-ns '#{projNameHyph}.ios.core)", 'inverse'
|
log interfaceConf[interfaceName].sampleCommandNs.replace(projNameHyphRx, projNameHyph), 'inverse'
|
||||||
log ''
|
log ''
|
||||||
log 'Changes you make via the REPL or by changing your .cljs files should appear live.', 'yellow'
|
log 'Changes you make via the REPL or by changing your .cljs files should appear live.', 'yellow'
|
||||||
log ''
|
log ''
|
||||||
|
@ -476,15 +498,17 @@ cli.version pkgJson.version
|
||||||
|
|
||||||
cli.command 'init <name>'
|
cli.command 'init <name>'
|
||||||
.description 'create a new ClojureScript React Native project'
|
.description 'create a new ClojureScript React Native project'
|
||||||
.action (name) ->
|
.option "-i, --interface [#{interfaceNames.join ' '}]", 'specify React interface', 'reagent'
|
||||||
|
.action (name, cmd) ->
|
||||||
if typeof name isnt 'string'
|
if typeof name isnt 'string'
|
||||||
logErr '''
|
logErr '''
|
||||||
re-natal init requires a project name as the first argument.
|
re-natal init requires a project name as the first argument.
|
||||||
e.g.
|
e.g.
|
||||||
re-natal init HelloWorld
|
re-natal init HelloWorld
|
||||||
'''
|
'''
|
||||||
|
unless interfaceConf[cmd.interface]
|
||||||
ensureFreePort -> init('reagent', name)
|
logErr "Unsupported React interface: #{cmd.interface}, one of [#{interfaceNames}] was expected."
|
||||||
|
ensureFreePort -> init(cmd.interface, name)
|
||||||
|
|
||||||
cli.command 'upgrade'
|
cli.command 'upgrade'
|
||||||
.description 'upgrades project files to current installed version of re-natal (the upgrade of re-natal itself is done via npm)'
|
.description 'upgrades project files to current installed version of re-natal (the upgrade of re-natal itself is done via npm)'
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
(ns $PROJECT_NAME_HYPHENATED$.$PLATFORM$.core
|
||||||
|
(:require-macros [natal-shell.components :refer [view text image touchable-highlight]]
|
||||||
|
[natal-shell.alert :refer [alert]])
|
||||||
|
(:require [om.next :as om :refer-macros [defui]]
|
||||||
|
[re-natal.support :as sup]
|
||||||
|
[$PROJECT_NAME_HYPHENATED$.state :as state]))
|
||||||
|
|
||||||
|
(set! js/React (js/require "react-native"))
|
||||||
|
|
||||||
|
(def app-registry (.-AppRegistry js/React))
|
||||||
|
(def logo-img (js/require "./images/cljs.png"))
|
||||||
|
|
||||||
|
(defui AppRoot
|
||||||
|
static om/IQuery
|
||||||
|
(query [this]
|
||||||
|
'[:app/msg])
|
||||||
|
Object
|
||||||
|
(render [this]
|
||||||
|
(.log js/console "rendering app")
|
||||||
|
(let [{:keys [app/msg]} (om/props this)]
|
||||||
|
(view {:style {:flexDirection "column" :margin 40 :alignItems "center"}}
|
||||||
|
(text {:style {:fontSize 30 :fontWeight "100" :marginBottom 20 :textAlign "center"}} msg)
|
||||||
|
(image {:source logo-img
|
||||||
|
:style {:width 80 :height 80 :marginBottom 30}})
|
||||||
|
(touchable-highlight {:style {:backgroundColor "#999" :padding 10 :borderRadius 5}
|
||||||
|
:onPress #(alert "HELLO!")}
|
||||||
|
(text {:style {:color "white" :textAlign "center" :fontWeight "bold"}} "press me"))))))
|
||||||
|
|
||||||
|
(defonce RootNode (sup/root-node 1))
|
||||||
|
(defonce app-root (om/factory RootNode))
|
||||||
|
|
||||||
|
(defn init []
|
||||||
|
(om/add-root! state/reconciler AppRoot 1)
|
||||||
|
(.registerComponent app-registry "$PROJECT_NAME$" (fn [] app-root)))
|
|
@ -0,0 +1,16 @@
|
||||||
|
(ns ^:figwheel-no-load env.$PLATFORM$.main
|
||||||
|
(:require [om.next :as om]
|
||||||
|
[$PROJECT_NAME_HYPHENATED$.$PLATFORM$.core :as core]
|
||||||
|
[$PROJECT_NAME_HYPHENATED$.state :as state]
|
||||||
|
[figwheel.client :as figwheel :include-macros true]))
|
||||||
|
|
||||||
|
(enable-console-print!)
|
||||||
|
|
||||||
|
(figwheel/watch-and-reload
|
||||||
|
:websocket-url "ws://localhost:3449/figwheel-ws"
|
||||||
|
:heads-up-display true
|
||||||
|
:jsload-callback #(om/add-root! state/reconciler core/AppRoot 1))
|
||||||
|
|
||||||
|
(core/init)
|
||||||
|
|
||||||
|
(def root-el (core/app-root))
|
|
@ -0,0 +1,4 @@
|
||||||
|
(ns env.$PLATFORM$.main
|
||||||
|
(:require [$PROJECT_NAME_HYPHENATED$.$PLATFORM$.core :as core]))
|
||||||
|
|
||||||
|
(core/init)
|
|
@ -0,0 +1,20 @@
|
||||||
|
(ns $PROJECT_NAME_HYPHENATED$.state
|
||||||
|
(:require [om.next :as om]
|
||||||
|
[re-natal.support :as sup]))
|
||||||
|
|
||||||
|
(defonce app-state (atom {:app/msg "Hello Clojure in iOS and Android!"}))
|
||||||
|
|
||||||
|
(defmulti read om/dispatch)
|
||||||
|
(defmethod read :default
|
||||||
|
[{:keys [state]} k _]
|
||||||
|
(let [st @state]
|
||||||
|
(if-let [[_ v] (find st k)]
|
||||||
|
{:value v}
|
||||||
|
{:value :not-found})))
|
||||||
|
|
||||||
|
(defonce reconciler
|
||||||
|
(om/reconciler
|
||||||
|
{:state app-state
|
||||||
|
:parser (om/parser {:read read})
|
||||||
|
:root-render sup/root-render
|
||||||
|
:root-unmount sup/root-unmount}))
|
|
@ -0,0 +1,35 @@
|
||||||
|
(ns re-natal.support
|
||||||
|
(:require [om.next :refer-macros [ui]]))
|
||||||
|
|
||||||
|
(def root-nodes (atom {}))
|
||||||
|
|
||||||
|
(defn root-node
|
||||||
|
"A substitute for a real root node (1) for mounting om-next component.
|
||||||
|
You have to call function :on-render and :on-unmount in reconciler :root-render :root-unmount function."
|
||||||
|
[id]
|
||||||
|
(let [content (atom nil)
|
||||||
|
instance (atom nil)
|
||||||
|
class (ui Object
|
||||||
|
(componentWillMount [this] (reset! instance this))
|
||||||
|
(render [_] @content))]
|
||||||
|
(swap! root-nodes assoc id {:on-render (fn [el]
|
||||||
|
(reset! content el)
|
||||||
|
(when @instance
|
||||||
|
(.forceUpdate @instance)))
|
||||||
|
:on-unmount (fn [])
|
||||||
|
:class class})
|
||||||
|
class))
|
||||||
|
(defn root-render
|
||||||
|
"Use this as reconciler :root-render function."
|
||||||
|
[el id]
|
||||||
|
(let [node (get @root-nodes id)
|
||||||
|
on-render (:on-render node)]
|
||||||
|
(when on-render (on-render el))))
|
||||||
|
|
||||||
|
(defn root-unmount
|
||||||
|
"Use this as reconciler :root-unmount function."
|
||||||
|
[id]
|
||||||
|
(let [node (get @root-nodes id)
|
||||||
|
unmount-fn (:on-unmount node)]
|
||||||
|
(when unmount-fn (unmount-fn))))
|
||||||
|
|
Loading…
Reference in New Issue