Chat refactoring: updated console (former sign-up) namespace

This commit is contained in:
alwx 2017-11-28 11:50:09 +01:00 committed by Andrey Shovkoplyas
parent 484e982bdf
commit a813ff9e9f
15 changed files with 386 additions and 427 deletions

View File

@ -0,0 +1,104 @@
(ns status-im.chat.console
(:require [status-im.ui.components.styles :refer [default-chat-color]]
[status-im.utils.random :as random]
[status-im.constants :as const]
[status-im.chat.constants :as chat-const]
[status-im.i18n :as i18n]
[clojure.string :as string]))
(defn console-message [{:keys [message-id content content-type]
:or {message-id (random/id)}}]
{:message-id message-id
:outgoing false
:chat-id const/console-chat-id
:from const/console-chat-id
:to "me"
:content content
:content-type content-type})
(def enter-confirmation-code-message
(console-message {:content {:command "confirmation-code"
:content (i18n/label :t/confirmation-code)}
:content-type const/content-type-command-request}))
(def incorrect-confirmation-code-message
(console-message {:content {:command "confirmation-code"
:content (i18n/label :t/incorrect-code)}
:content-type const/content-type-command-request}))
(def contacts-synchronised-message
(console-message {:content (i18n/label :t/contacts-syncronized)
:content-type const/text-content-type}))
(def phone-number-request-message
(console-message {:content {:command "phone"
:content (i18n/label :t/phone-number-required)}
:content-type const/content-type-command-request}))
(def shake-your-phone-message
(console-message {:content (i18n/label :t/shake-your-phone)
:content-type const/text-content-type}))
(def account-generation-message
(console-message {:message-id chat-const/crazy-math-message-id
:content (i18n/label :t/account-generation-message)
:content-type const/text-content-type}))
(def move-to-internal-failure-message
(console-message {:message-id chat-const/move-to-internal-failure-message-id
:content {:command "grant-permissions"
:content (i18n/label :t/move-to-internal-failure-message)}
:content-type const/content-type-command-request}))
(defn passphrase-messages [mnemonic signing-phrase crazy-math-message?]
[(console-message {:message-id chat-const/passphrase-message-id
:content (if crazy-math-message?
(i18n/label :t/phew-here-is-your-passphrase)
(i18n/label :t/here-is-your-passphrase))
:content-type const/text-content-type})
(console-message {:message-id (random/id)
:content mnemonic
:content-type const/text-content-type})
(console-message {:message-id chat-const/signing-phrase-message-id
:content (i18n/label :t/here-is-your-signing-phrase)
:content-type const/text-content-type})
(console-message {:message-id (random/id)
:content signing-phrase
:content-type const/text-content-type})])
(def intro-status-message
(console-message {:message-id chat-const/intro-status-message-id
:content (i18n/label :t/intro-status)
:content-type const/content-type-status}))
(def intro-message1
(console-message {:message-id chat-const/intro-message1-id
:content {:command "password"
:content (i18n/label :t/intro-message1)}
:content-type const/content-type-command-request}))
(def chat
{:chat-id const/console-chat-id
:name (string/capitalize const/console-chat-id)
:color default-chat-color
:group-chat false
:is-active true
:unremovable? true
:timestamp (.getTime (js/Date.))
:photo-path const/console-chat-id
:contacts [{:identity const/console-chat-id
:text-color "#FFFFFF"
:background-color "#AB7967"}]})
(def contact
{:whisper-identity const/console-chat-id
:name (string/capitalize const/console-chat-id)
:photo-path const/console-chat-id
:dapp? true
:unremovable? true
:bot-url "local://console-bot"
:status (i18n/label :t/intro-status)})

View File

@ -5,11 +5,14 @@
[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]
[status-im.chat.console :as console-chat]
[status-im.chat.constants :as chat-const]
[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.data-store.contacts :as contacts-store]
[status-im.data-store.requests :as requests-store]
[status-im.data-store.messages :as messages-store]
[status-im.ui.screens.navigation :as navigation]
[status-im.protocol.core :as protocol]
[status-im.constants :as const]
@ -28,17 +31,17 @@
(re-frame/reg-cofx
:stored-unviewed-messages
(fn [cofx _]
(assoc cofx :stored-unviewed-messages (msg-store/get-unviewed))))
(assoc cofx :stored-unviewed-messages (messages-store/get-unviewed))))
(re-frame/reg-cofx
:get-stored-message
(fn [cofx _]
(assoc cofx :get-stored-message msg-store/get-by-id)))
(assoc cofx :get-stored-message messages-store/get-by-id)))
(re-frame/reg-cofx
:get-stored-messages
(fn [cofx _]
(assoc cofx :get-stored-messages msg-store/get-by-chat-id)))
(assoc cofx :get-stored-messages messages-store/get-by-chat-id)))
(re-frame/reg-cofx
:all-stored-chats
@ -50,17 +53,18 @@
(fn [cofx _]
(assoc cofx :get-stored-chat chats-store/get-by-id)))
;;;; Effects
(re-frame/reg-fx
:update-message
(fn [message]
(msg-store/update-message message)))
(messages-store/update-message message)))
(re-frame/reg-fx
:save-message
(fn [{:keys [chat-id] :as message}]
(msg-store/save chat-id message)))
(fn [message]
(messages-store/save message)))
(re-frame/reg-fx
:save-chat
@ -107,8 +111,8 @@
[re-frame/trim-v]
(fn [db [details]]
(model/set-chat-ui-props db {:show-bottom-info? true
:show-emoji? false
:bottom-info details})))
:show-emoji? false
:bottom-info details})))
(def index-messages (partial into {} (map (juxt :message-id identity))))
@ -136,13 +140,14 @@
{:db db}
(cond-> {:db (-> db
(assoc :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]}
(update :chats assoc const/console-chat-id console-chat/chat))
:dispatch-n [[:add-contacts [console-chat/contact]]]
:save-chat console-chat/chat
:save-all-contacts [console-chat/contact]}
(not current-account-id)
(update :dispatch-n conj sign-up/intro-event))))
(update :dispatch-n concat [[:chat-received-message/add-when-commands-loaded console-chat/intro-message1]]))))
(handlers/register-handler-fx
:init-console-chat
@ -171,11 +176,10 @@
{}
stored-unanswered-requests)
chats (reduce (fn [acc {:keys [chat-id] :as chat}]
(assoc acc chat-id
(assoc chat
:unviewed-messages (get chat->unviewed-messages chat-id)
:requests (get chat->message-id->request chat-id)
:messages (index-messages (get-stored-messages chat-id)))))
(assoc acc chat-id (assoc chat
:unviewed-messages (get chat->unviewed-messages chat-id)
:requests (get chat->message-id->request chat-id)
:messages (index-messages (get-stored-messages chat-id)))))
{}
all-stored-chats)]
(-> db
@ -208,24 +212,24 @@
:show-mnemonic
[(re-frame/inject-cofx :get-stored-message) re-frame/trim-v]
(fn [{:keys [get-stored-message]} [mnemonic signing-phrase]]
(let [crazy-math-message? (get-stored-message chat-const/crazy-math-message-id)]
{:dispatch-n (sign-up/passphrase-messages-events mnemonic
signing-phrase
crazy-math-message?)})))
(let [crazy-math-message? (get-stored-message chat-const/crazy-math-message-id)
messages-events (->> (console-chat/passphrase-messages mnemonic signing-phrase crazy-math-message?)
(mapv #(vector :chat-received-message/add %)))]
{:dispatch-n messages-events})))
(handlers/register-handler-fx
:account-generation-message
[(re-frame/inject-cofx :get-stored-message)]
(fn [{:keys [get-stored-message]} _]
(when-not (get-stored-message chat-const/passphrase-message-id)
{:dispatch sign-up/account-generation-event})))
{:dispatch [:chat-received-message/add console-chat/account-generation-message]})))
(handlers/register-handler-fx
:move-to-internal-failure-message
[(re-frame/inject-cofx :get-stored-message)]
(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})))
{:dispatch [:chat-received-message/add console-chat/move-to-internal-failure-message]})))
(handlers/register-handler-fx
:browse-link-from-message

View File

@ -3,6 +3,7 @@
[status-im.utils.handlers :as handlers]
[status-im.constants :as const]
[status-im.i18n :as i18n]
[status-im.chat.console :as console-chat]
[status-im.chat.events.sign-up :as sign-up-events]
[status-im.ui.screens.accounts.events :as accounts-events]
[taoensso.timbre :as log]
@ -12,7 +13,7 @@
;;;; Helper fns
(defn console-respond-command-events
(defn console-respond-command-messages
[command random-id-seq]
(let [{:keys [command handler-data]} command]
(when command
@ -21,38 +22,26 @@
"js" (let [{:keys [err data messages]} handler-data
content (or err data)
message-events (mapv (fn [{:keys [message type]} id]
[:received-message
{:message-id id
:content (str type ": " message)
:content-type const/text-content-type
:outgoing false
:chat-id const/console-chat-id
:from const/console-chat-id
:to "me"}])
(console-chat/console-message
{:message-id id
:content (str type ": " message)
:content-type const/text-content-type}))
messages random-id-seq)]
(conj message-events
[:received-message
(console-chat/console-message
{:message-id (first random-id-seq)
:content (str content)
:content-type const/text-content-type
:outgoing false
:chat-id const/console-chat-id
:from const/console-chat-id
:to "me"}]))
:content-type const/text-content-type})))
(log/debug "ignoring command: " name))))))
(defn faucet-base-url->url [url]
(str url "/donate/0x%s"))
(defn- faucet-response-event [message-id content]
[:received-message
{:message-id message-id
:content content
:content-type const/text-content-type
:outgoing false
:chat-id const/console-chat-id
:from const/console-chat-id
:to "me"}])
[:chat-received-message/add
(console-chat/console-message {:message-id message-id
:content content
:content-type const/text-content-type})])
(def console-commands->fx
{"password"
@ -60,7 +49,7 @@
(accounts-events/create-account db (:password params)))
"phone"
(fn [{:keys [db]} {:keys [params id]}]
(fn [{:keys [db]} {:keys [params id]}]
(sign-up-events/sign-up db (:phone params) id))
"confirmation-code"
@ -71,34 +60,31 @@
(fn [{:keys [db random-id]} {:keys [params id]}]
(let [{:accounts/keys [accounts current-account-id]} db
current-address (get-in accounts [current-account-id :address])
faucet-url (faucet-base-url->url (:url params))]
{:http-get {:url (gstring/format faucet-url current-address)
faucet-url (faucet-base-url->url (:url params))]
{:http-get {:url (gstring/format faucet-url current-address)
:success-event-creator (fn [_]
(faucet-response-event
random-id
(i18n/label :t/faucet-success)))
random-id
(i18n/label :t/faucet-success)))
:failure-event-creator (fn [event]
(log/error "Faucet error" event)
(faucet-response-event
random-id
(i18n/label :t/faucet-error)))}}))
random-id
(i18n/label :t/faucet-error)))}}))
"debug"
(fn [{:keys [db random-id now] :as cofx} {:keys [params id]}]
(let [debug? (= "On" (:mode params))]
(-> {:db db}
(accounts-events/account-update {:debug? debug?
(accounts-events/account-update {:debug? debug?
:last-updated now})
(assoc :dispatch-n (if debug?
[[:initialize-debugging {:force-start? true}]
[:received-message
{:message-id random-id
:content (i18n/label :t/debug-enabled)
:content-type const/text-content-type
:outgoing false
:chat-id const/console-chat-id
:from const/console-chat-id
:to "me"}]]
[:chat-received-message/add
(console-chat/console-message
{:message-id random-id
:content (i18n/label :t/debug-enabled)
:content-type const/text-content-type})]]
[[:stop-debugging]])))))})
(def commands-names (set (keys console-commands->fx)))
@ -120,8 +106,9 @@
;; TODO(janherich) remove this once send-message events are refactored
(handlers/register-handler-fx
:console-respond-command
[(re-frame/inject-cofx :random-id-seq) re-frame/trim-v]
(fn [{:keys [random-id-seq]} [command]]
(when-let [events (console-respond-command-events command random-id-seq)]
{:dispatch-n events})))
:console-respond-command
[(re-frame/inject-cofx :random-id-seq) re-frame/trim-v]
(fn [{:keys [random-id-seq]} [command]]
(when-let [messages (console-respond-command-messages command random-id-seq)]
(let [events (mapv #(vector :chat-received-message/add %) messages)]
{:dispatch-n events}))))

View File

@ -2,17 +2,12 @@
(:require [re-frame.core :as re-frame]
[taoensso.timbre :as log]
[status-im.utils.handlers :as handlers]
[status-im.utils.random :as random]
[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.commands :as commands-model]
[status-im.chat.models.unviewed-messages :as unviewed-messages-model]
[status-im.chat.events.commands :as commands-events]
[status-im.chat.events.requests :as requests-events]
[status-im.data-store.chats :as chat-store]
[status-im.data-store.messages :as msg-store]))
[status-im.data-store.messages :as messages-store]
[status-im.chat.events.commands :as commands-events]
[status-im.chat.models.message :as message-model]))
;;;; Coeffects
(re-frame/reg-cofx
:pop-up-chat?
@ -24,88 +19,25 @@
(re-frame/reg-cofx
:message-exists?
(fn [cofx]
(assoc cofx :message-exists? msg-store/exists?)))
(assoc cofx :message-exists? messages-store/exists?)))
(re-frame/reg-cofx
:get-last-clock-value
(fn [cofx]
(assoc cofx :get-last-clock-value msg-store/get-last-clock-value)))
:get-last-clock-value
(fn [cofx]
(assoc cofx :get-last-clock-value messages-store/get-last-clock-value)))
(defn- get-current-account
[{:accounts/keys [accounts current-account-id]}]
(get accounts current-account-id))
(defn- lookup-response-ref
[access-scope->commands-responses account chat contacts response-name]
(let [available-commands-responses (commands-model/commands-responses :response
access-scope->commands-responses
account
chat
contacts)]
(:ref (get available-commands-responses response-name))))
;;;; FX
(defn- add-message-to-db
[db {:keys [message-id] :as message} chat-id]
(-> db
(chat-utils/add-message-to-db chat-id chat-id message (:new? message))
(unviewed-messages-model/add-unviewed-message chat-id message-id)))
(defn add-message
[{:keys [db message-exists? pop-up-chat? get-last-clock-value now] :as cofx}
{:keys [from group-id chat-id content-type content message-id timestamp clock-value]
:as message
:or {clock-value 0}}]
(let [{:keys [access-scope->commands-responses] :contacts/keys [contacts]} db
{:keys [public-key] :as current-account} (get-current-account db)
chat-identifier (or group-id chat-id from)]
;; proceed with adding message if message is not already stored in realm,
;; it's not from current user (outgoing message) and it's for relevant chat
;; (either current active chat or new chat not existing yet)
(when (and (not (message-exists? message-id))
(not= from public-key)
(pop-up-chat? chat-identifier))
(let [fx (if (get-in db [:chats chat-identifier])
(model/upsert-chat cofx {:chat-id chat-identifier
:group-chat (boolean group-id)})
(model/add-chat cofx chat-identifier))
command-request? (= content-type const/content-type-command-request)
command (:command content)
enriched-message (cond-> (assoc message
:chat-id chat-identifier
:timestamp (or timestamp now)
:show? true
:clock-value (clocks/receive
clock-value
(get-last-clock-value chat-identifier)))
(and command command-request?)
(assoc-in [:content :content-command-ref]
(lookup-response-ref access-scope->commands-responses
current-account
(get-in fx [:db :chats chat-identifier])
contacts
command)))]
(cond-> (-> fx
(update :db add-message-to-db enriched-message chat-identifier)
(assoc :save-message (dissoc enriched-message :new?)))
command-request?
(requests-events/add-request chat-identifier enriched-message))))))
(def ^:private receive-interceptors
[(re-frame/inject-cofx :message-exists?) (re-frame/inject-cofx :pop-up-chat?)
(re-frame/inject-cofx :get-last-clock-value) (re-frame/inject-cofx :get-stored-chat)
re-frame/trim-v])
;; we need this internal event without jail checking, otherwise no response for the jail
;; call to generate preview would result to infinite loop of `:received-message` events
(handlers/register-handler-fx
::received-message
receive-interceptors
message-model/receive-interceptors
(fn [cofx [message]]
(add-message cofx message)))
(message-model/receive cofx message)))
(handlers/register-handler-fx
:received-message
receive-interceptors
:chat-received-message/add
message-model/receive-interceptors
(fn [{:keys [db] :as cofx} [{:keys [content] :as message}]]
(if (:command content)
;; we are dealing with received command message, we can't add it right away,
@ -113,20 +45,20 @@
;; note that `request-command-message-data` implicitly wait till jail is ready and
;; call is made only after that
(commands-events/request-command-message-data
db message
{:data-type :preview
:proceed-event-creator (fn [preview]
[::received-message
(assoc-in message [:content :preview] preview)])})
db message
{:data-type :preview
:proceed-event-creator (fn [preview]
[::received-message
(assoc-in message [:content :preview] preview)])})
;; regular non command message, we can add it right away
(add-message cofx message))))
(message-model/receive cofx message))))
;; TODO janherich: get rid of this special case once they hacky app start-up sequence is refactored
(handlers/register-handler-fx
:received-message-when-commands-loaded
receive-interceptors
:chat-received-message/add-when-commands-loaded
message-model/receive-interceptors
(fn [{:keys [db] :as cofx} [{:keys [chat-id] :as message}]]
(if (and (:status-node-started? db)
(get-in db [:contacts/contacts chat-id :jail-loaded?]))
(add-message cofx message)
{:dispatch-later [{:ms 400 :dispatch [:received-message-when-commands-loaded message]}]})))
(message-model/receive cofx message)
{:dispatch-later [{:ms 400 :dispatch [:chat-received-message/add-when-commands-loaded message]}]})))

View File

@ -1,7 +1,7 @@
(ns status-im.chat.events.sign-up
(:require [re-frame.core :as re-frame]
[status-im.constants :as const]
[status-im.chat.sign-up :as sign-up]
[status-im.chat.console :as console-chat]
[status-im.utils.handlers :as handlers]
[status-im.utils.phone-number :as phone-number-util]
[status-im.utils.sms-listener :as sms-listener]
@ -84,7 +84,7 @@
(fn [{:keys [db random-id]} [message-id]]
(-> {:db db
:dispatch-n [;; create manual way for entering confirmation code
(sign-up/enter-confirmation-code-event random-id)
[:chat-received-message/add console-chat/enter-confirmation-code-message]
;; create automatic way for receiving confirmation code
start-listening-confirmation-code-sms-event]}
(message-seen message-id))))
@ -105,44 +105,45 @@
(defn- sign-up-confirmed [{:keys [db] :as fx} now]
(let [last-phone-number (extract-last-phone-number (:chats db))
fx (-> (stop-listening-confirmation-code-sms fx)
(update :dispatch-n conj
[:request-permissions [:read-contacts]
#(re-frame/dispatch [:sync-contacts (fn [contacts]
[::contacts-synced contacts])])]))]
fx (-> (stop-listening-confirmation-code-sms fx)
(update :dispatch-n conj
[:request-permissions [:read-contacts]
#(re-frame/dispatch [:sync-contacts (fn [contacts]
[::contacts-synced contacts])])]))]
(cond-> fx
last-phone-number (accounts-events/account-update {:phone last-phone-number
:last-updated now}))))
last-phone-number (accounts-events/account-update {:phone last-phone-number
:last-updated now}))))
(handlers/register-handler-fx
::sign-up-confirm-response
[re-frame/trim-v (re-frame/inject-cofx :random-id)]
(fn [{:keys [db random-id now]} [{:keys [message status]} message-id]]
(cond-> {:db db
:dispatch-n [[:received-message
{:message-id random-id
:content message
:content-type const/text-content-type
:outgoing false
:chat-id const/console-chat-id
:from const/console-chat-id
:to "me"}]]}
message-id
(message-seen message-id)
(let [messages (cond-> []
(= "confirmed" status)
(sign-up-confirmed now)
true
(conj (console-chat/console-message {:content message
:content-type const/text-content-type}))
(= "failed" status)
(update :dispatch-n conj (sign-up/incorrect-confirmation-code-event random-id)))))
(= "failed" status)
(conj console-chat/incorrect-confirmation-code-message))]
(cond-> {:db db
:dispatch-n (mapv #(vector :chat-received-message/add %) messages)}
message-id
(message-seen message-id)
(= "confirmed" status)
(sign-up-confirmed now)))))
(handlers/register-handler-fx
::contacts-synced
[re-frame/trim-v (re-frame/inject-cofx :random-id)]
(fn [{:keys [db random-id now] :as cofx} [contacts]]
(-> {:db db}
(accounts-events/account-update {:signed-up? true :last-updated now})
(assoc :dispatch (sign-up/contacts-synchronised-event random-id)))))
(accounts-events/account-update {:signed-up? true
:last-updated now})
(assoc :dispatch [:chat-received-message/add console-chat/contacts-synchronised-message]))))
(handlers/register-handler-fx
::http-request-failure

View File

@ -114,14 +114,17 @@
(fn [db [_ add-to-chat-id {:keys [chat-id command]}]]
(cu/add-message-to-db db add-to-chat-id chat-id command)))
(register-handler ::save-command!
(register-handler
::save-command!
(u/side-effect!
(fn [db [_ chat-id {:keys [command]} hidden-params]]
(let [command (cond-> (-> command
(let [
command (cond-> (-> command
(assoc :chat-id chat-id)
(update-in [:content :params] #(apply dissoc % hidden-params))
(dissoc :to-message :has-handler :raw-input)))]
(dispatch [:upsert-chat! {:chat-id chat-id}])
(messages/save chat-id command)))))
(messages/save command)))))
(register-handler ::dispatch-responded-requests!
(u/side-effect!
@ -193,26 +196,29 @@
(fn [db [_ {:keys [chat-id message]}]]
(cu/add-message-to-db db chat-id chat-id message)))
(register-handler ::save-message!
(register-handler
::save-message!
(after (fn [_ [_ params]]
(dispatch [::send-message! params])))
(u/side-effect!
(fn [_ [_ {:keys [chat-id message]}]]
(dispatch [:upsert-chat! {:chat-id chat-id}])
(messages/save chat-id message))))
(messages/save message))))
(register-handler ::send-dapp-message
(register-handler
::send-dapp-message
(u/side-effect!
(fn [{:accounts/keys [current-account-id] :as db} [_ chat-id {:keys [content]}]]
(let [data (get-in db [:local-storage chat-id])]
(status/call-function!
{:chat-id chat-id
:function :on-message-send
{:chat-id chat-id
:function :on-message-send
:parameters {:message content}
:context {:data data
:from current-account-id}})))))
:context {:data data
:from current-account-id}})))))
(register-handler :received-bot-response
(register-handler
:received-bot-response
(u/side-effect!
(fn [{:contacts/keys [contacts]} [_ {:keys [chat-id] :as params} {:keys [result bot-id] :as data}]]
(let [{:keys [returned context]} result
@ -221,7 +227,7 @@
content (or err text-message)]
(when update-db
(dispatch [:update-bot-db {:bot bot-id
:db update-db}]))
:db update-db}]))
(dispatch [:suggestions-handler (assoc params
:bot-id bot-id
:result data
@ -231,35 +237,34 @@
(when (or (not= type "debug")
js/goog.DEBUG
(get-in contacts [chat-id :debug?]))
(dispatch [:received-message
{:message-id (random/id)
:content (str type ": " message)
(dispatch [:chat-received-message/add
{:message-id (random/id)
:content (str type ": " message)
:content-type content-type-log-message
:outgoing false
:chat-id chat-id
:from chat-id
:to "me"}]))))
:outgoing false
:chat-id chat-id
:from chat-id
:to "me"}]))))
(when content
(dispatch [:received-message
{:message-id (random/id)
:content (str content)
(dispatch [:chat-received-message/add
{:message-id (random/id)
:content (str content)
:content-type text-content-type
:outgoing false
:chat-id chat-id
:from chat-id
:to "me"}]))))))
:outgoing false
:chat-id chat-id
:from chat-id
:to "me"}]))))))
(defn handle-message-from-bot [{:keys [message chat-id]}]
(cond
(string? message)
(dispatch [:received-message
{:message-id (random/id)
:content (str message)
:content-type text-content-type
:outgoing false
:chat-id chat-id
:from chat-id
:to "me"}])
(dispatch [:chat-received-message/add {:message-id (random/id)
:content (str message)
:content-type text-content-type
:outgoing false
:chat-id chat-id
:from chat-id
:to "me"}])
(= "request" (:type message))
(dispatch [:add-request-message!
@ -370,14 +375,15 @@
(protocol/send-message! (assoc-in options
[:message :to] chat-id))))))))
(register-handler :add-request-message!
(u/side-effect!
(fn [_ [_ {:keys [content chat-id]}]]
(dispatch [:received-message
{:message-id (random/id)
:content (assoc content :bot chat-id)
:content-type content-type-command-request
:outgoing false
:chat-id chat-id
:from chat-id
:to "me"}]))))
(register-handler
:add-request-message!
(u/side-effect!
(fn [_ [_ {:keys [content chat-id]}]]
(dispatch [:chat-received-message/add
{:message-id (random/id)
:content (assoc content :bot chat-id)
:content-type content-type-command-request
:outgoing false
:chat-id chat-id
:from chat-id
:to "me"}]))))

View File

@ -30,9 +30,9 @@
([{:keys [db] :as cofx} chat-id chat-props]
(let [new-chat (create-new-chat cofx chat-id chat-props)
existing-chats (:chats db)]
{:db (cond-> db
(not (contains? existing-chats chat-id))
(update :chats assoc chat-id new-chat))
{:db (cond-> db
(not (contains? existing-chats chat-id))
(update :chats assoc chat-id new-chat))
:save-chat new-chat})))
;; TODO (yenda): there should be an option to update the timestamp
@ -44,8 +44,8 @@
(let [chat (merge (or (get-stored-chat chat-id)
(create-new-chat cofx chat-id {}))
chat)]
{:db (update-in db [:chats chat-id] merge chat)
:save-chat chat}))
{:db (update-in db [:chats chat-id] merge chat)
:save-chat chat}))
;; TODO (yenda): an upsert is suppose to add the entry if it doesn't
;; exist and update it if it does

View File

@ -0,0 +1,77 @@
(ns status-im.chat.models.message
(:require [re-frame.core :as re-frame]
[status-im.utils.clocks :as clocks]
[status-im.constants :as constants]
[status-im.chat.utils :as chat-utils]
[status-im.chat.models :as chat-model]
[status-im.chat.models.commands :as commands-model]
[status-im.chat.models.unviewed-messages :as unviewed-messages-model]
[status-im.chat.events.requests :as requests-events]
[taoensso.timbre :as log]))
(defn- get-current-account
[{:accounts/keys [accounts current-account-id]}]
(get accounts current-account-id))
(def receive-interceptors
[(re-frame/inject-cofx :message-exists?)
(re-frame/inject-cofx :pop-up-chat?)
(re-frame/inject-cofx :get-last-clock-value)
(re-frame/inject-cofx :random-id)
(re-frame/inject-cofx :get-stored-chat)
re-frame/trim-v])
(defn- lookup-response-ref
[access-scope->commands-responses account chat contacts response-name]
(let [available-commands-responses (commands-model/commands-responses :response
access-scope->commands-responses
account
chat
contacts)]
(:ref (get available-commands-responses response-name))))
(defn- add-message-to-db
[db {:keys [message-id] :as message} chat-id]
(-> db
(chat-utils/add-message-to-db chat-id chat-id message (:new? message))
(unviewed-messages-model/add-unviewed-message chat-id message-id)))
(defn receive
[{:keys [db message-exists? pop-up-chat? get-last-clock-value now] :as cofx}
{:keys [from group-id chat-id content-type content message-id timestamp clock-value]
:as message
:or {clock-value 0}}]
(let [{:keys [access-scope->commands-responses] :contacts/keys [contacts]} db
{:keys [public-key] :as current-account} (get-current-account db)
chat-identifier (or group-id chat-id from)]
;; proceed with adding message if message is not already stored in realm,
;; it's not from current user (outgoing message) and it's for relevant chat
;; (either current active chat or new chat not existing yet)
(when (and (not (message-exists? message-id))
(not= from public-key)
(pop-up-chat? chat-identifier))
(let [fx (if (get-in db [:chats chat-identifier])
(chat-model/upsert-chat cofx {:chat-id chat-identifier
:group-chat (boolean group-id)})
(chat-model/add-chat cofx chat-identifier))
command-request? (= content-type constants/content-type-command-request)
command (:command content)
enriched-message (cond-> (assoc message
:chat-id chat-identifier
:timestamp (or timestamp now)
:show? true
:clock-value (clocks/receive
clock-value
(get-last-clock-value chat-identifier)))
(and command command-request?)
(assoc-in [:content :content-command-ref]
(lookup-response-ref access-scope->commands-responses
current-account
(get-in fx [:db :chats chat-identifier])
contacts
command)))]
(cond-> (-> fx
(update :db add-message-to-db enriched-message chat-identifier)
(assoc :save-message (dissoc enriched-message :new?)))
command-request?
(requests-events/add-request chat-identifier enriched-message))))))

View File

@ -1,154 +0,0 @@
(ns status-im.chat.sign-up
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
[status-im.ui.components.styles :refer [default-chat-color]]
[status-im.utils.random :as random]
[status-im.constants :as const]
[status-im.chat.constants :as chat-const]
[status-im.i18n :refer [label]]
[clojure.string :as s]))
(defn send-console-message [text]
{:message-id (random/id)
:from "me"
:to const/console-chat-id
:content text
:content-type const/text-content-type
:outgoing true})
;; -- Send phone number ----------------------------------------
(defn- confirmation-code-event [correct? message-id]
[:received-message
{:message-id message-id
:content {:command "confirmation-code"
:content (if correct?
(label :t/confirmation-code)
(label :t/incorrect-code))}
:content-type const/content-type-command-request
:outgoing false
:chat-id const/console-chat-id
:from const/console-chat-id
:to "me"}])
(def enter-confirmation-code-event (partial confirmation-code-event true))
(def incorrect-confirmation-code-event (partial confirmation-code-event false))
;; -- Send confirmation code and synchronize contacts---------------------------
(defn contacts-synchronised-event [message-id]
[:received-message
{:message-id message-id
:content (label :t/contacts-syncronized)
:content-type const/text-content-type
:outgoing false
:chat-id const/console-chat-id
:from const/console-chat-id
:to "me"}])
(def start-signup-events
[[:received-message
{:message-id (random/id)
:content {:command "phone"
:content (label :t/phone-number-required)}
:content-type const/content-type-command-request
:outgoing false
:chat-id const/console-chat-id
:from const/console-chat-id
:to "me"}]
[:received-message
{:message-id (random/id)
:content (label :t/shake-your-phone)
:content-type const/text-content-type
:outgoing false
:chat-id const/console-chat-id
:from const/console-chat-id
:to "me"}]])
;; -- Saving password ----------------------------------------
(def account-generation-event
[:received-message
{:message-id chat-const/crazy-math-message-id
:content (label :t/account-generation-message)
:content-type const/text-content-type
:outgoing false
:chat-id const/console-chat-id
:from const/console-chat-id
:to "me"}])
(def move-to-internal-failure-event
[:received-message
{:message-id chat-const/move-to-internal-failure-message-id
:content {:command "grant-permissions"
:content (label :t/move-to-internal-failure-message)}
:content-type const/content-type-command-request
:outgoing false
:chat-id const/console-chat-id
:from const/console-chat-id
:to "me"}])
(defn passphrase-messages-events [mnemonic signing-phrase crazy-math-message?]
[[:received-message
{:message-id chat-const/passphrase-message-id
:content (if crazy-math-message?
(label :t/phew-here-is-your-passphrase)
(label :t/here-is-your-passphrase))
:content-type const/text-content-type
:outgoing false
:chat-id const/console-chat-id
:from const/console-chat-id
:to "me"}]
[:received-message
{:message-id (random/id)
:content mnemonic
:content-type const/text-content-type
:outgoing false
:chat-id const/console-chat-id
:from const/console-chat-id
:to "me"}]
[:received-message
{:message-id chat-const/signing-phrase-message-id
:content (label :t/here-is-your-signing-phrase)
:content-type const/text-content-type
:outgoing false
:chat-id const/console-chat-id
:from const/console-chat-id
:to "me"}]
[:received-message
{:message-id (random/id)
:content signing-phrase
:content-type const/text-content-type
:outgoing false
:chat-id const/console-chat-id
:from const/console-chat-id
:to "me"}]])
(def intro-event
[:received-message-when-commands-loaded
{:chat-id const/console-chat-id
:message-id chat-const/intro-message1-id
:content {:command "password"
:content (label :t/intro-message1)}
:content-type const/content-type-command-request
:outgoing false
:from const/console-chat-id
:to "me"}])
(def console-chat
{:chat-id const/console-chat-id
:name (s/capitalize const/console-chat-id)
:color default-chat-color
:group-chat false
:is-active true
:unremovable? true
:timestamp (.getTime (js/Date.))
:photo-path const/console-chat-id
:contacts [{:identity const/console-chat-id
:text-color "#FFFFFF"
:background-color "#AB7967"}]})
(def console-contact
{:whisper-identity const/console-chat-id
:name (s/capitalize const/console-chat-id)
:photo-path const/console-chat-id
:dapp? true
:unremovable? true
:bot-url "local://console-bot"
:status (label :t/intro-status)})

View File

@ -88,8 +88,8 @@
[view st/location-container
[text {:style st/location-container-title}
(label :t/your-current-location)]
(let [{:keys [place_name center] :as feature} (get-in @cur-loc-geocoded [:features 0])]
[place-item {:title (:text feature) :address place_name :center center}])])))})))
(let [{:keys [place_name center] :as feature} (get-in @cur-loc-geocoded [:features 0])]
[place-item {:title (:text feature) :address place_name :center center}])])))})))
(defn places-nearby-view []
(let [geolocation (subscribe [:get :geolocation])

View File

@ -72,14 +72,12 @@
(update content :params dissoc :password :password-confirmation))))
(defn save
;; todo remove chat-id parameter
[chat-id {:keys [message-id content] :as message}]
[{:keys [message-id content] :as message}]
(when-not (data-store/exists? message-id)
(let [content' (prepare-content content)
message' (merge default-values
message
{:chat-id chat-id
:content content'
{:content content'
:timestamp (random/timestamp)})]
(data-store/save message'))))

View File

@ -137,7 +137,7 @@
(string/join " ")
(system-message message-id timestamp))
message' (assoc message :group-id group-id)]
(re-frame/dispatch [:received-message message']))))
(re-frame/dispatch [:chat-received-message/add message']))))
(re-frame/reg-fx
::chats-add-contact
@ -164,7 +164,7 @@
(string/join " ")
(system-message message-id timestamp))
message' (assoc message :group-id group-id)]
(re-frame/dispatch [:received-message message']))))
(re-frame/dispatch [:chat-received-message/add message']))))
(re-frame/reg-fx
::stop-watching-group!
@ -174,10 +174,11 @@
(re-frame/reg-fx
::participant-left-group-message
(fn [{:keys [chat-id from message-id timestamp]}]
(let [left-name (:name (contacts/get-by-id from))]
(->> (str (or left-name from) " " (i18n/label :t/left))
(system-message message-id timestamp)
(messages/save chat-id)))))
(let [left-name (:name (contacts/get-by-id from))
message-text (str (or left-name from) " " (i18n/label :t/left))]
(-> (system-message message-id timestamp message-text)
(assoc :chat-id chat-id)
(messages/save)))))
(re-frame/reg-fx
::participant-invited-to-group-message
@ -187,12 +188,12 @@
(i18n/label :t/You)
(:name (contacts/get-by-id identity)))]
(re-frame/dispatch
[:received-message
{:from "system"
:group-id chat-id
:timestamp timestamp
:message-id message-id
:content (str (or inviter-name from) " " (i18n/label :t/invited) " " (or invitee-name identity))
[:chat-received-message/add
{:from "system"
:group-id chat-id
:timestamp timestamp
:message-id message-id
:content (str (or inviter-name from) " " (i18n/label :t/invited) " " (or invitee-name identity))
:content-type constants/text-content-type}]))))
(re-frame/reg-fx
@ -201,16 +202,16 @@
(let [message-id' (or ack-of-message message-id)]
(when-let [{:keys [message-status] :as message} (messages/get-by-id message-id')]
(when-not (= (keyword message-status) :seen)
(let [group? (boolean group-id)
(let [group? (boolean group-id)
message' (-> (if (and group? (not= status :sent))
(update-in message
[:user-statuses from]
(fn [{old-status :status}]
{:id (random/id)
{:id (random/id)
:whisper-identity from
:status (if (= (keyword old-status) :seen)
old-status
status)}))
:status (if (= (keyword old-status) :seen)
old-status
status)}))
(assoc message :message-status status))
;; we need to dissoc preview because it has been saved before
(dissoc :preview))]
@ -227,7 +228,7 @@
(pending-messages/save pending-message)
(when (#{:message :group-message} type)
(messages/update-message {:message-id id
:delivery-status :pending}))))
:delivery-status :pending}))))
(re-frame/reg-fx
::status-init-jail
@ -326,7 +327,7 @@
route-event (case type
(:message
:group-message
:public-group-message) [:received-message (transform-protocol-message message)]
:public-group-message) [:chat-received-message/add (transform-protocol-message message)]
:ack (if (#{:message :group-message} (:type payload))
[:update-message-status message :delivered]
[:pending-message-remove message])
@ -357,7 +358,7 @@
(when route-event {:dispatch route-event})))))))
(defn update-message-status [db {:keys [message-id ack-of-message group-id from status]}]
(let [message-id' (or ack-of-message message-id)
(let [message-id' (or ack-of-message message-id)
update-group-status? (and group-id (not= status :sent))
message-path [:chats (or group-id from) :messages message-id']
current-status (if update-group-status?

View File

@ -3,7 +3,7 @@
[re-frame.core :refer [dispatch reg-fx]]
[status-im.utils.handlers :refer [register-handler-db register-handler-fx]]
[taoensso.timbre :as log]
[status-im.chat.sign-up :as sign-up]
[status-im.chat.console :as console-chat]
[status-im.utils.types :refer [json->clj]]
[status-im.data-store.core :as data-store]
[status-im.native-module.core :as status]
@ -126,9 +126,11 @@
(if (nil? error)
{:db (dissoc db :accounts/login)
:dispatch-n [[:stop-debugging]
[:initialize-account address (when (or new-account?
recover-in-progress?)
sign-up/start-signup-events)]
[:initialize-account
address
(when (or new-account? recover-in-progress?)
[[:chat-received-message/add console-chat/phone-number-request-message]
[:chat-received-message/add console-chat/shake-your-phone-message]])]
[:navigate-to-clean :chat-list]
(if new-account?
[:navigate-to-chat console-chat-id]

View File

@ -17,7 +17,7 @@
[status-im.utils.gfycat.core :refer [generate-gfy]]
[status-im.i18n :refer [label]]
[status-im.ui.screens.contacts.navigation]
[status-im.chat.sign-up :as sign-up]
[status-im.chat.console :as console-chat]
[status-im.commands.events.loading :as loading-events]
[cljs.spec.alpha :as spec]))
@ -234,7 +234,7 @@
:bot-url bot-url
:description description
:dapp-hash dapp-hash})
all-default-contacts (conj default-contacts sign-up/console-contact)]
all-default-contacts (conj default-contacts console-chat/contact)]
[[:add-contacts all-default-contacts]]))
(defn- prepare-add-chat-events [contacts default-contacts]

View File

@ -35,10 +35,11 @@
:content-type text-content-type})
(defn removed-participant-message [chat-id identity]
(let [contact-name (:name (contacts/get-by-id identity))]
(->> (str "You've removed " (or contact-name identity))
(system-message (random/id))
(messages/save chat-id))))
(let [contact-name (:name (contacts/get-by-id identity))
message-text (str "You've removed " (or contact-name identity))]
(-> (system-message (random/id) message-text)
(assoc :chat-id chat-id)
(messages/save))))
(reg-fx
::create-removing-messages