Send signed transaction to deleted chats

This commit is contained in:
Andrea Maria Piana 2018-04-19 09:48:04 +01:00 committed by Roman Volosovskyi
parent abff71d312
commit baf211e1f3
No known key found for this signature in database
GPG Key ID: 0238A4B5ECEE70DE
19 changed files with 262 additions and 190 deletions

View File

@ -123,7 +123,6 @@
:initialize-chats :initialize-chats
[(re-frame/inject-cofx :get-default-contacts-and-groups) [(re-frame/inject-cofx :get-default-contacts-and-groups)
(re-frame/inject-cofx :data-store/all-chats) (re-frame/inject-cofx :data-store/all-chats)
(re-frame/inject-cofx :data-store/inactive-chat-ids)
(re-frame/inject-cofx :data-store/get-messages) (re-frame/inject-cofx :data-store/get-messages)
(re-frame/inject-cofx :data-store/unviewed-messages) (re-frame/inject-cofx :data-store/unviewed-messages)
(re-frame/inject-cofx :data-store/message-ids) (re-frame/inject-cofx :data-store/message-ids)
@ -131,7 +130,6 @@
(re-frame/inject-cofx :data-store/get-local-storage-data)] (re-frame/inject-cofx :data-store/get-local-storage-data)]
(fn [{:keys [db (fn [{:keys [db
all-stored-chats all-stored-chats
inactive-chat-ids
stored-unanswered-requests stored-unanswered-requests
get-stored-messages get-stored-messages
stored-unviewed-messages stored-unviewed-messages
@ -152,9 +150,7 @@
{} {}
all-stored-chats)] all-stored-chats)]
(handlers/merge-fx cofx (handlers/merge-fx cofx
{:db (assoc db {:db (assoc db :chats chats)}
:chats chats
:deleted-chats inactive-chat-ids)}
(init-console-chat) (init-console-chat)
(group.events/add-default-groups) (group.events/add-default-groups)
(add-default-contacts))))) (add-default-contacts)))))
@ -222,26 +218,13 @@
(handlers/register-handler-fx (handlers/register-handler-fx
:add-chat-loaded-event :add-chat-loaded-event
[(re-frame/inject-cofx :data-store/get-chat) re-frame/trim-v] [re-frame/trim-v]
(fn [{:keys [db] :as cofx} [chat-id event]] (fn [{:keys [db] :as cofx} [chat-id event]]
(if (get (:chats db) chat-id) (if (get (:chats db) chat-id)
{:db (assoc-in db [:chats chat-id :chat-loaded-event] event)} {:db (assoc-in db [:chats chat-id :chat-loaded-event] event)}
(-> (models/add-chat chat-id cofx) ; chat not created yet, we have to create it (-> (models/upsert-chat {:chat-id chat-id} cofx) ; chat not created yet, we have to create it
(assoc-in [:db :chats chat-id :chat-loaded-event] event))))) (assoc-in [:db :chats chat-id :chat-loaded-event] event)))))
;; TODO(janherich): remove this unnecessary event in the future (only model function `add-chat` will stay)
(handlers/register-handler-fx
:add-chat
[(re-frame/inject-cofx :data-store/get-chat) re-frame/trim-v]
(fn [cofx [chat-id chat-props]]
(models/add-chat chat-id chat-props cofx)))
(defn- ensure-chat-exists
"Takes chat-id and coeffects map and returns fx to create chat if it doesn't exist"
[chat-id {:keys [db] :as cofx}]
(when-not (get-in cofx [:db :chats chat-id])
(models/add-chat chat-id cofx)))
(defn- navigate-to-chat (defn- navigate-to-chat
"Takes coeffects map and chat-id, returns effects necessary for navigation and preloading data" "Takes coeffects map and chat-id, returns effects necessary for navigation and preloading data"
[chat-id {:keys [navigation-replace?]} {:keys [db] :as cofx}] [chat-id {:keys [navigation-replace?]} {:keys [db] :as cofx}]
@ -263,14 +246,16 @@
(defn start-chat (defn start-chat
"Start a chat, making sure it exists" "Start a chat, making sure it exists"
[chat-id opts {:keys [db] :as cofx}] [chat-id opts {:keys [db] :as cofx}]
(when (not= (:current-public-key db) chat-id) ; don't allow to open chat with yourself ; don't allow to open chat with yourself
(when (not= (:current-public-key db) chat-id)
(handlers/merge-fx cofx (handlers/merge-fx cofx
(ensure-chat-exists chat-id) (models/upsert-chat {:chat-id chat-id
:is-active true})
(navigate-to-chat chat-id opts)))) (navigate-to-chat chat-id opts))))
(handlers/register-handler-fx (handlers/register-handler-fx
:start-chat :start-chat
[(re-frame/inject-cofx :data-store/get-chat) re-frame/trim-v] [re-frame/trim-v]
(fn [cofx [contact-id opts]] (fn [cofx [contact-id opts]]
(start-chat contact-id opts cofx))) (start-chat contact-id opts cofx)))
@ -279,7 +264,7 @@
:update-chat! :update-chat!
[re-frame/trim-v] [re-frame/trim-v]
(fn [cofx [chat]] (fn [cofx [chat]]
(models/update-chat chat cofx))) (models/upsert-chat chat cofx)))
(defn- remove-transport [chat-id {:keys [db] :as cofx}] (defn- remove-transport [chat-id {:keys [db] :as cofx}]
(let [{:keys [group-chat public?]} (get-in db [:chats chat-id])] (let [{:keys [group-chat public?]} (get-in db [:chats chat-id])]
@ -327,15 +312,11 @@
:create-new-public-chat :create-new-public-chat
[re-frame/trim-v] [re-frame/trim-v]
(fn [{:keys [db now] :as cofx} [topic]] (fn [{:keys [db now] :as cofx} [topic]]
(if (get-in db [:chats topic])
(handlers/merge-fx cofx
(navigation/navigate-to-clean :home)
(navigate-to-chat topic {}))
(handlers/merge-fx cofx (handlers/merge-fx cofx
(models/add-public-chat topic) (models/add-public-chat topic)
(navigation/navigate-to-clean :home) (navigation/navigate-to-clean :home)
(navigate-to-chat topic {}) (navigate-to-chat topic {})
(public-chat/join-public-chat topic))))) (public-chat/join-public-chat topic))))
(defn- group-name-from-contacts [selected-contacts all-contacts username] (defn- group-name-from-contacts [selected-contacts all-contacts username]
(->> selected-contacts (->> selected-contacts

View File

@ -25,71 +25,39 @@
:contacts [chat-id] :contacts [chat-id]
:last-clock-value 0})) :last-clock-value 0}))
(defn add-chat (defn upsert-chat
"Adds new chat to db & realm, if the chat with same id already exists, justs restores it" "Upsert chat when not deleted"
([chat-id cofx] [{:keys [chat-id] :as chat-props} {:keys [db] :as cofx}]
(add-chat chat-id {} cofx)) (let [chat (merge
([chat-id chat-props {:keys [db get-stored-chat] :as cofx}] (or (get (:chats db) chat-id)
(let [{:keys [deleted-chats]} db
new-chat (merge (if (get deleted-chats chat-id)
(assoc (get-stored-chat chat-id) :is-active true)
(create-new-chat chat-id cofx)) (create-new-chat chat-id cofx))
chat-props)] chat-props)]
{:db (-> db
(update :chats assoc chat-id new-chat) (if (:is-active chat)
(update :deleted-chats (fnil disj #{}) chat-id)) {:db (update-in db [:chats chat-id] merge chat)
:data-store/save-chat new-chat}))) :data-store/save-chat chat}
;; when chat is deleted, don't change anything
{:db db})))
(defn add-public-chat (defn add-public-chat
"Adds new public group chat to db & realm" "Adds new public group chat to db & realm"
[topic {:keys [db now] :as cofx}] [topic cofx]
(let [chat {:chat-id topic (upsert-chat {:chat-id topic
:name topic
:color styles/default-chat-color
:group-chat true
:public? true
:is-active true :is-active true
:timestamp now :name topic
:last-clock-value 0}] :group-chat true
{:db (assoc-in db [:chats topic] chat) :contacts []
:data-store/save-chat chat})) :public? true} cofx))
(defn add-group-chat (defn add-group-chat
"Adds new private group chat to db & realm" "Adds new private group chat to db & realm"
[chat-id chat-name admin participants {:keys [db now] :as cofx}] [chat-id chat-name admin participants cofx]
(let [chat {:chat-id chat-id (upsert-chat {:chat-id chat-id
:name chat-name :name chat-name
:color styles/default-chat-color :is-active true
:group-chat true :group-chat true
:group-admin admin :group-admin admin
:is-active true :contacts participants} cofx))
:timestamp now
:contacts participants
:last-clock-value 0}]
{:db (assoc-in db [:chats chat-id] chat)
:data-store/save-chat chat}))
;; TODO (yenda): there should be an option to update the timestamp
;; this shouldn't need a specific function like `upsert-chat` which
;; is wrongfuly named
(defn update-chat
"Updates chat properties when not deleted, if chat is not present in app-db, creates a default new one"
[{:keys [chat-id] :as chat-props} {:keys [db] :as cofx}]
(let [{:keys [chats deleted-chats]} db]
(if (get deleted-chats chat-id) ;; when chat is deleted, don't change anything
{:db db}
(let [chat (merge (or (get chats chat-id)
(create-new-chat chat-id cofx))
chat-props)]
{:db (update-in db [:chats chat-id] merge chat)
:data-store/save-chat chat}))))
;; TODO (yenda): an upsert is suppose to add the entry if it doesn't
;; exist and update it if it does
(defn upsert-chat
"Just like `update-chat` only implicitely updates timestamp"
[chat cofx]
(update-chat (assoc chat :timestamp (:now cofx)) cofx))
(defn new-update? [{:keys [added-to-at removed-at removed-from-at]} timestamp] (defn new-update? [{:keys [added-to-at removed-at removed-from-at]} timestamp]
(and (> timestamp added-to-at) (and (> timestamp added-to-at)
@ -98,15 +66,15 @@
(defn remove-chat [chat-id {:keys [db] :as cofx}] (defn remove-chat [chat-id {:keys [db] :as cofx}]
(let [{:keys [chat-id group-chat debug?]} (get-in db [:chats chat-id])] (let [{:keys [chat-id group-chat debug?]} (get-in db [:chats chat-id])]
(cond-> {:db (-> db (if debug?
(update :chats dissoc chat-id) (-> {:db db}
(update :deleted-chats (fnil conj #{}) chat-id))} (update-in [:db :chats] dissoc chat-id)
debug? (assoc :data-store/delete-chat chat-id))
(assoc :data-store/delete-chat chat-id) (-> {:db db}
(not debug?) (assoc-in [:db :chats chat-id :is-active] false)
(assoc :data-store/deactivate-chat chat-id)))) (assoc :data-store/deactivate-chat chat-id)))))
(defn bot-only-chat? [db chat-id] (defn bot-only-chat? [db chat-id]
(let [{:keys [group-chat contacts]} (get-in db [:chats chat-id])] (let [{:keys [group-chat contacts]} (get-in db [:chats chat-id])]
(and (not group-chat) (and (not group-chat)
(get-in db [:contacts/contacts (:identity (first contacts)) :dapp?])))) (get-in db [:contacts/contacts (first contacts) :dapp?]))))

View File

@ -13,8 +13,9 @@
[status-im.transport.message.v1.protocol :as protocol])) [status-im.transport.message.v1.protocol :as protocol]))
(def receive-interceptors (def receive-interceptors
[(re-frame/inject-cofx :data-store/get-message) (re-frame/inject-cofx :data-store/get-chat) [(re-frame/inject-cofx :data-store/get-message)
(re-frame/inject-cofx :random-id) re-frame/trim-v]) (re-frame/inject-cofx :random-id)
re-frame/trim-v])
(defn- lookup-response-ref (defn- lookup-response-ref
[access-scope->commands-responses account chat contacts response-name] [access-scope->commands-responses account chat contacts response-name]
@ -46,10 +47,9 @@
(update-in [:chats chat-id :unviewed-messages] (fnil conj #{}) message-id)) (update-in [:chats chat-id :unviewed-messages] (fnil conj #{}) message-id))
:data-store/save-message prepared-message})) :data-store/save-message prepared-message}))
(defn- prepare-chat [chat-id {:keys [db] :as cofx}] (defn- prepare-chat [chat-id {:keys [db now] :as cofx}]
(if (get-in db [:chats chat-id]) (chat-model/upsert-chat {:chat-id chat-id
(chat-model/upsert-chat {:chat-id chat-id} cofx) :timestamp now} cofx))
(chat-model/add-chat chat-id cofx)))
(defn- get-current-account [{:accounts/keys [accounts current-account-id]}] (defn- get-current-account [{:accounts/keys [accounts current-account-id]}]
(get accounts current-account-id)) (get accounts current-account-id))
@ -94,9 +94,12 @@
(not (= constants/system from))))))) (not (= constants/system from)))))))
(defn receive (defn receive
[{:keys [chat-id message-id] :as message} cofx] [{:keys [chat-id message-id] :as message} {:keys [now] :as cofx}]
(handlers/merge-fx cofx (handlers/merge-fx cofx
(prepare-chat chat-id) (chat-model/upsert-chat {:chat-id chat-id
; We activate a chat again on new messages
:is-active true
:timestamp now})
(add-received-message message) (add-received-message message)
(requests-events/add-request chat-id message-id))) (requests-events/add-request chat-id message-id)))
@ -115,14 +118,12 @@
(#{:group-user-message :public-group-user-message} message-type)) (#{:group-user-message :public-group-user-message} message-type))
(defn add-to-chat? (defn add-to-chat?
[{:keys [db get-stored-message]} {:keys [chat-id from message-id] :as message}] [{:keys [db]} {:keys [chat-id from message-id] :as message}]
(let [{:keys [chats deleted-chats current-public-key]} db (let [{:keys [chats current-public-key]} db
{:keys [messages not-loaded-message-ids]} (get chats chat-id)] {:keys [messages not-loaded-message-ids]} (get chats chat-id)]
(when (not= from current-public-key) (when (not= from current-public-key)
(not (or (get messages message-id) (not (or (get messages message-id)
(get not-loaded-message-ids message-id) (get not-loaded-message-ids message-id))))))
(and (get deleted-chats chat-id)
(get-stored-message message-id)))))))
(defn message-seen-by? [message user-pk] (defn message-seen-by? [message user-pk]
(= :seen (get-in message [:user-statuses user-pk]))) (= :seen (get-in message [:user-statuses user-pk])))
@ -130,8 +131,9 @@
;;;; Send message ;;;; Send message
(def send-interceptors (def send-interceptors
[(re-frame/inject-cofx :random-id) (re-frame/inject-cofx :random-id-seq) [(re-frame/inject-cofx :random-id)
(re-frame/inject-cofx :data-store/get-chat) re-frame/trim-v]) (re-frame/inject-cofx :random-id-seq)
re-frame/trim-v])
(defn- handle-message-from-bot [{:keys [random-id] :as cofx} {:keys [message chat-id]}] (defn- handle-message-from-bot [{:keys [random-id] :as cofx} {:keys [message chat-id]}]
(when-let [message (cond (when-let [message (cond
@ -203,11 +205,12 @@
(def ^:private transport-keys [:content :content-type :message-type :clock-value :timestamp]) (def ^:private transport-keys [:content :content-type :message-type :clock-value :timestamp])
(defn- upsert-and-send [{:keys [chat-id] :as message} cofx] (defn- upsert-and-send [{:keys [chat-id] :as message} {:keys [now] :as cofx}]
(let [send-record (protocol/map->Message (select-keys message transport-keys)) (let [send-record (protocol/map->Message (select-keys message transport-keys))
message-with-id (assoc message :message-id (transport.utils/message-id send-record))] message-with-id (assoc message :message-id (transport.utils/message-id send-record))]
(handlers/merge-fx cofx (handlers/merge-fx cofx
(chat-model/upsert-chat {:chat-id chat-id}) (chat-model/upsert-chat {:chat-id chat-id
:timestamp now})
(add-message chat-id message-with-id true) (add-message chat-id message-with-id true)
(send chat-id send-record)))) (send chat-id send-record))))
@ -216,7 +219,7 @@
(defn- prepare-command-message (defn- prepare-command-message
[identity [identity
{:keys [last-clock-value chat-id] :as chat} {:keys [chat-id last-clock-value] :as chat}
now now
{request-params :params {request-params :params
request-command :command request-command :command
@ -261,9 +264,11 @@
(defn send-command (defn send-command
[{{:keys [current-public-key chats] :as db} :db :keys [now] :as cofx} params] [{{:keys [current-public-key chats] :as db} :db :keys [now] :as cofx} params]
(let [{{:keys [handler-data to-message command] :as content} :command chat-id :chat-id} params (let [{{:keys [handler-data to-message command] :as content} :command chat-id :chat-id} params
; We send commands to deleted chats as well, i.e. signed later transactions
chat (or (get chats chat-id) {:chat-id chat-id})
request (:request handler-data)] request (:request handler-data)]
(handlers/merge-fx cofx (handlers/merge-fx cofx
(upsert-and-send (prepare-command-message current-public-key (get chats chat-id) now request content)) (upsert-and-send (prepare-command-message current-public-key chat now request content))
(add-console-responses command handler-data) (add-console-responses command handler-data)
(requests-events/request-answered chat-id to-message)))) (requests-events/request-answered chat-id to-message))))

View File

@ -2,7 +2,6 @@
(:require [cljs.spec.alpha :as s])) (:require [cljs.spec.alpha :as s]))
(s/def :chat/chats (s/nilable map?)) ; {id (string) chat (map)} active chats on chat's tab (s/def :chat/chats (s/nilable map?)) ; {id (string) chat (map)} active chats on chat's tab
(s/def :chat/deleted-chats (s/nilable set?)) ; set of deleted chat ids
(s/def :chat/current-chat-id (s/nilable string?)) ; current or last opened chat-id (s/def :chat/current-chat-id (s/nilable string?)) ; current or last opened chat-id
(s/def :chat/chat-id (s/nilable string?)) ; what is the difference ? ^ (s/def :chat/chat-id (s/nilable string?)) ; what is the difference ? ^
(s/def :chat/new-chat-name (s/nilable string?)) ; we have name in the new-chat why do we need this field (s/def :chat/new-chat-name (s/nilable string?)) ; we have name in the new-chat why do we need this field

View File

@ -1,7 +1,6 @@
(ns status-im.chat.subs (ns status-im.chat.subs
(:require [clojure.string :as string] (:require [clojure.string :as string]
[re-frame.core :refer [reg-sub subscribe]] [re-frame.core :refer [reg-sub subscribe]]
[status-im.constants :as constants]
[status-im.chat.constants :as chat-constants] [status-im.chat.constants :as chat-constants]
[status-im.chat.models.input :as input-model] [status-im.chat.models.input :as input-model]
[status-im.chat.models.commands :as commands-model] [status-im.chat.models.commands :as commands-model]
@ -52,18 +51,19 @@
platform/ios? kb-height platform/ios? kb-height
:default 0))) :default 0)))
(defn active-chats [dev-mode?] (defn- active-chat? [dev-mode? [_ chat]]
(fn [[_ chat]]
(and (:is-active chat) (and (:is-active chat)
(or dev-mode? (or dev-mode?
(not= const/console-chat-id (:chat-id chat)))))) (not= const/console-chat-id (:chat-id chat)))))
(defn active-chats [[chats {:keys [dev-mode?]}]]
(into {} (filter (partial active-chat? dev-mode?) chats)))
(reg-sub (reg-sub
:get-active-chats :get-active-chats
:<- [:get-chats] :<- [:get-chats]
:<- [:get-current-account] :<- [:get-current-account]
(fn [[chats {:keys [dev-mode?]}]] active-chats)
(into {} (filter (active-chats dev-mode?) chats))))
(reg-sub (reg-sub
:get-chat :get-chat

View File

@ -8,23 +8,14 @@
(re-frame/reg-cofx (re-frame/reg-cofx
:data-store/all-chats :data-store/all-chats
(fn [cofx _] (fn [cofx _]
(assoc cofx :all-stored-chats (data-store/get-all-active)))) (assoc cofx :all-stored-chats (data-store/get-all))))
(re-frame/reg-cofx
:data-store/inactive-chat-ids
(fn [cofx _]
(assoc cofx :inactive-chat-ids (data-store/get-inactive-ids))))
(re-frame/reg-cofx
:data-store/get-chat
(fn [cofx _]
(assoc cofx :get-stored-chat data-store/get-by-id)))
(re-frame/reg-fx (re-frame/reg-fx
:data-store/save-chat :data-store/save-chat
(fn [{:keys [chat-id] :as chat}] (fn [{:keys [chat-id] :as chat}]
(async/go (async/>! core/realm-queue #(data-store/save chat (data-store/exists? chat-id)))))) (async/go (async/>! core/realm-queue #(data-store/save chat (data-store/exists? chat-id))))))
; Only used in debug mode
(re-frame/reg-fx (re-frame/reg-fx
:data-store/delete-chat :data-store/delete-chat
(fn [chat-id] (fn [chat-id]

View File

@ -12,35 +12,13 @@
(realm/fix-map->vec :contacts) (realm/fix-map->vec :contacts)
(assoc :last-clock-value (or last-clock-value 0))))) (assoc :last-clock-value (or last-clock-value 0)))))
(defn get-all-active (defn get-all
[] []
(map normalize-chat (map normalize-chat
(-> (realm/get-by-field @realm/account-realm :chat :is-active true)
(realm/sorted :timestamp :desc)
realm/js-object->clj)))
(defn get-inactive-ids
[]
(-> (realm/get-by-field @realm/account-realm :chat :is-active false)
(.map (fn [chat _ _]
(aget chat "chat-id")))
realm/js-object->clj
set))
(defn- groups
[active?]
(-> @realm/account-realm (-> @realm/account-realm
(realm/get-all :chat) (realm/get-all :chat)
(realm/sorted :timestamp :desc) (realm/sorted :timestamp :desc)
(realm/filtered (str "group-chat = true && is-active = " realm/js-object->clj)))
(if active? "true" "false")))))
(defn get-active-group-chats
[]
(map (fn [{:keys [chat-id public?]}]
{:group-id chat-id
:public? public?})
(realm/js-object->clj (groups true))))
(defn- get-by-id-obj (defn- get-by-id-obj
[chat-id] [chat-id]

View File

@ -96,7 +96,7 @@
(models.message/receive (models.message/receive
(models.message/system-message chat-id random-id now (models.message/system-message chat-id random-id now
(str admin-name " " (i18n/label :t/removed-from-chat)))) (str admin-name " " (i18n/label :t/removed-from-chat))))
(models.chat/update-chat {:chat-id chat-id (models.chat/upsert-chat {:chat-id chat-id
:removed-from-at now :removed-from-at now
:is-active false}) :is-active false})
(transport/unsubscribe-from-chat chat-id)) (transport/unsubscribe-from-chat chat-id))

View File

@ -6,9 +6,13 @@
[status-im.transport.message.v1.protocol :as protocol] [status-im.transport.message.v1.protocol :as protocol]
[status-im.transport.utils :as transport.utils])) [status-im.transport.utils :as transport.utils]))
(defn- has-already-joined? [chat-id {:keys [db]}]
(get-in db [:transport/chats chat-id]))
(defn join-public-chat (defn join-public-chat
"Function producing all protocol level effects necessary for joining public chat identified by chat-id" "Function producing all protocol level effects necessary for joining public chat identified by chat-id"
[chat-id {:keys [db] :as cofx}] [chat-id {:keys [db] :as cofx}]
(when-not (has-already-joined? chat-id cofx)
(let [on-success (fn [sym-key sym-key-id] (let [on-success (fn [sym-key sym-key-id]
(re-frame/dispatch [::add-new-sym-key {:chat-id chat-id (re-frame/dispatch [::add-new-sym-key {:chat-id chat-id
:sym-key sym-key :sym-key sym-key
@ -17,7 +21,7 @@
{:shh/generate-sym-key-from-password {:web3 (:web3 db) {:shh/generate-sym-key-from-password {:web3 (:web3 db)
:password chat-id :password chat-id
:on-success on-success}} :on-success on-success}}
(protocol/init-chat chat-id)))) (protocol/init-chat chat-id)))))
(handlers/register-handler-fx (handlers/register-handler-fx
::add-new-sym-key ::add-new-sym-key

View File

@ -22,7 +22,7 @@
(handlers/merge-fx cofx (handlers/merge-fx cofx
{:db (update-in db [:contacts/contacts public-key] merge contact-props) {:db (update-in db [:contacts/contacts public-key] merge contact-props)
:data-store/save-contact contact-props} :data-store/save-contact contact-props}
(chat.models/add-chat public-key chat-props))))) (chat.models/upsert-chat chat-props)))))
(defn receive-contact-request-confirmation (defn receive-contact-request-confirmation
[public-key {:keys [name profile-image address fcm-token]} [public-key {:keys [name profile-image address fcm-token]}
@ -59,6 +59,6 @@
(if (chats public-key) (if (chats public-key)
(handlers/merge-fx cofx (handlers/merge-fx cofx
(update-contact contact) (update-contact contact)
(chat.models/update-chat {:chat-id chat-id (chat.models/upsert-chat {:chat-id chat-id
:name name})) :name name}))
(update-contact contact cofx)))))))) (update-contact contact cofx))))))))

View File

@ -80,7 +80,7 @@
(handlers/register-handler-fx (handlers/register-handler-fx
:set-contact-identity-from-qr :set-contact-identity-from-qr
[(re-frame/inject-cofx :random-id) (re-frame/inject-cofx :data-store/get-chat)] [(re-frame/inject-cofx :random-id)]
(fn [{{:accounts/keys [accounts current-account-id] :as db} :db :as cofx} [_ _ contact-identity]] (fn [{{:accounts/keys [accounts current-account-id] :as db} :db :as cofx} [_ _ contact-identity]]
(let [current-account (get accounts current-account-id) (let [current-account (get accounts current-account-id)
fx {:db (assoc db :contacts/new-identity contact-identity)}] fx {:db (assoc db :contacts/new-identity contact-identity)}]
@ -125,7 +125,7 @@
(handlers/register-handler-fx (handlers/register-handler-fx
:add-contact-handler :add-contact-handler
[(re-frame/inject-cofx :random-id) (re-frame/inject-cofx :data-store/get-chat)] [(re-frame/inject-cofx :random-id)]
(fn [{{:contacts/keys [new-identity] :as db} :db :as cofx} _] (fn [{{:contacts/keys [new-identity] :as db} :db :as cofx} _]
(when (seq new-identity) (when (seq new-identity)
(add-contact-and-open-chat new-identity cofx)))) (add-contact-and-open-chat new-identity cofx))))

View File

@ -195,7 +195,6 @@
:qr/qr-modal :qr/qr-modal
:qr/current-qr-context :qr/current-qr-context
:chat/chats :chat/chats
:chat/deleted-chats
:chat/current-chat-id :chat/current-chat-id
:chat/chat-id :chat/chat-id
:chat/new-chat :chat/new-chat

View File

@ -81,9 +81,7 @@
(re-frame/reg-cofx (re-frame/reg-cofx
:random-id-seq :random-id-seq
(fn [coeffects _] (fn [coeffects _]
(assoc coeffects :random-id-seq (assoc coeffects :random-id-seq (repeatedly random/id))))
((fn rand-id-seq []
(cons (random/id) (lazy-seq (rand-id-seq))))))))
;;;; FX ;;;; FX

View File

@ -27,7 +27,7 @@
(handlers/register-handler-fx (handlers/register-handler-fx
:profile/send-transaction :profile/send-transaction
[(re-frame/inject-cofx :data-store/get-chat) re-frame/trim-v] [re-frame/trim-v]
(fn [{{:contacts/keys [contacts]} :db :as cofx} [chat-id]] (fn [{{:contacts/keys [contacts]} :db :as cofx} [chat-id]]
(let [send-command (get-in contacts chat-const/send-command-ref)] (let [send-command (get-in contacts chat-const/send-command-ref)]
(handlers/merge-fx cofx (handlers/merge-fx cofx

View File

@ -23,7 +23,6 @@
:status "be the hero of your own journey" :status "be the hero of your own journey"
:network constants/default-network :network constants/default-network
:networks constants/default-networks :networks constants/default-networks
:wnode constants/default-wnode
:public-key "0x049b3a8c04f2c5bccda91c1f5e6434ae72957e93a31c0301b4563eda1d6ce419f63c503ebaee143115f96c1f04f232a7a22ca0454e9ee3d579ad1f870315b151d0"}) :public-key "0x049b3a8c04f2c5bccda91c1f5e6434ae72957e93a31c0301b4563eda1d6ce419f63c503ebaee143115f96c1f04f232a7a22ca0454e9ee3d579ad1f870315b151d0"})
(def new-account (def new-account
@ -34,7 +33,6 @@
:status "the future starts today, not tomorrow" :status "the future starts today, not tomorrow"
:network constants/default-network :network constants/default-network
:networks constants/default-networks :networks constants/default-networks
:wnode constants/default-wnode
:signing-phrase "long loan limo" :signing-phrase "long loan limo"
:public-key "0x04f5722fba79eb36d73263417531007f43d13af76c6233573a8e3e60f667710611feba0785d751b50609bfc0b7cef35448875c5392c0a91948c95798a0ce600847"}) :public-key "0x04f5722fba79eb36d73263417531007f43d13af76c6233573a8e3e60f667710611feba0785d751b50609bfc0b7cef35448875c5392c0a91948c95798a0ce600847"})

View File

@ -0,0 +1,102 @@
(ns status-im.test.chat.models
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.chat.models :as chat]))
(deftest upsert-chat-test
(testing "upserting a non existing chat"
(let [chat-id "some-chat-id"
contact-name "contact-name"
chat-props {:chat-id chat-id
:extra-prop "some"}
cofx {:now "now"
:db {:contacts/contacts {chat-id
{:name contact-name}}}}
response (chat/upsert-chat chat-props cofx)
actual-chat (get-in response [:db :chats chat-id])
store-chat-fx (:data-store/save-chat response)]
(testing "it adds the chat to the chats collection"
(is actual-chat))
(testing "it adds the extra props"
(is (= "some" (:extra-prop actual-chat))))
(testing "it adds the chat id"
(is (= chat-id (:chat-id actual-chat))))
(testing "it pulls the name from the contacts"
(is (= contact-name (:name actual-chat))))
(testing "it sets the timestamp"
(is (= "now" (:timestamp actual-chat))))
(testing "it adds the contact-id to the contact field"
(is (= chat-id (-> actual-chat :contacts first))))
(testing "it adds the fx to store a chat"
(is store-chat-fx))))
(testing "upserting an existing chat"
(let [chat-id "some-chat-id"
chat-props {:chat-id chat-id
:name "new-name"
:extra-prop "some"}
cofx {:db {:chats {chat-id {:is-active true
:name "old-name"}}}}
response (chat/upsert-chat chat-props cofx)
actual-chat (get-in response [:db :chats chat-id])
store-chat-fx (:data-store/save-chat response)]
(testing "it adds the chat to the chats collection"
(is actual-chat))
(testing "it adds the extra props"
(is (= "some" (:extra-prop actual-chat))))
(testing "it updates existins props"
(is (= "new-name" (:name actual-chat))))
(testing "it adds the fx to store a chat"
(is store-chat-fx))))
(testing "upserting a deleted chat"
(let [chat-id "some-chat-id"
contact-name "contact-name"
chat-props {:chat-id chat-id
:name "new-name"
:extra-prop "some"}
cofx {:some-cofx "b"
:db {:chats {chat-id {:is-active false
:name "old-name"}}}}]
(testing "it updates it if is-active is passed"
(is (get-in (chat/upsert-chat (assoc chat-props :is-active true) cofx) [:db :chats chat-id :is-active])))
(testing "it returns the db unchanged"
(is (= {:db (:db cofx)} (chat/upsert-chat chat-props cofx)))))))
(deftest add-group-chat
(let [chat-id "chat-id"
chat-name "chat-name"
admin "admin"
participants ["a"]
fx (chat/add-group-chat chat-id chat-name admin participants {})
store-fx (:data-store/save-chat 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 topic {})
store-fx (:data-store/save-chat fx)
chat (get-in fx [:db :chats topic])]
(testing "it saves the chat in the database"
(is store-fx))
(testing "it sets the name"
(is (= topic (:name chat))))
(testing "it sets the participants"
(is (= [] (:contacts chat))))
(testing "it sets the chat-id"
(is (= topic (:chat-id chat))))
(testing "it sets the group-chat flag"
(is (:group-chat chat)))
(testing "it does not sets the public flag"
(is (:public? chat)))))

View File

@ -0,0 +1,26 @@
(ns status-im.test.chat.models.message
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.chat.models.message :as message]))
(deftest add-to-chat?
(testing "it returns true when it's not in loaded message"
(is (message/add-to-chat? {:db {:chats {"a" {}}}}
{:message-id "message-id"
:from "a"
:chat-id "a"})))
(testing "it returns false when from is the same as pk"
(is (not (message/add-to-chat? {:db {:current-public-key "pk"
:chats {"a" {}}}}
{:message-id "message-id"
:from "pk"
:chat-id "a"}))))
(testing "it returns false when it's already in the loaded message"
(is (not (message/add-to-chat? {:db {:chats {"a" {:messages {"message-id" {}}}}}}
{:message-id "message-id"
:from "a"
:chat-id "a"}))))
(testing "it returns false when it's already in the not-loaded-message-ids"
(is (not (message/add-to-chat? {:db {:chats {"a" {:not-loaded-message-ids #{"message-id" }}}}}
{:message-id "message-id"
:from "a"
:chat-id "a"})))))

View File

@ -1,5 +1,6 @@
(ns status-im.test.chat.subs (ns status-im.test.chat.subs
(:require [cljs.test :refer-macros [deftest is testing]] (:require [cljs.test :refer-macros [deftest is testing]]
[status-im.constants :as const]
[status-im.chat.subs :as s])) [status-im.chat.subs :as s]))
(deftest test-message-datemark-groups (deftest test-message-datemark-groups
@ -134,3 +135,21 @@
(is (:last-in-group? actual-m2)) (is (:last-in-group? actual-m2))
(is (:last-in-group? actual-m3)) (is (:last-in-group? actual-m3))
(is (not (:last-in-group? actual-m4))))))) (is (not (:last-in-group? actual-m4)))))))
(deftest active-chats-test
(let [active-chat-1 {:is-active true :chat-id 1}
active-chat-2 {:is-active true :chat-id 2}
console {:is-active true :chat-id const/console-chat-id}
chats {1 active-chat-1
2 active-chat-2
3 {:is-active false :chat-id 3}
const/console-chat-id console}]
(testing "in normal it returns only chats with is-active, without console"
(is (= {1 active-chat-1
2 active-chat-2}
(s/active-chats [chats {:dev-mode? false}]))))
(testing "in dev-mode it returns only chats with is-active, keeping console"
(is (= {1 active-chat-1
2 active-chat-2
const/console-chat-id console}
(s/active-chats [chats {:dev-mode? true}]))))))

View File

@ -8,7 +8,9 @@
[status-im.test.wallet.transactions.views] [status-im.test.wallet.transactions.views]
[status-im.test.profile.events] [status-im.test.profile.events]
[status-im.test.bots.events] [status-im.test.bots.events]
[status-im.test.chat.models]
[status-im.test.chat.models.input] [status-im.test.chat.models.input]
[status-im.test.chat.models.message]
[status-im.test.chat.subs] [status-im.test.chat.subs]
[status-im.test.chat.views.message] [status-im.test.chat.views.message]
[status-im.test.i18n] [status-im.test.i18n]
@ -39,6 +41,7 @@
'status-im.test.utils.async 'status-im.test.utils.async
'status-im.test.chat.events 'status-im.test.chat.events
'status-im.test.chat.subs 'status-im.test.chat.subs
'status-im.test.chat.models
'status-im.test.accounts.events 'status-im.test.accounts.events
'status-im.test.contacts.events 'status-im.test.contacts.events
'status-im.test.profile.events 'status-im.test.profile.events
@ -47,6 +50,7 @@
'status-im.test.wallet.transactions.subs 'status-im.test.wallet.transactions.subs
'status-im.test.wallet.transactions.views 'status-im.test.wallet.transactions.views
'status-im.test.chat.models.input 'status-im.test.chat.models.input
'status-im.test.chat.models.message
'status-im.test.chat.views.message 'status-im.test.chat.views.message
'status-im.test.i18n 'status-im.test.i18n
'status-im.test.protocol.web3.inbox 'status-im.test.protocol.web3.inbox