implement new wallet flow

This commit is contained in:
Adrian Tiberius 2016-10-20 16:51:37 +03:00 committed by Roman Volosovskyi
parent 788cbc34f3
commit 083ade766e
30 changed files with 517 additions and 127 deletions

View File

@ -117,7 +117,7 @@ function sendTransaction(params, context) {
} }
} }
status.command({ var send = {
name: "send", name: "send",
icon: "money_white", icon: "money_white",
color: "#5fc48d", color: "#5fc48d",
@ -134,4 +134,36 @@ status.command({
}, },
handler: sendTransaction, handler: sendTransaction,
validator: validateBalance validator: validateBalance
};
status.command(send);
status.response(send);
status.command({
name: "request",
color: "#7099e6",
description: "Transaction request",
params: [{
name: "amount",
type: status.types.NUMBER
}],
preview: function (params) {
return status.components.text(
{},
params.amount + " ETH"
);
},
handler: function (params) {
return {
event: "request",
params: [params.amount]
request: {
command: "send",
params: {
amount: params.amount
},
content: "Requesting " + params.amount + "ETH"
}
};
},
}); });

View File

@ -1,6 +1,7 @@
var _status_catalog = { var _status_catalog = {
commands: {}, commands: {},
responses: {} responses: {},
functions: {}
}, },
status = {}; status = {};
@ -31,6 +32,7 @@ Command.prototype.create = function (com) {
this.preview = com.preview; this.preview = com.preview;
this["suggestions-trigger"] = com.suggestionsTrigger || "on-change"; this["suggestions-trigger"] = com.suggestionsTrigger || "on-change";
this.fullscreen = com.fullscreen; this.fullscreen = com.fullscreen;
this.request = com.request;
this.addToCatalog(); this.addToCatalog();
return this; return this;
@ -153,6 +155,9 @@ var status = {
var response = new Response(); var response = new Response();
return response.create(h); return response.create(h);
}, },
registerFunction: function (name, fn){
_status_catalog.functions[name] = fn;
},
autorun: function (commandName) { autorun: function (commandName) {
_status_catalog.autorun = commandName; _status_catalog.autorun = commandName;
}, },

View File

@ -25,3 +25,13 @@ status.command({
}); });
status.autorun("browse"); status.autorun("browse");
status.registerFunction("send", function (params, context) {
var data = {
from: context.from,
to: params.address,
value: web3.toWei(params.amount, "ether")
};
web3.eth.sendTransaction(data);
})

View File

@ -113,3 +113,56 @@
{:flex 1 {:flex 1
:color color-white :color color-white
:fontSize 16}) :fontSize 16})
;wallet-qr-code.cljs
(def wallet-qr-code
{:flex 1
:flex-direction :column})
(def account-toolbar
{:background-color "#2f3031"
:padding-bottom 45})
(def wallet-account-container
{:flex 1
:flexDirection :row
:height 69
:alignItems :center
:justifyContent :center})
(def qr-code
{:align-items :center
:padding-vertical 40})
(def footer
{:position :absolute
:left 0
:right 0
:bottom 0
:height 166
:background-color "#2f3031"})
(def wallet-info
{:align-items :center
:padding-top 42
:padding-bottom 20})
(def wallet-name-text
{:color color-white
:padding-bottom 5})
(def wallet-address-text
{:color "#999999"
})
(def done-button
{:flex 1
:flex-direction :column
:align-items :center
:height 60
:padding-top 20
:background-color "#7597e4"})
(def done-button-text
{:color color-white})

View File

@ -0,0 +1,44 @@
(ns status-im.accounts.views.wallet-qr-code
(:require-macros [status-im.utils.views :refer [defview]])
(:require [status-im.components.react :refer [view
text
image
touchable-highlight]]
[status-im.components.styles :refer [icon-close]]
[status-im.components.qr-code :refer [qr-code]]
[re-frame.core :refer [dispatch subscribe]]
[status-im.accounts.styles :as st]
[status-im.i18n :refer [label]]
[clojure.string :as s]))
(defview wallet-qr-code []
[{:keys [address photo-path name] :as account} [:get-current-account]
{:keys [amount]} [:get :contacts-click-params]]
[view st/wallet-qr-code
[view st/account-toolbar
[view st/wallet-account-container
[view st/photo-container
[view st/account-photo-container
[image {:source {:uri (if (s/blank? photo-path) :avatar photo-path)}
:style st/photo-image}]]]
[view st/name-container
[text {:style st/name-text
:number-of-lines 1} name]]
[view st/online-container
[touchable-highlight {:onPress #(dispatch [:navigate-back])}
[image {:source {:uri :icon-close-white}
:style icon-close}]]]]]
[view st/qr-code
[qr-code {:value (prn-str {:address address
:amount amount})
:size 200}]]
[view st/footer
[view st/wallet-info
[text {:style st/wallet-name-text} (label :t/main-wallet)]
[text {:style st/wallet-address-text} address]]
[touchable-highlight {:onPress #(dispatch [:navigate-back])}
[view st/done-button
[text {:style st/done-button-text} (label :t/done)]]]]])

View File

@ -7,7 +7,9 @@
[status-im.subs] [status-im.subs]
[status-im.components.react :refer [app-registry [status-im.components.react :refer [app-registry
keyboard keyboard
orientation]] orientation
view
modal]]
[status-im.components.main-tabs :refer [main-tabs]] [status-im.components.main-tabs :refer [main-tabs]]
[status-im.contacts.views.contact-list :refer [contact-list]] [status-im.contacts.views.contact-list :refer [contact-list]]
[status-im.contacts.views.new-contact :refer [new-contact]] [status-im.contacts.views.new-contact :refer [new-contact]]
@ -28,7 +30,9 @@
[status-im.profile.photo-capture.screen :refer [profile-photo-capture]] [status-im.profile.photo-capture.screen :refer [profile-photo-capture]]
status-im.data-store.core status-im.data-store.core
[taoensso.timbre :as log] [taoensso.timbre :as log]
[status-im.components.status :as status])) [status-im.components.status :as status]
[status-im.chat.styles.screen :as st]
[status-im.accounts.views.wallet-qr-code :refer [wallet-qr-code]]))
(defn init-back-button-handler! [] (defn init-back-button-handler! []
(let [new-listener (fn [] (let [new-listener (fn []
@ -55,7 +59,8 @@
(let [signed-up? (subscribe [:signed-up?]) (let [signed-up? (subscribe [:signed-up?])
view-id (subscribe [:get :view-id]) view-id (subscribe [:get :view-id])
account-id (subscribe [:get :current-account-id]) account-id (subscribe [:get :current-account-id])
keyboard-height (subscribe [:get :keyboard-height])] keyboard-height (subscribe [:get :keyboard-height])
modal-view (subscribe [:get :modal])]
(log/debug "Current account: " @account-id) (log/debug "Current account: " @account-id)
(r/create-class (r/create-class
{:component-will-mount {:component-will-mount
@ -75,7 +80,7 @@
(.addListener keyboard (.addListener keyboard
"keyboardDidHide" "keyboardDidHide"
#(when-not (= 0 @keyboard-height) #(when-not (= 0 @keyboard-height)
(dispatch [:set :keyboard-height 0])))) (dispatch [:set :keyboard-height 0]))))
:render :render
(fn [] (fn []
(when @view-id (when @view-id
@ -101,14 +106,28 @@
:recover recover :recover recover
:confirm confirm :confirm confirm
:my-profile my-profile)] :my-profile my-profile)]
[component]))))}))) [view
{:flex 1}
[component]
(when @modal-view
[view
st/chat-modal
[modal {:animation-type :slide
:transparent false
:on-request-close #(dispatch [:navigate-back])}
(let [component (case @modal-view
:qr-scanner qr-scanner
:wallet-qr-code wallet-qr-code
:confirm confirm
:contact-list-modal contact-list)]
[component])]])]))))})))
(defn init [& [env]] (defn init [& [env]]
(dispatch-sync [:reset-app]) (dispatch-sync [:reset-app])
(.registerComponent app-registry "StatusIm" #(r/reactify-component app-root) (.registerComponent app-registry "StatusIm" #(r/reactify-component app-root))
(dispatch [:listen-to-network-status!]) (dispatch [:listen-to-network-status!])
(dispatch [:initialize-crypt]) (dispatch [:initialize-crypt])
(dispatch [:initialize-geth]) (dispatch [:initialize-geth])
(status/set-soft-input-mode status/adjust-resize) (status/set-soft-input-mode status/adjust-resize)
(dispatch [:load-user-phone-number]) (dispatch [:load-user-phone-number])
(init-back-button-handler!))) (init-back-button-handler!))

View File

@ -24,7 +24,8 @@
valid-mobile-number?]] valid-mobile-number?]]
[status-im.components.status :as status] [status-im.components.status :as status]
[status-im.utils.types :refer [json->clj]] [status-im.utils.types :refer [json->clj]]
[status-im.chat.handlers.commands :refer [command-prefix]] status-im.chat.handlers.commands
[status-im.commands.utils :refer [command-prefix]]
[status-im.chat.utils :refer [console? not-console?]] [status-im.chat.utils :refer [console? not-console?]]
[status-im.constants :refer [console-chat-id]] [status-im.constants :refer [console-chat-id]]
[status-im.utils.gfycat.core :refer [generate-gfy]] [status-im.utils.gfycat.core :refer [generate-gfy]]
@ -324,8 +325,9 @@
(when (= current-chat-id wallet-chat-id) (when (= current-chat-id wallet-chat-id)
(dispatch [:cancel-command])) (dispatch [:cancel-command]))
(dispatch [:load-requests! chat-id]) (dispatch [:load-requests! chat-id])
(when-not commands-loaded? (if-not commands-loaded?
(dispatch [:load-commands! chat-id])) (dispatch [:load-commands! chat-id])
(dispatch [:invoke-chat-loaded-callbacks chat-id]))
(if (and (seq messages) (if (and (seq messages)
(not= (count messages) 1)) (not= (count messages) 1))
db' db'
@ -333,6 +335,26 @@
load-messages! load-messages!
init-chat)))) init-chat))))
(register-handler :add-chat-loaded-callback
(fn [db [_ chat-id callback]]
(log/debug "Add chat loaded callback: " chat-id callback)
(update-in db [::chat-loaded-callbacks chat-id] conj callback)))
(register-handler ::clear-chat-loaded-callbacks
(fn [db [_ chat-id]]
(log/debug "Clear chat loaded callback: " chat-id)
(assoc-in db [::chat-loaded-callbacks chat-id] nil)))
(register-handler :invoke-chat-loaded-callbacks
(u/side-effect!
(fn [db [_ chat-id]]
(log/debug "Invoking chat loaded callbacks: " chat-id)
(let [callbacks (get-in db [::chat-loaded-callbacks chat-id])]
(log/debug "Invoking chat loaded callbacks: " callbacks)
(doseq [callback callbacks]
(callback))
(dispatch [::clear-chat-loaded-callbacks chat-id])))))
(defn prepare-chat [{:keys [contacts]} chat-id chat] (defn prepare-chat [{:keys [contacts]} chat-id chat]
(let [name (get-in contacts [chat-id :name])] (let [name (get-in contacts [chat-id :name])]
(merge {:chat-id chat-id (merge {:chat-id chat-id

View File

@ -9,14 +9,13 @@
[status-im.i18n :as i18n] [status-im.i18n :as i18n]
[status-im.utils.datetime :as time] [status-im.utils.datetime :as time]
[status-im.utils.random :as random] [status-im.utils.random :as random]
[status-im.utils.platform :as platform])) [status-im.utils.platform :as platform]
[taoensso.timbre :as log]))
(def command-prefix "c ")
(defn content-by-command (defn content-by-command
[{:keys [type]} content] [{:keys [type]} content]
(if (and (= :command type) content) (if (and (= :command type) content)
(subs content (count command-prefix)) (subs content (count cu/command-prefix))
content)) content))
(defn invoke-suggestions-handler! (defn invoke-suggestions-handler!
@ -54,7 +53,7 @@
(after cancel-command!) (after cancel-command!)
(after #(dispatch [:clear-validation-errors]))] (after #(dispatch [:clear-validation-errors]))]
(fn [{:keys [current-chat-id] :as db} [_ content]] (fn [{:keys [current-chat-id] :as db} [_ content]]
(let [starts-as-command? (str/starts-with? content command-prefix) (let [starts-as-command? (str/starts-with? content cu/command-prefix)
command? (= :command (current-command db :type)) command? (= :command (current-command db :type))
{:keys [parameter-idx command]} (commands/get-command-input db) {:keys [parameter-idx command]} (commands/get-command-input db)
parameter-name (-> command :params (get parameter-idx) :name)] parameter-name (-> command :params (get parameter-idx) :name)]
@ -65,10 +64,10 @@
(assoc db :canceled-command (and command? (not starts-as-command?))))))) (assoc db :canceled-command (and command? (not starts-as-command?)))))))
(defn invoke-command-preview! (defn invoke-command-preview!
[{:keys [staged-command] :as db} [_ chat-id]] [{:keys [staged-command] :as db} [_ command-input chat-id]]
(let [{:keys [command id]} staged-command (let [{:keys [command id]} staged-command
{:keys [name type]} command {:keys [name type]} command
parameters (:params (commands/get-command-input db)) parameters (:params (or command-input (commands/get-command-input db)))
path [(if (= :command type) :commands :responses) path [(if (= :command type) :commands :responses)
name name
:preview] :preview]
@ -88,7 +87,7 @@
(register-handler ::validate! (register-handler ::validate!
(u/side-effect! (u/side-effect!
(fn [_ [_ {:keys [chat-id handler]} {:keys [error result]}]] (fn [_ [_ command-input {:keys [chat-id handler]} {:keys [error result]}]]
;; todo handle error ;; todo handle error
(when-not error (when-not error
(let [{:keys [errors validationHandler parameters]} (:returned result)] (let [{:keys [errors validationHandler parameters]} (:returned result)]
@ -97,18 +96,20 @@
validationHandler validationHandler
(dispatch [::validation-handler! (dispatch [::validation-handler!
command-input
chat-id chat-id
validationHandler validationHandler
parameters]) parameters])
:else (if handler :else (if handler
(handler) (handler)
(dispatch [::finish-command-staging chat-id])))))))) (dispatch [::finish-command-staging command-input chat-id]))))))))
(register-handler :stage-command (register-handler :stage-command
(fn [{:keys [current-chat-id current-account-id] :as db}] (fn [{:keys [current-chat-id current-account-id] :as db} [_ command-input command]]
(let [command-input (commands/get-command-input db) (let [command-input (or command-input (commands/get-command-input db))
command (commands/get-chat-command db)] command (or command (commands/get-chat-command db))]
(log/debug "Staging command 1: " command-input command)
(dispatch [::start-command-validation! {:command-input command-input (dispatch [::start-command-validation! {:command-input command-input
:command command :command command
:chat-id current-chat-id :chat-id current-chat-id
@ -118,9 +119,9 @@
(register-handler ::finish-command-staging (register-handler ::finish-command-staging
[(after #(dispatch [:start-cancel-command])) [(after #(dispatch [:start-cancel-command]))
(after invoke-command-preview!)] (after invoke-command-preview!)]
(fn [db [_ chat-id]] (fn [db [_ command-input chat-id]]
(let [db (assoc-in db [:chats chat-id :input-text] nil) (let [db (assoc-in db [:chats chat-id :input-text] nil)
{:keys [command content to-message-id params]} (command-input db) {:keys [command content to-message-id params]} (or command-input (command-input db))
command-info {:command command command-info {:command command
:params params :params params
:to-message to-message-id :to-message to-message-id
@ -140,7 +141,7 @@
[{:keys [current-chat-id] :as db} [_ command-key type]] [{:keys [current-chat-id] :as db} [_ command-key type]]
(-> db (-> db
(commands/set-command-input (or type :commands) command-key) (commands/set-command-input (or type :commands) command-key)
(assoc-in [:chats current-chat-id :command-input :content] command-prefix) (assoc-in [:chats current-chat-id :command-input :content] cu/command-prefix)
(assoc :disable-input true))) (assoc :disable-input true)))
(register-handler :set-chat-command (register-handler :set-chat-command
@ -150,6 +151,7 @@
set-chat-command) set-chat-command)
(defn set-response-command [db [_ to-message-id command-key]] (defn set-response-command [db [_ to-message-id command-key]]
(log/debug "set-response-command: " to-message-id command-key)
(-> db (-> db
(commands/set-command-input :responses to-message-id command-key) (commands/set-command-input :responses to-message-id command-key)
(assoc :canceled-command false))) (assoc :canceled-command false)))
@ -186,9 +188,9 @@
:description (apply i18n/label (wrap-params description))}]))) :description (apply i18n/label (wrap-params description))}])))
(def validation-handlers (def validation-handlers
{:phone (fn [chat-id [number]] {:phone (fn [command-input chat-id [number]]
(if (pn/valid-mobile-number? number) (if (pn/valid-mobile-number? number)
(dispatch [::finish-command-staging chat-id]) (dispatch [::finish-command-staging command-input chat-id])
(dispatch-error! chat-id :t/phone-number :t/invalid-phone)))}) (dispatch-error! chat-id :t/phone-number :t/invalid-phone)))})
(defn validator [name] (defn validator [name]
@ -196,9 +198,9 @@
(register-handler ::validation-handler! (register-handler ::validation-handler!
(u/side-effect! (u/side-effect!
(fn [_ [_ chat-id name params]] (fn [_ [_ command-input chat-id name params]]
(when-let [handler (validator name)] (when-let [handler (validator name)]
(handler chat-id params))))) (handler command-input chat-id params)))))
(register-handler ::set-validation-error (register-handler ::set-validation-error
(after #(dispatch [:fix-response-height])) (after #(dispatch [:fix-response-height]))
@ -251,7 +253,7 @@
(status/call-jail chat-id (status/call-jail chat-id
path path
parameters parameters
#(dispatch [::validate! data %])))))) #(dispatch [::validate! command-input data %]))))))
(register-handler :set-command-parameter (register-handler :set-command-parameter
(fn [db [_ {:keys [value parameter]}]] (fn [db [_ {:keys [value parameter]}]]

View File

@ -2,7 +2,8 @@
(:require [re-frame.core :refer [after dispatch enrich]] (:require [re-frame.core :refer [after dispatch enrich]]
[status-im.utils.handlers :refer [register-handler]] [status-im.utils.handlers :refer [register-handler]]
[status-im.data-store.requests :as requests] [status-im.data-store.requests :as requests]
[status-im.utils.handlers :refer [register-handler] :as u])) [status-im.utils.handlers :refer [register-handler] :as u]
[taoensso.timbre :as log]))
(defn store-request! (defn store-request!
[{:keys [new-request] :as db}] [{:keys [new-request] :as db}]
@ -15,6 +16,7 @@
:type (:command content) :type (:command content)
:added (js/Date.)} :added (js/Date.)}
request' (update request :type keyword)] request' (update request :type keyword)]
(log/debug "Adding request: " request')
(-> db (-> db
(update-in [:chats chat-id :requests] conj request') (update-in [:chats chat-id :requests] conj request')
(assoc :new-request request)))) (assoc :new-request request))))

View File

@ -7,6 +7,7 @@
[status-im.utils.datetime :as time] [status-im.utils.datetime :as time]
[re-frame.core :refer [enrich after dispatch path]] [re-frame.core :refer [enrich after dispatch path]]
[status-im.chat.utils :as cu] [status-im.chat.utils :as cu]
[status-im.commands.utils :as commands-utils]
[status-im.constants :refer [text-content-type [status-im.constants :refer [text-content-type
content-type-command content-type-command
content-type-command-request content-type-command-request
@ -18,17 +19,20 @@
[status-im.chat.handlers.console :as console])) [status-im.chat.handlers.console :as console]))
(defn prepare-command (defn prepare-command
[identity chat-id clock-value [identity chat-id clock-value request
{:keys [id preview preview-string params command to-message handler-data]}] {:keys [id preview preview-string params command to-message handler-data]}]
(let [content {:command (command :name) (let [content (or request {:command (command :name)
:params params}] :params params})]
{:message-id id {:message-id id
:from identity :from identity
:to chat-id :to chat-id
:timestamp (time/now-ms) :timestamp (time/now-ms)
:content (assoc content :preview preview-string :content (assoc content :preview preview-string
:handler-data handler-data) :handler-data handler-data
:content-type content-type-command :type (name (:type command)))
:content-type (if request
content-type-command-request
content-type-command)
:outgoing true :outgoing true
:preview preview-string :preview preview-string
:rendered-preview preview :rendered-preview preview
@ -62,7 +66,7 @@
(u/side-effect! (u/side-effect!
(fn [_ [_ {:keys [commands message chat-id] :as params}]] (fn [_ [_ {:keys [commands message chat-id] :as params}]]
(doseq [{:keys [command] :as message} commands] (doseq [{:keys [command] :as message} commands]
(let [params' (assoc params :staged-command message) (let [params' (assoc params :staged-command message)
command-name (:name (:command message))] command-name (:name (:command message))]
(if (:sent-to-jail? message) (if (:sent-to-jail? message)
;; todo there could be other reasons for "long-running" ;; todo there could be other reasons for "long-running"
@ -88,11 +92,13 @@
(register-handler :prepare-command! (register-handler :prepare-command!
(u/side-effect! (u/side-effect!
(fn [{:keys [current-public-key] :as db} (fn [{:keys [current-public-key] :as db}
[_ add-to-chat-id {:keys [chat-id staged-command handler-data] :as params}]] [_ add-to-chat-id {:keys [chat-id staged-command command handler-data] :as params}]]
(let [{:keys [clock-value]} (get-in db [:chats add-to-chat-id]) (let [{:keys [clock-value]} (get-in db [:chats add-to-chat-id])
request (:request (:handler-data command))
command' (->> (assoc staged-command :handler-data handler-data) command' (->> (assoc staged-command :handler-data handler-data)
(prepare-command current-public-key chat-id clock-value) (prepare-command current-public-key chat-id clock-value request)
(cu/check-author-direction db chat-id))] (cu/check-author-direction db chat-id))]
(log/debug "Handler data: " request handler-data (dissoc params :commands :staged-command))
(dispatch [:clear-command chat-id (:id staged-command)]) (dispatch [:clear-command chat-id (:id staged-command)])
(dispatch [::send-command! add-to-chat-id (assoc params :command command')]) (dispatch [::send-command! add-to-chat-id (assoc params :command command')])
@ -216,24 +222,25 @@
(register-handler ::send-command-protocol! (register-handler ::send-command-protocol!
(u/side-effect! (u/side-effect!
(fn [{:keys [web3 current-public-key chats] :as db} [_ {:keys [chat-id command]}]] (fn [{:keys [web3 current-public-key chats] :as db}
(let [{:keys [content message-id clock-value]} command] [_ {:keys [chat-id command]}]]
(when (cu/not-console? chat-id) (log/debug "sending command: " command)
(let [{:keys [public-key private-key]} (chats chat-id) (when (cu/not-console? chat-id)
{:keys [group-chat]} (get-in db [:chats chat-id]) (let [{:keys [public-key private-key]} (chats chat-id)
payload {:content content {:keys [group-chat]} (get-in db [:chats chat-id])
:content-type content-type-command
:timestamp (datetime/now-ms) payload (-> command
:clock-value clock-value} (select-keys [:content :content-type :clock-value])
options {:web3 web3 (assoc :timestamp (datetime/now-ms)))
:message {:from current-public-key options {:web3 web3
:message-id message-id :message {:from current-public-key
:payload payload}}] :message-id (:message-id command)
(if group-chat :payload payload}}]
(protocol/send-group-message! (assoc options (if group-chat
:group-id chat-id (protocol/send-group-message! (assoc options
:keypair {:public public-key :group-id chat-id
:private private-key})) :keypair {:public public-key
(protocol/send-message! (assoc-in options :private private-key}))
[:message :to] chat-id))))) (protocol/send-message! (assoc-in options
(dispatch [:inc-clock chat-id]))))) [:message :to] chat-id)))
(dispatch [:inc-clock chat-id]))))))

View File

@ -3,21 +3,70 @@
[status-im.utils.handlers :refer [register-handler]] [status-im.utils.handlers :refer [register-handler]]
[status-im.utils.handlers :as u] [status-im.utils.handlers :as u]
[status-im.utils.types :as t] [status-im.utils.types :as t]
[taoensso.timbre :as log])) [status-im.i18n :refer [label]]
[taoensso.timbre :as log]
[status-im.models.commands :as commands]
[status-im.commands.utils :as cu]
[status-im.components.status :as s]
[status-im.constants :as c]
[cljs.reader :refer [read-string]]))
(def web3 (js/require "web3"))
(defn by-public-key [public-key contacts]
(when-let [{:keys [address]} (contacts public-key)]
(when address {:address address})))
(defn scan-qr-handler
[{:keys [contacts]} [_ _ data]]
(log/debug "scaned qr" data)
(let [data' (read-string data)
data'' (cond
(map? data') data'
(.isAddress web3.prototype data') {:address data'}
(string? data') (by-public-key data' contacts)
:else nil)]
(when data''
(dispatch [:send-to-webview-bridge
{:params data''
:event (name :webview-send-transaction)}]))))
(register-handler :webview-address-from-qr
(u/side-effect! scan-qr-handler))
(register-handler :set-webview-bridge (register-handler :set-webview-bridge
(fn [db [_ bridge]] (fn [db [_ bridge]]
(assoc db :webview-bridge bridge))) (assoc db :webview-bridge bridge)))
(defn contacts-click-handler [whisper-identity] (defn contacts-click-handler [whisper-identity action params]
#(dispatch [:chat-with-command whisper-identity :send])) (log/debug "Contact clicked: " whisper-identity action params)
(dispatch [:navigate-back])
(when action
(if (= whisper-identity :qr-scan)
(if (= action :send)
(dispatch [:show-scan-qr :webview-address-from-qr])
(dispatch [:navigate-to-modal :wallet-qr-code]))
(dispatch [:chat-with-command whisper-identity action params]))))
(register-handler ::send-command
(u/side-effect!
(fn [db [_ command-key params]]
(let [command (commands/get-response-or-command :commands db command-key)
command-input {:content (str cu/command-prefix "0")
:command command
:parameter-idx 0
:params {"amount" (:amount params)}
:to-message-id nil}]
(log/debug "Staging command: " command-key command command-input)
(dispatch [:stage-command command-input command])))))
(defn chat-with-command (defn chat-with-command
[_ [_ whisper-identity command]] [_ [_ whisper-identity command-key params]]
(dispatch [:start-chat whisper-identity {} :navigate-back])
(dispatch [:remove-contacts-click-handler]) (dispatch [:remove-contacts-click-handler])
(let [callback #(dispatch [:set-chat-command command])] (dispatch [:add-chat-loaded-callback whisper-identity
(dispatch [:add-commands-loading-callback whisper-identity callback]))) #(dispatch [::send-command command-key params])])
(dispatch [:start-chat whisper-identity]))
(register-handler :chat-with-command (register-handler :chat-with-command
(u/side-effect! chat-with-command)) (u/side-effect! chat-with-command))
@ -25,15 +74,47 @@
(register-handler :webview-bridge-message (register-handler :webview-bridge-message
(u/side-effect! (u/side-effect!
(fn [_ [_ message-string]] (fn [_ [_ message-string]]
(let [message (t/json->clj message-string) (let [{:keys [event options] :as message} (t/json->clj message-string)
event (keyword (:event message))] event' (keyword event)
params (:data options)]
(log/debug (str "message from webview: " message)) (log/debug (str "message from webview: " message))
(case event (case event'
:webview-send-transaction (dispatch [:navigate-to :contact-list contacts-click-handler]) :webview-send-transaction (dispatch [:show-contacts-menu contacts-click-handler :send params])
(log/error (str "Unknown event: " event))))))) :webview-receive-transaction (dispatch [:show-contacts-menu contacts-click-handler :request params])
:webview-scan-qr (dispatch [:show-scan-qr :webview-address-from-qr])
:webview-send-eth (dispatch [:webview-send-eth! params])
(log/error (str "Unknown event: " event')))))))
(register-handler :show-contacts-menu
(after #(dispatch [:navigate-to-modal :contact-list-modal]))
(fn [db [_ click-handler action params]]
(assoc db :contacts-click-handler click-handler
:contacts-click-action action
:contacts-click-params params)))
(def qr-context {:toolbar-title (label :t/address)})
(register-handler :show-scan-qr
(after #(dispatch [:navigate-to-modal :qr-scanner qr-context]))
(fn [db [_ click-handler]]
(assoc-in db [:qr-codes qr-context] click-handler)))
(register-handler :send-to-webview-bridge (register-handler :send-to-webview-bridge
(u/side-effect! (u/side-effect!
(fn [{:keys [webview-bridge]} [_ data]] (fn [{:keys [webview-bridge]} [_ data]]
(when webview-bridge (when webview-bridge
(.sendToBridge webview-bridge (t/clj->json data)))))) (.sendToBridge webview-bridge (t/clj->json data))))))
(register-handler :webview-send-eth!
(u/side-effect!
(fn [{:keys [current-account-id]} [_ {:keys [amount address]}]]
(let [context {:from current-account-id}
path [:functions :send]
parameters {:context context
:parameters {:amount amount
:address address}}]
(s/call-jail c/wallet-chat-id
path
parameters
(fn [data]
(log/debug :webview-send-eth-callback data)))))))

View File

@ -5,6 +5,7 @@
animated-view animated-view
text text
icon icon
modal
touchable-highlight touchable-highlight
list-view list-view
list-item]] list-item]]

View File

@ -191,3 +191,10 @@
(def bottom-info-row-text2 (def bottom-info-row-text2
{:color "#888888"}) {:color "#888888"})
(def chat-modal
{:position :absolute
:left 0
:top 0
:right 0
:bottom 0})

View File

@ -49,16 +49,17 @@
(reaction (get-in @db [:command-suggestions @chat-id]))))) (reaction (get-in @db [:command-suggestions @chat-id])))))
(register-sub :get-commands (register-sub :get-commands
(fn [db _] (fn [db [_ chat-id]]
(reaction (commands/get-commands @db)))) (let [current-chat (or chat-id (@db :current-chat-id))]
(reaction (or (get-in @db [:chats current-chat :commands]) {})))))
(register-sub :get-chat-by-id (register-sub :get-chat-by-id
(fn [_ [_ chat-id]] (fn [_ [_ chat-id]]
(reaction (chats/get-by-id chat-id)))) (reaction (chats/get-by-id chat-id))))
(register-sub :get-responses (register-sub :get-responses
(fn [db _] (fn [db [_ chat-id]]
(let [current-chat (@db :current-chat-id)] (let [current-chat (or chat-id (@db :current-chat-id))]
(reaction (or (get-in @db [:chats current-chat :responses]) {}))))) (reaction (or (get-in @db [:chats current-chat :responses]) {})))))
(register-sub :get-commands-and-responses (register-sub :get-commands-and-responses

View File

@ -104,7 +104,10 @@
(str params))])) (str params))]))
(defview message-content-command [{:keys [content rendered-preview chat-id to from outgoing] :as message}] (defview message-content-command [{:keys [content rendered-preview chat-id to from outgoing] :as message}]
[commands [:get-commands-and-responses (if outgoing to from)] [commands [(if (= (:type content) "response")
:get-responses
:get-commands)
(if outgoing to from)]
current-chat-id [:get-current-chat-id] current-chat-id [:get-current-chat-id]
contact-chat [:get-in [:chats (if outgoing to from)]]] contact-chat [:get-in [:chats (if outgoing to from)]]]
(let [{:keys [command params]} (parse-command-message-content commands content) (let [{:keys [command params]} (parse-command-message-content commands content)
@ -341,6 +344,7 @@
:message-id message-id}]))) :message-id message-id}])))
:reagent-render :reagent-render
(fn [{:keys [outgoing group-chat] :as message}] (fn [{:keys [outgoing group-chat] :as message}]
(log/debug "I HAVE A MESSAGE: " message)
[message-container message [message-container message
[view [view
(let [incoming-group (and group-chat (not outgoing))] (let [incoming-group (and group-chat (not outgoing))]

View File

@ -9,11 +9,13 @@
touchable-highlight]] touchable-highlight]]
[status-im.chat.styles.message :as st] [status-im.chat.styles.message :as st]
[status-im.models.commands :refer [parse-command-request]] [status-im.models.commands :refer [parse-command-request]]
[status-im.components.animation :as anim])) [status-im.components.animation :as anim]
[taoensso.timbre :as log]))
(def request-message-icon-scale-delay 600) (def request-message-icon-scale-delay 600)
(defn set-chat-command [message-id command] (defn set-chat-command [message-id command]
(log/debug "set-chat-command: " message-id command)
(dispatch [:set-response-chat-command message-id (keyword (:name command))])) (dispatch [:set-response-chat-command message-id (keyword (:name command))]))
(defn label [command] (defn label [command]
@ -76,7 +78,8 @@
status-initialized? (subscribe [:get :status-module-initialized?])] status-initialized? (subscribe [:get :status-module-initialized?])]
(fn [{:keys [message-id content from incoming-group]}] (fn [{:keys [message-id content from incoming-group]}]
(let [commands @commands-atom (let [commands @commands-atom
{:keys [command content]} (parse-command-request commands content)] {:keys [command content]} (parse-command-request commands content)
_ (log/debug "message-content: " command content)]
[view st/comand-request-view [view st/comand-request-view
[touchable-highlight [touchable-highlight
{:on-press (when (and (not @answered?) @status-initialized?) {:on-press (when (and (not @answered?) @status-initialized?)

View File

@ -25,7 +25,8 @@
[status-im.utils.datetime :as dt] [status-im.utils.datetime :as dt]
[taoensso.timbre :as log] [taoensso.timbre :as log]
[status-im.utils.name :refer [shortened-name]] [status-im.utils.name :refer [shortened-name]]
[status-im.utils.js-resources :as js-res])) [status-im.utils.js-resources :as js-res]
[status-im.commands.utils :as cu]))
(defn drag-icon [] (defn drag-icon []
[view st/drag-container [view st/drag-container
@ -117,7 +118,7 @@
(when-not (= "about:blank" url) (when-not (= "about:blank" url)
(if loading (if loading
(dispatch [:set-web-view-url url]) (dispatch [:set-web-view-url url])
(dispatch [:set-chat-command-content (str "c " url)]))))) (dispatch [:set-chat-command-content (str cu/command-prefix url)])))))
(defn web-view-error [] (defn web-view-error []
(r/as-element (r/as-element

View File

@ -21,6 +21,7 @@
{:keys [result error]}]] {:keys [result error]}]]
(let [{:keys [context returned]} result (let [{:keys [context returned]} result
{handler-error :error} returned] {handler-error :error} returned]
(log/debug "command handler: " result error parameters)
(cond (cond
handler-error handler-error
(log/debug :error-from-handler handler-error (log/debug :error-from-handler handler-error

View File

@ -59,6 +59,7 @@
(status/parse-jail identity file (status/parse-jail identity file
(fn [result] (fn [result]
(let [{:keys [error result]} (json->clj result)] (let [{:keys [error result]} (json->clj result)]
(log/debug "Error parsing commands: " error result)
(if error (if error
(dispatch [::loading-failed! identity ::error-in-jail error]) (dispatch [::loading-failed! identity ::error-in-jail error])
(if identity (if identity
@ -125,7 +126,8 @@
(after save-commands-js!) (after save-commands-js!)
(after #(dispatch [:check-autorun])) (after #(dispatch [:check-autorun]))
(after (fn [_ [id]] (after (fn [_ [id]]
(dispatch [:invoke-commands-loading-callbacks id])))] (dispatch [:invoke-commands-loading-callbacks id])
(dispatch [:invoke-chat-loaded-callbacks id])))]
add-commands) add-commands)
(reg-handler ::add-all-commands (reg-handler ::add-all-commands

View File

@ -6,6 +6,8 @@
[re-frame.core :refer [dispatch trim-v debug]] [re-frame.core :refer [dispatch trim-v debug]]
[status-im.utils.handlers :refer [register-handler]])) [status-im.utils.handlers :refer [register-handler]]))
(def command-prefix "c ")
(defn json->clj [json] (defn json->clj [json]
(when-not (= json "undefined") (when-not (= json "undefined")
(js->clj (.parse js/JSON json) :keywordize-keys true))) (js->clj (.parse js/JSON json) :keywordize-keys true)))

View File

@ -30,6 +30,13 @@
[db [_ _ click-handler]] [db [_ _ click-handler]]
(assoc db :contacts-click-handler click-handler)) (assoc db :contacts-click-handler click-handler))
(register-handler :remove-contacts-click-handler
(fn [db]
(dissoc db
:contacts-click-handler
:contacts-click-action)))
(defn save-contact (defn save-contact
[_ [_ contact]] [_ [_ contact]]
(contacts/save contact)) (contacts/save contact))

View File

@ -211,3 +211,8 @@
(def qr-input (def qr-input
{:margin-right 42}) {:margin-right 42})
(def scan-qr-icon
{:margin 18
:width 25
:height 19})

View File

@ -8,6 +8,18 @@
(defn on-press [whisper-identity] (defn on-press [whisper-identity]
#(dispatch [:start-chat whisper-identity {} :navigation-replace])) #(dispatch [:start-chat whisper-identity {} :navigation-replace]))
(defn letter-view [letter]
[view st/letter-container
(when letter
[text {:style st/letter-text} letter])])
(defview contact-view-with-letter [{:keys [whisper-identity letter] :as contact} click-handler action params]
[touchable-highlight
{:onPress #(click-handler whisper-identity action params)}
[view st/contact-container
[letter-view letter]
[contact-inner-view contact]]])
(defview contact-view [{:keys [whisper-identity] :as contact}] (defview contact-view [{:keys [whisper-identity] :as contact}]
[chat [:get-chat whisper-identity]] [chat [:get-chat whisper-identity]]
[touchable-highlight [touchable-highlight

View File

@ -6,16 +6,20 @@
touchable-highlight touchable-highlight
list-view list-view
list-item]] list-item]]
[status-im.contacts.views.contact :refer [contact-view on-press]] [status-im.contacts.views.contact :refer [contact-view
on-press
contact-view-with-letter]]
[status-im.components.status-bar :refer [status-bar]] [status-im.components.status-bar :refer [status-bar]]
[status-im.components.toolbar.view :refer [toolbar]] [status-im.components.toolbar.view :refer [toolbar]]
[status-im.components.toolbar.styles :refer [toolbar-background1]] [status-im.components.toolbar.styles :refer [toolbar-background1]]
[status-im.components.drawer.view :refer [drawer-view open-drawer]] [status-im.components.drawer.view :refer [drawer-view open-drawer]]
[status-im.components.styles :refer [icon-search]] [status-im.components.styles :refer [icon-search
icon-back]]
[status-im.contacts.styles :as st] [status-im.contacts.styles :as st]
[status-im.utils.listview :as lw] [status-im.utils.listview :as lw]
[status-im.i18n :refer [label]] [status-im.i18n :refer [label]]
[status-im.utils.platform :refer [platform-specific]])) [status-im.utils.platform :refer [platform-specific]]
[status-im.contacts.views.contact-inner :refer [contact-inner-view]]))
(defn new-group-chat-view [] (defn new-group-chat-view []
[touchable-highlight [touchable-highlight
@ -29,21 +33,42 @@
[text {:style st/name-text} [text {:style st/name-text}
(label :t/new-group-chat)]]]]]) (label :t/new-group-chat)]]]]])
(defn render-row [click-handler] (defn render-row [chat-modal click-handler action params]
(fn [row _ _] (fn [row _ _]
(list-item (list-item
[contact-view row (if chat-modal
(or click-handler [contact-view-with-letter row click-handler action params]
(let [whisper-identity (:whisper-identity row)] [contact-view row
(on-press whisper-identity)))]))) (or click-handler
(let [whisper-identity (:whisper-identity row)]
(on-press whisper-identity)))]))))
(defn qr-scan [click-handler action]
[touchable-highlight
{:onPress #(click-handler :qr-scan action)}
[view st/contact-container
[view st/contact-inner-container
[image {:source {:uri :icon_menu_group}
:style st/scan-qr-icon}]
[view st/info-container
[text {:style st/name-text
:number-of-lines 1}
(label :t/scan-qr)]]]]])
(defview contact-list-toolbar [] (defview contact-list-toolbar []
[group [:get :contacts-group]] [group [:get :contacts-group]
modal [:get :modal]]
[view [view
[status-bar] [status-bar]
[toolbar {:title (label (if (= group :dapps) [toolbar {:title (label (if-not group
:t/contacts-group-dapps :t/contacts
:t/contacts-group-new-chat)) (if (= group :dapps)
:t/contacts-group-dapps
:t/contacts-group-new-chat)))
:nav-action (when modal
{:handler #(dispatch [:navigate-back])
:image {:source {:uri :icon_back}
:style icon-back}})
:background-color toolbar-background1 :background-color toolbar-background1
:style (get-in platform-specific [:component-styles :toolbar]) :style (get-in platform-specific [:component-styles :toolbar])
:actions [{:image {:source {:uri :icon_search} :actions [{:image {:source {:uri :icon_search}
@ -53,21 +78,26 @@
(defview contact-list [] (defview contact-list []
[contacts [:contacts-with-letters] [contacts [:contacts-with-letters]
group [:get :contacts-group] group [:get :contacts-group]
click-handler [:get :contacts-click-handler]] modal [:get :modal]
click-handler [:get :contacts-click-handler]
action [:get :contacts-click-action]
params [:get :contacts-click-params]]
(let [show-new-group-chat? (and (= group :people) (let [show-new-group-chat? (and (= group :people)
(get-in platform-specific [:chats :new-chat-in-toolbar?]))] (get-in platform-specific [:chats :new-chat-in-toolbar?]))]
[drawer-view [drawer-view
[view st/contacts-list-container [view st/contacts-list-container
[contact-list-toolbar] [contact-list-toolbar]
;; todo add stub ;; todo add stub
(when modal
[qr-scan click-handler action])
(when contacts (when contacts
[list-view {:dataSource (lw/to-datasource contacts) [list-view {:dataSource (lw/to-datasource contacts)
:enableEmptySections true :enableEmptySections true
:renderRow (render-row click-handler) :renderRow (render-row modal click-handler action params)
:renderHeader #(list-item :renderHeader #(list-item
[view [view
(if show-new-group-chat? (if show-new-group-chat?
[new-group-chat-view]) [new-group-chat-view])
[view st/spacing-top]]) [view st/spacing-top]])
:renderFooter #(list-item [view st/spacing-bottom]) :renderFooter #(list-item [view st/spacing-bottom])
:style st/contacts-list}])]])) :style st/contacts-list}])]]))

View File

@ -3,7 +3,9 @@
[re-frame.core :refer [subscribe dispatch dispatch-sync]] [re-frame.core :refer [subscribe dispatch dispatch-sync]]
[status-im.handlers] [status-im.handlers]
[status-im.subs] [status-im.subs]
[status-im.components.react :refer [app-registry [status-im.components.react :refer [view
modal
app-registry
keyboard keyboard
orientation]] orientation]]
[status-im.components.main-tabs :refer [main-tabs]] [status-im.components.main-tabs :refer [main-tabs]]
@ -24,7 +26,9 @@
[status-im.profile.screen :refer [profile my-profile]] [status-im.profile.screen :refer [profile my-profile]]
[status-im.profile.photo-capture.screen :refer [profile-photo-capture]] [status-im.profile.photo-capture.screen :refer [profile-photo-capture]]
status-im.data-store.core status-im.data-store.core
[taoensso.timbre :as log])) [taoensso.timbre :as log]
[status-im.chat.styles.screen :as st]
[status-im.accounts.views.wallet-qr-code :refer [wallet-qr-code]]))
(defn orientation->keyword [o] (defn orientation->keyword [o]
(keyword (.toLowerCase o))) (keyword (.toLowerCase o)))
@ -38,7 +42,7 @@
(defn app-root [] (defn app-root []
(let [signed-up? (subscribe [:signed-up?]) (let [signed-up? (subscribe [:signed-up?])
_ (log/debug "signed up: " @signed-up?) modal-view (subscribe [:get :modal])
view-id (subscribe [:get :view-id]) view-id (subscribe [:get :view-id])
account-id (subscribe [:get :current-account-id]) account-id (subscribe [:get :current-account-id])
keyboard-height (subscribe [:get :keyboard-height])] keyboard-height (subscribe [:get :keyboard-height])]
@ -86,7 +90,21 @@
:login login :login login
:confirm confirm :confirm confirm
:my-profile my-profile)] :my-profile my-profile)]
[component]))))}))) [view
{:flex 1}
[component]
(when @modal-view
[view
st/chat-modal
[modal {:animation-type :slide
:transparent false
:on-request-close #(dispatch [:navigate-back])}
(let [component (case @modal-view
:qr-scanner qr-scanner
:wallet-qr-code wallet-qr-code
:confirm confirm
:contact-list-modal contact-list)]
[component])]])]))))})))
(defn init [] (defn init []
(dispatch-sync [:reset-app]) (dispatch-sync [:reset-app])

View File

@ -70,4 +70,5 @@
(update content :command #((keyword %) commands))) (update content :command #((keyword %) commands)))
(defn parse-command-request [commands content] (defn parse-command-request [commands content]
(log/debug "parse-command-request: " commands content)
(update content :command #((keyword %) commands))) (update content :command #((keyword %) commands)))

View File

@ -24,6 +24,11 @@
(defmethod preload-data! :default [db _] db) (defmethod preload-data! :default [db _] db)
(defn -preload-data! [{:keys [was-modal?] :as db} & args]
(if was-modal?
(dissoc db :was-modal)
(apply preload-data! db args)))
(register-handler :navigate-forget (register-handler :navigate-forget
(enrich preload-data!) (enrich preload-data!)
(fn [db [_ new-view-id]] (fn [db [_ new-view-id]]
@ -36,16 +41,25 @@
db db
(push-view db new-view-id)))) (push-view db new-view-id))))
(register-handler :navigate-to-modal
(enrich preload-data!)
(fn [db [_ modal-view]]
(assoc db :modal modal-view)))
(register-handler :navigation-replace (register-handler :navigation-replace
(enrich preload-data!) (enrich preload-data!)
(fn [db [_ view-id]] (fn [db [_ view-id]]
(replace-view db view-id))) (replace-view db view-id)))
(register-handler :navigate-back (register-handler :navigate-back
(enrich preload-data!) (enrich -preload-data!)
(fn [{:keys [navigation-stack view-id] :as db} _] (fn [{:keys [navigation-stack view-id modal] :as db} _]
(if (>= 1 (count navigation-stack)) (cond
db modal (assoc db :modal nil
:was-modal? true)
(>= 1 (count navigation-stack)) db
:else
(let [[previous-view-id :as navigation-stack'] (pop navigation-stack) (let [[previous-view-id :as navigation-stack'] (pop navigation-stack)
first-in-stack (first navigation-stack)] first-in-stack (first navigation-stack)]
(if (= view-id first-in-stack) (if (= view-id first-in-stack)
@ -67,10 +81,6 @@
(fn [db [_]] (fn [db [_]]
(assoc db :prev-tab-view-id nil))) (assoc db :prev-tab-view-id nil)))
(register-handler :remove-contacts-click-handler
(fn [db]
(dissoc db :contacts-click-handler)))
(defn show-profile (defn show-profile
[db [_ identity]] [db [_ identity]]
(-> db (-> db

View File

@ -4,20 +4,25 @@
[status-im.components.react :refer [view [status-im.components.react :refer [view
image]] image]]
[status-im.components.camera :refer [camera]] [status-im.components.camera :refer [camera]]
[status-im.components.styles :refer [icon-search]] [status-im.components.styles :refer [icon-search
icon-back]]
[status-im.components.status-bar :refer [status-bar]] [status-im.components.status-bar :refer [status-bar]]
[status-im.components.toolbar.view :refer [toolbar]] [status-im.components.toolbar.view :refer [toolbar]]
[status-im.components.toolbar.styles :refer [toolbar-background1]] [status-im.components.toolbar.styles :refer [toolbar-background1]]
[status-im.qr-scanner.styles :as st] [status-im.qr-scanner.styles :as st]
[status-im.utils.types :refer [json->clj]] [status-im.utils.types :refer [json->clj]]
[status-im.components.styles :as cst]
[clojure.string :as str])) [clojure.string :as str]))
(defn qr-scanner-toolbar [title] (defview qr-scanner-toolbar [title]
[modal [:get :modal]]
[view [view
[status-bar] [status-bar]
[toolbar {:title title [toolbar {:title title
:background-color toolbar-background1 :background-color toolbar-background1
:nav-action (when modal
{:handler #(dispatch [:navigate-back])
:image {:source {:uri :icon_back}
:style icon-back}})
:actions [{:image {:source {:uri :icon_lock_white} :actions [{:image {:source {:uri :icon_lock_white}
:style icon-search} :style icon-search}
:handler #()}]}]]) :handler #()}]}]])
@ -30,6 +35,7 @@
(let [data (-> (.-data code) (let [data (-> (.-data code)
(str/replace #"ethereum:" ""))] (str/replace #"ethereum:" ""))]
(dispatch [:set-qr-code identifier data]))) (dispatch [:set-qr-code identifier data])))
:barCodeTypes [:qr]
:style st/barcode-scanner}] :style st/barcode-scanner}]
[view st/rectangle-container [view st/rectangle-container
[view st/rectangle [view st/rectangle

View File

@ -30,7 +30,7 @@
(assoc-in [:confirm-transactions :password] 0))) (assoc-in [:confirm-transactions :password] 0)))
(defn on-unlock (defn on-unlock
[ids password previous-view-id] [ids password]
(dispatch [:set :wrong-password? false]) (dispatch [:set :wrong-password? false])
(doseq [id ids] (doseq [id ids]
(status/complete-transaction (status/complete-transaction
@ -38,15 +38,13 @@
password password
#(dispatch [:transaction-completed #(dispatch [:transaction-completed
{:id id {:id id
:response % :response %}]))))
:previous-view-id previous-view-id}]))))
(register-handler :accept-transactions (register-handler :accept-transactions
(u/side-effect! (u/side-effect!
(fn [{:keys [transactions navigation-stack]} [_ password]] (fn [{:keys [transactions]} [_ password]]
(let [ids (keys transactions) (let [ids (keys transactions)]
previous-view-id (second navigation-stack)] (on-unlock ids password)))))
(on-unlock ids password previous-view-id)))))
(register-handler :deny-transactions (register-handler :deny-transactions
(u/side-effect! (u/side-effect!
@ -125,7 +123,7 @@
(remove-pending-message db message-id))) (remove-pending-message db message-id)))
(register-handler :transaction-queued (register-handler :transaction-queued
(after #(dispatch [:navigate-to :confirm])) (after #(dispatch [:navigate-to-modal :confirm]))
(fn [db [_ {:keys [id message_id args]}]] (fn [db [_ {:keys [id message_id args]}]]
(let [{:keys [from to value]} args (let [{:keys [from to value]} args
transaction {:id id transaction {:id id
@ -137,7 +135,7 @@
(register-handler :transaction-completed (register-handler :transaction-completed
(u/side-effect! (u/side-effect!
(fn [{:keys [transactions]} [_ {:keys [id response previous-view-id]}]] (fn [{:keys [transactions]} [_ {:keys [id response]}]]
(let [{:keys [hash error] :as parsed-response} (t/json->clj response) (let [{:keys [hash error] :as parsed-response} (t/json->clj response)
{:keys [message-id]} (transactions id)] {:keys [message-id]} (transactions id)]
(log/debug :parsed-response parsed-response) (log/debug :parsed-response parsed-response)
@ -148,7 +146,7 @@
:message-id message-id}]) :message-id message-id}])
(dispatch [::check-completed-transaction! (dispatch [::check-completed-transaction!
{:message-id message-id}]) {:message-id message-id}])
(dispatch [:navigation-replace previous-view-id])) (dispatch [:navigate-back]))
(dispatch [::remove-transaction id]))))))) (dispatch [::remove-transaction id])))))))
(register-handler ::add-transactions-hash (register-handler ::add-transactions-hash

View File

@ -201,6 +201,10 @@
:recover-access "Recover access" :recover-access "Recover access"
:add-account "Add account" :add-account "Add account"
;wallet-qr-code
:done "Done"
:main-wallet "Main Wallet"
;validation ;validation
:invalid-phone "Invalid phone number" :invalid-phone "Invalid phone number"
:amount "Amount" :amount "Amount"