Simplify input handling

Signed-off-by: Andrey Shovkoplyas <motor4ik@gmail.com>
This commit is contained in:
janherich 2018-02-17 12:48:05 +01:00 committed by Andrey Shovkoplyas
parent 526d11469a
commit 15f4c90caa
No known key found for this signature in database
GPG Key ID: EAAB7C8622D860A4
7 changed files with 116 additions and 207 deletions

View File

@ -26,7 +26,7 @@
content-command-name :content-command
:keys [content-command-scope-bitmask bot scope-bitmask params type]} :content
:keys [chat-id group-id jail-id] :as message}
{:keys [data-type proceed-event-creator cache-data?] :as opts}]
{:keys [data-type] :as opts}]
(let [{:accounts/keys [current-account-id]
:contacts/keys [contacts]} db
jail-id (or bot jail-id chat-id)
@ -56,21 +56,9 @@
(handlers/register-handler-fx
::jail-command-data-response
[re-frame/trim-v]
(fn [{:keys [db]} [{{:keys [returned]} :result}
{:keys [message-id chat-id]}
{:keys [data-type proceed-event-creator cache-data?]}]]
(let [existing-message (get-in db [:chats chat-id :messages message-id])]
(cond-> {}
(and cache-data? existing-message returned)
(as-> fx
(let [updated-message (assoc-in existing-message [:content data-type] returned)]
(assoc fx
:db (assoc-in db [:chats chat-id :messages message-id] updated-message)
:update-message (select-keys updated-message [:message-id :content]))))
proceed-event-creator
(assoc :dispatch (proceed-event-creator returned))))))
(fn [{:keys [db]} [{{:keys [returned]} :result} {:keys [chat-id]} {:keys [proceed-event-creator]}]]
(when proceed-event-creator
{:dispatch (proceed-event-creator returned)})))
(handlers/register-handler-fx
:request-command-message-data

View File

@ -236,77 +236,50 @@
(min (count input-text)))]
(merge fx (update-text-selection new-db new-selection)))))))
(defn- request-command-data
"Requests command data from jail"
[{:keys [bot-db] :contacts/keys [contacts] :as db}
{{:keys [command
metadata
args]
:as content} :content
:keys [chat-id group-id jail-id data-type event-after-creator message-id current-time]}]
(let [{:keys [dapp? dapp-url name]} (get contacts chat-id)
metadata (merge metadata
(when dapp?
{:url (i18n/get-contact-translated chat-id :dapp-url dapp-url)
:name (i18n/get-contact-translated chat-id :name name)}))
owner-id (:owner-id command)
bot-db (get bot-db owner-id)
params (merge (input-model/args->params content)
{:bot-db bot-db
:metadata metadata})
;; function creating "message shaped" data from command, because that's what `request-command-message-data` expects
(defn- command->message
[{:keys [bot-db current-chat-id chats]} {:keys [command] :as command-params}]
(cond-> {:chat-id current-chat-id
:jail-id (:owner-id command)
:content {:command (:name command)
:type (:type command)
:scope-bitmask (:scope-bitmask command)
:params (assoc (input-model/args->params command-params)
:bot-db (get bot-db (:owner-id command)))}}
(get-in chats [current-chat-id :group-chat])
(assoc :group-id current-chat-id)))
command-message {:command command
:params params
:to-message (:to-message-id metadata)
:created-at current-time
:id message-id
:chat-id chat-id
:jail-id (or owner-id jail-id)}
request-data {:message-id message-id
:chat-id chat-id
:group-id group-id
:jail-id (or owner-id jail-id)
:content {:command (:name command)
:scope-bitmask (:scope-bitmask command)
:params params
:type (:type command)}}]
(commands-events/request-command-message-data db request-data
{:data-type data-type
:proceed-event-creator (partial event-after-creator
command-message)})))
;; TODO (janherich) request-command-data functions and event need to be refactored, they are needlessly complicated
(defn proceed-command
"Proceed with command processing by setting up and executing chain of events:
"Proceed with command processing by creating command message + setting up and executing chain of events:
1. Params validation
2. Short preview fetching
3. Preview fetching"
[{:keys [current-chat-id chats] :as db} {{:keys [bot]} :command :as content} message-id current-time]
(let [params-template {:content content
:chat-id current-chat-id
:group-id (when (get-in chats [current-chat-id :group-chat])
current-chat-id)
:jail-id (or bot current-chat-id)
:message-id message-id
:current-time current-time}
preview-params (merge params-template
{:data-type :preview
:event-after-creator (fn [command-message jail-response]
[::send-command
(assoc-in command-message [:command :preview] jail-response)])})
short-preview-params (merge params-template
{:data-type :short-preview
:event-after-creator (fn [_ jail-response]
[::request-command-data
(assoc-in preview-params [:content :command :short-preview] jail-response)])})
validation-params (merge params-template
{:data-type :validator
:event-after-creator (fn [_ jail-response]
[::proceed-validation
jail-response
[[::request-command-data short-preview-params]]])})]
(request-command-data db validation-params)))
[{:keys [bot-db current-chat-id chats] :as db} {:keys [command metadata] :as command-params} message-id current-time]
(let [message (command->message db command-params)
cmd-params {:command command
:params (get-in message [:content :params])
:to-message (:to-message-id metadata)
:created-at current-time
:id message-id
:chat-id current-chat-id
:jail-id (:jail-id message)}
event-chain {:data-type :validator
:proceed-event-creator (fn [validation-response]
[::proceed-validation
validation-response
[[:request-command-message-data
message
{:data-type :short-preview
:proceed-event-creator (fn [short-preview]
[:request-command-message-data
message
{:data-type :preview
:proceed-event-creator (fn [preview]
[::send-command
(update cmd-params :command merge
{:short-preview short-preview
:preview preview})])}])}]]])}]
(commands-events/request-command-message-data db message event-chain)))
;;;; Handlers
@ -392,28 +365,22 @@
(validator params error-events-creator))]
{:dispatch-n (or error-events proceed-events)})))
(handlers/register-handler-fx
::request-command-data
[re-frame/trim-v]
(fn [{:keys [db]} [command-params]]
(request-command-data db command-params)))
(handlers/register-handler-fx
::send-command
message-model/send-interceptors
(fn [cofx [{:keys [command] :as command-message}]]
(let [{{:keys [current-public-key current-chat-id]
:accounts/keys [current-account-id] :as db} :db} cofx
fx (message-model/process-command cofx
(fn [{:keys [db] :as cofx} [{:keys [command] :as command-message}]]
(let [{:keys [current-public-key current-chat-id] :accounts/keys [current-account-id]} db
new-db (-> (model/set-chat-ui-props db {:sending-in-progress? false})
(clear-seq-arguments)
(set-chat-input-metadata nil)
(set-chat-input-text nil))]
(merge {:db new-db}
(message-model/process-command (assoc cofx :db new-db)
{:message (get-in db [:chats current-chat-id :input-text])
:command command-message
:chat-id current-chat-id
:identity current-public-key
:address current-account-id})]
(update fx :db #(-> %
(clear-seq-arguments)
(set-chat-input-metadata nil)
(set-chat-input-text nil))))))
:address current-account-id})))))
(defn command-complete?
[chat-command]
@ -443,8 +410,7 @@
(set-chat-input-text nil)))
{:message-text input-text
:chat-id current-chat-id
:identity current-public-key
:address (:accounts/current-account-id db)})))
:identity current-public-key})))
(handlers/register-handler-fx
@ -490,15 +456,13 @@
seq-arguments (get-in chats [current-chat-id :seq-arguments])
command (-> (input-model/selected-chat-command db)
(assoc :args (into [] (conj seq-arguments text))))]
(request-command-data db {:content command
:chat-id current-chat-id
:jail-id (or (get-in command [:command :bot]) current-chat-id)
:data-type :validator
:event-after-creator (fn [_ jail-response]
[::proceed-validation
jail-response
[[::update-seq-arguments current-chat-id]
[:send-current-message]]])}))))
(commands-events/request-command-message-data db (command->message db command)
{:data-type :validator
:proceed-event-creator (fn [validation-response]
[::proceed-validation
validation-response
[[::update-seq-arguments current-chat-id]
[:send-current-message]]])}))))
(handlers/register-handler-db
:set-chat-seq-arg-input-text

View File

@ -12,7 +12,7 @@
;; Effects
(re-frame/reg-fx
:chat-requests/mark-as-answered
::mark-as-answered
(fn [{:keys [chat-id message-id]}]
(requests-store/mark-as-answered chat-id message-id)))
@ -21,15 +21,15 @@
(fn [request]
(requests-store/save request)))
;; Handlers
;; Functions
(handlers/register-handler-fx
:request-answered
[re-frame/trim-v]
(fn [{:keys [db]} [chat-id message-id]]
{:db (update-in db [:chats chat-id :requests] dissoc message-id)
:chat-requests/mark-as-answered {:chat-id chat-id
:message-id message-id}}))
(defn request-answered
"Takes fx, chat-id and message, updates fx with necessary data for markin request as answered"
[fx chat-id message-id]
(-> fx
(update-in [:db :chats chat-id :requests] dissoc message-id)
(assoc ::mark-as-answered {:chat-id chat-id
:message-id message-id})))
(defn add-request
"Takes fx, chat-id and message, updates fx with necessary data for adding new request"

View File

@ -37,7 +37,7 @@
:chat-send-message/send-command
message-model/send-interceptors
(fn [cofx [add-to-chat-id params]]
(message-model/send-command cofx nil add-to-chat-id params)))
(message-model/send-command cofx add-to-chat-id params)))
(handlers/register-handler-fx
:chat-send-message/from-jail

View File

@ -4,10 +4,8 @@
[status-im.chat.events.console :as console-events]
[status-im.chat.events.requests :as requests-events]
[status-im.chat.models :as chat-model]
[status-im.chat.models.commands :as commands-model]
[status-im.utils.datetime :as datetime-utils]
[status-im.utils.clocks :as clocks-utils]
[status-im.utils.random :as random]))
[status-im.chat.models.commands :as commands-model]
[status-im.utils.clocks :as clocks-utils]))
(defn- get-current-account
[{:accounts/keys [accounts current-account-id]}]
@ -102,10 +100,10 @@
[(re-frame/inject-cofx :random-id) (re-frame/inject-cofx :random-id-seq)
(re-frame/inject-cofx :get-stored-chat) re-frame/trim-v])
(defn- handle-message-from-bot [cofx {:keys [message chat-id]}]
(defn- handle-message-from-bot [{:keys [random-id] :as cofx} {:keys [message chat-id]}]
(when-let [message (cond
(string? message)
{:message-id (random/id)
{:message-id random-id
:content (str message)
:content-type constants/text-content-type
:outgoing false
@ -114,7 +112,7 @@
:to "me"}
(= "request" (:type message))
{:message-id (random/id)
{:message-id random-id
:content (assoc (:content message) :bot chat-id)
:content-type constants/content-type-command-request
:outgoing false
@ -140,38 +138,23 @@
:from current-account-id}}})))
(defn- generate-message
[{:keys [web3 current-public-key chats network-status]}
{:keys [chat-id command message] :as args}]
(if command
(let [payload (-> command
(select-keys [:content :content-type
:clock-value :show?])
(assoc :timestamp (datetime-utils/now-ms)))
payload (if (= network-status :offline)
(assoc payload :show? false)
payload)]
{:from current-public-key
:message-id (:message-id command)
:payload payload})
(let [message' (select-keys message [:from :message-id])
payload (select-keys message [:timestamp :content :content-type
:clock-value :show?])
payload (if (= network-status :offline)
(assoc payload :show? false)
payload)]
(assoc message' :payload payload))))
[{:keys [network-status]} chat-id message]
(assoc (select-keys message [:from :message-id])
:payload (cond-> (select-keys message [:content :content-type :clock-value :timestamp :show?])
(= :offline network-status)
(assoc :show? false))))
(defn send
[{{:keys [web3 chats]
:accounts/keys [accounts current-account-id]
:contacts/keys [contacts] :as db} :db :as cofx}
{:keys [chat-id command] :as args}]
{:keys [chat-id command message] :as args}]
(let [{:keys [dapp? fcm-token]} (get contacts chat-id)]
(if dapp?
(send-dapp-message! cofx args)
(let [{:keys [group-chat public?]} (get-in db [:chats chat-id])
options {:web3 web3
:message (generate-message db args)}]
:message (generate-message db chat-id (or command message))}]
(cond
(and group-chat (not public?))
(let [{:keys [public-key private-key]} (get chats chat-id)]
@ -190,16 +173,16 @@
:payload {:title "Status" :body "You have a new message"}
:tokens [fcm-token]}})))))))
(defn- prepare-message [params chat]
(defn- prepare-message [params chat now random-id]
(let [{:keys [chat-id identity message-text]} params
{:keys [group-chat public? last-clock-value]} chat
message {:message-id (random/id)
message {:message-id random-id
:chat-id chat-id
:content message-text
:from identity
:content-type constants/text-content-type
:outgoing true
:timestamp (datetime-utils/now-ms)
:timestamp now
:clock-value (clocks-utils/send last-clock-value)
:show? true}]
(cond-> message
@ -215,21 +198,17 @@
(not group-chat)
(assoc :to chat-id :message-type :user-message))))
(defn send-message [{{:keys [network-status] :as db} :db
:keys [now]}
{:keys [chat-id] :as params}]
(defn send-message [{:keys [db now random-id] :as cofx} {:keys [chat-id] :as params}]
(let [chat (get-in db [:chats chat-id])
message (prepare-message params chat)
message (prepare-message params chat now random-id)
params' (assoc params :message message)
fx {:db (add-message-to-db db chat-id message true)
:save-message message}]
(-> (merge fx (chat-model/upsert-chat (assoc fx :now now)
{:chat-id chat-id}))
(as-> fx'
(merge fx' (send fx' params'))))))
fx (-> (chat-model/upsert-chat cofx {:chat-id chat-id})
(update :db add-message-to-db chat-id message true)
(assoc :save-message message))]
(merge fx (send cofx params'))))
(defn- prepare-command
[identity chat-id clock-value
[identity chat-id now clock-value
{request-params :params
request-command :command
:keys [prefill prefillBotDb]
@ -255,7 +234,7 @@
{:message-id id
:from identity
:to chat-id
:timestamp (datetime-utils/now-ms)
:timestamp now
:content content'
:content-type (or content-type
(if request
@ -269,8 +248,7 @@
:show? true}))
(defn send-command
[{{:keys [current-public-key network-status chats] :as db} :db
:keys [now random-id-seq]} result add-to-chat-id params]
[{{:keys [current-public-key chats] :as db} :db :keys [now random-id-seq] :as cofx} add-to-chat-id params]
(let [{{:keys [handler-data
command]
:as content} :command
@ -280,29 +258,19 @@
hidden-params (->> (:params command)
(filter :hidden)
(map :name))
command' (prepare-command current-public-key chat-id last-clock-value request content)
command' (prepare-command current-public-key chat-id now last-clock-value request content)
params' (assoc params :command command')
fx {:db (-> (merge db (:db result))
(add-message-to-db chat-id command' true))
:save-message (-> command'
(assoc :chat-id chat-id)
(update-in [:content :params]
#(apply dissoc % hidden-params))
(dissoc :to-message :has-handler :raw-input))}]
(cond-> (merge fx
(chat-model/upsert-chat (assoc fx :now now)
{:chat-id chat-id})
(dissoc result :db))
true
(as-> fx'
(merge fx' (send fx' params')))
fx (-> (chat-model/upsert-chat cofx {:chat-id chat-id})
(update :db add-message-to-db chat-id command' true)
(assoc :save-message (-> command'
(assoc :chat-id chat-id)
(update-in [:content :params]
#(apply dissoc % hidden-params))
(dissoc :to-message :has-handler :raw-input))))]
(cond-> (merge fx (send cofx params'))
(:to-message command')
(assoc :chat-requests/mark-as-answered {:chat-id chat-id
:message-id (:to-message command')})
(requests-events/request-answered chat-id (:to-message command'))
(= constants/console-chat-id chat-id)
(as-> fx'
@ -313,8 +281,8 @@
(defn invoke-console-command-handler
[{:keys [db] :as cofx} {:keys [chat-id command] :as command-params}]
(let [fx-fn (get console-events/console-commands->fx (-> command :command :name))
result (fx-fn cofx command)]
(send-command cofx result chat-id command-params)))
fx (fx-fn cofx command)]
(merge fx (send-command (assoc cofx :db (or (:db fx) db)) chat-id command-params))))
(defn invoke-command-handlers
[{{:keys [bot-db]
@ -347,16 +315,13 @@
(defn process-command
[{:keys [db] :as cofx} {:keys [command message chat-id] :as params}]
(let [{:keys [command] :as content} command]
(-> {:db (chat-model/set-chat-ui-props db {:sending-in-progress? false})}
(cond
(and (= constants/console-chat-id chat-id)
(console-events/commands-names (:name command)))
(invoke-console-command-handler cofx params)
(as-> fx'
(cond
(and (= constants/console-chat-id chat-id)
(console-events/commands-names (:name command)))
(invoke-console-command-handler (merge cofx fx') params)
(:has-handler command)
(invoke-command-handlers cofx params)
(:has-handler command)
(merge fx' (invoke-command-handlers fx' params))
:else
(merge fx' (send-command cofx fx' chat-id params)))))))
:else
(send-command cofx chat-id params))))

View File

@ -65,11 +65,7 @@
(defview message-content-command
[{:keys [content params] :as message}]
(letsubs [command [:get-command (:content-command-ref content)]]
{:component-will-mount #(when-not (:preview content)
(re-frame/dispatch [:request-command-message-data
message {:data-type :preview
:cache-data? true}]))}
(letsubs [command [:get-command (:content-command-ref content)]]
(let [preview (:preview content)
{:keys [type color] icon-path :icon} command]
[react/view style/content-command-view

View File

@ -77,11 +77,7 @@
[{:keys [message-id content] :as message}]
(letsubs [command [:get-command (:content-command-ref content)]
answered? [:is-request-answered? message-id]
status-initialized? [:get :status-module-initialized?]]
{:component-will-mount #(when-not (:preview content)
(dispatch [:request-command-message-data
message {:data-type :preview
:cache-data? true}]))}
status-initialized? [:get :status-module-initialized?]]
(let [{:keys [prefill prefill-bot-db prefillBotDb params preview]
text-content :text} content
command (if (and params command)