diff --git a/src/status_im/android/core.cljs b/src/status_im/android/core.cljs index f289a24192..338bf04880 100644 --- a/src/status_im/android/core.cljs +++ b/src/status_im/android/core.cljs @@ -22,7 +22,7 @@ ;; in handlers (let [stack (subscribe [:get :navigation-stack]) creating? (subscribe [:get :accounts/creating-account?]) - result-box (subscribe [:chat-ui-props :result-box]) + result-box (subscribe [:get-current-chat-ui-prop :result-box]) webview (subscribe [:get :webview-bridge])] (cond @creating? true diff --git a/src/status_im/bots/subs.cljs b/src/status_im/bots/subs.cljs index 83bbbdd1db..1e64993b7f 100644 --- a/src/status_im/bots/subs.cljs +++ b/src/status_im/bots/subs.cljs @@ -2,14 +2,11 @@ (:require [re-frame.core :as re-frame] [status-im.chat.models.input :as input-model])) -(re-frame/reg-sub - :bot-db - (fn [db] - (:bot-db db))) +(re-frame/reg-sub :get-bot-db :bot-db) (re-frame/reg-sub :current-bot-db - :<- [:bot-db] + :<- [:get-bot-db] :<- [:selected-chat-command] (fn [[bot-db command]] (let [command-owner (get-in command [:command :owner-id])] diff --git a/src/status_im/chat/events/input.cljs b/src/status_im/chat/events/input.cljs index 3e5891eee6..522bd60705 100644 --- a/src/status_im/chat/events/input.cljs +++ b/src/status_im/chat/events/input.cljs @@ -6,7 +6,6 @@ [status-im.chat.utils :as chat-utils] [status-im.chat.models :as model] [status-im.chat.models.input :as input-model] - [status-im.chat.models.commands :as commands-model] [status-im.chat.events.commands :as commands-events] [status-im.chat.events.animation :as animation-events] [status-im.bots.events :as bots-events] @@ -64,6 +63,9 @@ (and dapp? (str/blank? chat-text)) (assoc-in [:chats current-chat-id :parameter-boxes :message] nil)))) +;; TODO janherich: this is super fragile and won't work at all for group chats with bots. +;; The proper way how to do it is to check each chat participant and call `:on-message-input-change` +;; jail function in each participant's jail (defn call-on-message-input-change "Calls bot's `on-message-input-change` function" [{:keys [current-chat-id current-account-id chats local-storage] :as db}] @@ -99,7 +101,7 @@ [{:keys [current-chat-id] :as db} index arg move-to-next?] (let [command (-> (get-in db [:chats current-chat-id :input-text]) (input-model/split-command-args)) - seq-params? (-> (input-model/selected-chat-command db current-chat-id) + seq-params? (-> (input-model/selected-chat-command db) (get-in [:command :sequential-params]))] (if seq-params? (set-chat-seq-arg-input-text db arg) @@ -114,7 +116,7 @@ (input-model/join-command-args command-args) (when (and move-to-next? (= index (dec (count command-args)))) - const/spacing-char))] + const/spacing-char))] (set-chat-input-text db input-text))))) (defn load-chat-parameter-box @@ -160,9 +162,8 @@ (defn update-text-selection "Updates text selection in active chat input" - [{:keys [current-chat-id] :as db} selection] - (let [input-text (get-in db [:chats current-chat-id :input-text]) - command (input-model/selected-chat-command db current-chat-id input-text) + [db selection] + (let [command (input-model/selected-chat-command db) new-db (model/set-chat-ui-props db {:selection selection}) chat-parameter-box-fx (when command (load-chat-parameter-box new-db (:command command)))] @@ -213,13 +214,10 @@ (defn set-contact-as-command-argument "Sets contact as command argument for active chat" - [{:keys [current-chat-id] :as db} {:keys [bot-db-key contact arg-index]}] + [db {:keys [bot-db-key contact arg-index]}] (let [name (str/replace (:name contact) (re-pattern const/arg-wrapping-char) "") contact (select-keys contact [:address :whisper-identity :name :photo-path :dapp?]) - command-owner (-> db - (input-model/selected-chat-command current-chat-id) - :command - :owner-id)] + command-owner (get-in (input-model/selected-chat-command db) [:command :owner-id])] (-> db (set-command-argument arg-index name true) (bots-events/set-in-bot-db {:bot command-owner @@ -441,8 +439,7 @@ [(re-frame/inject-cofx :random-id)] (fn [{{:keys [current-chat-id current-public-key] :as db} :db message-id :random-id current-time :now} _] (let [input-text (get-in db [:chats current-chat-id :input-text]) - chat-command (-> db - (input-model/selected-chat-command current-chat-id input-text) + chat-command (-> (input-model/selected-chat-command db) (as-> selected-command (if (get-in selected-command [:command :sequential-params]) (assoc selected-command :args @@ -493,7 +490,7 @@ (fn [{{:keys [current-chat-id chats] :as db} :db} _] (let [text (get-in chats [current-chat-id :seq-argument-input-text]) seq-arguments (get-in chats [current-chat-id :seq-arguments]) - command (-> (input-model/selected-chat-command db current-chat-id) + 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 @@ -520,8 +517,7 @@ (handlers/register-handler-fx :select-prev-argument (fn [{{:keys [chat-ui-props current-chat-id] :as db} :db} _] - (let [input-text (get-in db [:chats current-chat-id :input-text]) - command (input-model/selected-chat-command db current-chat-id input-text)] + (let [command (input-model/selected-chat-command db)] (if (get-in command [:command :sequential-params]) (-> db (set-command-argument 0 "" false) diff --git a/src/status_im/chat/models/input.cljs b/src/status_im/chat/models/input.cljs index 1791588020..b30e200303 100644 --- a/src/status_im/chat/models/input.cljs +++ b/src/status_im/chat/models/input.cljs @@ -96,45 +96,44 @@ (str/join const/spacing-char)))) (defn selected-chat-command - "Returns a map containing `:command`, `:metadata` and `:args` keys. - Can also return `nil` if there is no selected command. + "Takes whole db, or current chat and available commands/responses and returns a map + containing `:command`, `:metadata` and `:args` keys. Can also return `nil` if there is no selected command. * `:command` key contains a map with all information about command. * `:metadata` is also a map which contains some additional information, usually not visible by user. For instance, we can add a `:to-message-id` key to this map, and this key will allow us to identity the request we're responding to. * `:args` contains all arguments provided by user." - ([{:keys [current-chat-id access-scope->commands-responses] - :contacts/keys [contacts] - :accounts/keys [accounts current-account-id] :as db} chat-id input-text] - (let [chat-id (or chat-id current-chat-id) - chat (get-in db [:chats chat-id]) - {:keys [input-metadata seq-arguments requests]} chat - command-args (split-command-args input-text) - command-name (first command-args)] - (when (starts-as-command? (or command-name "")) - (let [account (get accounts current-account-id) - available-commands-responses (merge (commands-model/commands-responses :command - access-scope->commands-responses - account - chat - contacts) - (commands-model/requested-responses access-scope->commands-responses - account - chat - contacts - (vals requests)))] - (when-let [{{:keys [message-id]} :request :as command} (get available-commands-responses (subs command-name 1))] - {:command command - :metadata (if (and (nil? (:to-message-id input-metadata)) message-id) - (assoc input-metadata :to-message-id message-id) - input-metadata) - :args (->> (if (empty? seq-arguments) + ([{:keys [input-text input-metadata seq-arguments] :as current-chat} commands responses] + (let [[command-name :as command-args] (split-command-args input-text)] + (when-let [{{:keys [message-id]} :request :as command} (and command-name + (starts-as-command? command-name) + (get (merge commands + responses) + (subs command-name 1)))] + {:command command + :metadata (if (and message-id (not (:to-message-id input-metadata))) + (assoc input-metadata :to-message-id message-id) + input-metadata) + :args (into [] (if (empty? seq-arguments) (rest command-args) - seq-arguments) - (into []))}))))) - ([{:keys [current-chat-id] :as db} chat-id] - (selected-chat-command db chat-id (get-in db [:chats chat-id :input-text])))) + seq-arguments))}))) + ([{:keys [chats current-chat-id access-scope->commands-responses] + :contacts/keys [contacts] + :accounts/keys [accounts current-account-id] :as db}] + (let [chat (get chats current-chat-id) + account (get accounts current-account-id)] + (selected-chat-command chat + (commands-model/commands-responses :command + access-scope->commands-responses + account + chat + contacts) + (commands-model/requested-responses access-scope->commands-responses + account + chat + contacts + (vals (:requests chat))))))) (def *no-argument-error* -1) @@ -169,7 +168,7 @@ (let [input-text (get-in db [:chats current-chat-id :input-text]) seq-arguments (get-in db [:chats current-chat-id :seq-arguments]) selection (get-in db [:chat-ui-props current-chat-id :selection]) - chat-command (selected-chat-command db current-chat-id)] + chat-command (selected-chat-command db)] (current-chat-argument-position chat-command input-text selection seq-arguments))) (defn command-completion @@ -178,30 +177,25 @@ * `:less-than-needed` means that the command is not complete and additional arguments should be provided; * `:more-than-needed` means that the command is more than complete and contains redundant arguments; * `:no-command` means that there is no selected command." - ([{:keys [current-chat-id] :as db} chat-id] - (let [chat-id (or chat-id current-chat-id) - input-text (get-in db [:chats chat-id :input-text]) - chat-command (selected-chat-command db chat-id)] - (command-completion chat-command))) - ([{:keys [args] :as chat-command}] - (let [args (remove str/blank? args) - params (get-in chat-command [:command :params]) - required-params (remove :optional params)] - (if chat-command - (cond - (or (= (count args) (count params)) - (= (count args) (count required-params))) - :complete + [{:keys [args] :as chat-command}] + (let [args (remove str/blank? args) + params (get-in chat-command [:command :params]) + required-params (remove :optional params)] + (if chat-command + (cond + (or (= (count args) (count params)) + (= (count args) (count required-params))) + :complete - (< (count args) (count required-params)) - :less-than-needed + (< (count args) (count required-params)) + :less-than-needed - (> (count args) (count params)) - :more-than-needed + (> (count args) (count params)) + :more-than-needed - :default - :no-command) - :no-command)))) + :default + :no-command) + :no-command))) (defn args->params "Uses `args` (which is a list or vector like ['Jarrad' '1.0']) and command's `params` @@ -228,8 +222,7 @@ (defn modified-db-after-change "Returns the new db object that should be used after any input change." [{:keys [current-chat-id] :as db}] - (let [input-text (get-in db [:chats current-chat-id :input-text]) - command (selected-chat-command db current-chat-id input-text) + (let [command (selected-chat-command db) prev-command (get-in db [:chat-ui-props current-chat-id :prev-command])] (if command (cond-> db diff --git a/src/status_im/chat/screen.cljs b/src/status_im/chat/screen.cljs index af8cd2aa0f..72b4e3c74d 100644 --- a/src/status_im/chat/screen.cljs +++ b/src/status_im/chat/screen.cljs @@ -86,7 +86,7 @@ (list-item [chat-message message]))) (defn toolbar-action [] - (let [show-actions (subscribe [:chat-ui-props :show-actions?])] + (let [show-actions (subscribe [:get-current-chat-ui-prop :show-actions?])] (fn [] (let [show-actions @show-actions] [touchable-highlight @@ -108,7 +108,7 @@ (label :t/add-to-contacts)]]])) (defview chat-toolbar [] - [show-actions? [:chat-ui-props :show-actions?] + [show-actions? [:get-current-chat-ui-prop :show-actions?] accounts [:get-accounts] creating? [:get :accounts/creating-account?]] [view @@ -175,9 +175,9 @@ (defview chat [] [group-chat [:chat :group-chat] - show-actions? [:chat-ui-props :show-actions?] - show-bottom-info? [:chat-ui-props :show-bottom-info?] - show-emoji? [:chat-ui-props :show-emoji?] + show-actions? [:get-current-chat-ui-prop :show-actions?] + show-bottom-info? [:get-current-chat-ui-prop :show-bottom-info?] + show-emoji? [:get-current-chat-ui-prop :show-emoji?] layout-height [:get :layout-height] input-text [:chat :input-text]] {:component-did-mount #(dispatch [:check-and-open-dapp!]) diff --git a/src/status_im/chat/subs.cljs b/src/status_im/chat/subs.cljs index 4ad9efda4f..360524c982 100644 --- a/src/status_im/chat/subs.cljs +++ b/src/status_im/chat/subs.cljs @@ -14,17 +14,36 @@ [taoensso.timbre :as log] [clojure.string :as str])) -(reg-sub - :chat-ui-props - (fn [db [_ ui-element chat-id]] - (let [current-chat-id (subscribe [:get-current-chat-id]) - data (get-in db [:chat-ui-props (or chat-id @current-chat-id) ui-element])] - (cond-> data - (:markup data) - (update :markup commands-utils/generate-hiccup) +(reg-sub :chats :chats) - (and (= ui-element :validation-messages) data) - commands-utils/generate-hiccup)))) +(reg-sub :get-current-chat-id :current-chat-id) + +(reg-sub :chat-ui-props :chat-ui-props) + +(reg-sub + :get-current-chat-ui-props + :<- [:chat-ui-props] + :<- [:get-current-chat-id] + (fn [[chat-ui-props id]] + (get chat-ui-props id))) + +(reg-sub + :get-current-chat-ui-prop + :<- [:get-current-chat-ui-props] + (fn [ui-props [_ prop]] + (get ui-props prop))) + +(reg-sub + :validation-messages + :<- [:get-current-chat-ui-props] + (fn [ui-props] + (some-> ui-props :validation-messages commands-utils/generate-hiccup))) + +(reg-sub + :result-box-markup + :<- [:get-current-chat-ui-props] + (fn [ui-props] + (some-> ui-props :result-box :markup commands-utils/generate-hiccup))) (reg-sub :chat-input-margin @@ -32,11 +51,6 @@ (fn [kb-height] (if ios? kb-height 0))) -(reg-sub - :chats - (fn [db] - (:chats db))) - (reg-sub :get-current-chat :<- [:chats] @@ -53,16 +67,16 @@ (reg-sub :get-commands-for-chat - :<- [:get-commands-responses-by-access-scope] + :<- [:get-commands-responses-by-access-scope] :<- [:get-current-account] :<- [:get-current-chat] :<- [:get-contacts] - (fn [[commands-responses account chat contacts]] + (fn [[commands-responses account chat contacts]] (commands-model/commands-responses :command commands-responses account chat contacts))) (reg-sub :get-responses-for-chat - :<- [:get-commands-responses-by-access-scope] + :<- [:get-commands-responses-by-access-scope] :<- [:get-current-account] :<- [:get-current-chat] :<- [:get-contacts] @@ -90,61 +104,54 @@ available-commands-responses) (reg-sub - :get-available-commands-responses - :<- [:get-commands-for-chat] - :<- [:get-responses-for-chat] - (fn [[commands responses]] - (map->sorted-seq (merge commands responses)))) - -(reg-sub - :get-current-chat-id - (fn [db] - (:current-chat-id db))) - -(reg-sub - :get-chat-by-id - (fn [_ [_ chat-id]] - (chats/get-by-id chat-id))) + :get-available-commands-responses + :<- [:get-commands-for-chat] + :<- [:get-responses-for-chat] + (fn [[commands responses]] + (map->sorted-seq (merge commands responses)))) (reg-sub :selected-chat-command - (fn [db [_ chat-id]] - (let [current-chat-id (subscribe [:get :current-chat-id]) - input-text (subscribe [:chat :input-text])] - (input-model/selected-chat-command db (or chat-id @current-chat-id) @input-text)))) + :<- [:get-current-chat] + :<- [:get-commands-for-chat] + :<- [:get-responses-for-chat] + (fn [[chat commands responses]] + (input-model/selected-chat-command chat commands responses))) (reg-sub :current-chat-argument-position :<- [:selected-chat-command] :<- [:chat :input-text] :<- [:chat :seq-arguments] - :<- [:chat-ui-props :selection] - (fn [[command input-text seq-arguments selection]] + :<- [:get-current-chat-ui-prop :selection] + (fn [[command input-text seq-arguments selection]] (input-model/current-chat-argument-position command input-text selection seq-arguments))) (reg-sub :chat-parameter-box - (fn [db] - (let [chat-id (subscribe [:get-current-chat-id]) - command (subscribe [:selected-chat-command]) - index (subscribe [:current-chat-argument-position])] - (cond - (and @command (not= @index input-model/*no-argument-error*)) - (let [command-name (get-in @command [:command :name])] - (get-in db [:chats @chat-id :parameter-boxes command-name @index])) + :<- [:get-current-chat] + :<- [:selected-chat-command] + :<- [:current-chat-argument-position] + (fn [[current-chat selected-chat-command argument-position]] + (cond + (and selected-chat-command + (not= argument-position input-model/*no-argument-error*)) + (get-in current-chat [:parameter-boxes + (get-in selected-chat-command [:command :name]) + argument-position]) - (not @command) - (get-in db [:chats @chat-id :parameter-boxes :message]) + (not selected-chat-command) + (get-in current-chat [:parameter-boxes :message]) - :default - nil)))) + :default + nil))) (reg-sub - :show-parameter-box? + :show-parameter-box? :<- [:chat-parameter-box] :<- [:show-suggestions?] :<- [:chat :input-text] - :<- [:chat-ui-props :validation-messages] + :<- [:validation-messages] (fn [[chat-parameter-box show-suggestions? input-text validation-messages]] (and (get chat-parameter-box :markup) (not validation-messages) @@ -152,109 +159,116 @@ (reg-sub :command-completion - (fn [db [_ chat-id]] - (input-model/command-completion db chat-id))) + :<- [:selected-chat-command] + input-model/command-completion) (reg-sub :show-suggestions? - (fn [db [_ chat-id]] - (let [chat-id (or chat-id (db :current-chat-id)) - show-suggestions? (subscribe [:chat-ui-props :show-suggestions? chat-id]) - input-text (subscribe [:chat :input-text chat-id]) - selected-command (subscribe [:selected-chat-command chat-id]) - commands-responses (subscribe [:get-available-commands-responses])] - (and (or @show-suggestions? (input-model/starts-as-command? (str/trim (or @input-text "")))) - (not (:command @selected-command)) - (seq @commands-responses))))) + :<- [:get-current-chat-ui-prop :show-suggestions?] + :<- [:chat :input-text] + :<- [:selected-chat-command] + :<- [:get-available-commands-responses] + (fn [[show-suggestions? input-text selected-command commands-responses]] + (and (or show-suggestions? (input-model/starts-as-command? (str/trim (or input-text "")))) + (not (:command selected-command)) + (seq commands-responses)))) -(reg-sub :get-chat - (fn [db [_ chat-id]] - (get-in db [:chats chat-id]))) - -(reg-sub :get-response - (fn [db [_ n]] - (let [chat-id (subscribe [:get-current-chat-id])] - (get-in db [:contacts/contacts @chat-id :responses n])))) - -(reg-sub :is-request-answered? +(reg-sub + :is-request-answered? :<- [:chat :requests] (fn [requests [_ message-id]] (not= "open" (get-in requests [message-id :status])))) -(reg-sub :unviewed-messages-count +(reg-sub + :unviewed-messages-count (fn [db [_ chat-id]] (get-in db [:unviewed-messages chat-id :count]))) -(reg-sub :web-view-extra-js - (fn [db] - (let [chat-id (subscribe [:get-current-chat-id])] - (get-in db [:web-view-extra-js @chat-id])))) +(reg-sub + :web-view-extra-js + :<- [:get-current-chat] + (fn [current-chat] + (:web-view-extra-js current-chat))) -(reg-sub :all-messages-loaded? - (fn [db] - (let [chat-id (subscribe [:get-current-chat-id])] - (get-in db [:chats @chat-id :all-loaded?])))) +(reg-sub + :all-messages-loaded? + :<- [:get-current-chat] + (fn [current-chat] + (:all-loaded? current-chat))) -(reg-sub :photo-path +(reg-sub + :photo-path :<- [:get-contacts] (fn [contacts [_ id]] (:photo-path (contacts id)))) -(reg-sub :get-last-message - (fn [db [_ chat-id]] - (let [{:keys [last-message messages]} (get-in db [:chats chat-id])] +;; TODO janherich: this is just bad and horribly ineffecient (always sorting to get last msg + +;; stale `:last-message` in app-db) refactor messages data-model to properly index them ASAP +(reg-sub + :get-last-message + :<- [:chats] + (fn [chats [_ chat-id]] + (let [{:keys [last-message messages]} (get chats chat-id)] (->> (conj messages last-message) - (sort-by :clock-value >) - (filter :show?) - (first))))) + (sort-by :clock-value >) + (filter :show?) + first)))) -(reg-sub :get-message-short-preview-markup +(reg-sub + :get-message-short-preview-markup (fn [db [_ message-id]] (get-in db [:message-data :short-preview message-id :markup]))) -(reg-sub :get-last-message-short-preview +(reg-sub + :get-last-message-short-preview (fn [db [_ chat-id]] (let [last-message (subscribe [:get-last-message chat-id]) preview (subscribe [:get-message-short-preview-markup (:message-id @last-message)])] (when-let [markup @preview] (commands-utils/generate-hiccup markup))))) -(reg-sub :get-default-container-area-height - :<- [:chat-ui-props :input-height] +(reg-sub + :get-default-container-area-height + :<- [:get-current-chat-ui-prop :input-height] :<- [:get :layout-height] :<- [:chat-input-margin] (fn [[input-height layout-height chat-input-margin]] (let [bottom (+ input-height chat-input-margin)] (input-utils/default-container-area-height bottom layout-height)))) -(reg-sub :get-max-container-area-height - :<- [:chat-ui-props :input-height] +(reg-sub + :get-max-container-area-height + :<- [:get-current-chat-ui-prop :input-height] :<- [:get :layout-height] :<- [:chat-input-margin] (fn [[input-height layout-height chat-input-margin]] (let [bottom (+ input-height chat-input-margin)] (input-utils/max-container-area-height bottom layout-height)))) -(reg-sub :chat-animations +(reg-sub + :chat-animations (fn [db [_ key type]] (let [chat-id (subscribe [:get-current-chat-id])] (get-in db [:chat-animations @chat-id key type])))) -(reg-sub :get-chat-last-outgoing-message - (fn [db [_ chat-id]] - (->> (:messages (get-in db [:chats chat-id])) +(reg-sub + :get-chat-last-outgoing-message + :<- [:chats] + (fn [chats [_ chat-id]] + (->> (:messages (get chats chat-id)) (filter :outgoing) (sort-by :clock-value >) - (first)))) + first))) -(reg-sub :get-message-preview-markup +(reg-sub + :get-message-preview-markup (fn [db [_ message-id]] (get-in db [:message-data :preview message-id :markup]))) (reg-sub - :get-message-preview - (fn [[_ message-id]] - [(subscribe [:get-message-preview-markup message-id])]) - (fn [[markup]] - (when markup - (commands-utils/generate-hiccup markup)))) + :get-message-preview + (fn [[_ message-id]] + [(subscribe [:get-message-preview-markup message-id])]) + (fn [[markup]] + (when markup + (commands-utils/generate-hiccup markup)))) diff --git a/src/status_im/chat/views/bottom_info.cljs b/src/status_im/chat/views/bottom_info.cljs index c3f24f99af..5417af4db7 100644 --- a/src/status_im/chat/views/bottom_info.cljs +++ b/src/status_im/chat/views/bottom_info.cljs @@ -67,7 +67,7 @@ (list-item [message-status-row contact row])))) (defn bottom-info-view [] - (let [bottom-info (subscribe [:chat-ui-props :bottom-info]) + (let [bottom-info (subscribe [:get-current-chat-ui-prop :bottom-info]) contacts (subscribe [:get-contacts])] (r/create-class {:display-name "bottom-info-view" diff --git a/src/status_im/chat/views/input/animations/expandable.cljs b/src/status_im/chat/views/input/animations/expandable.cljs index 7a0edf1518..9b032ca09a 100644 --- a/src/status_im/chat/views/input/animations/expandable.cljs +++ b/src/status_im/chat/views/input/animations/expandable.cljs @@ -54,9 +54,9 @@ (defn expandable-view [{:keys [key height hide-overlay?]} & _] (let [anim-value (anim/create-value 0) - input-height (subscribe [:chat-ui-props :input-height]) + input-height (subscribe [:get-current-chat-ui-prop :input-height]) max-height (subscribe [:get-max-container-area-height]) - fullscreen? (subscribe [:chat-ui-props :fullscreen?]) + fullscreen? (subscribe [:get-current-chat-ui-prop :fullscreen?]) chat-input-margin (subscribe [:chat-input-margin]) to-changed-height (subscribe [:chat-animations key :height]) changes-counter (subscribe [:chat-animations key :changes-counter]) diff --git a/src/status_im/chat/views/input/box_header.cljs b/src/status_im/chat/views/input/box_header.cljs index 41c01417de..4da7dda522 100644 --- a/src/status_im/chat/views/input/box_header.cljs +++ b/src/status_im/chat/views/input/box_header.cljs @@ -11,7 +11,7 @@ (defn get-header [type] (fn [] (let [parameter-box (subscribe [:chat-parameter-box]) - result-box (subscribe [:chat-ui-props :result-box]) + result-box (subscribe [:get-current-chat-ui-prop :result-box]) chat-id (subscribe [:get-current-chat-id]) command (subscribe [:selected-chat-command]) index (subscribe [:current-chat-argument-position])] @@ -36,4 +36,4 @@ (dispatch [:set-in [:chats @chat-id :parameter-boxes command-name @index] nil])) (dispatch [:set-chat-ui-props {:result-box nil}])))} [view style/header-close-container - [icon :close_light_gray style/header-icon]]]]]))))) \ No newline at end of file + [icon :close_light_gray style/header-icon]]]]]))))) diff --git a/src/status_im/chat/views/input/input.cljs b/src/status_im/chat/views/input/input.cljs index 93612ef38e..975a070864 100644 --- a/src/status_im/chat/views/input/input.cljs +++ b/src/status_im/chat/views/input/input.cljs @@ -55,8 +55,8 @@ (defn- basic-text-input [_] (let [input-text (subscribe [:chat :input-text]) command (subscribe [:selected-chat-command]) - sending-in-progress? (subscribe [:chat-ui-props :sending-in-progress?]) - input-focused? (subscribe [:chat-ui-props :input-focused?]) + sending-in-progress? (subscribe [:get-current-chat-ui-prop :sending-in-progress?]) + input-focused? (subscribe [:get-current-chat-ui-prop :input-focused?]) input-ref (atom nil)] (fn [{:keys [set-layout-height-fn set-container-width-fn height single-line-input?]}] [text-input @@ -143,7 +143,7 @@ (let [command (subscribe [:selected-chat-command]) arg-pos (subscribe [:current-chat-argument-position]) seq-arg-input-text (subscribe [:chat :seq-argument-input-text]) - sending-in-progress? (subscribe [:chat-ui-props :sending-in-progress?])] + sending-in-progress? (subscribe [:get-current-chat-ui-prop :sending-in-progress?])] (fn [{:keys [command-width container-width]}] (when (get-in @command [:command :sequential-params]) (let [{:keys [placeholder hidden type]} (get-in @command [:command :params @arg-pos])] @@ -210,7 +210,7 @@ selected-command [:selected-chat-command] input-text [:chat :input-text] seq-arg-input-text [:chat :seq-argument-input-text] - result-box [:chat-ui-props :result-box]] + result-box [:get-current-chat-ui-prop :result-box]] (let [single-line-input? (:singleLineInput result-box) {:keys [hide-send-button sequential-params]} (:command selected-command)] [view style/input-container @@ -236,7 +236,7 @@ (defn container [] (let [margin (subscribe [:chat-input-margin]) - show-emoji? (subscribe [:chat-ui-props :show-emoji?]) + show-emoji? (subscribe [:get-current-chat-ui-prop :show-emoji?]) input-text (subscribe [:chat :input-text]) anim-margin (anim/create-value 10) container-anim-margin (anim/create-value 16) diff --git a/src/status_im/chat/views/input/input_actions.cljs b/src/status_im/chat/views/input/input_actions.cljs index d4de5412f7..89d76a7fda 100644 --- a/src/status_im/chat/views/input/input_actions.cljs +++ b/src/status_im/chat/views/input/input_actions.cljs @@ -8,7 +8,7 @@ (defmethod action-view :fullscreen [_] - (let [fullscreen? (re-frame/subscribe [:chat-ui-props :fullscreen?])] + (let [fullscreen? (re-frame/subscribe [:get-current-chat-ui-prop :fullscreen?])] (fn [] [react/touchable-highlight {:on-press #(re-frame/dispatch [:set-chat-ui-props {:fullscreen? (not @fullscreen?)}])} @@ -20,7 +20,7 @@ (defmethod action-view :web-view-back [_] - (let [result-box (re-frame/subscribe [:chat-ui-props :result-box]) + (let [result-box (re-frame/subscribe [:get-current-chat-ui-prop :result-box]) webview (re-frame/subscribe [:get :webview-bridge])] (fn [] [react/touchable-highlight @@ -33,7 +33,7 @@ (defmethod action-view :web-view-forward [_] - (let [result-box (re-frame/subscribe [:chat-ui-props :result-box]) + (let [result-box (re-frame/subscribe [:get-current-chat-ui-prop :result-box]) webview (re-frame/subscribe [:get :webview-bridge])] (fn [] [react/touchable-highlight @@ -54,7 +54,7 @@ [react/icon (str "action_" image) style/action-view-icon]]]) (defn input-actions-view [] - (let [result-box (re-frame/subscribe [:chat-ui-props :result-box])] + (let [result-box (re-frame/subscribe [:get-current-chat-ui-prop :result-box])] (fn [] (let [{:keys [actions]} @result-box] [react/view style/actions-container diff --git a/src/status_im/chat/views/input/result_box.cljs b/src/status_im/chat/views/input/result_box.cljs index a4f0d5419a..61d71c0bfc 100644 --- a/src/status_im/chat/views/input/result_box.cljs +++ b/src/status_im/chat/views/input/result_box.cljs @@ -2,10 +2,10 @@ (:require-macros [status-im.utils.views :refer [defview]]) (:require [re-frame.core :refer [subscribe dispatch]] [status-im.ui.components.react :refer [view - scroll-view - touchable-highlight - text - icon]] + scroll-view + touchable-highlight + text + icon]] [status-im.chat.views.input.animations.expandable :refer [expandable-view]] [status-im.chat.views.input.box-header :as box-header] [status-im.ui.components.sync-state.offline :refer [offline-view]])) @@ -15,8 +15,8 @@ markup]) (defview result-box-view [] - [{:keys [markup] :as result-box} [:chat-ui-props :result-box]] - (when result-box + [markup [:result-box-markup]] + (when markup [expandable-view {:key :result-box :draggable? true :custom-header (box-header/get-header :result-box)} diff --git a/src/status_im/chat/views/input/validation_messages.cljs b/src/status_im/chat/views/input/validation_messages.cljs index ac1f09717f..26c5dc1a0c 100644 --- a/src/status_im/chat/views/input/validation_messages.cljs +++ b/src/status_im/chat/views/input/validation_messages.cljs @@ -19,8 +19,8 @@ (defview validation-messages-view [] (letsubs [chat-input-margin [:chat-input-margin] - input-height [:chat-ui-props :input-height] - messages [:chat-ui-props :validation-messages]] + input-height [:get-current-chat-ui-prop :input-height] + messages [:validation-messages]] (when messages [c/view (style/root (+ input-height chat-input-margin)) (if (string? messages) diff --git a/src/status_im/chat/views/input/web_view.cljs b/src/status_im/chat/views/input/web_view.cljs index b939c96df1..48f9e72184 100644 --- a/src/status_im/chat/views/input/web_view.cljs +++ b/src/status_im/chat/views/input/web_view.cljs @@ -32,7 +32,7 @@ (defview bridged-web-view [{:keys [url]}] [extra-js [:web-view-extra-js] rpc-url [:get :rpc-url] - result-box [:chat-ui-props :result-box]] + result-box [:get-current-chat-ui-prop :result-box]] (when url [webview-bridge {:ref #(dispatch [:chat-webview-bridge/set-ref %]) diff --git a/src/status_im/chat/views/message/message.cljs b/src/status_im/chat/views/message/message.cljs index 78438801c5..e6740e598d 100644 --- a/src/status_im/chat/views/message/message.cljs +++ b/src/status_im/chat/views/message/message.cljs @@ -246,7 +246,7 @@ (defview group-message-delivery-status [{:keys [message-id group-id message-status user-statuses] :as msg}] [app-db-message-user-statuses [:get-in [:message-data :user-statuses message-id]] app-db-message-status-value [:get-in [:message-data :statuses message-id :status]] - chat [:get-chat-by-id group-id] + chat [:get-current-chat] contacts [:get-contacts]] (let [status (or message-status app-db-message-status-value :sending) user-statuses (merge user-statuses app-db-message-user-statuses) diff --git a/src/status_im/chat/views/toolbar_content.cljs b/src/status_im/chat/views/toolbar_content.cljs index bf03635819..7572ba64c6 100644 --- a/src/status_im/chat/views/toolbar_content.cljs +++ b/src/status_im/chat/views/toolbar_content.cljs @@ -68,7 +68,7 @@ contacts [:chat :contacts] public? [:chat :public?] public-key [:chat :public-key] - show-actions? [:chat-ui-props :show-actions?] + show-actions? [:get-current-chat-ui-prop :show-actions?] accounts [:get-accounts] contact [:get-in [:contacts/contacts @chat-id]] sync-state [:sync-state] diff --git a/src/status_im/commands/subs.cljs b/src/status_im/commands/subs.cljs index c6c695ace2..4d0a48fc7d 100644 --- a/src/status_im/commands/subs.cljs +++ b/src/status_im/commands/subs.cljs @@ -1,13 +1,10 @@ (ns status-im.commands.subs (:require [re-frame.core :refer [reg-sub]])) -(reg-sub - :get-commands-responses-by-access-scope - (fn [db _] - (:access-scope->commands-responses db))) +(reg-sub :get-commands-responses-by-access-scope :access-scope->commands-responses) (reg-sub :get-command :<- [:get-contacts] - (fn [contacts [_ ref]] + (fn [contacts [_ ref]] (some->> ref (get-in contacts)))) diff --git a/src/status_im/ui/screens/accounts/subs.cljs b/src/status_im/ui/screens/accounts/subs.cljs index 6ba1ce588a..cb416712b0 100644 --- a/src/status_im/ui/screens/accounts/subs.cljs +++ b/src/status_im/ui/screens/accounts/subs.cljs @@ -1,14 +1,20 @@ (ns status-im.ui.screens.accounts.subs (:require [re-frame.core :refer [reg-sub subscribe]])) -(reg-sub - :get-accounts - (fn [db _] - (get db :accounts/accounts))) +(reg-sub :get-current-public-key + (fn [db] + (:current-public-key db))) -(reg-sub - :get-current-account - :<- [:get :accounts/current-account-id] +(reg-sub :get-accounts + (fn [db] + (:accounts/accounts db))) + +(reg-sub :get-current-account-id + (fn [db] + (:accounts/current-account-id db))) + +(reg-sub :get-current-account + :<- [:get-current-account-id] :<- [:get-accounts] (fn [[account-id accounts]] (some-> accounts (get account-id)))) diff --git a/src/status_im/ui/screens/contacts/subs.cljs b/src/status_im/ui/screens/contacts/subs.cljs index 9df9f5551c..a89afaeafd 100644 --- a/src/status_im/ui/screens/contacts/subs.cljs +++ b/src/status_im/ui/screens/contacts/subs.cljs @@ -154,12 +154,9 @@ (:name (contacts identity)))) (reg-sub :chat-by-id - (fn [db [_ chat-id]] - (get-in db [:chats chat-id]))) - -(reg-sub :current-chat - (fn [db _] - (get-in db [:chats (:current-chat-id db)]))) + :<- [:chats] + (fn [chats [_ chat-id]] + (get chats chat-id))) (defn chat-contacts [[chat contacts] [_ fn]] (when chat @@ -171,7 +168,7 @@ (vals contacts))))) (reg-sub :contacts-current-chat - :<- [:current-chat] + :<- [:get-current-chat] :<- [:get-contacts] chat-contacts) @@ -195,7 +192,7 @@ (fn [[_ chat-id] _] [(if chat-id (subscribe [:chat-by-id chat-id]) - (subscribe [:current-chat])) + (subscribe [:get-current-chat])) (subscribe [:contacts-by-chat filter chat-id])]) (fn [[chat contacts] [_ chat-id]] (when (and chat (not (:group-chat chat))) diff --git a/src/status_im/ui/screens/discover/subs.cljs b/src/status_im/ui/screens/discover/subs.cljs index 5aab0cb84c..3cc345f856 100644 --- a/src/status_im/ui/screens/discover/subs.cljs +++ b/src/status_im/ui/screens/discover/subs.cljs @@ -2,18 +2,25 @@ (:require [re-frame.core :refer [reg-sub]] [status-im.utils.datetime :as time])) -(defn- calculate-priority [{:keys [chats current-public-key] - :contacts/keys [contacts]} +(reg-sub :get-discoveries :discoveries) + +(reg-sub :get-current-tag :current-tag) + +(reg-sub :get-discover-search-tags :discover-search-tags) + +(reg-sub :get-tags :tags) + +(defn- calculate-priority [chats current-public-key contacts {:keys [whisper-id created-at]}] (let [contact (get contacts whisper-id) chat (get chats whisper-id) seen-online-recently? (< (- (time/now-ms) (get contact :last-online)) time/hour) me? (= current-public-key whisper-id)] - (+ created-at ;; message is newer => priority is higher - (if (or me? contact) time/day 0) ;; user exists in contact list => increase priority - (if (or me? chat) time/day 0) ;; chat with this user exists => increase priority - (if (or me? seen-online-recently?) time/hour 0)))) ;; the user was online recently => increase priority + (+ created-at ; message is newer => priority is higher + (if (or me? contact) time/day 0) ; user exists in contact list => increase priority + (if (or me? chat) time/day 0) ; chat with this user exists => increase priority + (if (or me? seen-online-recently?) time/hour 0)))) ; the user was online recently => increase priority (defn- get-discoveries-by-tags [discoveries current-tag tags] @@ -24,45 +31,59 @@ tags') (vals discoveries)))) -(reg-sub :get-popular-discoveries - (fn [db [_ limit tags]] - (let [discoveries (:discoveries db) - current-tag (:current-tag db) - search-tags (:discover-search-tags db)] - (let [discoveries (->> (get-discoveries-by-tags discoveries current-tag (or tags search-tags)) - (map #(assoc % :priority (calculate-priority db %))) - (sort-by :priority >))] - {:discoveries (take limit discoveries) - :total (count discoveries)})))) +(reg-sub + :get-popular-discoveries + :<- [:get-discoveries] + :<- [:get-current-tag] + :<- [:get-discover-search-tags] + :<- [:chats] + :<- [:get-contacts] + :<- [:get-current-public-key] + (fn [[discoveries current-tag discover-search-tags chats contacts public-key] + [_ limit tags]] + (let [discoveries (->> (get-discoveries-by-tags discoveries + current-tag + (or tags discover-search-tags)) + (map #(assoc % :priority (calculate-priority chats public-key contacts %))) + (sort-by :priority >))] + {:discoveries (take limit discoveries) + :total (count discoveries)}))) -(reg-sub :get-top-discovery-per-tag - (fn [{:keys [discoveries tags]} [_ limit]] +(reg-sub + :get-top-discovery-per-tag + :<- [:get-discoveries] + :<- [:get-tags] + (fn [[discoveries tags] [_ limit]] (let [tag-names (map :name (take limit tags))] - (for [tag tag-names] - (let [results (get-discoveries-by-tags discoveries tag nil)] + (for [tag tag-names] + (let [results (get-discoveries-by-tags discoveries tag nil)] [tag {:discovery (first results) :total (count results)}]))))) -(reg-sub :get-recent-discoveries - (fn [db] - (sort-by :created-at > (vals (:discoveries db))))) +(reg-sub + :get-recent-discoveries + :<- [:get-discoveries] + (fn [discoveries] + (sort-by :created-at > (vals discoveries)))) -(reg-sub :get-popular-tags - (fn [db [_ limit]] - (take limit (:tags db)))) +(reg-sub + :get-popular-tags + :<- [:get-tags] + (fn [tags [_ limit]] + (take limit tags))) -(reg-sub :get-discover-search-results - (fn [db] - (let [discoveries (:discoveries db) - current-tag (:current-tag db) - tags (:discover-search-tags db)] - (get-discoveries-by-tags discoveries current-tag tags)))) +(reg-sub + :get-discover-search-results + :<- [:get-discoveries] + :<- [:get-current-tag] + :<- [:get-discover-search-tags] + (fn [[discoveries current-tag discover-search-tags]] + (get-discoveries-by-tags discoveries current-tag discover-search-tags))) -(reg-sub :get-all-dapps - (fn [db] - (let [dapp? (->> (get-in db [:group/contact-groups "dapps" :contacts]) - (map :identity) - set)] - (->> (:contacts/contacts db) - (filter #(-> % key dapp?)) - (into {}))))) +(reg-sub + :get-all-dapps + :<- [:get-contact-groups] + :<- [:get-contacts] + (fn [[groups contacts]] + (let [dapp-ids (into #{} (map :identity) (get-in groups ["dapps" :contacts]))] + (select-keys contacts dapp-ids)))) diff --git a/test/cljs/status_im/test/chat/models/input.cljs b/test/cljs/status_im/test/chat/models/input.cljs index 132938a222..029b0ff5dd 100644 --- a/test/cljs/status_im/test/chat/models/input.cljs +++ b/test/cljs/status_im/test/chat/models/input.cljs @@ -65,28 +65,40 @@ (is (= "/send 1.0 \"John Doe\"" (input/join-command-args ["/send" "1.0" "John Doe"])))) (deftest selected-chat-command - (is (= (input/selected-chat-command fake-db "test1" "/global-command1") + (is (= (input/selected-chat-command (-> fake-db + (assoc :current-chat-id "test1") + (assoc-in [:chats "test1" :input-text] "/global-command1"))) {:command {:name "global-command1" :ref ["0x1" :command 0 "global-command1"]} :metadata nil :args ["arg1" "arg2"]})) - (is (= (input/selected-chat-command fake-db "test2" "/command2") + (is (= (input/selected-chat-command (-> fake-db + (assoc :current-chat-id "test2") + (assoc-in [:chats "test2" :input-text] "/command2"))) {:command {:name "command2" :ref ["0x1" :command 4 "command2"]} :metadata nil :args []})) - (is (nil? (input/selected-chat-command fake-db "test1" "/command3"))) - (is (= (input/selected-chat-command fake-db "test1" "/command2") + (is (nil? (input/selected-chat-command (-> fake-db + (assoc :current-chat-id "test1") + (assoc-in [:chats "test1" :input-text] "/command3"))))) + (is (= (input/selected-chat-command (-> fake-db + (assoc :current-chat-id "test1") + (assoc-in [:chats "test1" :input-text] "/command2"))) {:command {:name "command2" :ref ["0x1" :command 2 "command2"]} :metadata nil :args ["arg1" "arg2"]})) - (is (= (input/selected-chat-command fake-db "test2" "/response1 arg1") + (is (= (input/selected-chat-command (-> fake-db + (assoc :current-chat-id "test2") + (assoc-in [:chats "test2" :input-text] "/response1 arg1"))) {:command {:name "response1" :ref ["0x2" :response 4 "response1"]} :metadata nil :args ["arg1"]})) - (is (= (input/selected-chat-command fake-db "test4" "/command2 arg1") + (is (= (input/selected-chat-command (-> fake-db + (assoc :current-chat-id "test4") + (assoc-in [:chats "test4" :input-text] "/command2 arg1"))) {:command {:name "command2" :ref ["0x1" :command 4 "command2"]} :metadata {:meta-k "meta-v"}