Fix bot subscriptions
This commit is contained in:
parent
abe7f0a42a
commit
0ccfefa6c3
|
@ -95,7 +95,7 @@ function amountParameterBox(params, context) {
|
||||||
sliderValue: sliderValue
|
sliderValue: sliderValue
|
||||||
});
|
});
|
||||||
|
|
||||||
}catch (err){
|
} catch (err) {
|
||||||
|
|
||||||
status.setDefaultDb({
|
status.setDefaultDb({
|
||||||
transaction: txData,
|
transaction: txData,
|
||||||
|
|
|
@ -35,7 +35,7 @@ status.defineSubscription(
|
||||||
function(params) {
|
function(params) {
|
||||||
return getFeeExplanation(params.value);
|
return getFeeExplanation(params.value);
|
||||||
}
|
}
|
||||||
)
|
);
|
||||||
|
|
||||||
function amountParameterBox(params, context) {
|
function amountParameterBox(params, context) {
|
||||||
if (!params["bot-db"]) {
|
if (!params["bot-db"]) {
|
||||||
|
@ -62,13 +62,25 @@ function amountParameterBox(params, context) {
|
||||||
|
|
||||||
var sliderValue = params["bot-db"]["sliderValue"] || 0;
|
var sliderValue = params["bot-db"]["sliderValue"] || 0;
|
||||||
|
|
||||||
status.setDefaultDb({
|
try {
|
||||||
transaction: txData,
|
|
||||||
calculatedFee: calculateFee(sliderValue, txData),
|
|
||||||
feeExplanation: getFeeExplanation(sliderValue),
|
|
||||||
sliderValue: sliderValue
|
|
||||||
});
|
|
||||||
|
|
||||||
|
status.setDefaultDb({
|
||||||
|
transaction: txData,
|
||||||
|
calculatedFee: calculateFee(sliderValue, txData),
|
||||||
|
feeExplanation: getFeeExplanation(sliderValue),
|
||||||
|
sliderValue: sliderValue
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
|
||||||
|
status.setDefaultDb({
|
||||||
|
transaction: txData,
|
||||||
|
calculatedFee: "0",
|
||||||
|
feeExplanation: "",
|
||||||
|
sliderValue: sliderValue
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title: I18n.t('send_title'),
|
title: I18n.t('send_title'),
|
||||||
showBack: true,
|
showBack: true,
|
||||||
|
|
|
@ -1,54 +1,45 @@
|
||||||
(ns status-im.bots.events
|
(ns status-im.bots.events
|
||||||
(:require [re-frame.core :as re-frame]
|
(:require [re-frame.core :as re-frame]
|
||||||
[status-im.utils.handlers :as handlers]))
|
[status-im.utils.handlers :as handlers]
|
||||||
|
[status-im.chat.models.input :as input-model]
|
||||||
|
[taoensso.timbre :as log]))
|
||||||
|
|
||||||
;;;; Helper fns
|
;;;; Helper fns
|
||||||
|
|
||||||
(defn- chats-with-bot [chats bot]
|
(defn- subscription-values [sub-params current-bot-db]
|
||||||
(reduce (fn [acc [_ {:keys [chat-id contacts]}]]
|
(reduce (fn [sub-values [sub-key sub-path]]
|
||||||
(let [contacts (map :identity contacts)]
|
(assoc sub-values sub-key (get-in current-bot-db sub-path)))
|
||||||
(if (some #{bot} contacts)
|
|
||||||
(conj acc chat-id)
|
|
||||||
acc)))
|
|
||||||
[]
|
|
||||||
chats))
|
|
||||||
|
|
||||||
(defn- subscription-values [subscriptions current-bot-db]
|
|
||||||
(reduce (fn [sub-values [sub-name sub-path]]
|
|
||||||
(assoc sub-values sub-name (get-in current-bot-db sub-path)))
|
|
||||||
{}
|
{}
|
||||||
subscriptions))
|
sub-params))
|
||||||
|
|
||||||
;; TODO(janherich): optimze this, for sure we don't need to re-calculate all bot subscriptions every time something in bot db changes
|
;; TODO(janherich): do this properly instead of the ugly hack with hardcoded bot-db key
|
||||||
|
;; und uneffective lookup of the owner of selected-chat-command
|
||||||
(defn- check-subscriptions-fx
|
(defn- check-subscriptions-fx
|
||||||
[db {:keys [bot path value]}]
|
[{:keys [bot-db bot-subscriptions chats current-chat-id] :as app-db} path]
|
||||||
(let [{:keys [bot-db chats]} db
|
(let [owner-id (some-> app-db
|
||||||
subscriptions (get-in db [:bot-subscriptions path])]
|
(input-model/selected-chat-command current-chat-id (get-in app-db [:chats current-chat-id :input-text]))
|
||||||
{:call-jail-function-n
|
:command
|
||||||
(for [{:keys [bot subscriptions name]} subscriptions
|
:owner-id)]
|
||||||
:let [subs-values (subscription-values subscriptions (get bot-db bot))]]
|
(when-let [subscriptions (and owner-id (get-in bot-subscriptions (concat [owner-id] [path])))]
|
||||||
{:chat-id bot
|
{:call-jail-function-n
|
||||||
:function :subscription
|
(for [[sub-name sub-params] subscriptions]
|
||||||
:parameters {:name name
|
{:chat-id owner-id
|
||||||
:subscriptions subs-values}
|
:function :subscription
|
||||||
:callback-events-creator (fn [jail-response]
|
:parameters {:name sub-name
|
||||||
(into [[::calculated-subscription
|
:subscriptions (subscription-values sub-params
|
||||||
{:bot bot
|
(get bot-db current-chat-id))}
|
||||||
:path [name]
|
:callback-events-creator (fn [jail-response]
|
||||||
:result jail-response}]]
|
[[::calculated-subscription
|
||||||
(map (fn [chat-id]
|
{:bot current-chat-id
|
||||||
[::calculated-subscription
|
:path [sub-name]
|
||||||
{:bot chat-id
|
:result jail-response}]])})})))
|
||||||
:path [name]
|
|
||||||
:result jail-response}])
|
|
||||||
(chats-with-bot chats bot))))})}))
|
|
||||||
|
|
||||||
(defn set-in-bot-db
|
(defn set-in-bot-db
|
||||||
[{:keys [current-chat-id] :as app-db} {:keys [bot path value] :as params}]
|
[{:keys [current-chat-id] :as app-db} {:keys [bot path value] :as params}]
|
||||||
(let [bot (or bot current-chat-id)
|
(let [bot (or bot current-chat-id)
|
||||||
new-db (assoc-in app-db (concat [:bot-db bot] path) value)]
|
new-db (assoc-in app-db (concat [:bot-db bot] path) value)]
|
||||||
(merge {:db new-db}
|
(merge {:db new-db}
|
||||||
(check-subscriptions-fx new-db params))))
|
(check-subscriptions-fx new-db path))))
|
||||||
|
|
||||||
(defn update-bot-db
|
(defn update-bot-db
|
||||||
[{:keys [current-chat-id] :as app-db} {:keys [bot db]}]
|
[{:keys [current-chat-id] :as app-db} {:keys [bot db]}]
|
||||||
|
@ -59,6 +50,28 @@
|
||||||
[{:keys [current-chat-id] :as app-db}]
|
[{:keys [current-chat-id] :as app-db}]
|
||||||
(assoc-in app-db [:bot-db current-chat-id] nil))
|
(assoc-in app-db [:bot-db current-chat-id] nil))
|
||||||
|
|
||||||
|
(def ^:private keywordize-vector (partial mapv keyword))
|
||||||
|
|
||||||
|
;; TODO(janherich): do something with this horrible triple nested reduce so it's more readable
|
||||||
|
(defn add-active-bot-subscriptions
|
||||||
|
[app-db bot-identities]
|
||||||
|
(let [relevant-bots (select-keys (:contacts/contacts app-db) bot-identities)
|
||||||
|
active-subscriptions (reduce (fn [acc [bot-id {:keys [subscriptions]}]]
|
||||||
|
(reduce (fn [acc [sub-key {:keys [subscriptions]}]]
|
||||||
|
(reduce (fn [acc [sub-param-key sub-param-path]]
|
||||||
|
(update-in acc [bot-id (keywordize-vector sub-param-path)]
|
||||||
|
assoc sub-key (into {}
|
||||||
|
(map (fn [[k v]]
|
||||||
|
[k (keywordize-vector v)]))
|
||||||
|
subscriptions)))
|
||||||
|
acc
|
||||||
|
subscriptions))
|
||||||
|
acc
|
||||||
|
subscriptions))
|
||||||
|
{}
|
||||||
|
relevant-bots)]
|
||||||
|
(assoc app-db :bot-subscriptions active-subscriptions)))
|
||||||
|
|
||||||
;;;; Handlers
|
;;;; Handlers
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
|
@ -73,21 +86,6 @@
|
||||||
(fn [db [params]]
|
(fn [db [params]]
|
||||||
(update-bot-db db params)))
|
(update-bot-db db params)))
|
||||||
|
|
||||||
(handlers/register-handler-db
|
|
||||||
:register-bot-subscription
|
|
||||||
[re-frame/trim-v]
|
|
||||||
(fn [db [{:keys [bot subscriptions] :as opts}]]
|
|
||||||
(reduce
|
|
||||||
(fn [db [sub-name sub-path]]
|
|
||||||
(let [keywordized-sub-path (mapv keyword
|
|
||||||
(if (coll? sub-path)
|
|
||||||
sub-path
|
|
||||||
[sub-path]))]
|
|
||||||
(update-in db [:bot-subscriptions keywordized-sub-path] conj
|
|
||||||
(assoc-in opts [:subscriptions sub-name] keywordized-sub-path))))
|
|
||||||
db
|
|
||||||
subscriptions)))
|
|
||||||
|
|
||||||
(handlers/register-handler-db
|
(handlers/register-handler-db
|
||||||
::calculated-subscription
|
::calculated-subscription
|
||||||
[re-frame/trim-v]
|
[re-frame/trim-v]
|
||||||
|
|
|
@ -1,12 +1,6 @@
|
||||||
(ns status-im.bots.subs
|
(ns status-im.bots.subs
|
||||||
(:require [re-frame.core :refer [reg-sub subscribe]]))
|
(:require [re-frame.core :refer [reg-sub subscribe]]))
|
||||||
|
|
||||||
(reg-sub
|
|
||||||
:bot-subscription
|
|
||||||
(fn [db [_ path]]
|
|
||||||
(let [chat-id (subscribe [:get-current-chat-id])]
|
|
||||||
(get-in db (concat [:bot-db @chat-id] path)))))
|
|
||||||
|
|
||||||
(reg-sub
|
(reg-sub
|
||||||
:current-bot-db
|
:current-bot-db
|
||||||
(fn [db]
|
(fn [db]
|
||||||
|
|
|
@ -46,6 +46,10 @@
|
||||||
|
|
||||||
;;;; Helper functions
|
;;;; Helper functions
|
||||||
|
|
||||||
|
(defn- extract-command-request-owners [commands requests]
|
||||||
|
[commands requests]
|
||||||
|
(into #{} (keep :owner-id) (concat commands requests)))
|
||||||
|
|
||||||
(defn update-suggestions
|
(defn update-suggestions
|
||||||
"Update suggestions for current chat input, takes db as the only argument
|
"Update suggestions for current chat input, takes db as the only argument
|
||||||
and returns map with keys :db (new db with up-to-date suggestions) and (optionally)
|
and returns map with keys :db (new db with up-to-date suggestions) and (optionally)
|
||||||
|
@ -58,9 +62,14 @@
|
||||||
(= type :grant-permissions))))
|
(= type :grant-permissions))))
|
||||||
commands (commands-model/commands-for-chat db current-chat-id)
|
commands (commands-model/commands-for-chat db current-chat-id)
|
||||||
{:keys [dapp?]} (get-in db [:contacts/contacts current-chat-id])
|
{:keys [dapp?]} (get-in db [:contacts/contacts current-chat-id])
|
||||||
new-db (cond-> db
|
;; TODO(janherich) surely there is a better place to merge in possible commands/request/subscriptions into current chat
|
||||||
true (assoc-in [:chats current-chat-id :possible-requests] requests)
|
;; then in `:update-suggestions` which is called whenever commands for chat are loaded, chat view is opened
|
||||||
true (assoc-in [:chats current-chat-id :possible-commands] commands)
|
;; or new message is received from network - it's unnecessary to call it as a response to last two events
|
||||||
|
new-db (cond-> (-> db
|
||||||
|
(update-in [:chats current-chat-id] merge {:possible-commands commands
|
||||||
|
:possible-requests requests})
|
||||||
|
(bots-events/add-active-bot-subscriptions (extract-command-request-owners
|
||||||
|
commands requests)))
|
||||||
(and dapp?
|
(and dapp?
|
||||||
(str/blank? chat-text))
|
(str/blank? chat-text))
|
||||||
(assoc-in [:chats current-chat-id :parameter-boxes :message] nil))]
|
(assoc-in [:chats current-chat-id :parameter-boxes :message] nil))]
|
||||||
|
@ -90,12 +99,12 @@
|
||||||
(let [chat-text (str/trim (or (get-in chats [current-chat-id :input-text]) ""))
|
(let [chat-text (str/trim (or (get-in chats [current-chat-id :input-text]) ""))
|
||||||
{:keys [dapp?]} (get-in db [:contacts/contacts current-chat-id])]
|
{:keys [dapp?]} (get-in db [:contacts/contacts current-chat-id])]
|
||||||
(cond-> {:db db}
|
(cond-> {:db db}
|
||||||
(and dapp? (not (str/blank? chat-text)))
|
(and dapp? (not (str/blank? chat-text)))
|
||||||
(assoc :call-jail-function {:chat-id current-chat-id
|
(assoc :call-jail-function {:chat-id current-chat-id
|
||||||
:function :on-message-input-change
|
:function :on-message-input-change
|
||||||
:parameters {:message chat-text}
|
:parameters {:message chat-text}
|
||||||
:context {:data (get local-storage current-chat-id)
|
:context {:data (get local-storage current-chat-id)
|
||||||
:from current-account-id}}))))
|
:from current-account-id}}))))
|
||||||
|
|
||||||
(defn set-chat-input-metadata
|
(defn set-chat-input-metadata
|
||||||
"Set input metadata for active chat. Takes db and metadata and returns updated db."
|
"Set input metadata for active chat. Takes db and metadata and returns updated db."
|
||||||
|
@ -193,14 +202,14 @@
|
||||||
(load-chat-parameter-box new-db (:command command)))]
|
(load-chat-parameter-box new-db (:command command)))]
|
||||||
(cond-> {:db new-db}
|
(cond-> {:db new-db}
|
||||||
|
|
||||||
chat-parameter-box-fx
|
chat-parameter-box-fx
|
||||||
(merge chat-parameter-box-fx)
|
(merge chat-parameter-box-fx)
|
||||||
|
|
||||||
(and (= selection (+ (count const/command-char)
|
(and (= selection (+ (count const/command-char)
|
||||||
(count (get-in command [:command :name]))
|
(count (get-in command [:command :name]))
|
||||||
(count const/spacing-char)))
|
(count const/spacing-char)))
|
||||||
(get-in command [:command :sequential-params]))
|
(get-in command [:command :sequential-params]))
|
||||||
(merge (chat-input-focus new-db :seq-input-ref)))))
|
(merge (chat-input-focus new-db :seq-input-ref)))))
|
||||||
|
|
||||||
(defn select-chat-input-command
|
(defn select-chat-input-command
|
||||||
"Selects command + (optional) arguments as input for active chat"
|
"Selects command + (optional) arguments as input for active chat"
|
||||||
|
@ -221,19 +230,19 @@
|
||||||
(input-model/join-command-args prefill)))))
|
(input-model/join-command-args prefill)))))
|
||||||
fx (assoc (load-chat-parameter-box db' command) :db db')]
|
fx (assoc (load-chat-parameter-box db' command) :db db')]
|
||||||
(cond-> fx
|
(cond-> fx
|
||||||
prefill-bot-db (update :db bots-events/update-bot-db {:db prefill-bot-db})
|
prefill-bot-db (update :db bots-events/update-bot-db {:db prefill-bot-db})
|
||||||
|
|
||||||
(not (and sequential-params
|
(not (and sequential-params
|
||||||
prevent-auto-focus?))
|
prevent-auto-focus?))
|
||||||
(merge (chat-input-focus (:db fx) :input-ref))
|
(merge (chat-input-focus (:db fx) :input-ref))
|
||||||
|
|
||||||
sequential-params
|
sequential-params
|
||||||
(as-> fx'
|
(as-> fx'
|
||||||
(cond-> (update fx' :db
|
(cond-> (update fx' :db
|
||||||
set-chat-seq-arg-input-text
|
set-chat-seq-arg-input-text
|
||||||
(str/join const/spacing-char prefill))
|
(str/join const/spacing-char prefill))
|
||||||
(not prevent-auto-focus?)
|
(not prevent-auto-focus?)
|
||||||
(merge fx' (chat-input-focus (:db fx') :seq-input-ref)))))))
|
(merge fx' (chat-input-focus (:db fx') :seq-input-ref)))))))
|
||||||
|
|
||||||
(defn set-contact-as-command-argument
|
(defn set-contact-as-command-argument
|
||||||
"Sets contact as command argument for active chat"
|
"Sets contact as command argument for active chat"
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
[status-im.utils.handlers :as handlers]
|
[status-im.utils.handlers :as handlers]
|
||||||
[status-im.utils.utils :refer [show-popup]]
|
[status-im.utils.utils :refer [show-popup]]
|
||||||
[status-im.utils.types :refer [json->clj]]
|
[status-im.utils.types :refer [json->clj]]
|
||||||
[status-im.commands.utils :refer [generate-hiccup reg-handler]]
|
[status-im.commands.utils :refer [reg-handler]]
|
||||||
[clojure.string :as s]
|
[clojure.string :as s]
|
||||||
[status-im.components.react :as r]
|
[status-im.components.react :as r]
|
||||||
[status-im.constants :refer [console-chat-id]]
|
[status-im.constants :refer [console-chat-id]]
|
||||||
|
|
|
@ -182,13 +182,7 @@
|
||||||
(reg-handler ::add-commands
|
(reg-handler ::add-commands
|
||||||
[(after (fn [_ [id]]
|
[(after (fn [_ [id]]
|
||||||
(dispatch [:invoke-commands-loading-callbacks id])
|
(dispatch [:invoke-commands-loading-callbacks id])
|
||||||
(dispatch [:invoke-chat-loaded-callbacks id])))
|
(dispatch [:invoke-chat-loaded-callbacks id])))
|
||||||
(after (fn [{:contacts/keys [contacts]} [id]]
|
|
||||||
(let [subscriptions (get-in contacts [id :subscriptions])]
|
|
||||||
(doseq [[name opts] subscriptions]
|
|
||||||
(dispatch [:register-bot-subscription
|
|
||||||
(assoc opts :bot id
|
|
||||||
:name name)])))))
|
|
||||||
(after #(dispatch [:update-suggestions]))]
|
(after #(dispatch [:update-suggestions]))]
|
||||||
add-commands)
|
add-commands)
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
(:require [status-im.components.react :as r]
|
(:require [status-im.components.react :as r]
|
||||||
[re-frame.core :refer [dispatch]]
|
[re-frame.core :refer [dispatch]]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
[cljs.core.async :refer [<! timeout]]
|
[cljs.core.async :as async :refer [<! timeout]]
|
||||||
[status-im.utils.js-resources :as js-res]
|
[status-im.utils.js-resources :as js-res]
|
||||||
[status-im.utils.platform :as p]
|
[status-im.utils.platform :as p]
|
||||||
[status-im.utils.scheduler :as scheduler]
|
[status-im.utils.scheduler :as scheduler]
|
||||||
|
@ -126,9 +126,10 @@
|
||||||
(defn execute-call [{:keys [jail-id path params callback]}]
|
(defn execute-call [{:keys [jail-id path params callback]}]
|
||||||
(when status
|
(when status
|
||||||
(call-module
|
(call-module
|
||||||
#(do
|
#(do
|
||||||
(log/debug :call-jail :jail-id jail-id)
|
(log/debug :call-jail :jail-id jail-id)
|
||||||
(log/debug :call-jail :path path)
|
(log/debug :call-jail :path path)
|
||||||
|
(log/debug :call-jail :params params)
|
||||||
;; this debug message can contain sensitive info
|
;; this debug message can contain sensitive info
|
||||||
#_(log/debug :call-jail :params params)
|
#_(log/debug :call-jail :params params)
|
||||||
(let [params' (update params :context assoc
|
(let [params' (update params :context assoc
|
||||||
|
@ -154,7 +155,8 @@
|
||||||
(defn remove-duplicate-calls
|
(defn remove-duplicate-calls
|
||||||
"Removes duplicates by [jail path] keys, remains the last one."
|
"Removes duplicates by [jail path] keys, remains the last one."
|
||||||
[[all-keys calls] {:keys [jail-id path] :as call}]
|
[[all-keys calls] {:keys [jail-id path] :as call}]
|
||||||
(if (contains? all-keys [jail-id path])
|
(if (and (contains? all-keys [jail-id path])
|
||||||
|
(not= (second path) :subscription))
|
||||||
[all-keys calls]
|
[all-keys calls]
|
||||||
[(conj all-keys [jail-id path])
|
[(conj all-keys [jail-id path])
|
||||||
(conj calls call)]))
|
(conj calls call)]))
|
||||||
|
@ -167,7 +169,7 @@
|
||||||
(let [[_ new-calls] (reduce remove-duplicate-calls [#{} '()] @raw-jail-calls)]
|
(let [[_ new-calls] (reduce remove-duplicate-calls [#{} '()] @raw-jail-calls)]
|
||||||
(reset! raw-jail-calls '())
|
(reset! raw-jail-calls '())
|
||||||
(swap! jail-calls (fn [old-calls]
|
(swap! jail-calls (fn [old-calls]
|
||||||
(concat new-calls old-calls))))
|
(concat new-calls old-calls))))
|
||||||
(recur (<! (timeout check-raw-calls-interval)))))
|
(recur (<! (timeout check-raw-calls-interval)))))
|
||||||
|
|
||||||
(defn execute-calls-loop!
|
(defn execute-calls-loop!
|
||||||
|
@ -175,8 +177,8 @@
|
||||||
which reduces chances of response shuffling"
|
which reduces chances of response shuffling"
|
||||||
[]
|
[]
|
||||||
(go-loop [_ nil]
|
(go-loop [_ nil]
|
||||||
(let [next-call (last @jail-calls)]
|
(let [next-call (first @jail-calls)]
|
||||||
(swap! jail-calls butlast)
|
(swap! jail-calls rest)
|
||||||
(when next-call
|
(when next-call
|
||||||
(execute-call next-call)))
|
(execute-call next-call)))
|
||||||
(recur (<! (timeout interval-between-calls)))))
|
(recur (<! (timeout interval-between-calls)))))
|
||||||
|
|
Loading…
Reference in New Issue