statusAPI in webview

This commit is contained in:
Roman Volosovskyi 2016-08-03 16:15:04 +03:00
parent bf308bfd21
commit effadc6d5f
23 changed files with 284 additions and 94 deletions

View File

@ -25,7 +25,8 @@
"react-native-fs", "react-native-fs",
"react-native-dialogs", "react-native-dialogs",
"react-native-image-resizer", "react-native-image-resizer",
"react-native-image-crop-picker" "react-native-image-crop-picker",
"react-native-webview-bridge"
], ],
"imageDirs": [ "imageDirs": [
"images" "images"

View File

@ -137,6 +137,7 @@ dependencies {
compile project(':react-native-orientation') compile project(':react-native-orientation')
compile project(':react-native-fs') compile project(':react-native-fs')
compile project(':react-native-image-crop-picker') compile project(':react-native-image-crop-picker')
compile project(':react-native-webview-bridge')
//compile(name:'statusgo-android-16', ext:'aar') //compile(name:'statusgo-android-16', ext:'aar')
compile(group: 'status-im', name: 'status-go', version: 'unlock', ext: 'aar') compile(group: 'status-im', name: 'status-go', version: 'unlock', ext: 'aar')

View File

@ -22,6 +22,7 @@ import com.statusim.geth.module.GethPackage;
import com.aakashns.reactnativedialogs.ReactNativeDialogsPackage; import com.aakashns.reactnativedialogs.ReactNativeDialogsPackage;
import fr.bamlab.rnimageresizer.ImageResizerPackage; import fr.bamlab.rnimageresizer.ImageResizerPackage;
import com.reactnative.picker.PickerPackage; import com.reactnative.picker.PickerPackage;
import com.github.alinz.reactnativewebviewbridge.WebViewBridgePackage;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -52,7 +53,9 @@ public class MainApplication extends Application implements ReactApplication {
new GethPackage(), new GethPackage(),
new ReactNativeDialogsPackage(), new ReactNativeDialogsPackage(),
new ImageResizerPackage(), new ImageResizerPackage(),
new PickerPackage() new PickerPackage(),
new WebViewBridgePackage()
); );
} }
}; };

View File

@ -27,5 +27,9 @@ include ':react-native-orientation', ':app'
project(':react-native-orientation').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-orientation/android') project(':react-native-orientation').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-orientation/android')
include ':react-native-fs' include ':react-native-fs'
project(':react-native-fs').projectDir = new File(settingsDir, '../node_modules/react-native-fs/android') project(':react-native-fs').projectDir = new File(settingsDir, '../node_modules/react-native-fs/android')
include ':react-native-image-crop-picker' include ':react-native-image-crop-picker'
project(':react-native-image-crop-picker').projectDir = new File(settingsDir, '../node_modules/react-native-image-crop-picker/android') project(':react-native-image-crop-picker').projectDir = new File(settingsDir, '../node_modules/react-native-image-crop-picker/android')
include ':react-native-webview-bridge'
project(':react-native-webview-bridge').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview-bridge/android')

View File

@ -50,6 +50,7 @@
"react-native-tcp": "^1.0.1", "react-native-tcp": "^1.0.1",
"react-native-udp": "^1.2.5", "react-native-udp": "^1.2.5",
"react-native-vector-icons": "^2.0.3", "react-native-vector-icons": "^2.0.3",
"react-native-webview-bridge": "github:rasom/react-native-webview-bridge#master",
"readable-stream": "^1.0.33", "readable-stream": "^1.0.33",
"realm": "^0.14.0", "realm": "^0.14.0",
"stream-browserify": "^1.0.0", "stream-browserify": "^1.0.0",

View File

@ -274,6 +274,7 @@ function validateBalance(params) {
] ]
}; };
} }
var balance = web3.eth.getBalance(params.command.address); var balance = web3.eth.getBalance(params.command.address);
if (bn(val).greaterThan(bn(balance))) { if (bn(val).greaterThan(bn(balance))) {
return { return {

View File

@ -131,6 +131,9 @@ var status = {
var response = new Response(); var response = new Response();
return response.create(h); return response.create(h);
}, },
autorun: function (commandName) {
_status_catalog.autorun = commandName;
},
types: { types: {
TEXT: 'text', TEXT: 'text',
NUMBER: 'number', NUMBER: 'number',

20
resources/wallet.js Normal file
View File

@ -0,0 +1,20 @@
function wallet() {
var url = 'http://127.0.0.1:3450';
return {webViewUrl: url};
}
status.command({
name: "wallet",
description: "wallet",
color: "#ffa500",
fullscreen: true,
suggestionsTrigger: 'on-send',
params: [{
name: "webpage",
suggestions: wallet,
type: status.types.TEXT
}]
});
status.autorun("wallet");

26
resources/webview.js Normal file
View File

@ -0,0 +1,26 @@
(function () {
window.statusAPI = {
dispatch: function (event, options) {
console.log("statusAPI.dispatch: " + JSON.stringify(options));
if (options.callback) {
console.log(options.callback);
statusAPI.callbacks[event] = options.callback;
}
var json = JSON.stringify({
event: event,
options: options
});
console.log("sending from webview: " + json);
WebViewBridge.send(json);
},
callbacks: {}
};
WebViewBridge.onMessage = function (messageString) {
console.log("received from react-native: " + messageString);
var message = JSON.parse(messageString);
if (statusAPI.callbacks[message.event]) {
statusAPI.callbacks[message.event](message.params);
}
};
}());

View File

@ -45,11 +45,13 @@
(dispatch-sync [:add-account account]) (dispatch-sync [:add-account account])
(dispatch [:login-account address password]))))) (dispatch [:login-account address password])))))
(register-handler (register-handler :create-account
:create-account (after #(dispatch [:init-wallet-chat]))
(fn [db [_ password]] (u/side-effect!
(geth/create-account password (fn [result] (account-created result password))) (fn [_ [_ password]]
db)) (geth/create-account
password
#(account-created % password)))))
(defn save-account-to-realm! (defn save-account-to-realm!
[{:keys [current-account-id accounts]} _] [{:keys [current-account-id accounts]} _]

View File

@ -1,6 +1,7 @@
(ns status-im.chat.handlers (ns status-im.chat.handlers
(:require-macros [cljs.core.async.macros :as am]) (:require-macros [cljs.core.async.macros :as am])
(:require [re-frame.core :refer [enrich after debug dispatch path]] (:require [re-frame.core :refer [enrich after debug dispatch]]
[status-im.models.commands :as commands] [status-im.models.commands :as commands]
[clojure.string :as str] [clojure.string :as str]
[status-im.components.styles :refer [default-chat-color]] [status-im.components.styles :refer [default-chat-color]]
@ -30,7 +31,9 @@
status-im.chat.handlers.unviewed-messages status-im.chat.handlers.unviewed-messages
status-im.chat.handlers.send-message status-im.chat.handlers.send-message
status-im.chat.handlers.receive-message status-im.chat.handlers.receive-message
[cljs.core.async :as a])) [cljs.core.async :as a]
status-im.chat.handlers.webview-bridge
status-im.chat.handlers.wallet-chat))
(register-handler :set-show-actions (register-handler :set-show-actions
(fn [db [_ show-actions]] (fn [db [_ show-actions]]
@ -250,17 +253,18 @@
init-chat)))) init-chat))))
(defn prepare-chat (defn prepare-chat
[{:keys [contacts] :as db} [_ contact-id]] [{:keys [contacts] :as db} [_ contcat-id options]]
(let [name (get-in contacts [contact-id :name]) (let [name (get-in contacts [contcat-id :name])
chat {:chat-id contact-id chat (merge {:chat-id contcat-id
:name (or name contact-id) :name (or name contcat-id)
:color default-chat-color :color default-chat-color
:group-chat false :group-chat false
:is-active true :is-active true
:timestamp (.getTime (js/Date.)) :timestamp (.getTime (js/Date.))
:contacts [{:identity contact-id}] :contacts [{:identity contcat-id}]
:dapp-url nil :dapp-url nil
:dapp-hash nil}] :dapp-hash nil}
options)]
(assoc db :new-chat chat))) (assoc db :new-chat chat)))
(defn add-chat [{:keys [new-chat] :as db} [_ chat-id]] (defn add-chat [{:keys [new-chat] :as db} [_ chat-id]]
@ -273,15 +277,22 @@
(chats/create-chat new-chat)) (chats/create-chat new-chat))
(defn open-chat! (defn open-chat!
[_ [_ chat-id]] [_ [_ chat-id _ navigation-type]]
(dispatch [:navigate-to :chat chat-id])) (dispatch [(or navigation-type :navigate-to) :chat chat-id]))
(register-handler :start-chat (register-handler ::start-chat!
(-> prepare-chat (-> prepare-chat
((enrich add-chat)) ((enrich add-chat))
((after save-chat!)) ((after save-chat!))
((after open-chat!)))) ((after open-chat!))))
(register-handler :start-chat
(u/side-effect!
(fn [{:keys [chats]} [_ contcat-id options navigation-type]]
(if (chats contcat-id)
(dispatch [(or navigation-type :navigate-to) :chat contcat-id])
(dispatch [::start-chat! contcat-id options navigation-type])))))
(register-handler :add-chat (register-handler :add-chat
(-> prepare-chat (-> prepare-chat
((enrich add-chat)) ((enrich add-chat))
@ -392,3 +403,14 @@
(if (get-in db [:chats chat-id]) (if (get-in db [:chats chat-id])
(update-in db [:chats chat-id] merge new-chat-data) (update-in db [:chats chat-id] merge new-chat-data)
db))) db)))
(register-handler :check-autorun
(u/side-effect!
(fn [{:keys [current-chat-id] :as db}]
(let [autorun (get-in db [:chats current-chat-id :autorun])]
(when autorun
(am/go
;;todo: find another way to make it work...
(a/<! (a/timeout 100))
(dispatch [:set-chat-command (keyword autorun)])
(dispatch [:animate-command-suggestions])))))))

View File

@ -0,0 +1,10 @@
(ns status-im.chat.handlers.wallet-chat
(:require [re-frame.core :refer [after enrich path dispatch]]
[status-im.utils.handlers :refer [register-handler] :as u]))
(register-handler :init-wallet-chat
(u/side-effect!
(fn []
(dispatch [:add-chat "wallet" {:name "Wallet"
:dapp-url "http://127.0.0.1:3450"}]))))

View File

@ -0,0 +1,39 @@
(ns status-im.chat.handlers.webview-bridge
(:require [re-frame.core :refer [after dispatch enrich]]
[status-im.utils.handlers :refer [register-handler]]
[status-im.utils.handlers :as u]
[status-im.utils.types :as t]
[status-im.utils.logging :as log]))
(register-handler :set-webview-bridge
(fn [db [_ bridge]]
(assoc db :webview-bridge bridge)))
(defn contacts-click-handler [whisper-identity]
#(dispatch [:chat-with-command whisper-identity :send]))
(defn chat-with-command
[_ [_ whisper-identity command]]
(dispatch [:start-chat whisper-identity {} :navigate-back])
(dispatch [:remove-contacts-click-handler])
(let [callback #(dispatch [:set-chat-command command])]
(dispatch [:add-commands-loading-callback whisper-identity callback])))
(register-handler :chat-with-command
(u/side-effect! chat-with-command))
(register-handler :webview-bridge-message
(u/side-effect!
(fn [_ [_ message-string]]
(let [message (t/json->clj message-string)
event (keyword (:event message))]
(log/debug (str "message from webview: " message))
(case event
:webview-send-transaction (dispatch [:show-contacts contacts-click-handler])
(log/error (str "Unknown event: " event)))))))
(register-handler :send-to-webview-bridge
(u/side-effect!
(fn [{:keys [webview-bridge]} [_ data]]
(when webview-bridge
(.sendToBridge webview-bridge (t/clj->json data))))))

View File

@ -288,24 +288,25 @@
[animated-view {:style (st/messages-container messages-offset)} [animated-view {:style (st/messages-container messages-offset)}
messages])}))) messages])})))
(defview chat [{platform-specific :platform-specific}] (defn chat [{platform-specific :platform-specific}]
[group-chat [:chat :group-chat] (let [group-chat (subscribe [:chat :group-chat])
show-actions-atom [:show-actions] show-actions (subscribe [:show-actions])
command [:get-chat-command] command? (subscribe [:command?])
command? [:command?] layout-height (subscribe [:get :layout-height])]
suggestions [:get-suggestions] (r/create-class
to-msg-id [:get-chat-command-to-msg-id] {:component-did-mount #(dispatch [:check-autorun])
layout-height [:get :layout-height]] :reagent-render
(fn [{platform-specific :platform-specific}]
[view {:style st/chat-view [view {:style st/chat-view
:onLayout (fn [event] :onLayout (fn [event]
(let [height (.. event -nativeEvent -layout -height)] (let [height (.. event -nativeEvent -layout -height)]
(when (not= height layout-height) (when (not= height @layout-height)
(dispatch [:set-layout-height height]))))} (dispatch [:set-layout-height height]))))}
[chat-toolbar platform-specific] [chat-toolbar platform-specific]
[messages-container [messages-container
[messages-view platform-specific group-chat]] [messages-view platform-specific @group-chat]]
(when group-chat [typing-all platform-specific]) (when @group-chat [typing-all platform-specific])
[response-view] [response-view]
(when-not command? [suggestion-container]) (when-not @command? [suggestion-container])
[chat-message-new platform-specific] [chat-message-new platform-specific]
(when show-actions-atom [actions-view platform-specific])]) (when @show-actions [actions-view platform-specific])])})))

View File

@ -39,7 +39,7 @@
:onChangeText (when-not disable? command/set-input-message) :onChangeText (when-not disable? command/set-input-message)
:onSubmitEditing (on-press-commands-handler command)}) :onSubmitEditing (on-press-commands-handler command)})
(defview message-input [input-options {:keys [suggestions-trigger] :as command}] (defview message-input [input-options command]
[command? [:command?] [command? [:command?]
input-message [:get-chat-input-text] input-message [:get-chat-input-text]
input-command [:get-chat-command-content] input-command [:get-chat-command-content]
@ -66,7 +66,7 @@
[view st/input-view [view st/input-view
[plain-message/commands-button] [plain-message/commands-button]
[message-input-container [message-input-container
[message-input input-options]] [message-input input-options command]]
;; TODO emoticons: not implemented ;; TODO emoticons: not implemented
[plain-message/smile-button] [plain-message/smile-button]
(when (or command? valid-plain-message?) (when (or command? valid-plain-message?)

View File

@ -1,6 +1,7 @@
(ns status-im.chat.views.response (ns status-im.chat.views.response
(:require-macros [reagent.ratom :refer [reaction]] (:require-macros [reagent.ratom :refer [reaction]]
[status-im.utils.views :refer [defview]]) [status-im.utils.views :refer [defview]]
[status-im.utils.slurp :refer [slurp]])
(:require [re-frame.core :refer [subscribe dispatch]] (:require [re-frame.core :refer [subscribe dispatch]]
[reagent.core :as r] [reagent.core :as r]
[status-im.components.react :refer [view [status-im.components.react :refer [view
@ -18,7 +19,8 @@
[status-im.components.animation :as anim] [status-im.components.animation :as anim]
[status-im.chat.suggestions-responder :as resp] [status-im.chat.suggestions-responder :as resp]
[status-im.chat.constants :as c] [status-im.chat.constants :as c]
[status-im.chat.views.command-validation :as cv])) [status-im.chat.views.command-validation :as cv]
[status-im.components.webview-bridge :refer [webview-bridge]]))
(defn drag-icon [] (defn drag-icon []
[view st/drag-container [view st/drag-container
@ -97,8 +99,12 @@
(defview suggestions-web-view [] (defview suggestions-web-view []
[url [:web-view-url]] [url [:web-view-url]]
(when url (when url
[web-view {:source {:uri url} [webview-bridge
{:ref #(dispatch [:set-webview-bridge %])
:on-bridge-message #(dispatch [:webview-bridge-message %])
:source {:uri url}
:java-script-enabled true :java-script-enabled true
:injected-java-script (slurp "resources/webview.js")
:style {:height 300} :style {:height 300}
:on-navigation-state-change on-navigation-change}])) :on-navigation-state-change on-navigation-change}]))

View File

@ -23,12 +23,18 @@
(defn fetch-commands! (defn fetch-commands!
[db [identity]] [db [identity]]
(when true (when true
;;when-let [url (:dapp-url (get-in db [:chats identity]))] ;-let [url (get-in db [:chats identity :dapp-url])]
;; todo fix this after demo (cond
(if true (= "console" identity)
;(= "console" identity) (dispatch [::validate-hash identity (slurp "resources/commands.js")])
(= "wallet" identity)
(dispatch [::validate-hash identity (slurp "resources/wallet.js")])
:else
(dispatch [::validate-hash identity (slurp "resources/commands.js")]) (dispatch [::validate-hash identity (slurp "resources/commands.js")])
#_(http-get (s/join "/" [url commands-js]) #_(http-get (s/join "/" [url commands-js])
#(dispatch [::validate-hash identity %]) #(dispatch [::validate-hash identity %])
#(dispatch [::loading-failed! identity ::file-was-not-found]))))) #(dispatch [::loading-failed! identity ::file-was-not-found])))))
@ -69,11 +75,12 @@
(into {}))) (into {})))
(defn add-commands (defn add-commands
[db [id _ {:keys [commands responses]}]] [db [id _ {:keys [commands responses autorun] :as data}]]
(-> db (-> db
(update-in [id :commands] merge (mark-as :command commands)) (update-in [id :commands] merge (mark-as :command commands))
(update-in [id :responses] merge (mark-as :response responses)) (update-in [id :responses] merge (mark-as :response responses))
(assoc-in [id :commands-loaded] true))) (assoc-in [id :commands-loaded] true)
(assoc-in [id :autorun] autorun)))
(defn save-commands-js! (defn save-commands-js!
[_ [id file]] [_ [id file]]
@ -101,7 +108,26 @@
(reg-handler ::add-commands (reg-handler ::add-commands
[(path :chats) [(path :chats)
(after save-commands-js!)] (after save-commands-js!)
(after #(dispatch [:check-autorun]))
(after (fn [_ [id]]
(dispatch [:invoke-commands-loading-callbacks id])))]
add-commands) add-commands)
(reg-handler ::loading-failed! (u/side-effect! loading-failed!)) (reg-handler ::loading-failed! (u/side-effect! loading-failed!))
(reg-handler :add-commands-loading-callback
(fn [db [chat-id callback]]
(update-in db [::commands-callbacks chat-id] conj callback)))
(reg-handler :invoke-commands-loading-callbacks
(u/side-effect!
(fn [db [chat-id]]
(let [callbacks (get-in db [::commands-callbacks chat-id])]
(doseq [callback callbacks]
(callback))
(dispatch [::clear-commands-callbacks chat-id])))))
(reg-handler ::clear-commands-callbacks
(fn [db [chat-id]]
(assoc-in db [::commands-callbacks chat-id] nil)))

View File

@ -7,7 +7,6 @@
view view
text text
image image
navigator
drawer-layout-android drawer-layout-android
touchable-opacity]] touchable-opacity]]
[status-im.resources :as res] [status-im.resources :as res]
@ -64,7 +63,7 @@
:handler #(dispatch [:navigate-to :discovery]) :handler #(dispatch [:navigate-to :discovery])
:platform-specific platform-specific}] :platform-specific platform-specific}]
[menu-item {:name (label :t/contacts) [menu-item {:name (label :t/contacts)
:handler #(dispatch [:show-contacts navigator]) :handler #(dispatch [:show-contacts])
:platform-specific platform-specific}] :platform-specific platform-specific}]
[menu-item {:name (label :t/invite-friends) [menu-item {:name (label :t/invite-friends)
:handler (fn [] :handler (fn []

View File

@ -0,0 +1,9 @@
(ns status-im.components.webview-bridge
(:require [status-im.utils.utils :as u]
[reagent.core :as r]))
(def webview-bridge-class
(r/adapt-react-class (u/require "react-native-webview-bridge")))
(defn webview-bridge [opts]
[webview-bridge-class opts])

View File

@ -11,7 +11,7 @@
list-item] :as react] list-item] :as react]
[status-im.components.action-button :refer [action-button [status-im.components.action-button :refer [action-button
action-button-item]] action-button-item]]
[status-im.contacts.views.contact :refer [contact-extended-view]] [status-im.contacts.views.contact :refer [contact-extended-view on-press]]
[status-im.components.status-bar :refer [status-bar]] [status-im.components.status-bar :refer [status-bar]]
[status-im.components.toolbar :refer [toolbar]] [status-im.components.toolbar :refer [toolbar]]
[status-im.components.drawer.view :refer [open-drawer]] [status-im.components.drawer.view :refer [open-drawer]]
@ -41,7 +41,7 @@
(def contacts-limit 10) (def contacts-limit 10)
(defn contact-group [contacts contacts-count title group top?] (defn contact-group [contacts contacts-count title group top? click-handler]
[view st/contact-group [view st/contact-group
[view st/contact-group-header [view st/contact-group-header
(when-not top? (when-not top?
@ -55,9 +55,14 @@
;; todo what if there is no contacts, should we show some information ;; todo what if there is no contacts, should we show some information
;; about this? ;; about this?
[view {:flexDirection :column} [view {:flexDirection :column}
(for [contact contacts] (doall
;; TODO not imlemented: contact more button handler ;; TODO not imlemented: contact more button handler
^{:key contact} [contact-extended-view contact nil nil])] (map (fn [contact]
(let [whisper-identity (:whisper-identity contact)
click-handler (or click-handler on-press)]
^{:key contact}
[contact-extended-view contact nil (click-handler whisper-identity) nil]))
contacts))]
(when (= contacts-limit (count contacts)) (when (= contacts-limit (count contacts))
[view st/show-all [view st/show-all
[touchable-highlight {:on-press #(dispatch [:show-group-contacts group])} [touchable-highlight {:on-press #(dispatch [:show-group-contacts group])}
@ -66,6 +71,7 @@
(defn contact-list [{platform-specific :platform-specific}] (defn contact-list [{platform-specific :platform-specific}]
(let [contacts (subscribe [:get-contacts-with-limit contacts-limit]) (let [contacts (subscribe [:get-contacts-with-limit contacts-limit])
contcats-count (subscribe [:contacts-count]) contcats-count (subscribe [:contacts-count])
click-handler (subscribe [:get :contacts-click-handler])
show-toolbar-shadow? (r/atom false)] show-toolbar-shadow? (r/atom false)]
(fn [] (fn []
[view st/contacts-list-container [view st/contacts-list-container
@ -79,17 +85,18 @@
:onScroll (fn [e] :onScroll (fn [e]
(let [offset (.. e -nativeEvent -contentOffset -y)] (let [offset (.. e -nativeEvent -contentOffset -y)]
(reset! show-toolbar-shadow? (<= st/contact-group-header-height offset))))} (reset! show-toolbar-shadow? (<= st/contact-group-header-height offset))))}
;; TODO not implemented: dapps and persons separation
[contact-group [contact-group
@contacts @contacts
@contcats-count @contcats-count
(label :t/contacs-group-dapps) (label :t/contacs-group-dapps)
:dapps true] :dapps true
@click-handler]
[contact-group [contact-group
@contacts @contacts
@contcats-count @contcats-count
(label :t/contacs-group-people) (label :t/contacs-group-people)
:people false]] :people false
@click-handler]]
[view st/empty-contact-groups [view st/empty-contact-groups
[react/icon :group_big st/empty-contacts-icon] [react/icon :group_big st/empty-contacts-icon]
[text {:style st/empty-contacts-text} (label :t/no-contacts)]]) [text {:style st/empty-contacts-text} (label :t/no-contacts)]])

View File

@ -1,7 +1,7 @@
(ns status-im.contacts.views.contact (ns status-im.contacts.views.contact
(:require-macros [status-im.utils.views :refer [defview]]) (:require-macros [status-im.utils.views :refer [defview]])
(:require [status-im.components.react :refer [view text icon touchable-highlight]] (:require [status-im.components.react :refer [view text icon touchable-highlight]]
[re-frame.core :refer [dispatch subscribe]] [re-frame.core :refer [dispatch]]
[status-im.contacts.styles :as st] [status-im.contacts.styles :as st]
[status-im.contacts.views.contact-inner :refer [contact-inner-view]])) [status-im.contacts.views.contact-inner :refer [contact-inner-view]]))
@ -10,23 +10,21 @@
(when letter (when letter
[text {:style st/letter-text} letter])]) [text {:style st/letter-text} letter])])
(defn on-press [chat whisper-identity] (defn on-press [whisper-identity]
(if chat #(dispatch [:start-chat whisper-identity]))
#(dispatch [:navigate-to :chat whisper-identity])
#(dispatch [:start-chat whisper-identity])))
(defview contact-with-letter-view [{:keys [whisper-identity letter] :as contact}] (defview contact-with-letter-view [{:keys [whisper-identity letter] :as contact}]
[chat [:get-chat whisper-identity]] [chat [:get-chat whisper-identity]]
[touchable-highlight [touchable-highlight
{:onPress (on-press chat whisper-identity)} {:onPress (on-press whisper-identity)}
[view st/contact-container [view st/contact-container
[letter-view letter] [letter-view letter]
[contact-inner-view contact]]]) [contact-inner-view contact]]])
(defview contact-extended-view [{:keys [whisper-identity] :as contact} info more-click-handler] (defview contact-extended-view [{:keys [whisper-identity] :as contact} info click-handler more-click-handler]
[chat [:get-chat whisper-identity]] [chat [:get-chat whisper-identity]]
[touchable-highlight [touchable-highlight
{:onPress (on-press chat whisper-identity)} {:onPress click-handler}
[view st/contact-container [view st/contact-container
[contact-inner-view contact info] [contact-inner-view contact info]
[touchable-highlight [touchable-highlight

View File

@ -6,7 +6,7 @@
touchable-highlight touchable-highlight
list-view list-view
list-item]] list-item]]
[status-im.contacts.views.contact :refer [contact-with-letter-view]] [status-im.contacts.views.contact :refer [contact-with-letter-view on-press]]
[status-im.components.status-bar :refer [status-bar]] [status-im.components.status-bar :refer [status-bar]]
[status-im.components.toolbar :refer [toolbar]] [status-im.components.toolbar :refer [toolbar]]
[status-im.components.drawer.view :refer [drawer-view open-drawer]] [status-im.components.drawer.view :refer [drawer-view open-drawer]]
@ -20,9 +20,12 @@
[status-im.i18n :refer [label]] [status-im.i18n :refer [label]]
[status-im.components.styles :as cst])) [status-im.components.styles :as cst]))
(defn render-row [row _ _] (defn render-row [click-handler]
(list-item [contact-with-letter-view row])) (fn [row _ _]
(list-item [contact-with-letter-view row
(or click-handler
(let [whisper-identity (:whisper-identity row)]
(on-press whisper-identity)))])))
(defview contact-list-toolbar [platform-specific] (defview contact-list-toolbar [platform-specific]
[group [:get :contacts-group]] [group [:get :contacts-group]]
@ -37,7 +40,9 @@
:handler (fn [])}}]]) :handler (fn [])}}]])
(defview contact-list [{platform-specific :platform-specific}] (defview contact-list [{platform-specific :platform-specific}]
[contacts [:contacts-with-letters]] [contacts [:contacts-with-letters]
click-handler [:get :contacts-click-handler]]
(let [click-handler click-handler]
[drawer-view {:platform-specific platform-specific} [drawer-view {:platform-specific platform-specific}
[view st/contacts-list-container [view st/contacts-list-container
[contact-list-toolbar platform-specific] [contact-list-toolbar platform-specific]
@ -46,5 +51,5 @@
(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 :renderRow (render-row click-handler)
:style st/contacts-list}])]]) :style st/contacts-list}])]]))

View File

@ -66,8 +66,14 @@
(assoc :new-chat-name nil))))) (assoc :new-chat-name nil)))))
(register-handler :show-contacts (register-handler :show-contacts
(fn [db _] (fn [db [_ click-handler]]
(push-view db :contact-list))) (-> db
(assoc :contacts-click-handler click-handler)
(push-view :contact-list))))
(register-handler :remove-contacts-click-handler
(fn [db]
(dissoc db :contacts-click-handler)))
(register-handler :show-group-contacts (register-handler :show-group-contacts
(fn [db [_ group]] (fn [db [_ group]]