fetch commands.js init

Former-commit-id: 0f4581476d
This commit is contained in:
Roman Volosovskyi 2016-06-08 15:14:35 +03:00
parent 2b4f410fd7
commit 34f1e2fa17
10 changed files with 204 additions and 68 deletions

View File

@ -56,7 +56,6 @@
(dispatch [:load-user-phone-number])
(dispatch [:load-contacts])
;; load commands from remote server (todo: uncomment)
;; (dispatch [:load-commands])
(dispatch [:init-console-chat])
(dispatch [:init-chat])
(init-back-button-handler!)

View File

@ -250,9 +250,14 @@
([{:keys [messages current-chat-id] :as db} _]
(assoc-in db [:chats current-chat-id :messages] messages)))
(defn load-commands!
[{:keys [current-chat-id]}]
(dispatch [:load-commands! current-chat-id]))
(register-handler :init-chat
(-> load-messages!
((enrich init-chat))
((after load-commands!))
debug))
(defn initialize-chats

View File

@ -184,6 +184,9 @@
(def console-chat
{:chat-id "console"
:name "console"
; todo remove/change dapp config fot console
:dapp-url "http://localhost:8185"
:dapp-hash 123
:color default-chat-color
:group-chat false
:is-active true

View File

@ -2,22 +2,29 @@
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
[status-im.db :as db]
[status-im.models.commands :refer [commands
suggestions
get-commands
get-chat-command-request
get-chat-command-to-msg-id
clear-staged-commands]]
get-commands
get-chat-command-request
get-chat-command-to-msg-id
clear-staged-commands]]
[status-im.utils.utils :refer [log on-error http-get]]
[clojure.string :as s]))
(defn suggestion? [text]
(= (get text 0) "!"))
(defn get-suggestions [db text]
(if (suggestion? text)
;; TODO change 'commands' to 'suggestions'
(filterv #(.startsWith (:text %) text) (get-commands db))
[]))
(defn can-be-suggested? [text]
(fn [{:keys [name]}]
(.startsWith (str "!" name) text)))
(defn get-suggestions
[{:keys [current-chat-id] :as db} text]
(let [commands (get-in db [:chats current-chat-id :commands])]
(if (suggestion? text)
;; TODO change 'commands' to 'suggestions'
(->> commands
vals
(filter (can-be-suggested? text)))
[])))
(defn get-command [db text]
(when (suggestion? text)
@ -45,15 +52,6 @@
staged-commands))
(clear-staged-commands db)))
(defn execute-commands-js [body]
(.eval js/window body)
(let [commands (.-commands js/window)]
(dispatch [:set-commands (map #(update % :command keyword)
(js->clj commands :keywordize-keys true))])))
(defn load-commands []
(http-get "chat-commands.js" execute-commands-js nil))
(defn check-suggestion [db message]
(when-let [suggestion-text (when (string? message)
(re-matches #"^![^\s]+\s" message))]

View File

@ -1,11 +1,12 @@
(ns status-im.chat.views.suggestions
(:require-macros [status-im.utils.views :refer [defview]])
(:require [re-frame.core :refer [subscribe dispatch]]
[status-im.components.react :refer [view
text
icon
touchable-highlight
list-view
list-item]]
text
icon
touchable-highlight
list-view
list-item]]
[status-im.utils.listview :refer [to-datasource]]
[status-im.chat.styles.suggestions :as st]))
@ -13,11 +14,11 @@
(dispatch [:set-chat-command command]))
(defn suggestion-list-item
[{:keys [description command]
label :text
[{:keys [description]
label :name
:as suggestion}]
[touchable-highlight
{:onPress #(set-command-input (keyword command))}
{:onPress #(set-command-input (keyword label))}
[view st/suggestion-container
[view st/suggestion-sub-container
[view (st/suggestion-background suggestion)
@ -28,19 +29,17 @@
(defn render-row [row _ _]
(list-item [suggestion-list-item row]))
(defn suggestions-view []
(let [suggestions-atom (subscribe [:get-suggestions])]
(fn []
(let [suggestions @suggestions-atom]
(when (seq suggestions)
[view
[touchable-highlight {:style st/drag-down-touchable
:onPress (fn []
;; TODO hide suggestions?
)}
[view
[icon :drag_down st/drag-down-icon]]]
[view (st/suggestions-container (count suggestions))
[list-view {:dataSource (to-datasource suggestions)
:enableEmptySections true
:renderRow render-row}]]])))))
(defview suggestions-view []
[suggestions [:get-suggestions]]
(when (seq suggestions)
[view
[touchable-highlight {:style st/drag-down-touchable
:onPress (fn []
;; TODO hide suggestions?
)}
[view
[icon :drag_down st/drag-down-icon]]]
[view (st/suggestions-container (count suggestions))
[list-view {:dataSource (to-datasource suggestions)
:enableEmptySections true
:renderRow render-row}]]]))

View File

@ -0,0 +1,148 @@
(ns status-im.commands.handlers
(:require [re-frame.core :refer [register-handler after dispatch subscribe
trim-v debug]]
[status-im.utils.handlers :as u]
[status-im.components.react :as r]
[status-im.utils.utils :refer [http-get toast]]
[clojure.string :as s]))
;; commands loading flow
; ┌────────────────────────────┐
; │ user starts chat with dapp │
; └────────────────────────────┘
; │
; ▼
; ┌───────────────────────┐
; │ fetch current │
; │ `commands.js` hash │
; └───────────────────────┘
; │
; ▼
; ┌───────────────────────────┐
; │try to fetch `commands.js` │
; └───────────────────────────┘
; │
; ▼
;┌───┐ ┌─────────────────────────┐ ┌───┐
;│no ├────────│ there is `commands.js` │────┤yes│
;└─┬─┘ └─────────────────────────┘ └─┬─┘
; │ │
; │ ▼
; │ ┌───────────────────┐
; │ ┌────┐ │ Is file's hash │
; │ │nope├─────────────────│ equal to current? │
; │ └─┬──┘ └───────────────────┘
; │ │ │
; │ │ ┌─┴─┐
; │ │ │yes│
; │ │ └─┬─┘
; │ │ │
; │ │ ▼
; │ │ ┌────┐ ┌──────────────────────────┐ ┌────┐
; │ │ │fail├──│ ask `otto` to handle js │──┤succ│
; │ │ └──┬─┘ └──────────────────────────┘ └─┬──┘
; │ │ │ │
; │ │ │ ▼
; │ │ │ ┌────────────────────────────┐
; │ │ ▼ │ save commands │
; │ │ ┌────────────────────────┐ │ save js ? │
; │ │ │the dapp emit a message │ │ add some API object form │
; │ └─▶│ saying js is broken │ │ otto to app-db │
; │ └────────────────────────┘ └────────────────────────────┘
; │ │ │
; │ │ │
; │ ┌───────────────────┘ ▼
; │ │ ┌─────────────────────────┐
; │ │ │ if it is necessary show │
; │ ▼ │ as fullscreen │
; │ ┌───────────┐ └─────────────────────────┘
; │ │ │ │
; └─▶│ Fin' │◀──────────────────────────────────────────┘
; │ │
; └───────────┘
(defn reg-handler
([name handler] (reg-handler name nil handler))
([name middleware handler]
(register-handler name [debug trim-v middleware] handler)))
(def commands-js "commands.js")
(defn fetch-commands!
[db [identity]]
(when-let [url (:dapp-url (get-in db [:chats identity]))]
(http-get (s/join "/" [url commands-js])
#(dispatch [::validate-hash identity %])
#(dispatch [::loading-failed! identity ::file-was-not-found]))))
(defn dispatch-loaded!
[db [identity file]]
(if (::valid-hash db)
(dispatch [::parse-commands! identity file])
(dispatch [::loading-failed! identity ::wrong-hash])))
(defn get-hash-by-dentity
[db identity]
(get-in db [:chats identity :dapp-hash]))
(defn get-hash-by-file
[file]
;; todo implement
123)
(defn get-jail []
(.-Jail (.-NativeModules r/react)))
(defn parse [file success-callback fail-callback]
(.parse (get-jail) file success-callback fail-callback))
(defn json->clj [json]
(js->clj (.parse js/JSON json) :keywordize-keys true))
(defn parse-commands! [_ [identity file]]
(parse file
(fn [result]
(let [commands (json->clj result)]
(dispatch [::add-commands identity commands])))
#(dispatch [::loading-failed! identity ::error-in-jail %])))
(defn validate-hash
[db [identity file]]
(let [valid? (= (get-hash-by-dentity db identity)
(get-hash-by-file file))]
(assoc db ::valid-hash valid?)))
(defn save-commands!
[db]
#_(realm/save (::new-commands db)))
(defn add-commands
[db [id commands-obj]]
(let [commands (:commands commands-obj)]
(-> db
(update-in [:chats id :commands] merge commands)
(assoc db ::new-commands commands))))
(defn loading-failed
[db [id reason details]]
(let [url (get-in db [:chats id :dapp-url])]
(toast (s/join "\n" ["commands.js loading failed"
url
id
(name reason)
details]))))
(reg-handler :load-commands! (u/side-effect! fetch-commands!))
(reg-handler ::validate-hash
(after dispatch-loaded!)
validate-hash)
(reg-handler ::parse-commands! (u/side-effect! parse-commands!))
(reg-handler ::add-commands
(after save-commands!)
add-commands)
(reg-handler ::loading-failed! (u/side-effect! loading-failed))

View File

@ -5,8 +5,6 @@
[status-im.db :refer [app-db schema]]
[status-im.persistence.simple-kv-store :as kv]
[status-im.protocol.state.storage :as storage]
[status-im.models.commands :refer [set-commands]]
[status-im.chat.suggestions :refer [load-commands]]
[status-im.utils.logging :as log]
[status-im.utils.crypt :refer [gen-random-bytes]]
[status-im.utils.handlers :as u]
@ -17,7 +15,8 @@
status-im.discovery.handlers
status-im.new-group.handlers
status-im.participants.handlers
status-im.protocol.handlers))
status-im.protocol.handlers
status-im.commands.handlers))
;; -- Middleware ------------------------------------------------------------
;;
@ -75,17 +74,6 @@
(fn [_ _]
(log/debug "crypt initialized"))))
(register-handler :load-commands
(u/side-effect!
(fn [_ [action]]
(log/debug action)
(load-commands))))
(register-handler :set-commands
(fn [db [action commands]]
(log/debug action commands)
(set-commands db commands)))
;; -- User data --------------------------------------------------------------
(register-handler :load-user-phone-number
(fn [db [_]]

View File

@ -64,12 +64,6 @@
;; (get db :commands)
commands)
(defn set-commands [db commands]
(assoc db :commands commands))
;; todo delete
(def suggestions (filterv :suggestion commands))
(defn get-command [db command-key]
(first (filter #(= command-key (:command %)) (get-commands db))))

View File

@ -51,6 +51,10 @@
:timestamp "int"
:contacts {:type "list"
:objectType "chat-contact"}
:dapp-url {:type :string
:optional true}
:dapp-hash {:type :int
:optional true}
:last-msg-id "string"}}
{:name :tag
:primaryKey :name

View File

@ -41,10 +41,8 @@
(toast (str error))))))))
(defn http-get
([action on-success on-error]
(-> (.fetch js/window
(str const/server-address action)
(clj->js {:method "GET"}))
([url on-success on-error]
(-> (.fetch js/window url (clj->js {:method "GET"}))
(.then (fn [response]
(log response)
(.text response)))