diff --git a/src/status_im/chat/events.cljs b/src/status_im/chat/events.cljs index a308f98b42..cfae96657e 100644 --- a/src/status_im/chat/events.cljs +++ b/src/status_im/chat/events.cljs @@ -123,7 +123,6 @@ :initialize-chats [(re-frame/inject-cofx :get-default-contacts-and-groups) (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/unviewed-messages) (re-frame/inject-cofx :data-store/message-ids) @@ -131,7 +130,6 @@ (re-frame/inject-cofx :data-store/get-local-storage-data)] (fn [{:keys [db all-stored-chats - inactive-chat-ids stored-unanswered-requests get-stored-messages stored-unviewed-messages @@ -152,9 +150,7 @@ {} all-stored-chats)] (handlers/merge-fx cofx - {:db (assoc db - :chats chats - :deleted-chats inactive-chat-ids)} + {:db (assoc db :chats chats)} (init-console-chat) (group.events/add-default-groups) (add-default-contacts))))) @@ -222,26 +218,13 @@ (handlers/register-handler-fx :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]] (if (get (:chats db) chat-id) {: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))))) -;; 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 "Takes coeffects map and chat-id, returns effects necessary for navigation and preloading data" [chat-id {:keys [navigation-replace?]} {:keys [db] :as cofx}] @@ -263,14 +246,16 @@ (defn start-chat "Start a chat, making sure it exists" [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 - (ensure-chat-exists chat-id) + (models/upsert-chat {:chat-id chat-id + :is-active true}) (navigate-to-chat chat-id opts)))) (handlers/register-handler-fx :start-chat - [(re-frame/inject-cofx :data-store/get-chat) re-frame/trim-v] + [re-frame/trim-v] (fn [cofx [contact-id opts]] (start-chat contact-id opts cofx))) @@ -279,7 +264,7 @@ :update-chat! [re-frame/trim-v] (fn [cofx [chat]] - (models/update-chat chat cofx))) + (models/upsert-chat chat cofx))) (defn- remove-transport [chat-id {:keys [db] :as cofx}] (let [{:keys [group-chat public?]} (get-in db [:chats chat-id])] @@ -311,7 +296,7 @@ [re-frame/trim-v] (fn [cofx [chat-id]] (handlers/merge-fx cofx - (models/remove-chat chat-id) + (models/remove-chat chat-id) (navigation/replace-view :home)))) (handlers/register-handler-fx @@ -327,15 +312,11 @@ :create-new-public-chat [re-frame/trim-v] (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 - (models/add-public-chat topic) - (navigation/navigate-to-clean :home) - (navigate-to-chat topic {}) - (public-chat/join-public-chat topic))))) + (handlers/merge-fx cofx + (models/add-public-chat topic) + (navigation/navigate-to-clean :home) + (navigate-to-chat topic {}) + (public-chat/join-public-chat topic)))) (defn- group-name-from-contacts [selected-contacts all-contacts username] (->> selected-contacts diff --git a/src/status_im/chat/models.cljs b/src/status_im/chat/models.cljs index 911dcf95f4..97b66289f0 100644 --- a/src/status_im/chat/models.cljs +++ b/src/status_im/chat/models.cljs @@ -25,71 +25,39 @@ :contacts [chat-id] :last-clock-value 0})) -(defn add-chat - "Adds new chat to db & realm, if the chat with same id already exists, justs restores it" - ([chat-id cofx] - (add-chat chat-id {} cofx)) - ([chat-id chat-props {:keys [db get-stored-chat] :as cofx}] - (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)) - chat-props)] - {:db (-> db - (update :chats assoc chat-id new-chat) - (update :deleted-chats (fnil disj #{}) chat-id)) - :data-store/save-chat new-chat}))) +(defn upsert-chat + "Upsert chat when not deleted" + [{:keys [chat-id] :as chat-props} {:keys [db] :as cofx}] + (let [chat (merge + (or (get (:chats db) chat-id) + (create-new-chat chat-id cofx)) + chat-props)] + + (if (:is-active chat) + {:db (update-in db [:chats chat-id] merge chat) + :data-store/save-chat chat} + ;; when chat is deleted, don't change anything + {:db db}))) (defn add-public-chat "Adds new public group chat to db & realm" - [topic {:keys [db now] :as cofx}] - (let [chat {:chat-id topic - :name topic - :color styles/default-chat-color - :group-chat true - :public? true - :is-active true - :timestamp now - :last-clock-value 0}] - {:db (assoc-in db [:chats topic] chat) - :data-store/save-chat chat})) + [topic cofx] + (upsert-chat {:chat-id topic + :is-active true + :name topic + :group-chat true + :contacts [] + :public? true} cofx)) (defn add-group-chat "Adds new private group chat to db & realm" - [chat-id chat-name admin participants {:keys [db now] :as cofx}] - (let [chat {:chat-id chat-id - :name chat-name - :color styles/default-chat-color - :group-chat true - :group-admin admin - :is-active true - :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)) + [chat-id chat-name admin participants cofx] + (upsert-chat {:chat-id chat-id + :name chat-name + :is-active true + :group-chat true + :group-admin admin + :contacts participants} cofx)) (defn new-update? [{:keys [added-to-at removed-at removed-from-at]} timestamp] (and (> timestamp added-to-at) @@ -98,15 +66,15 @@ (defn remove-chat [chat-id {:keys [db] :as cofx}] (let [{:keys [chat-id group-chat debug?]} (get-in db [:chats chat-id])] - (cond-> {:db (-> db - (update :chats dissoc chat-id) - (update :deleted-chats (fnil conj #{}) chat-id))} - debug? - (assoc :data-store/delete-chat chat-id) - (not debug?) - (assoc :data-store/deactivate-chat chat-id)))) + (if debug? + (-> {:db db} + (update-in [:db :chats] dissoc chat-id) + (assoc :data-store/delete-chat chat-id)) + (-> {:db db} + (assoc-in [:db :chats chat-id :is-active] false) + (assoc :data-store/deactivate-chat chat-id))))) (defn bot-only-chat? [db chat-id] (let [{:keys [group-chat contacts]} (get-in db [:chats chat-id])] (and (not group-chat) - (get-in db [:contacts/contacts (:identity (first contacts)) :dapp?])))) + (get-in db [:contacts/contacts (first contacts) :dapp?])))) diff --git a/src/status_im/chat/models/message.cljs b/src/status_im/chat/models/message.cljs index 60030a964c..1d19dc64d2 100644 --- a/src/status_im/chat/models/message.cljs +++ b/src/status_im/chat/models/message.cljs @@ -13,8 +13,9 @@ [status-im.transport.message.v1.protocol :as protocol])) (def receive-interceptors - [(re-frame/inject-cofx :data-store/get-message) (re-frame/inject-cofx :data-store/get-chat) - (re-frame/inject-cofx :random-id) re-frame/trim-v]) + [(re-frame/inject-cofx :data-store/get-message) + (re-frame/inject-cofx :random-id) + re-frame/trim-v]) (defn- lookup-response-ref [access-scope->commands-responses account chat contacts response-name] @@ -46,10 +47,9 @@ (update-in [:chats chat-id :unviewed-messages] (fnil conj #{}) message-id)) :data-store/save-message prepared-message})) -(defn- prepare-chat [chat-id {:keys [db] :as cofx}] - (if (get-in db [:chats chat-id]) - (chat-model/upsert-chat {:chat-id chat-id} cofx) - (chat-model/add-chat chat-id cofx))) +(defn- prepare-chat [chat-id {:keys [db now] :as cofx}] + (chat-model/upsert-chat {:chat-id chat-id + :timestamp now} cofx)) (defn- get-current-account [{:accounts/keys [accounts current-account-id]}] (get accounts current-account-id)) @@ -94,9 +94,12 @@ (not (= constants/system from))))))) (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 - (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) (requests-events/add-request chat-id message-id))) @@ -115,14 +118,12 @@ (#{:group-user-message :public-group-user-message} message-type)) (defn add-to-chat? - [{:keys [db get-stored-message]} {:keys [chat-id from message-id] :as message}] - (let [{:keys [chats deleted-chats current-public-key]} db - {:keys [messages not-loaded-message-ids]} (get chats chat-id)] + [{:keys [db]} {:keys [chat-id from message-id] :as message}] + (let [{:keys [chats current-public-key]} db + {:keys [messages not-loaded-message-ids]} (get chats chat-id)] (when (not= from current-public-key) (not (or (get messages message-id) - (get not-loaded-message-ids message-id) - (and (get deleted-chats chat-id) - (get-stored-message message-id))))))) + (get not-loaded-message-ids message-id)))))) (defn message-seen-by? [message user-pk] (= :seen (get-in message [:user-statuses user-pk]))) @@ -130,8 +131,9 @@ ;;;; Send message (def send-interceptors - [(re-frame/inject-cofx :random-id) (re-frame/inject-cofx :random-id-seq) - (re-frame/inject-cofx :data-store/get-chat) re-frame/trim-v]) + [(re-frame/inject-cofx :random-id) + (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]}] (when-let [message (cond @@ -203,11 +205,12 @@ (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)) message-with-id (assoc message :message-id (transport.utils/message-id send-record))] (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) (send chat-id send-record)))) @@ -216,7 +219,7 @@ (defn- prepare-command-message [identity - {:keys [last-clock-value chat-id] :as chat} + {:keys [chat-id last-clock-value] :as chat} now {request-params :params request-command :command @@ -261,9 +264,11 @@ (defn send-command [{{: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 + ; 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)] (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) (requests-events/request-answered chat-id to-message)))) diff --git a/src/status_im/chat/specs.cljs b/src/status_im/chat/specs.cljs index 3447d0dfa1..48731d7774 100644 --- a/src/status_im/chat/specs.cljs +++ b/src/status_im/chat/specs.cljs @@ -2,7 +2,6 @@ (: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/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/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 diff --git a/src/status_im/chat/subs.cljs b/src/status_im/chat/subs.cljs index b96abaa8bf..9c54e4aad6 100644 --- a/src/status_im/chat/subs.cljs +++ b/src/status_im/chat/subs.cljs @@ -1,7 +1,6 @@ (ns status-im.chat.subs (:require [clojure.string :as string] [re-frame.core :refer [reg-sub subscribe]] - [status-im.constants :as constants] [status-im.chat.constants :as chat-constants] [status-im.chat.models.input :as input-model] [status-im.chat.models.commands :as commands-model] @@ -52,18 +51,19 @@ platform/ios? kb-height :default 0))) -(defn active-chats [dev-mode?] - (fn [[_ chat]] - (and (:is-active chat) - (or dev-mode? - (not= const/console-chat-id (:chat-id chat)))))) +(defn- active-chat? [dev-mode? [_ chat]] + (and (:is-active chat) + (or dev-mode? + (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 :get-active-chats :<- [:get-chats] :<- [:get-current-account] - (fn [[chats {:keys [dev-mode?]}]] - (into {} (filter (active-chats dev-mode?) chats)))) + active-chats) (reg-sub :get-chat diff --git a/src/status_im/data_store/chats.cljs b/src/status_im/data_store/chats.cljs index 86d29b9de8..12942e1d67 100644 --- a/src/status_im/data_store/chats.cljs +++ b/src/status_im/data_store/chats.cljs @@ -8,23 +8,14 @@ (re-frame/reg-cofx :data-store/all-chats (fn [cofx _] - (assoc cofx :all-stored-chats (data-store/get-all-active)))) - -(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))) + (assoc cofx :all-stored-chats (data-store/get-all)))) (re-frame/reg-fx :data-store/save-chat (fn [{:keys [chat-id] :as chat}] (async/go (async/>! core/realm-queue #(data-store/save chat (data-store/exists? chat-id)))))) +; Only used in debug mode (re-frame/reg-fx :data-store/delete-chat (fn [chat-id] diff --git a/src/status_im/data_store/realm/chats.cljs b/src/status_im/data_store/realm/chats.cljs index d9fff175a6..a0c001be57 100644 --- a/src/status_im/data_store/realm/chats.cljs +++ b/src/status_im/data_store/realm/chats.cljs @@ -12,36 +12,14 @@ (realm/fix-map->vec :contacts) (assoc :last-clock-value (or last-clock-value 0))))) -(defn get-all-active +(defn get-all [] (map normalize-chat - (-> (realm/get-by-field @realm/account-realm :chat :is-active true) + (-> @realm/account-realm + (realm/get-all :chat) (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/get-all :chat) - (realm/sorted :timestamp :desc) - (realm/filtered (str "group-chat = true && is-active = " - (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 [chat-id] (realm/get-one-by-field @realm/account-realm :chat :chat-id chat-id)) @@ -72,7 +50,7 @@ (fn [] (doto chat (aset "is-active" false) - (aset "removed-at" (datetime/timestamp))))))) + (aset "removed-at" (datetime/timestamp))))))) (defn add-contacts [chat-id identities] diff --git a/src/status_im/transport/message/v1/group_chat.cljs b/src/status_im/transport/message/v1/group_chat.cljs index 8f67bad9e9..5992d0fc09 100644 --- a/src/status_im/transport/message/v1/group_chat.cljs +++ b/src/status_im/transport/message/v1/group_chat.cljs @@ -94,9 +94,9 @@ (if (removed me) ;; we were removed (handlers/merge-fx cofx (models.message/receive - (models.message/system-message chat-id random-id now - (str admin-name " " (i18n/label :t/removed-from-chat)))) - (models.chat/update-chat {:chat-id chat-id + (models.message/system-message chat-id random-id now + (str admin-name " " (i18n/label :t/removed-from-chat)))) + (models.chat/upsert-chat {:chat-id chat-id :removed-from-at now :is-active false}) (transport/unsubscribe-from-chat chat-id)) diff --git a/src/status_im/transport/message/v1/public_chat.cljs b/src/status_im/transport/message/v1/public_chat.cljs index f5c13120b1..723a694ea5 100644 --- a/src/status_im/transport/message/v1/public_chat.cljs +++ b/src/status_im/transport/message/v1/public_chat.cljs @@ -6,18 +6,22 @@ [status-im.transport.message.v1.protocol :as protocol] [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 "Function producing all protocol level effects necessary for joining public chat identified by chat-id" [chat-id {:keys [db] :as cofx}] - (let [on-success (fn [sym-key sym-key-id] - (re-frame/dispatch [::add-new-sym-key {:chat-id chat-id - :sym-key sym-key - :sym-key-id sym-key-id}]))] - (handlers/merge-fx cofx - {:shh/generate-sym-key-from-password {:web3 (:web3 db) - :password chat-id - :on-success on-success}} - (protocol/init-chat chat-id)))) + (when-not (has-already-joined? chat-id cofx) + (let [on-success (fn [sym-key sym-key-id] + (re-frame/dispatch [::add-new-sym-key {:chat-id chat-id + :sym-key sym-key + :sym-key-id sym-key-id}]))] + (handlers/merge-fx cofx + {:shh/generate-sym-key-from-password {:web3 (:web3 db) + :password chat-id + :on-success on-success}} + (protocol/init-chat chat-id))))) (handlers/register-handler-fx ::add-new-sym-key diff --git a/src/status_im/ui/screens/contacts/core.cljs b/src/status_im/ui/screens/contacts/core.cljs index 3b07526421..10bb6f6091 100644 --- a/src/status_im/ui/screens/contacts/core.cljs +++ b/src/status_im/ui/screens/contacts/core.cljs @@ -22,7 +22,7 @@ (handlers/merge-fx cofx {:db (update-in db [:contacts/contacts public-key] merge 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 [public-key {:keys [name profile-image address fcm-token]} @@ -59,6 +59,6 @@ (if (chats public-key) (handlers/merge-fx cofx (update-contact contact) - (chat.models/update-chat {:chat-id chat-id + (chat.models/upsert-chat {:chat-id chat-id :name name})) (update-contact contact cofx)))))))) diff --git a/src/status_im/ui/screens/contacts/events.cljs b/src/status_im/ui/screens/contacts/events.cljs index b23f36a529..33939ec064 100644 --- a/src/status_im/ui/screens/contacts/events.cljs +++ b/src/status_im/ui/screens/contacts/events.cljs @@ -80,7 +80,7 @@ (handlers/register-handler-fx :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]] (let [current-account (get accounts current-account-id) fx {:db (assoc db :contacts/new-identity contact-identity)}] @@ -125,7 +125,7 @@ (handlers/register-handler-fx :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} _] (when (seq new-identity) (add-contact-and-open-chat new-identity cofx)))) diff --git a/src/status_im/ui/screens/db.cljs b/src/status_im/ui/screens/db.cljs index a61f35bce6..196f7a9952 100644 --- a/src/status_im/ui/screens/db.cljs +++ b/src/status_im/ui/screens/db.cljs @@ -195,7 +195,6 @@ :qr/qr-modal :qr/current-qr-context :chat/chats - :chat/deleted-chats :chat/current-chat-id :chat/chat-id :chat/new-chat diff --git a/src/status_im/ui/screens/events.cljs b/src/status_im/ui/screens/events.cljs index a16db5ceb3..93b3f2cfe6 100644 --- a/src/status_im/ui/screens/events.cljs +++ b/src/status_im/ui/screens/events.cljs @@ -81,9 +81,7 @@ (re-frame/reg-cofx :random-id-seq (fn [coeffects _] - (assoc coeffects :random-id-seq - ((fn rand-id-seq [] - (cons (random/id) (lazy-seq (rand-id-seq)))))))) + (assoc coeffects :random-id-seq (repeatedly random/id)))) ;;;; FX diff --git a/src/status_im/ui/screens/profile/events.cljs b/src/status_im/ui/screens/profile/events.cljs index 42e0e2c8c5..3244a6939f 100644 --- a/src/status_im/ui/screens/profile/events.cljs +++ b/src/status_im/ui/screens/profile/events.cljs @@ -27,7 +27,7 @@ (handlers/register-handler-fx :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]] (let [send-command (get-in contacts chat-const/send-command-ref)] (handlers/merge-fx cofx diff --git a/test/cljs/status_im/test/accounts/events.cljs b/test/cljs/status_im/test/accounts/events.cljs index 5bf9515e8d..5aa934c5dd 100644 --- a/test/cljs/status_im/test/accounts/events.cljs +++ b/test/cljs/status_im/test/accounts/events.cljs @@ -23,7 +23,6 @@ :status "be the hero of your own journey" :network constants/default-network :networks constants/default-networks - :wnode constants/default-wnode :public-key "0x049b3a8c04f2c5bccda91c1f5e6434ae72957e93a31c0301b4563eda1d6ce419f63c503ebaee143115f96c1f04f232a7a22ca0454e9ee3d579ad1f870315b151d0"}) (def new-account @@ -34,7 +33,6 @@ :status "the future starts today, not tomorrow" :network constants/default-network :networks constants/default-networks - :wnode constants/default-wnode :signing-phrase "long loan limo" :public-key "0x04f5722fba79eb36d73263417531007f43d13af76c6233573a8e3e60f667710611feba0785d751b50609bfc0b7cef35448875c5392c0a91948c95798a0ce600847"}) diff --git a/test/cljs/status_im/test/chat/models.cljs b/test/cljs/status_im/test/chat/models.cljs new file mode 100644 index 0000000000..cd27d2ded5 --- /dev/null +++ b/test/cljs/status_im/test/chat/models.cljs @@ -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))))) diff --git a/test/cljs/status_im/test/chat/models/message.cljs b/test/cljs/status_im/test/chat/models/message.cljs new file mode 100644 index 0000000000..4c64331348 --- /dev/null +++ b/test/cljs/status_im/test/chat/models/message.cljs @@ -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"}))))) diff --git a/test/cljs/status_im/test/chat/subs.cljs b/test/cljs/status_im/test/chat/subs.cljs index 18b9422573..791096632a 100644 --- a/test/cljs/status_im/test/chat/subs.cljs +++ b/test/cljs/status_im/test/chat/subs.cljs @@ -1,5 +1,6 @@ (ns status-im.test.chat.subs (:require [cljs.test :refer-macros [deftest is testing]] + [status-im.constants :as const] [status-im.chat.subs :as s])) (deftest test-message-datemark-groups @@ -134,3 +135,21 @@ (is (:last-in-group? actual-m2)) (is (:last-in-group? actual-m3)) (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}])))))) diff --git a/test/cljs/status_im/test/runner.cljs b/test/cljs/status_im/test/runner.cljs index c4264a872b..8a7b3ea451 100644 --- a/test/cljs/status_im/test/runner.cljs +++ b/test/cljs/status_im/test/runner.cljs @@ -8,7 +8,9 @@ [status-im.test.wallet.transactions.views] [status-im.test.profile.events] [status-im.test.bots.events] + [status-im.test.chat.models] [status-im.test.chat.models.input] + [status-im.test.chat.models.message] [status-im.test.chat.subs] [status-im.test.chat.views.message] [status-im.test.i18n] @@ -39,6 +41,7 @@ 'status-im.test.utils.async 'status-im.test.chat.events 'status-im.test.chat.subs + 'status-im.test.chat.models 'status-im.test.accounts.events 'status-im.test.contacts.events 'status-im.test.profile.events @@ -47,6 +50,7 @@ 'status-im.test.wallet.transactions.subs 'status-im.test.wallet.transactions.views 'status-im.test.chat.models.input + 'status-im.test.chat.models.message 'status-im.test.chat.views.message 'status-im.test.i18n 'status-im.test.protocol.web3.inbox