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
|
||||
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)
|
||||
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
|
||||
```
|
||||
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.
|
||||
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.
|
||||
|
||||
```
|
||||
|
|
|
@ -37,11 +37,26 @@ interfaceConf =
|
|||
ios: ["core.cljs"]
|
||||
android: ["core.cljs"]
|
||||
common: ["handlers.cljs", "subs.cljs", "db.cljs"]
|
||||
other: []
|
||||
deps: ['[reagent "0.5.1" :exclusions [cljsjs/react]]'
|
||||
'[re-frame "0.6.0"]'
|
||||
'[prismatic/schema "1.0.4"]']
|
||||
shims: ["cljsjs.react"]
|
||||
sampleCommandNs: '(in-ns \'$PROJECT_NAME_HYPHENATED$.ios.core)'
|
||||
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') ->
|
||||
console.log chalk[color] s
|
||||
|
@ -246,6 +261,7 @@ shimCljsNamespace = (ns) ->
|
|||
|
||||
copySrcFiles = (interfaceName, projName, projNameUs, projNameHyph) ->
|
||||
cljsDir = interfaceConf[interfaceName].cljsDir
|
||||
|
||||
fileNames = interfaceConf[interfaceName].sources.common;
|
||||
for fileName in fileNames
|
||||
path = "src/#{projNameUs}/#{fileName}"
|
||||
|
@ -261,6 +277,12 @@ copySrcFiles = (interfaceName, projName, projNameUs, projNameHyph) ->
|
|||
fs.copySync("#{resources}/#{cljsDir}/#{fileName}", path)
|
||||
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;
|
||||
for namespace in shims
|
||||
shimCljsNamespace(namespace)
|
||||
|
@ -348,7 +370,7 @@ init = (interfaceName, projName) ->
|
|||
log 'Reload the app in simulator'
|
||||
log ''
|
||||
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 'Changes you make via the REPL or by changing your .cljs files should appear live.', 'yellow'
|
||||
log ''
|
||||
|
@ -476,15 +498,17 @@ cli.version pkgJson.version
|
|||
|
||||
cli.command 'init <name>'
|
||||
.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'
|
||||
logErr '''
|
||||
re-natal init requires a project name as the first argument.
|
||||
e.g.
|
||||
re-natal init HelloWorld
|
||||
'''
|
||||
|
||||
ensureFreePort -> init('reagent', name)
|
||||
unless interfaceConf[cmd.interface]
|
||||
logErr "Unsupported React interface: #{cmd.interface}, one of [#{interfaceNames}] was expected."
|
||||
ensureFreePort -> init(cmd.interface, name)
|
||||
|
||||
cli.command 'upgrade'
|
||||
.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