Fix bot subscriptions
This commit is contained in:
parent
abe7f0a42a
commit
0ccfefa6c3
|
@ -95,7 +95,7 @@ function amountParameterBox(params, context) {
|
|||
sliderValue: sliderValue
|
||||
});
|
||||
|
||||
}catch (err){
|
||||
} catch (err) {
|
||||
|
||||
status.setDefaultDb({
|
||||
transaction: txData,
|
||||
|
|
|
@ -35,7 +35,7 @@ status.defineSubscription(
|
|||
function(params) {
|
||||
return getFeeExplanation(params.value);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
function amountParameterBox(params, context) {
|
||||
if (!params["bot-db"]) {
|
||||
|
@ -62,13 +62,25 @@ function amountParameterBox(params, context) {
|
|||
|
||||
var sliderValue = params["bot-db"]["sliderValue"] || 0;
|
||||
|
||||
status.setDefaultDb({
|
||||
transaction: txData,
|
||||
calculatedFee: calculateFee(sliderValue, txData),
|
||||
feeExplanation: getFeeExplanation(sliderValue),
|
||||
sliderValue: sliderValue
|
||||
});
|
||||
try {
|
||||
|
||||
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 {
|
||||
title: I18n.t('send_title'),
|
||||
showBack: true,
|
||||
|
|
|
@ -1,54 +1,45 @@
|
|||
(ns status-im.bots.events
|
||||
(: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
|
||||
|
||||
(defn- chats-with-bot [chats bot]
|
||||
(reduce (fn [acc [_ {:keys [chat-id contacts]}]]
|
||||
(let [contacts (map :identity contacts)]
|
||||
(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)))
|
||||
(defn- subscription-values [sub-params current-bot-db]
|
||||
(reduce (fn [sub-values [sub-key sub-path]]
|
||||
(assoc sub-values sub-key (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
|
||||
[db {:keys [bot path value]}]
|
||||
(let [{:keys [bot-db chats]} db
|
||||
subscriptions (get-in db [:bot-subscriptions path])]
|
||||
{:call-jail-function-n
|
||||
(for [{:keys [bot subscriptions name]} subscriptions
|
||||
:let [subs-values (subscription-values subscriptions (get bot-db bot))]]
|
||||
{:chat-id bot
|
||||
:function :subscription
|
||||
:parameters {:name name
|
||||
:subscriptions subs-values}
|
||||
:callback-events-creator (fn [jail-response]
|
||||
(into [[::calculated-subscription
|
||||
{:bot bot
|
||||
:path [name]
|
||||
:result jail-response}]]
|
||||
(map (fn [chat-id]
|
||||
[::calculated-subscription
|
||||
{:bot chat-id
|
||||
:path [name]
|
||||
:result jail-response}])
|
||||
(chats-with-bot chats bot))))})}))
|
||||
[{:keys [bot-db bot-subscriptions chats current-chat-id] :as app-db} path]
|
||||
(let [owner-id (some-> app-db
|
||||
(input-model/selected-chat-command current-chat-id (get-in app-db [:chats current-chat-id :input-text]))
|
||||
:command
|
||||
:owner-id)]
|
||||
(when-let [subscriptions (and owner-id (get-in bot-subscriptions (concat [owner-id] [path])))]
|
||||
{:call-jail-function-n
|
||||
(for [[sub-name sub-params] subscriptions]
|
||||
{:chat-id owner-id
|
||||
:function :subscription
|
||||
:parameters {:name sub-name
|
||||
:subscriptions (subscription-values sub-params
|
||||
(get bot-db current-chat-id))}
|
||||
:callback-events-creator (fn [jail-response]
|
||||
[[::calculated-subscription
|
||||
{:bot current-chat-id
|
||||
:path [sub-name]
|
||||
:result jail-response}]])})})))
|
||||
|
||||
(defn set-in-bot-db
|
||||
[{:keys [current-chat-id] :as app-db} {:keys [bot path value] :as params}]
|
||||
(let [bot (or bot current-chat-id)
|
||||
new-db (assoc-in app-db (concat [:bot-db bot] path) value)]
|
||||
(merge {:db new-db}
|
||||
(check-subscriptions-fx new-db params))))
|
||||
(check-subscriptions-fx new-db path))))
|
||||
|
||||
(defn update-bot-db
|
||||
[{:keys [current-chat-id] :as app-db} {:keys [bot db]}]
|
||||
|
@ -59,6 +50,28 @@
|
|||
[{:keys [current-chat-id] :as app-db}]
|
||||
(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/register-handler-fx
|
||||
|
@ -73,21 +86,6 @@
|
|||
(fn [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
|
||||
::calculated-subscription
|
||||
[re-frame/trim-v]
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
(ns status-im.bots.subs
|
||||
(: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
|
||||
:current-bot-db
|
||||
(fn [db]
|
||||
|
|
|
@ -46,6 +46,10 @@
|
|||
|
||||
;;;; Helper functions
|
||||
|
||||
(defn- extract-command-request-owners [commands requests]
|
||||
[commands requests]
|
||||
(into #{} (keep :owner-id) (concat commands requests)))
|
||||
|
||||
(defn update-suggestions
|
||||
"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)
|
||||
|
@ -58,9 +62,14 @@
|
|||
(= type :grant-permissions))))
|
||||
commands (commands-model/commands-for-chat db current-chat-id)
|
||||
{:keys [dapp?]} (get-in db [:contacts/contacts current-chat-id])
|
||||
new-db (cond-> db
|
||||
true (assoc-in [:chats current-chat-id :possible-requests] requests)
|
||||
true (assoc-in [:chats current-chat-id :possible-commands] commands)
|
||||
;; TODO(janherich) surely there is a better place to merge in possible commands/request/subscriptions into current chat
|
||||
;; then in `:update-suggestions` which is called whenever commands for chat are loaded, chat view is opened
|
||||
;; 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?
|
||||
(str/blank? chat-text))
|
||||
(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]) ""))
|
||||
{:keys [dapp?]} (get-in db [:contacts/contacts current-chat-id])]
|
||||
(cond-> {:db db}
|
||||
(and dapp? (not (str/blank? chat-text)))
|
||||
(assoc :call-jail-function {:chat-id current-chat-id
|
||||
:function :on-message-input-change
|
||||
:parameters {:message chat-text}
|
||||
:context {:data (get local-storage current-chat-id)
|
||||
:from current-account-id}}))))
|
||||
(and dapp? (not (str/blank? chat-text)))
|
||||
(assoc :call-jail-function {:chat-id current-chat-id
|
||||
:function :on-message-input-change
|
||||
:parameters {:message chat-text}
|
||||
:context {:data (get local-storage current-chat-id)
|
||||
:from current-account-id}}))))
|
||||
|
||||
(defn set-chat-input-metadata
|
||||
"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)))]
|
||||
(cond-> {:db new-db}
|
||||
|
||||
chat-parameter-box-fx
|
||||
(merge chat-parameter-box-fx)
|
||||
chat-parameter-box-fx
|
||||
(merge chat-parameter-box-fx)
|
||||
|
||||
(and (= selection (+ (count const/command-char)
|
||||
(count (get-in command [:command :name]))
|
||||
(count const/spacing-char)))
|
||||
(get-in command [:command :sequential-params]))
|
||||
(merge (chat-input-focus new-db :seq-input-ref)))))
|
||||
(and (= selection (+ (count const/command-char)
|
||||
(count (get-in command [:command :name]))
|
||||
(count const/spacing-char)))
|
||||
(get-in command [:command :sequential-params]))
|
||||
(merge (chat-input-focus new-db :seq-input-ref)))))
|
||||
|
||||
(defn select-chat-input-command
|
||||
"Selects command + (optional) arguments as input for active chat"
|
||||
|
@ -221,19 +230,19 @@
|
|||
(input-model/join-command-args prefill)))))
|
||||
fx (assoc (load-chat-parameter-box db' command) :db db')]
|
||||
(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
|
||||
prevent-auto-focus?))
|
||||
(merge (chat-input-focus (:db fx) :input-ref))
|
||||
(not (and sequential-params
|
||||
prevent-auto-focus?))
|
||||
(merge (chat-input-focus (:db fx) :input-ref))
|
||||
|
||||
sequential-params
|
||||
(as-> fx'
|
||||
(cond-> (update fx' :db
|
||||
set-chat-seq-arg-input-text
|
||||
(str/join const/spacing-char prefill))
|
||||
(not prevent-auto-focus?)
|
||||
(merge fx' (chat-input-focus (:db fx') :seq-input-ref)))))))
|
||||
sequential-params
|
||||
(as-> fx'
|
||||
(cond-> (update fx' :db
|
||||
set-chat-seq-arg-input-text
|
||||
(str/join const/spacing-char prefill))
|
||||
(not prevent-auto-focus?)
|
||||
(merge fx' (chat-input-focus (:db fx') :seq-input-ref)))))))
|
||||
|
||||
(defn set-contact-as-command-argument
|
||||
"Sets contact as command argument for active chat"
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
[status-im.utils.handlers :as handlers]
|
||||
[status-im.utils.utils :refer [show-popup]]
|
||||
[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]
|
||||
[status-im.components.react :as r]
|
||||
[status-im.constants :refer [console-chat-id]]
|
||||
|
|
|
@ -182,13 +182,7 @@
|
|||
(reg-handler ::add-commands
|
||||
[(after (fn [_ [id]]
|
||||
(dispatch [:invoke-commands-loading-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)])))))
|
||||
(dispatch [:invoke-chat-loaded-callbacks id])))
|
||||
(after #(dispatch [:update-suggestions]))]
|
||||
add-commands)
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
(:require [status-im.components.react :as r]
|
||||
[re-frame.core :refer [dispatch]]
|
||||
[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.platform :as p]
|
||||
[status-im.utils.scheduler :as scheduler]
|
||||
|
@ -126,9 +126,10 @@
|
|||
(defn execute-call [{:keys [jail-id path params callback]}]
|
||||
(when status
|
||||
(call-module
|
||||
#(do
|
||||
#(do
|
||||
(log/debug :call-jail :jail-id jail-id)
|
||||
(log/debug :call-jail :path path)
|
||||
(log/debug :call-jail :params params)
|
||||
;; this debug message can contain sensitive info
|
||||
#_(log/debug :call-jail :params params)
|
||||
(let [params' (update params :context assoc
|
||||
|
@ -154,7 +155,8 @@
|
|||
(defn remove-duplicate-calls
|
||||
"Removes duplicates by [jail path] keys, remains the last one."
|
||||
[[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]
|
||||
[(conj all-keys [jail-id path])
|
||||
(conj calls call)]))
|
||||
|
@ -167,7 +169,7 @@
|
|||
(let [[_ new-calls] (reduce remove-duplicate-calls [#{} '()] @raw-jail-calls)]
|
||||
(reset! raw-jail-calls '())
|
||||
(swap! jail-calls (fn [old-calls]
|
||||
(concat new-calls old-calls))))
|
||||
(concat new-calls old-calls))))
|
||||
(recur (<! (timeout check-raw-calls-interval)))))
|
||||
|
||||
(defn execute-calls-loop!
|
||||
|
@ -175,8 +177,8 @@
|
|||
which reduces chances of response shuffling"
|
||||
[]
|
||||
(go-loop [_ nil]
|
||||
(let [next-call (last @jail-calls)]
|
||||
(swap! jail-calls butlast)
|
||||
(let [next-call (first @jail-calls)]
|
||||
(swap! jail-calls rest)
|
||||
(when next-call
|
||||
(execute-call next-call)))
|
||||
(recur (<! (timeout interval-between-calls)))))
|
||||
|
|
Loading…
Reference in New Issue