Prepare to use status-go based protocol: 1-1 and public chat management APIs.

Connect to stubs of status-go protocol API, behind the flag. Since status-go isn't updated yet, setting this flag will break the app.
What needs to be tested is no regressions in a normal mode.

Signed-off-by: Igor Mandrigin <i@mandrigin.ru>
This commit is contained in:
Igor Mandrigin 2019-05-29 15:05:56 +02:00
parent 513ca85f27
commit af6c784ab4
No known key found for this signature in database
GPG Key ID: 4A0EDDE26E66BC8B
8 changed files with 127 additions and 78 deletions

1
.env
View File

@ -21,3 +21,4 @@ STICKERS_ENABLED=1
PARTITIONED_TOPIC=0
CONTRACT_NODES=1
MOBILE_UI_FOR_DESKTOP=0
STATUS_GO_PROTOCOL=0

View File

@ -5,6 +5,7 @@
[status-im.data-store.messages :as messages-store]
[status-im.data-store.user-statuses :as user-statuses-store]
[status-im.contact-code.core :as contact-code]
[taoensso.timbre :as log]
[status-im.i18n :as i18n]
[status-im.transport.chat.core :as transport.chat]
[status-im.transport.utils :as transport.utils]
@ -20,6 +21,7 @@
[status-im.utils.platform :as platform]
[status-im.utils.priority-map :refer [empty-message-map]]
[status-im.utils.utils :as utils]
[status-im.utils.config :as config]
[status-im.mailserver.core :as mailserver]
[status-im.transport.partitioned-topic :as transport.topic]))
@ -101,34 +103,30 @@
(or (get (:chats db) chat-id)
(create-new-chat chat-id cofx))
chat-props)]
{:db (update-in db [:chats chat-id] merge chat)
:data-store/tx [(chats-store/save-chat-tx chat)]}))
(fx/defn add-public-chat
"Adds new public group chat to db & realm"
[cofx topic]
(upsert-chat cofx
{:chat-id topic
:is-active true
:name topic
:group-chat true
:contacts #{}
:public? true
:might-have-join-time-messages? true
:unviewed-messages-count 0
:loaded-unviewed-messages-ids #{}}))
(fx/defn add-group-chat
"Adds new private group chat to db & realm"
[cofx chat-id chat-name admin participants]
(upsert-chat cofx
{:chat-id chat-id
:name chat-name
:is-active true
:group-chat true
:group-admin admin
:contacts participants}))
(if config/use-status-go-protocol?
{:json-rpc/call [{:method "status_joinPublicChat"
:params [topic]
:on-success
#(log/debug "successfully joined a public chat:" topic)
:on-error
(fn [error]
(log/error "can't join a public chat:" error))}]}
(upsert-chat cofx
{:chat-id topic
:is-active true
:name topic
:group-chat true
:contacts #{}
:public? true
:might-have-join-time-messages? true
:unviewed-messages-count 0
:loaded-unviewed-messages-ids #{}})))
(fx/defn clear-history
"Clears history of the particular chat"
@ -159,27 +157,37 @@
(assoc-in [:current-chat-id] nil))
:data-store/tx [(chats-store/deactivate-chat-tx chat-id now)]})
;; TODO: There's a race condition here, as the removal of the filter (async)
;; is done at the same time as the removal of the chat, so a message
;; might come between and restore the chat. Multiple way to handle this
;; (remove chat only after the filter has been removed, probably the safest,
;; flag the chat to ignore new messages, change receive method for public/group chats)
;; For now to keep the code simplier and avoid significant changes, best to leave as it is.
(fx/defn remove-chat
"Removes chat completely from app, producing all necessary effects for that"
[{:keys [db now] :as cofx} chat-id]
(fx/merge cofx
#(when (public-chat? % chat-id)
(transport.chat/unsubscribe-from-chat % chat-id))
#(when (group-chat? % chat-id)
(mailserver/remove-chat-from-mailserver-topic % chat-id))
(mailserver/remove-gaps chat-id)
(mailserver/remove-range chat-id)
(deactivate-chat chat-id)
(clear-history chat-id)
#(when (one-to-one-chat? % chat-id)
(contact-code/stop-listening % chat-id))
(navigation/navigate-to-cofx :home {})))
(if config/use-status-go-protocol?
(fx/merge cofx
{:json-rpc/call [{:method "status_removeChat"
:params [chat-id]
:on-success
#(log/debug "successfully removed a chat:" chat-id)
:on-error
(fn [error]
(log/error "can't remove a chat:" error))}]}
(navigation/navigate-to-cofx :home {}))
(fx/merge cofx
;; TODO: There's a race condition here, as the removal of the filter (async)
;; is done at the same time as the removal of the chat, so a message
;; might come between and restore the chat. Multiple way to handle this
;; (remove chat only after the filter has been removed, probably the safest,
;; flag the chat to ignore new messages, change receive method for public/group chats)
;; For now to keep the code simplier and avoid significant changes, best to leave as it is.
#(when (public-chat? % chat-id)
(transport.chat/unsubscribe-from-chat % chat-id))
#(when (group-chat? % chat-id)
(mailserver/remove-chat-from-mailserver-topic % chat-id))
(mailserver/remove-gaps chat-id)
(mailserver/remove-range chat-id)
(deactivate-chat chat-id)
(clear-history chat-id)
#(when (one-to-one-chat? % chat-id)
(contact-code/stop-listening % chat-id))
(navigation/navigate-to-cofx :home {}))))
(fx/defn send-messages-seen
[{:keys [db] :as cofx} chat-id message-ids]
@ -287,10 +295,20 @@
[{:keys [db] :as cofx} chat-id opts]
;; don't allow to open chat with yourself
(when (not= (accounts.db/current-public-key cofx) chat-id)
(fx/merge cofx
(upsert-chat {:chat-id chat-id
:is-active true})
(navigate-to-chat chat-id opts))))
(if config/use-status-go-protocol?
(fx/merge cofx
{:json-rpc/call [{:method "status_startOneOnOneChat"
:params [chat-id]
:on-success
#(log/debug "successfully started a 1-1 chat with:" chat-id)
:on-error
(fn [error]
(log/error "can't start a 1-1 chat:" error))}]}
(navigate-to-chat chat-id opts))
(fx/merge cofx
(upsert-chat {:chat-id chat-id
:is-active true})
(navigate-to-chat chat-id opts)))))
(fx/defn start-public-chat
"Starts a new public chat"

View File

@ -1,11 +1,14 @@
(ns status-im.chat.models.loading
(:require [status-im.accounts.db :as accounts.db]
(:require [re-frame.core :as re-frame]
[status-im.accounts.db :as accounts.db]
[status-im.chat.commands.core :as commands]
[status-im.chat.models :as chat-model]
[status-im.mailserver.core :as mailserver]
[status-im.utils.config :as config]
[status-im.utils.datetime :as time]
[status-im.utils.fx :as fx]
[status-im.utils.priority-map :refer [empty-message-map]]
[status-im.mailserver.core :as mailserver]))
[taoensso.timbre :as log]))
(def index-messages (partial into empty-message-map
(map (juxt :message-id identity))))
@ -60,10 +63,37 @@
message-id)))
statuses))
(fx/defn initialize-chats
"Initialize persisted chats on startup"
(fx/defn update-chats-in-app-db
{:events [:chats-list/load-success]}
[{:keys [db] :as cofx} chats]
(fx/merge cofx
{:db (assoc db :chats chats)}
(commands/load-commands commands/register)))
(defn- unkeywordize-chat-names
[chats]
(reduce-kv
(fn [acc chat-keyword chat]
(assoc acc (name chat-keyword) chat))
{}
chats))
(defn load-chats-from-rpc
[cofx]
(fx/merge cofx
{:json-rpc/call [{:method "status_chats"
:params []
:on-error
#(log/error "can't retrieve chats list from status-go:" %)
:on-success
#(re-frame/dispatch
[:chats-list/load-success
(unkeywordize-chat-names (:chats %))])}]}))
(defn initialize-chats-legacy
"Use realm + clojure to manage chats"
[{:keys [db get-all-stored-chats] :as cofx}
{:keys [from to] :or {from 0 to nil}}]
from to]
(let [old-chats (:chats db)
chats (reduce (fn [acc {:keys [chat-id] :as chat}]
(assoc acc chat-id
@ -74,9 +104,15 @@
{}
(get-all-stored-chats from to))
chats (merge old-chats chats)]
(fx/merge cofx
{:db (assoc db :chats chats)}
(commands/load-commands commands/register))))
(update-chats-in-app-db cofx chats)))
(fx/defn initialize-chats
"Initialize persisted chats on startup"
[cofx
{:keys [from to] :or {from 0 to nil}}]
(if config/use-status-go-protocol?
(load-chats-from-rpc cofx)
(initialize-chats-legacy cofx from to)))
(defn load-more-messages
"Loads more messages for current chat"
@ -84,7 +120,9 @@
get-stored-messages :get-stored-messages
get-stored-user-statuses :get-stored-user-statuses
get-referenced-messages :get-referenced-messages :as cofx}]
(when-not (get-in db [:chats current-chat-id :all-loaded?])
;; TODO: re-implement functionality for status-go protocol
(when-not (or config/use-status-go-protocol?
(get-in db [:chats current-chat-id :all-loaded?]))
(let [previous-pagination-info (get-in db [:chats current-chat-id :pagination-info])
{:keys [messages
pagination-info

View File

@ -22,7 +22,11 @@
"eth_getTransactionByHash" {}
"eth_getTransactionReceipt" {}
"eth_newBlockFilter" {:subscription? true}
"eth_newFilter" {:subscription? true}})
"eth_newFilter" {:subscription? true}
"status_joinPublicChat" {}
"status_chats" {}
"status_startOneOnOneChat" {}
"status_removeChat" {}})
(defn call
[{:keys [method params on-success on-error]}]
@ -72,3 +76,10 @@
on-success)
:on-error
on-error}))
;; effects
(re-frame/reg-fx
:json-rpc/call
(fn [params]
(doseq [param params]
(call param))))

View File

@ -1,6 +1,7 @@
(ns status-im.signals.core
(:require [status-im.accounts.db :as accounts.db]
[status-im.accounts.login.core :as accounts.login]
[status-im.chat.models.loading :as chat.loading]
[status-im.contact-recovery.core :as contact-recovery]
[status-im.ethereum.subscriptions :as ethereum.subscriptions]
[status-im.hardwallet.core :as hardwallet]
@ -75,4 +76,5 @@
"discovery.summary" (summary cofx event)
"subscriptions.data" (ethereum.subscriptions/handle-signal cofx event)
"subscriptions.error" (ethereum.subscriptions/handle-error cofx event)
"status.chats.did-change" (chat.loading/load-chats-from-rpc cofx)
(log/debug "Event " type " not handled"))))

View File

@ -39,6 +39,8 @@
(def contract-nodes-enabled? (enabled? (get-config :CONTRACT_NODES "0")))
(def mobile-ui-for-desktop? (enabled? (get-config :MOBILE_UI_FOR_DESKTOP "0")))
(def use-status-go-protocol? (enabled? (get-config :STATUS_GO_PROTOCOL "0")))
;; CONFIG VALUES
(def log-level
(-> (get-config :LOG_LEVEL "error")

View File

@ -14,7 +14,7 @@
:shh/add-new-sym-keys :shh/get-new-sym-keys :shh/post
:shh/send-direct-message :shh/remove-filter
:shh/generate-sym-key-from-password :transport/confirm-messages-processed
:group-chats/extract-membership-signature :utils/dispatch-later})
:group-chats/extract-membership-signature :utils/dispatch-later :json-rpc/call})
(defn- safe-merge [fx new-fx]
(if (:merging-fx-with-common-keys fx)

View File

@ -48,29 +48,6 @@
(testing "it adds the fx to store a chat"
(is store-chat-fx)))))
(deftest add-group-chat
(let [chat-id "chat-id"
chat-name "chat-name"
admin "admin"
participants ["a"]
fx (chat/add-group-chat {:db {}} chat-id chat-name admin participants)
store-fx (:data-store/tx fx)
group-chat (get-in fx [:db :chats chat-id])]
(testing "it saves the chat in the database"
(is store-fx))
(testing "it sets the name"
(is (= chat-name (:name group-chat))))
(testing "it sets the admin"
(is (= admin (:group-admin group-chat))))
(testing "it sets the participants"
(is (= participants (:contacts group-chat))))
(testing "it sets the chat-id"
(is (= chat-id (:chat-id group-chat))))
(testing "it sets the group-chat flag"
(is (:group-chat group-chat)))
(testing "it does not sets the public flag"
(is (not (:public? group-chat))))))
(deftest add-public-chat
(let [topic "topic"
fx (chat/add-public-chat {:db {}} topic)