Proceed with move from side-effect to functional
This commit is contained in:
parent
e9cf3db400
commit
d39357996b
|
@ -2,6 +2,7 @@
|
|||
(:require [re-frame.core :as re-frame]
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.utils.handlers :as handlers]
|
||||
[status-im.utils.gfycat.core :as gfycat]
|
||||
[status-im.chat.models :as model]
|
||||
[status-im.chat.models.unviewed-messages :as unviewed-messages-model]
|
||||
[status-im.chat.sign-up :as sign-up]
|
||||
|
@ -10,6 +11,7 @@
|
|||
[status-im.data-store.messages :as msg-store]
|
||||
[status-im.data-store.contacts :as contacts-store]
|
||||
[status-im.data-store.chats :as chats-store]
|
||||
[status-im.ui.screens.navigation :as navigation]
|
||||
[status-im.protocol.core :as protocol]
|
||||
[status-im.constants :as const]
|
||||
[status-im.components.list-selection :as list-selection]
|
||||
|
@ -23,34 +25,44 @@
|
|||
;;;; Coeffects
|
||||
|
||||
(re-frame/reg-cofx
|
||||
:stored-unviewed-messages
|
||||
(fn [cofx _]
|
||||
(assoc cofx :stored-unviewed-messages (msg-store/get-unviewed))))
|
||||
:stored-unviewed-messages
|
||||
(fn [cofx _]
|
||||
(assoc cofx :stored-unviewed-messages (msg-store/get-unviewed))))
|
||||
|
||||
(re-frame/reg-cofx
|
||||
:get-stored-message
|
||||
(fn [cofx _]
|
||||
(assoc cofx :get-stored-message msg-store/get-by-id)))
|
||||
:get-stored-message
|
||||
(fn [cofx _]
|
||||
(assoc cofx :get-stored-message msg-store/get-by-id)))
|
||||
|
||||
(re-frame/reg-cofx
|
||||
:get-stored-messages
|
||||
(fn [cofx _]
|
||||
(assoc cofx :get-stored-messages msg-store/get-by-chat-id)))
|
||||
:get-stored-messages
|
||||
(fn [cofx _]
|
||||
(assoc cofx :get-stored-messages msg-store/get-by-chat-id)))
|
||||
|
||||
(re-frame/reg-cofx
|
||||
:get-last-stored-message
|
||||
(fn [cofx _]
|
||||
(assoc cofx :get-last-stored-message msg-store/get-last-message)))
|
||||
:get-last-stored-message
|
||||
(fn [cofx _]
|
||||
(assoc cofx :get-last-stored-message msg-store/get-last-message)))
|
||||
|
||||
(re-frame/reg-cofx
|
||||
:get-message-previews
|
||||
(fn [cofx _]
|
||||
(assoc cofx :message-previews (msg-store/get-previews))))
|
||||
:get-message-previews
|
||||
(fn [cofx _]
|
||||
(assoc cofx :message-previews (msg-store/get-previews))))
|
||||
|
||||
(re-frame/reg-cofx
|
||||
:all-stored-chats
|
||||
(fn [cofx _]
|
||||
(assoc cofx :all-stored-chats (chats-store/get-all))))
|
||||
:all-stored-chats
|
||||
(fn [cofx _]
|
||||
(assoc cofx :all-stored-chats (chats-store/get-all))))
|
||||
|
||||
(re-frame/reg-cofx
|
||||
:get-stored-chat
|
||||
(fn [cofx _]
|
||||
(assoc cofx :get-stored-chat chats-store/get-by-id)))
|
||||
|
||||
(re-frame/reg-cofx
|
||||
:gfy-generator
|
||||
(fn [cofx _]
|
||||
(assoc cofx :gfy-generator gfycat/generate-gfy)))
|
||||
|
||||
;;;; Effects
|
||||
|
||||
|
@ -84,26 +96,6 @@
|
|||
(fn [[command link]]
|
||||
(list-selection/browse command link)))
|
||||
|
||||
;;;; Helper fns
|
||||
|
||||
(defn init-console-chat
|
||||
[{:keys [chats] :accounts/keys [current-account-id] :as db} existing-account?]
|
||||
(if (get chats const/console-chat-id)
|
||||
{:db db}
|
||||
(cond-> {:db (-> db
|
||||
(assoc :new-chat sign-up/console-chat)
|
||||
(update :chats assoc const/console-chat-id sign-up/console-chat)
|
||||
(assoc :current-chat-id const/console-chat-id))
|
||||
:dispatch-n [[:add-contacts [sign-up/console-contact]]]
|
||||
:save-chat sign-up/console-chat
|
||||
:save-all-contacts [sign-up/console-contact]}
|
||||
|
||||
(not current-account-id)
|
||||
(update :dispatch-n concat sign-up/intro-events)
|
||||
|
||||
existing-account?
|
||||
(update :dispatch-n concat sign-up/start-signup-events))))
|
||||
|
||||
;;;; Handlers
|
||||
|
||||
(handlers/register-handler-db
|
||||
|
@ -165,6 +157,24 @@
|
|||
message))
|
||||
messages)))))
|
||||
|
||||
(defn- init-console-chat
|
||||
[{:keys [chats] :accounts/keys [current-account-id] :as db} existing-account?]
|
||||
(if (chats const/console-chat-id)
|
||||
{:db db}
|
||||
(cond-> {:db (-> db
|
||||
(assoc :new-chat sign-up/console-chat
|
||||
:current-chat-id const/console-chat-id)
|
||||
(update :chats assoc const/console-chat-id sign-up/console-chat))
|
||||
:dispatch-n [[:add-contacts [sign-up/console-contact]]]
|
||||
:save-chat sign-up/console-chat
|
||||
:save-all-contacts [sign-up/console-contact]}
|
||||
|
||||
(not current-account-id)
|
||||
(update :dispatch-n concat sign-up/intro-events)
|
||||
|
||||
existing-account?
|
||||
(update :dispatch-n concat sign-up/start-signup-events))))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:init-console-chat
|
||||
(fn [{:keys [db]} _]
|
||||
|
@ -248,17 +258,116 @@
|
|||
(fn [{:keys [get-stored-message]} _]
|
||||
(when-not (get-stored-message chat-const/move-to-internal-failure-message-id)
|
||||
{:dispatch sign-up/move-to-internal-failure-event})))
|
||||
(comment
|
||||
(handlers/register-handler-fx
|
||||
:init-chat
|
||||
[(re-frame/inject-cofx :get-stored-messages)]
|
||||
(fn [{:keys [db get-stored-messages]} _]
|
||||
(let [current-chat-id (:current-chat-id db)]
|
||||
{:db (assoc-in [:chats current-chat-id :messages] (get-stored-messages current-chat-id))
|
||||
;; TODO(janherich): make this dispatch into fn call once commands loading is refactored
|
||||
:dispatch [:load-commands! current-chat-id]}))))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:browse-link-from-message
|
||||
(fn [{{:keys [global-commands]} :db} [_ link]]
|
||||
{:browse [(:browse global-commands) link]}))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:init-chat
|
||||
[(re-frame/inject-cofx :get-stored-messages)]
|
||||
(fn [{:keys [db get-stored-messages]} _]
|
||||
(let [current-chat-id (:current-chat-id db)]
|
||||
{:db (assoc-in db [:chats current-chat-id :messages] (get-stored-messages current-chat-id))
|
||||
;; TODO(janherich): make this dispatch into fn call once commands loading is refactored
|
||||
:dispatch [:load-commands! current-chat-id]})))
|
||||
|
||||
(defn- jail-init-callback
|
||||
[{:keys [db] :as fx} chat-id]
|
||||
(let [bot-url (get-in db [:contacts/contacts chat-id :bot-url])
|
||||
was-opened? (get-in db [:chats chat-id :was-opened?])]
|
||||
(if (and (not was-opened?) bot-url)
|
||||
(assoc fx :call-jail-function {:chat-id chat-id
|
||||
:function :init
|
||||
:context {:from (:accounts/current-account-id db)}})
|
||||
fx)))
|
||||
|
||||
(defn preload-chat-data
|
||||
"Takes coeffects map and chat-id, returns effects necessary when navigating to chat"
|
||||
[{:keys [db get-stored-messages]} chat-id]
|
||||
(let [messages (get-in db [:chats chat-id :messages])
|
||||
chat-loaded-event (get-in db [:chats chat-id :chat-loaded-event])
|
||||
commands-loaded? (get-in db [:contacts/contacts chat-id :commands-loaded?])]
|
||||
(cond-> {:db (-> db
|
||||
(assoc :current-chat-id chat-id)
|
||||
(assoc-in [:chats chat-id :was-opened?] true)
|
||||
(model/set-chat-ui-props {:validation-messages nil})
|
||||
(update-in [:chats chat-id] dissoc :chat-loaded-event))
|
||||
:dispatch-n [[:load-requests! chat-id]]}
|
||||
(not commands-loaded?)
|
||||
(update :dispatch-n conj [:load-commands! chat-id #(re-frame/dispatch [::jail-init-callback chat-id])])
|
||||
|
||||
commands-loaded?
|
||||
(jail-init-callback chat-id)
|
||||
;; TODO(janherich): what's the purpose of the second term in AND ?
|
||||
(and (seq messages)
|
||||
(not= (count messages) 1))
|
||||
(assoc-in [:db :chats chat-id :messages] (get-stored-messages chat-id))
|
||||
|
||||
chat-loaded-event
|
||||
(update :dispatch-n conj chat-loaded-event))))
|
||||
|
||||
(handlers/register-handler-db
|
||||
:add-chat-loaded-event
|
||||
[re-frame/trim-v]
|
||||
(fn [db [chat-id event]]
|
||||
(assoc-in db [:chats chat-id :chat-loaded-event] event)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
::jail-init-callback
|
||||
[re-frame/trim-v]
|
||||
(fn [{:keys [db]} [chat-id]]
|
||||
(jail-init-callback {:db db} chat-id)))
|
||||
|
||||
;; 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 :gfy-generator) re-frame/trim-v]
|
||||
(fn [cofx [chat-id]]
|
||||
(model/add-chat cofx chat-id)))
|
||||
|
||||
(defn- navigate-to-chat
|
||||
[cofx chat-id navigation-replace?]
|
||||
(let [nav-fn (if navigation-replace?
|
||||
#(navigation/navigate-to % :chat)
|
||||
#(navigation/replace-view % :chat))]
|
||||
(-> cofx
|
||||
(preload-chat-data chat-id)
|
||||
(update :db nav-fn))))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:navigate-to-chat
|
||||
[(re-frame/inject-cofx :get-stored-messages) re-frame/trim-v]
|
||||
(fn [cofx [chat-id {:keys [navigation-replace?]}]]
|
||||
(navigate-to-chat cofx chat-id navigation-replace?)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:start-chat
|
||||
[(re-frame/inject-cofx :gfy-generator)
|
||||
(re-frame/inject-cofx :get-stored-messages)
|
||||
re-frame/trim-v]
|
||||
(fn [{:keys [db] :as cofx} [contact-id {:keys [navigation-replace?]}]]
|
||||
(when (not= (:current-public-key db) contact-id) ; don't allow to open chat with yourself
|
||||
(if (get (:chats db) contact-id)
|
||||
(navigate-to-chat cofx contact-id navigation-replace?) ; existing chat, just preload and displey
|
||||
(let [add-chat-fx (model/add-chat cofx contact-id)] ; new chat, create before preload & display
|
||||
(merge add-chat-fx
|
||||
(navigate-to-chat (assoc cofx :db (:db add-chat-fx))
|
||||
contact-id
|
||||
navigation-replace?)))))))
|
||||
|
||||
;; TODO(janherich): remove this unnecessary event in the future (only model function `update-chat` will stay)
|
||||
(handlers/register-handler-fx
|
||||
:update-chat!
|
||||
[(re-frame/inject-cofx :get-stored-chat) re-frame/trim-v]
|
||||
(fn [cofx [chat]]
|
||||
(model/update-chat cofx chat)))
|
||||
|
||||
;; TODO(janherich): remove this unnecessary event in the future (only model function `upsert-chat` will stay)
|
||||
(handlers/register-handler-fx
|
||||
:upsert-chat!
|
||||
[(re-frame/inject-cofx :get-stored-chat) re-frame/trim-v]
|
||||
(fn [cofx [chat]]
|
||||
(model/upsert-chat cofx chat)))
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
[status-im.utils.clocks :as clocks]
|
||||
[status-im.constants :as const]
|
||||
[status-im.chat.utils :as chat-utils]
|
||||
[status-im.chat.models :as model]
|
||||
[status-im.chat.models.unviewed-messages :as unviewed-messages-model]
|
||||
[status-im.data-store.chats :as chat-store]
|
||||
[status-im.data-store.messages :as msg-store]))
|
||||
|
@ -33,7 +34,7 @@
|
|||
|
||||
(defn add-message
|
||||
[{:keys [db message-exists? get-last-stored-message pop-up-chat?
|
||||
get-last-clock-value now random-id]}
|
||||
get-last-clock-value now random-id] :as cofx}
|
||||
{:keys [from group-id chat-id content-type
|
||||
message-id timestamp clock-value]
|
||||
:as message
|
||||
|
@ -54,16 +55,17 @@
|
|||
:timestamp (or timestamp now)
|
||||
:clock-value (clocks/receive
|
||||
clock-value
|
||||
(get-last-clock-value chat-identifier)))]
|
||||
(cond-> {:db (-> db
|
||||
(chat-utils/add-message-to-db chat-identifier chat-identifier enriched-message
|
||||
(:new? enriched-message))
|
||||
(unviewed-messages-model/add-unviewed-message chat-identifier message-id)
|
||||
(assoc-in [:chats chat-identifier :last-message] message))
|
||||
:dispatch-n [[:upsert-chat! {:chat-id chat-identifier
|
||||
:group-chat group-chat?}]
|
||||
[:request-command-message-data enriched-message :short-preview]]
|
||||
:save-message (dissoc enriched-message :new?)}
|
||||
(get-last-clock-value chat-identifier)))
|
||||
fx (model/upsert-chat cofx {:chat-id chat-identifier
|
||||
:group-chat group-chat?})]
|
||||
(cond-> (-> fx
|
||||
(update :db #(-> %
|
||||
(chat-utils/add-message-to-db chat-identifier chat-identifier enriched-message
|
||||
(:new? enriched-message))
|
||||
(unviewed-messages-model/add-unviewed-message chat-identifier message-id)
|
||||
(assoc-in [:chats chat-identifier :last-message] message)))
|
||||
(assoc :dispatch-n [[:request-command-message-data enriched-message :short-preview]]
|
||||
:save-message (dissoc enriched-message :new?)))
|
||||
|
||||
(get-in enriched-message [:content :command])
|
||||
(update :dispatch-n conj [:request-command-preview enriched-message])
|
||||
|
@ -78,7 +80,7 @@
|
|||
(def ^:private receive-interceptors
|
||||
[(re-frame/inject-cofx :message-exists?) (re-frame/inject-cofx :get-last-stored-message)
|
||||
(re-frame/inject-cofx :pop-up-chat?) (re-frame/inject-cofx :get-last-clock-value)
|
||||
(re-frame/inject-cofx :random-id) re-frame/trim-v])
|
||||
(re-frame/inject-cofx :random-id) (re-frame/inject-cofx :get-stored-chat) re-frame/trim-v])
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:received-protocol-message!
|
||||
|
|
|
@ -1,186 +1,24 @@
|
|||
(ns status-im.chat.handlers
|
||||
(:require-macros [cljs.core.async.macros :as am])
|
||||
(:require [re-frame.core :refer [enrich after debug dispatch reg-fx]]
|
||||
[cljs.core.async :as a]
|
||||
[clojure.string :as string]
|
||||
[status-im.components.styles :refer [default-chat-color]]
|
||||
[status-im.chat.constants :as chat-const]
|
||||
[status-im.components.styles :refer [default-chat-color]]
|
||||
[status-im.chat.constants :as chat-consts]
|
||||
[status-im.protocol.core :as protocol]
|
||||
[status-im.data-store.chats :as chats]
|
||||
[status-im.data-store.contacts :as contacts]
|
||||
[status-im.data-store.chats :as chats]
|
||||
[status-im.data-store.messages :as messages]
|
||||
[status-im.data-store.pending-messages :as pending-messages]
|
||||
[status-im.constants :refer [text-content-type
|
||||
content-type-command
|
||||
content-type-command-request
|
||||
console-chat-id]]
|
||||
[status-im.utils.random :as random]
|
||||
[status-im.chat.sign-up :as sign-up-service]
|
||||
[status-im.ui.screens.navigation :as nav]
|
||||
[status-im.utils.handlers :refer [register-handler register-handler-fx] :as u]
|
||||
[status-im.utils.phone-number :refer [format-phone-number
|
||||
valid-mobile-number?]]
|
||||
[status-im.native-module.core :as status]
|
||||
[status-im.utils.types :refer [json->clj]]
|
||||
[status-im.chat.utils :refer [console? not-console? safe-trim]]
|
||||
[status-im.utils.gfycat.core :refer [generate-gfy]]
|
||||
[status-im.utils.random :as random]
|
||||
[status-im.utils.handlers :refer [register-handler register-handler-fx] :as u]
|
||||
status-im.chat.events
|
||||
status-im.chat.handlers.requests
|
||||
status-im.chat.handlers.send-message
|
||||
[cljs.core.async :as a]
|
||||
status-im.chat.handlers.webview-bridge
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(defn load-messages!
|
||||
([db] (load-messages! db nil))
|
||||
([{:keys [current-chat-id] :as db} _]
|
||||
(let [messages (messages/get-by-chat-id current-chat-id)]
|
||||
(assoc db :messages messages))))
|
||||
|
||||
(defn init-chat
|
||||
([db] (init-chat db nil))
|
||||
([{:keys [messages current-chat-id] :as db} _]
|
||||
(-> db
|
||||
(assoc-in [:chats current-chat-id :messages] messages)
|
||||
(dissoc :messages))))
|
||||
|
||||
(defn load-commands!
|
||||
[{:keys [current-chat-id]} _]
|
||||
(dispatch [:load-commands! current-chat-id]))
|
||||
|
||||
(register-handler :init-chat
|
||||
(after #(dispatch [:load-requests!]))
|
||||
|
||||
(u/handlers->
|
||||
load-messages!
|
||||
init-chat
|
||||
load-commands!))
|
||||
|
||||
(defmethod nav/preload-data! :chat
|
||||
[{:keys [current-chat-id] :accounts/keys [current-account-id] :as db} [_ _ id]]
|
||||
(let [chat-id (or id current-chat-id)
|
||||
messages (get-in db [:chats chat-id :messages])
|
||||
db' (-> db
|
||||
(assoc :current-chat-id chat-id)
|
||||
(assoc-in [:chats chat-id :was-opened?] true))
|
||||
commands-loaded? (get-in db [:contacts/contacts chat-id :commands-loaded?])
|
||||
bot-url (get-in db [:contacts/contacts chat-id :bot-url])
|
||||
was-opened? (get-in db [:chats chat-id :was-opened?])
|
||||
call-init-command #(do
|
||||
(dispatch [:invoke-chat-loaded-callbacks chat-id])
|
||||
(when (and (not was-opened?) bot-url)
|
||||
(status/call-function!
|
||||
{:chat-id chat-id
|
||||
:function :init
|
||||
:context {:from current-account-id}})))]
|
||||
; Reset validation messages, if any
|
||||
(dispatch [:set-chat-ui-props {:validation-messages nil}])
|
||||
(dispatch [:load-requests! chat-id])
|
||||
;; todo rewrite this. temporary fix for https://github.com/status-im/status-react/issues/607
|
||||
#_(dispatch [:load-commands! chat-id])
|
||||
(if-not commands-loaded?
|
||||
(dispatch [:load-commands! chat-id call-init-command])
|
||||
(call-init-command))
|
||||
(if (and (seq messages)
|
||||
(not= (count messages) 1))
|
||||
db'
|
||||
(-> db'
|
||||
load-messages!
|
||||
init-chat))))
|
||||
|
||||
(register-handler :add-chat-loaded-callback
|
||||
(fn [db [_ chat-id callback]]
|
||||
(log/debug "Add chat loaded callback: " chat-id callback)
|
||||
(update-in db [:chat-loaded-callbacks chat-id] conj callback)))
|
||||
|
||||
(register-handler ::clear-chat-loaded-callbacks
|
||||
(fn [db [_ chat-id]]
|
||||
(log/debug "Clear chat loaded callback: " chat-id)
|
||||
(assoc-in db [:chat-loaded-callbacks chat-id] nil)))
|
||||
|
||||
(register-handler :invoke-chat-loaded-callbacks
|
||||
(u/side-effect!
|
||||
(fn [db [_ chat-id]]
|
||||
(log/debug "Invoking chat loaded callbacks: " chat-id)
|
||||
(let [callbacks (get-in db [:chat-loaded-callbacks chat-id])]
|
||||
(log/debug "Invoking chat loaded callbacks: " callbacks)
|
||||
(doseq [callback callbacks]
|
||||
(callback))
|
||||
(dispatch [::clear-chat-loaded-callbacks chat-id])))))
|
||||
|
||||
(defn prepare-chat [{:contacts/keys [contacts]} chat-id chat]
|
||||
(let [name (get-in contacts [chat-id :name])
|
||||
whisper-identity (get-in contacts [chat-id :whisper-identity])]
|
||||
(merge {:chat-id chat-id
|
||||
:name (or name (generate-gfy whisper-identity))
|
||||
:color default-chat-color
|
||||
:group-chat false
|
||||
:is-active true
|
||||
:timestamp (.getTime (js/Date.))
|
||||
:contacts [{:identity chat-id}]}
|
||||
chat)))
|
||||
|
||||
(defn add-new-chat
|
||||
[db [_ chat-id chat]]
|
||||
(assoc db :new-chat (prepare-chat db chat-id chat)))
|
||||
|
||||
(defn add-chat [{:keys [new-chat chats] :as db} [_ chat-id]]
|
||||
(if-not (get chats chat-id)
|
||||
(update db :chats assoc chat-id new-chat)
|
||||
db))
|
||||
|
||||
(defn save-new-chat!
|
||||
[{{:keys [chat-id] :as new-chat} :new-chat} _]
|
||||
(when-not (chats/exists? chat-id)
|
||||
(chats/save new-chat)))
|
||||
|
||||
(defn open-chat!
|
||||
[_ [_ chat-id _ navigation-type]]
|
||||
(dispatch [(or navigation-type :navigate-to) :chat chat-id]))
|
||||
|
||||
(register-handler ::start-chat!
|
||||
(u/handlers->
|
||||
add-new-chat
|
||||
add-chat
|
||||
save-new-chat!
|
||||
open-chat!))
|
||||
|
||||
(register-handler :start-chat
|
||||
(u/side-effect!
|
||||
(fn [{:keys [chats current-public-key]}
|
||||
[_ contact-id options navigation-type]]
|
||||
(when-not (= current-public-key contact-id)
|
||||
(if (chats contact-id)
|
||||
(dispatch [(or navigation-type :navigate-to) :chat contact-id])
|
||||
(dispatch [::start-chat! contact-id options navigation-type]))))))
|
||||
|
||||
(register-handler :add-chat
|
||||
(u/handlers->
|
||||
add-new-chat
|
||||
add-chat
|
||||
save-new-chat!))
|
||||
|
||||
(defn update-chat!
|
||||
[_ [_ {:keys [name] :as chat}]]
|
||||
(let [chat' (if name chat (dissoc chat :name))]
|
||||
(chats/save chat')))
|
||||
|
||||
(register-handler :update-chat!
|
||||
(after update-chat!)
|
||||
(fn [db [_ {:keys [chat-id name] :as chat}]]
|
||||
(let [chat' (if name chat (dissoc chat :name))]
|
||||
(if (get-in db [:chats chat-id])
|
||||
(update-in db [:chats chat-id] merge chat')
|
||||
db))))
|
||||
|
||||
(register-handler :upsert-chat!
|
||||
(fn [db [_ {:keys [chat-id] :as opts}]]
|
||||
(let [chat (if (chats/exists? chat-id)
|
||||
(-> (chats/get-by-id chat-id)
|
||||
(assoc :timestamp (random/timestamp))
|
||||
(merge opts))
|
||||
(prepare-chat db chat-id opts))]
|
||||
(chats/save chat)
|
||||
(update-in db [:chats chat-id] merge chat))))
|
||||
status-im.chat.handlers.send-message
|
||||
status-im.chat.handlers.webview-bridge))
|
||||
|
||||
(defn remove-chat
|
||||
[db [_ chat-id]]
|
||||
|
@ -207,33 +45,36 @@
|
|||
[_ [_ chat-id]]
|
||||
(pending-messages/delete-all-by-chat-id chat-id))
|
||||
|
||||
(register-handler :leave-group-chat
|
||||
;; todo oreder of operations tbd
|
||||
(register-handler
|
||||
:leave-group-chat
|
||||
;; todo order of operations tbd
|
||||
(after (fn [_ _] (dispatch [:navigation-replace :chat-list])))
|
||||
(u/side-effect!
|
||||
(fn [{:keys [web3 current-chat-id chats current-public-key]} _]
|
||||
(let [{:keys [public-key private-key public?]} (chats current-chat-id)]
|
||||
(protocol/stop-watching-group!
|
||||
(fn [{:keys [web3 current-chat-id chats current-public-key]} _]
|
||||
(let [{:keys [public-key private-key public?]} (chats current-chat-id)]
|
||||
(protocol/stop-watching-group!
|
||||
{:web3 web3
|
||||
:group-id current-chat-id})
|
||||
(when-not public?
|
||||
(protocol/leave-group-chat!
|
||||
{:web3 web3
|
||||
:group-id current-chat-id})
|
||||
(when-not public?
|
||||
(protocol/leave-group-chat!
|
||||
{:web3 web3
|
||||
:group-id current-chat-id
|
||||
:keypair {:public public-key
|
||||
:private private-key}
|
||||
:message {:from current-public-key
|
||||
:message-id (random/id)}})))
|
||||
(dispatch [:remove-chat current-chat-id]))))
|
||||
:group-id current-chat-id
|
||||
:keypair {:public public-key
|
||||
:private private-key}
|
||||
:message {:from current-public-key
|
||||
:message-id (random/id)}})))
|
||||
(dispatch [:remove-chat current-chat-id]))))
|
||||
|
||||
(register-handler :remove-chat
|
||||
(register-handler
|
||||
:remove-chat
|
||||
(u/handlers->
|
||||
remove-chat
|
||||
delete-messages!
|
||||
remove-pending-messages!
|
||||
delete-chat!))
|
||||
remove-chat
|
||||
delete-messages!
|
||||
remove-pending-messages!
|
||||
delete-chat!))
|
||||
|
||||
(register-handler :check-and-open-dapp!
|
||||
(register-handler
|
||||
:check-and-open-dapp!
|
||||
(u/side-effect!
|
||||
(fn [{:keys [current-chat-id global-commands]
|
||||
:contacts/keys [contacts]}]
|
||||
|
@ -249,33 +90,34 @@
|
|||
|
||||
(register-handler :update-group-message
|
||||
(u/side-effect!
|
||||
(fn [{:keys [current-public-key web3 chats]}
|
||||
[_ {:keys [from]
|
||||
{:keys [group-id keypair timestamp]} :payload}]]
|
||||
(let [{:keys [private public]} keypair]
|
||||
(let [is-active (chats/is-active? group-id)
|
||||
chat {:chat-id group-id
|
||||
:public-key public
|
||||
:private-key private
|
||||
:updated-at timestamp}]
|
||||
(when (and (= from (get-in chats [group-id :group-admin]))
|
||||
(or (not (chats/exists? group-id))
|
||||
(chats/new-update? timestamp group-id)))
|
||||
(dispatch [:update-chat! chat])
|
||||
(when is-active
|
||||
(protocol/start-watching-group!
|
||||
{:web3 web3
|
||||
:group-id group-id
|
||||
:identity current-public-key
|
||||
:keypair keypair
|
||||
:callback #(dispatch [:incoming-message %1 %2])}))))))))
|
||||
(fn [{:keys [current-public-key web3 chats]}
|
||||
[_ {:keys [from]
|
||||
{:keys [group-id keypair timestamp]} :payload}]]
|
||||
(let [{:keys [private public]} keypair]
|
||||
(let [is-active (chats/is-active? group-id)
|
||||
chat {:chat-id group-id
|
||||
:public-key public
|
||||
:private-key private
|
||||
:updated-at timestamp}]
|
||||
(when (and (= from (get-in chats [group-id :group-admin]))
|
||||
(or (not (chats/exists? group-id))
|
||||
(chats/new-update? timestamp group-id)))
|
||||
(dispatch [:update-chat! chat])
|
||||
(when is-active
|
||||
(protocol/start-watching-group!
|
||||
{:web3 web3
|
||||
:group-id group-id
|
||||
:identity current-public-key
|
||||
:keypair keypair
|
||||
:callback #(dispatch [:incoming-message %1 %2])}))))))))
|
||||
|
||||
(register-handler :update-message-overhead!
|
||||
(register-handler
|
||||
:update-message-overhead!
|
||||
(u/side-effect!
|
||||
(fn [_ [_ chat-id network-status]]
|
||||
(if (= network-status :offline)
|
||||
(chats/inc-message-overhead chat-id)
|
||||
(chats/reset-message-overhead chat-id)))))
|
||||
(fn [_ [_ chat-id network-status]]
|
||||
(if (= network-status :offline)
|
||||
(chats/inc-message-overhead chat-id)
|
||||
(chats/reset-message-overhead chat-id)))))
|
||||
|
||||
(reg-fx
|
||||
::save-public-chat
|
||||
|
@ -286,11 +128,11 @@
|
|||
::start-watching-group
|
||||
(fn [{:keys [group-id web3 current-public-key keypair]}]
|
||||
(protocol/start-watching-group!
|
||||
{:web3 web3
|
||||
:group-id group-id
|
||||
:identity current-public-key
|
||||
:keypair keypair
|
||||
:callback #(dispatch [:incoming-message %1 %2])})))
|
||||
{:web3 web3
|
||||
:group-id group-id
|
||||
:identity current-public-key
|
||||
:keypair keypair
|
||||
:callback #(dispatch [:incoming-message %1 %2])})))
|
||||
|
||||
(register-handler-fx
|
||||
:create-new-public-chat
|
||||
|
@ -304,13 +146,13 @@
|
|||
:is-active true
|
||||
:timestamp (random/timestamp)}]
|
||||
(merge
|
||||
(when-not exists?
|
||||
{:db (assoc-in db [:chats (:chat-id chat)] chat)
|
||||
::save-public-chat chat
|
||||
::start-watching-group (merge {:group-id topic}
|
||||
(select-keys db [:web3 :current-public-key]))})
|
||||
{:dispatch-n [[:navigate-to-clean :chat-list]
|
||||
[:navigate-to :chat topic]]}))))
|
||||
(when-not exists?
|
||||
{:db (assoc-in db [:chats (:chat-id chat)] chat)
|
||||
::save-public-chat chat
|
||||
::start-watching-group (merge {:group-id topic}
|
||||
(select-keys db [:web3 :current-public-key]))})
|
||||
{:dispatch-n [[:navigate-to-clean :chat-list]
|
||||
[:navigate-to-chat topic]]}))))
|
||||
|
||||
(reg-fx
|
||||
::save-chat
|
||||
|
@ -323,23 +165,23 @@
|
|||
(let [{:keys [chat-id public-key private-key contacts name]} new-chat
|
||||
identities (mapv :identity contacts)]
|
||||
(protocol/invite-to-group!
|
||||
{:web3 web3
|
||||
:group {:id chat-id
|
||||
:name name
|
||||
:contacts (conj identities current-public-key)
|
||||
:admin current-public-key
|
||||
:keypair {:public public-key
|
||||
:private private-key}}
|
||||
:identities identities
|
||||
:message {:from current-public-key
|
||||
:message-id (random/id)}})
|
||||
{:web3 web3
|
||||
:group {:id chat-id
|
||||
:name name
|
||||
:contacts (conj identities current-public-key)
|
||||
:admin current-public-key
|
||||
:keypair {:public public-key
|
||||
:private private-key}}
|
||||
:identities identities
|
||||
:message {:from current-public-key
|
||||
:message-id (random/id)}})
|
||||
(protocol/start-watching-group!
|
||||
{:web3 web3
|
||||
:group-id chat-id
|
||||
:identity current-public-key
|
||||
:keypair {:public public-key
|
||||
:private private-key}
|
||||
:callback #(dispatch [:incoming-message %1 %2])}))))
|
||||
{:web3 web3
|
||||
:group-id chat-id
|
||||
:identity current-public-key
|
||||
:keypair {:public public-key
|
||||
:private private-key}
|
||||
:callback #(dispatch [:incoming-message %1 %2])}))))
|
||||
|
||||
(defn group-name-from-contacts [contacts selected-contacts username]
|
||||
(->> (select-keys contacts selected-contacts)
|
||||
|
@ -381,7 +223,7 @@
|
|||
::start-listen-group (merge {:new-chat new-chat}
|
||||
(select-keys db [:web3 :current-public-key]))
|
||||
:dispatch-n [[:navigate-to-clean :chat-list]
|
||||
[:navigate-to :chat (:chat-id new-chat)]]})))
|
||||
[:navigate-to-chat (:chat-id new-chat)]]})))
|
||||
|
||||
(register-handler-fx
|
||||
:group-chat-invite-received
|
||||
|
|
|
@ -119,6 +119,7 @@
|
|||
(update-in [:content :params] #(apply dissoc % hidden-params))
|
||||
(dissoc :to-message :has-handler :raw-input))
|
||||
preview (assoc :preview (pr-str preview)))]
|
||||
(dispatch [:upsert-chat! {:chat-id chat-id}])
|
||||
(messages/save chat-id command)))))
|
||||
|
||||
(register-handler ::dispatch-responded-requests!
|
||||
|
@ -201,8 +202,7 @@
|
|||
(dispatch [::send-message! params])))
|
||||
(u/side-effect!
|
||||
(fn [_ [_ {:keys [chat-id message]}]]
|
||||
(dispatch [:upsert-chat! {:chat-id chat-id
|
||||
:timestamp (datetime/now-ms)}])
|
||||
(dispatch [:upsert-chat! {:chat-id chat-id}])
|
||||
(messages/save chat-id message))))
|
||||
|
||||
(register-handler ::send-dapp-message
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
(ns status-im.chat.models)
|
||||
(ns status-im.chat.models
|
||||
(:require [status-im.components.styles :as styles]))
|
||||
|
||||
(defn set-chat-ui-props
|
||||
"Updates ui-props in active chat by merging provided kvs into them"
|
||||
|
@ -9,3 +10,37 @@
|
|||
"Toggles chat ui prop in active chat"
|
||||
[{:keys [current-chat-id] :as db} ui-element]
|
||||
(update-in db [:chat-ui-props current-chat-id ui-element] not))
|
||||
|
||||
(defn- create-new-chat
|
||||
[{:keys [db gfy-generator now]} chat-id]
|
||||
(let [{:keys [name whisper-identity]} (get-in db [:contacts/contacts chat-id])]
|
||||
{:chat-id chat-id
|
||||
:name (or name (gfy-generator whisper-identity))
|
||||
:color styles/default-chat-color
|
||||
:group-chat false
|
||||
:is-active true
|
||||
:timestamp now
|
||||
:contacts [{:identity chat-id}]}))
|
||||
|
||||
(defn add-chat
|
||||
[{:keys [db] :as cofx} chat-id]
|
||||
(let [new-chat (create-new-chat cofx chat-id)
|
||||
existing-chats (:chats db)]
|
||||
{:db (cond-> (assoc db :new-chat new-chat)
|
||||
(not (contains? existing-chats chat-id))
|
||||
(update :chats assoc chat-id new-chat))
|
||||
:save-chat new-chat}))
|
||||
|
||||
(defn update-chat
|
||||
"Updates chat properties, if chat is not present in db, creates a default new one"
|
||||
[{:keys [db get-stored-chat]} {:keys [chat-id] :as chat}]
|
||||
(let [chat (merge (or (get-stored-chat chat-id)
|
||||
(create-new-chat db chat-id))
|
||||
chat)]
|
||||
{:db (update-in db [:chats chat-id] merge chat)
|
||||
:save-chat chat}))
|
||||
|
||||
(defn upsert-chat
|
||||
"Just like `update-chat` only implicitely updates timestamp"
|
||||
[cofx chat]
|
||||
(update-chat cofx (assoc chat :timestamp (:now cofx))))
|
||||
|
|
|
@ -182,10 +182,9 @@
|
|||
(reg-handler ::parse-commands! (u/side-effect! parse-commands!))
|
||||
|
||||
(reg-handler ::add-commands
|
||||
[(after (fn [_ [id]]
|
||||
(dispatch [:invoke-commands-loading-callbacks id])
|
||||
(dispatch [:invoke-chat-loaded-callbacks id])))
|
||||
(after #(dispatch [:update-suggestions]))]
|
||||
(after (fn [_ [id]]
|
||||
(dispatch [:invoke-commands-loading-callbacks id])
|
||||
(dispatch [:update-suggestions])))
|
||||
add-commands)
|
||||
|
||||
(reg-handler ::loading-failed! (u/side-effect! loading-failed!))
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
(defn save
|
||||
[{:keys [last-message-id chat-id] :as chat}]
|
||||
;; TODO(janherich): remove `:last-message-id`, seems like it's not used anywhere anymore
|
||||
(let [chat (assoc chat :last-message-id (or last-message-id ""))]
|
||||
(data-store/save chat (data-store/exists? chat-id))))
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@
|
|||
[:initialize-account address]]
|
||||
(if new-account?
|
||||
[[:navigate-to-clean :chat-list]
|
||||
[:navigate-to :chat console-chat-id]]
|
||||
[:navigate-to-chat console-chat-id]]
|
||||
[[:navigate-to-clean :chat-list]
|
||||
[:navigate-to :chat-list]]))}
|
||||
(log/debug "Error changing acount: " error))))
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
:on-press #(re-frame/dispatch [:navigate-to :new-chat])}])
|
||||
|
||||
(defn chat-list-item [[chat-id chat] edit?]
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to :chat chat-id])}
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to-chat chat-id])}
|
||||
[react/view
|
||||
[inner-item/chat-list-item-inner-view (assoc chat :chat-id chat-id) edit?]]])
|
||||
|
||||
|
|
|
@ -323,7 +323,7 @@
|
|||
(when-not (get-in db [:contacts/contacts whisper-identity])
|
||||
(let [contact (assoc contact :address (public-key->address whisper-identity))]
|
||||
{:dispatch-n [[::add-new-contact contact]
|
||||
[:start-chat whisper-identity {} :navigation-replace]]}))))
|
||||
[:start-chat whisper-identity {:navigation-replace? true}]]}))))
|
||||
|
||||
(register-handler-fx
|
||||
:add-pending-contact
|
||||
|
@ -419,10 +419,10 @@
|
|||
:open-chat-with-contact
|
||||
(fn [_ [_ {:keys [whisper-identity dapp?] :as contact}]]
|
||||
{:dispatch-n (concat
|
||||
[[:navigate-to-clean :chat-list]
|
||||
[:start-chat whisper-identity {}]]
|
||||
(when-not dapp?
|
||||
[[::send-contact-request contact]]))}))
|
||||
[[:navigate-to-clean :chat-list]
|
||||
[:start-chat whisper-identity]]
|
||||
(when-not dapp?
|
||||
[[::send-contact-request contact]]))}))
|
||||
|
||||
(register-handler-fx
|
||||
:add-contact-handler
|
||||
|
|
|
@ -1,70 +1,86 @@
|
|||
(ns status-im.ui.screens.navigation
|
||||
(:require [re-frame.core :refer [enrich]]
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.utils.handlers :refer [register-handler-db]]
|
||||
[status-im.constants :refer [console-chat-id]]))
|
||||
|
||||
(defmulti preload-data!
|
||||
(fn [db [_ view-id]] (or view-id (:view-id db))))
|
||||
;; private helper fns
|
||||
|
||||
(defmethod preload-data! :default [db _] db)
|
||||
|
||||
(defn -preload-data! [{:keys [was-modal?] :as db} & args]
|
||||
(if was-modal?
|
||||
(dissoc db :was-modal?) ;;TODO check how it worked with this bug
|
||||
(apply preload-data! db args)))
|
||||
|
||||
(register-handler-db
|
||||
:navigate-forget
|
||||
(enrich preload-data!)
|
||||
(fn [db [_ new-view-id]]
|
||||
(assoc db :view-id new-view-id)))
|
||||
|
||||
(defn push-view [db view-id]
|
||||
(defn- push-view [db view-id]
|
||||
(-> db
|
||||
(update :navigation-stack conj view-id)
|
||||
(assoc :view-id view-id)))
|
||||
|
||||
(register-handler-db
|
||||
:navigate-to
|
||||
(enrich preload-data!)
|
||||
(fn [{:keys [view-id] :as db} [_ new-view-id]]
|
||||
(if (= view-id new-view-id)
|
||||
db
|
||||
(push-view db new-view-id))))
|
||||
|
||||
(register-handler-db
|
||||
:navigate-to-modal
|
||||
(enrich preload-data!)
|
||||
(fn [db [_ modal-view]]
|
||||
(assoc db :modal modal-view)))
|
||||
|
||||
(defn replace-top-element [stack view-id]
|
||||
(defn- replace-top-element [stack view-id]
|
||||
(let [stack' (if (> 2 (count stack))
|
||||
(list :chat-list)
|
||||
(pop stack))]
|
||||
(conj stack' view-id)))
|
||||
|
||||
(defn replace-view [db view-id]
|
||||
(defn- replace-view [db view-id]
|
||||
(-> db
|
||||
(update :navigation-stack replace-top-element view-id)
|
||||
(assoc :view-id view-id)))
|
||||
|
||||
(register-handler-db
|
||||
:navigation-replace
|
||||
(enrich preload-data!)
|
||||
(fn [db [_ view-id]]
|
||||
(replace-view db view-id)))
|
||||
|
||||
(defn- can-navigate-back? [db]
|
||||
(not (get db :accounts/creating-account?)))
|
||||
|
||||
(defn- navigate-to-clean [db view-id]
|
||||
(-> db
|
||||
(assoc :navigation-stack (list))
|
||||
(push-view view-id)))
|
||||
|
||||
;; public fns
|
||||
|
||||
(defmulti preload-data!
|
||||
(fn [db [_ view-id]] (or view-id (:view-id db))))
|
||||
|
||||
(defmethod preload-data! :default [db _] db)
|
||||
|
||||
(defn- -preload-data! [{:keys [was-modal?] :as db} & args]
|
||||
(if was-modal?
|
||||
(dissoc db :was-modal?) ;;TODO check how it worked with this bug
|
||||
(apply preload-data! db args)))
|
||||
|
||||
(defn navigate-to
|
||||
"Navigates to particular view"
|
||||
[{:keys [view-id] :as db} go-to-view-id]
|
||||
(if (= view-id go-to-view-id)
|
||||
db
|
||||
(push-view db go-to-view-id)))
|
||||
|
||||
;; event handlers
|
||||
|
||||
(register-handler-db
|
||||
:navigate-forget
|
||||
(re-frame/enrich preload-data!)
|
||||
(fn [db [_ new-view-id]]
|
||||
(assoc db :view-id new-view-id)))
|
||||
|
||||
(register-handler-db
|
||||
:navigate-to
|
||||
(re-frame/enrich preload-data!)
|
||||
(fn [db [_ new-view-id]]
|
||||
(navigate-to db new-view-id)))
|
||||
|
||||
(register-handler-db
|
||||
:navigate-to-modal
|
||||
(re-frame/enrich preload-data!)
|
||||
(fn [db [_ modal-view]]
|
||||
(assoc db :modal modal-view)))
|
||||
|
||||
(register-handler-db
|
||||
:navigation-replace
|
||||
(re-frame/enrich preload-data!)
|
||||
(fn [db [_ view-id]]
|
||||
(replace-view db view-id)))
|
||||
|
||||
(register-handler-db
|
||||
:navigate-back
|
||||
(enrich -preload-data!)
|
||||
(re-frame/enrich -preload-data!)
|
||||
(fn [{:keys [navigation-stack view-id modal] :as db} _]
|
||||
(cond
|
||||
modal (assoc db :modal nil
|
||||
:was-modal? true)
|
||||
:was-modal? true)
|
||||
(>= 1 (count navigation-stack)) db
|
||||
|
||||
:else
|
||||
|
@ -78,11 +94,6 @@
|
|||
(assoc db :view-id first-in-stack)))
|
||||
db))))
|
||||
|
||||
(defn navigate-to-clean [db view-id]
|
||||
(-> db
|
||||
(assoc :navigation-stack (list))
|
||||
(push-view view-id)))
|
||||
|
||||
(register-handler-db
|
||||
:navigate-to-clean
|
||||
(fn [db [_ view-id]]
|
||||
|
@ -90,7 +101,7 @@
|
|||
|
||||
(register-handler-db
|
||||
:navigate-to-tab
|
||||
(enrich preload-data!)
|
||||
(re-frame/enrich preload-data!)
|
||||
(fn [db [_ view-id]]
|
||||
(-> db
|
||||
(assoc :prev-tab-view-id (:view-id db))
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
;; We allow to change phone number only from console because this requires entering SMS verification code.
|
||||
(fn [{:keys [db]} _]
|
||||
(let [phone-command (first (get-in db [:contacts/contacts "console" :responses :phone]))]
|
||||
{:dispatch-n [[:navigate-to :chat console-chat-id]
|
||||
{:dispatch-n [[:navigate-to-chat console-chat-id]
|
||||
[:select-chat-input-command phone-command]]})))
|
||||
|
||||
(defn get-current-account [{:keys [:accounts/current-account-id] :as db}]
|
||||
|
|
|
@ -4,22 +4,20 @@
|
|||
[status-im.ui.screens.wallet.db :as wallet.db]
|
||||
[re-frame.core :as re-frame]))
|
||||
|
||||
(defn chat-loaded-callback [request-command]
|
||||
(fn []
|
||||
(re-frame/dispatch [:select-chat-input-command request-command])
|
||||
;;TODO get rid of timeout
|
||||
(js/setTimeout #(re-frame/dispatch [:send-current-message]) 100)))
|
||||
(handlers/register-handler-fx
|
||||
::wallet-send-chat-request
|
||||
(fn [_ [_ amount]]
|
||||
{:dispatch [:select-chat-input-command {:name "request" :prefill [amount]}]
|
||||
;; TODO get rid of the timeout
|
||||
:dispatch-later [{:ms 100 :dispatch [:send-current-message]}]}))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:wallet-send-request
|
||||
(fn [{{:wallet/keys [request-transaction] :as db} :db} [_ {:keys [whisper-identity]}]]
|
||||
(let [request-command (first (get-in db [:contacts/contacts "transactor-personal" :commands :request]))]
|
||||
{:dispatch-n [[:navigate-back]
|
||||
[:navigate-to-clean :chat-list]
|
||||
[:add-chat-loaded-callback whisper-identity (chat-loaded-callback
|
||||
(assoc request-command
|
||||
:prefill [(:amount request-transaction)]))]
|
||||
[:start-chat whisper-identity]]})))
|
||||
(fn [{{:wallet/keys [request-transaction]} :db} [_ {:keys [whisper-identity]}]]
|
||||
{:dispatch-n [[:navigate-back]
|
||||
[:navigate-to-clean :chat-list]
|
||||
[:add-chat-loaded-event whisper-identity [::wallet-send-chat-request (:amount request-transaction)]]
|
||||
[:start-chat whisper-identity]]}))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:wallet-validate-request-amount
|
||||
|
|
Loading…
Reference in New Issue