From 5c359886e5a8ad1acf33ed88b90a33fa4a03485e Mon Sep 17 00:00:00 2001 From: Eric Dvorsak Date: Mon, 20 Nov 2017 23:24:07 +0100 Subject: [PATCH] [feature] refactor discover events use re-frame idiomatic register-handler-fx, reg-fx and coeffect. the events are still not free of side-effects as there is some db calls involved which will be taken care of in a future PR it also reduces the events fired at app init from 3 to 1 discover-related event --- src/status_im/data_store/core.cljs | 3 +- src/status_im/data_store/discover.cljs | 53 ++-- src/status_im/data_store/realm/discover.cljs | 50 +-- .../realm/schemas/account/v19/core.cljs | 2 +- .../realm/schemas/account/v20/core.cljs | 31 ++ .../realm/schemas/account/v20/discover.cljs | 14 + src/status_im/protocol/discoveries.cljs | 11 +- src/status_im/protocol/handlers.cljs | 52 +-- src/status_im/ui/screens/db.cljs | 9 +- .../ui/screens/discover/all_dapps/views.cljs | 2 +- src/status_im/ui/screens/discover/db.cljs | 3 +- src/status_im/ui/screens/discover/events.cljs | 300 ++++++++++-------- .../ui/screens/discover/navigation.cljs | 7 + .../discover/popular_hashtags/views.cljs | 13 +- .../discover/recent_statuses/views.cljs | 12 +- .../discover/search_results/views.cljs | 47 ++- src/status_im/ui/screens/discover/subs.cljs | 145 +++++---- src/status_im/ui/screens/discover/views.cljs | 45 ++- src/status_im/ui/screens/events.cljs | 158 +++++---- src/status_im/ui/screens/views.cljs | 2 +- src/status_im/utils/handlers.cljs | 2 +- 21 files changed, 507 insertions(+), 454 deletions(-) create mode 100644 src/status_im/data_store/realm/schemas/account/v20/core.cljs create mode 100644 src/status_im/data_store/realm/schemas/account/v20/discover.cljs create mode 100644 src/status_im/ui/screens/discover/navigation.cljs diff --git a/src/status_im/data_store/core.cljs b/src/status_im/data_store/core.cljs index a79c7cb3a8..471610022a 100644 --- a/src/status_im/data_store/core.cljs +++ b/src/status_im/data_store/core.cljs @@ -1,5 +1,6 @@ (ns status-im.data-store.core - (:require [status-im.data-store.realm.core :as data-source])) + (:require [status-im.data-store.realm.core :as data-source] + [status-im.utils.handlers :as handlers])) (defn init [] diff --git a/src/status_im/data_store/discover.cljs b/src/status_im/data_store/discover.cljs index fbd86e49f8..2d7d22a1e3 100644 --- a/src/status_im/data_store/discover.cljs +++ b/src/status_im/data_store/discover.cljs @@ -1,28 +1,33 @@ (ns status-im.data-store.discover - (:require [status-im.data-store.realm.discover :as data-store]) - (:refer-clojure :exclude [exists?])) + (:require [re-frame.core :as re-frame] + [status-im.data-store.realm.discover :as data-store] + [status-im.utils.handlers :as handlers])) + +;; stores a collection of discover messages +;; removes the tags from the discovers because there is no +;; need to store them and realm doesn't support lists +;; of string +;; also deletes the oldest queries if the number of discovers stored is +;; above maximum-number-of-discoveries +(re-frame/reg-fx + :data-store.discover/save-all + (fn [[discovers maximum-number-of-discoveries]] + (data-store/save-all (mapv #(dissoc % :tags) discovers)) + (data-store/delete :created-at :asc maximum-number-of-discoveries))) (defn get-all - [ordering] - (mapv #(update % :tags vals) - (data-store/get-all-as-list ordering))) - -(defn save - [discover] - (data-store/save discover)) - -(defn exists? - [message-id] - (data-store/exists? message-id)) - -(defn save-all - [discoveries] - (data-store/save-all discoveries)) - -(defn delete - [by ordering critical-count to-delete-count] - (data-store/delete by ordering critical-count to-delete-count)) - -(defn get-all-tags + ;; extracts the hashtags from the status and put them into a set + ;; for each discover + ;; returns a map of discovers that can be used as is in the app-db [] - (data-store/get-all-tags)) + (reduce (fn [acc {:keys [message-id status] :as discover}] + (let [tags (handlers/get-hashtags status) + discover (assoc discover :tags tags)] + (assoc acc message-id discover))) + {} + (data-store/get-all-as-list :asc))) + +(re-frame/reg-cofx + :data-store/discoveries + (fn [cofx _] + (assoc cofx :data-store/discoveries (get-all)))) diff --git a/src/status_im/data_store/realm/discover.cljs b/src/status_im/data_store/realm/discover.cljs index 52ad77a364..9c885024f3 100644 --- a/src/status_im/data_store/realm/discover.cljs +++ b/src/status_im/data_store/realm/discover.cljs @@ -13,67 +13,27 @@ [ordering] (realm/js-object->clj (get-all ordering))) -(defn get-tag-by-name [tag] - (log/debug "Getting tag: " tag) - (realm/get-one-by-field-clj @realm/account-realm :tag :name tag)) - -(defn- update-tag-counter [func tag] - (let [tag (:name tag) - tag-object (get-tag-by-name tag)] - (if tag-object - (realm/create @realm/account-realm :tag - {:name tag - :count (func (:count tag-object))} - true)))) - -(defn- update-tags-counter [func tags] - (doseq [tag (distinct tags)] - (update-tag-counter func tag))) - -(defn- get-tags - [message-id] - (-> (realm/get-one-by-field-clj @realm/account-realm :discover :message-id message-id) - :tags - vals)) - -(defn- upsert-discover [{:keys [message-id tags] :as discover}] - (log/debug "Creating/updating discover with tags: " tags) - (let [prev-tags (get-tags message-id)] - (when prev-tags - (update-tags-counter dec prev-tags)) - (realm/create @realm/account-realm :discover discover true) - (update-tags-counter inc tags))) - -(defn exists? - [message-id] - (realm/exists? @realm/account-realm :discover {:message-id message-id})) - (defn save [discover] (realm/write @realm/account-realm - #(upsert-discover discover))) + #(realm/create @realm/account-realm :discover discover true))) (defn save-all [discoveries] (realm/write @realm/account-realm (fn [] (doseq [discover discoveries] - (upsert-discover discover))))) + (realm/create @realm/account-realm :discover discover true))))) (defn delete - [by ordering critical-count to-delete-count] + [by ordering max-count] (let [discoveries (realm/get-all @realm/account-realm :discover) count (realm/get-count discoveries)] - (if (> count critical-count) + (if (> count max-count) (let [to-delete (-> discoveries (realm/sorted by ordering) - (realm/page 0 to-delete-count))] + (realm/page 0 (- max-count count)))] (realm/write @realm/account-realm (fn [] (log/debug (str "Deleting " (realm/get-count to-delete) " discoveries")) (realm/delete @realm/account-realm to-delete))))))) - -(defn get-all-tags [] - (-> (realm/get-all @realm/account-realm :tag) - (realm/sorted :count :desc) - realm/js-object->clj)) diff --git a/src/status_im/data_store/realm/schemas/account/v19/core.cljs b/src/status_im/data_store/realm/schemas/account/v19/core.cljs index 0ffc805941..5d7c0f2643 100644 --- a/src/status_im/data_store/realm/schemas/account/v19/core.cljs +++ b/src/status_im/data_store/realm/schemas/account/v19/core.cljs @@ -110,7 +110,7 @@ from (aget msg "from") msg-status (aget msg "message-status") statuses (aget msg "user-statuses")] - (when statuses + (when statuses (.map statuses (fn [status _ _] (aset status "status-id" (str message-id "-" from)) (aset status "message-id" message-id) diff --git a/src/status_im/data_store/realm/schemas/account/v20/core.cljs b/src/status_im/data_store/realm/schemas/account/v20/core.cljs new file mode 100644 index 0000000000..2cfe658aad --- /dev/null +++ b/src/status_im/data_store/realm/schemas/account/v20/core.cljs @@ -0,0 +1,31 @@ +(ns status-im.data-store.realm.schemas.account.v20.core + (:require [status-im.data-store.realm.schemas.account.v19.chat :as chat] + [status-im.data-store.realm.schemas.account.v1.chat-contact :as chat-contact] + [status-im.data-store.realm.schemas.account.v19.contact :as contact] + [status-im.data-store.realm.schemas.account.v20.discover :as discover] + [status-im.data-store.realm.schemas.account.v19.message :as message] + [status-im.data-store.realm.schemas.account.v12.pending-message :as pending-message] + [status-im.data-store.realm.schemas.account.v1.processed-message :as processed-message] + [status-im.data-store.realm.schemas.account.v19.request :as request] + [status-im.data-store.realm.schemas.account.v19.user-status :as user-status] + [status-im.data-store.realm.schemas.account.v5.contact-group :as contact-group] + [status-im.data-store.realm.schemas.account.v5.group-contact :as group-contact] + [status-im.data-store.realm.schemas.account.v8.local-storage :as local-storage] + [taoensso.timbre :as log] + [cljs.reader :as reader])) + +(def schema [chat/schema + chat-contact/schema + contact/schema + discover/schema + message/schema + pending-message/schema + processed-message/schema + request/schema + user-status/schema + contact-group/schema + group-contact/schema + local-storage/schema]) + +(defn migration [old-realm new-realm] + (log/debug "migrating v20 account database: " old-realm new-realm)) diff --git a/src/status_im/data_store/realm/schemas/account/v20/discover.cljs b/src/status_im/data_store/realm/schemas/account/v20/discover.cljs new file mode 100644 index 0000000000..6cac634f13 --- /dev/null +++ b/src/status_im/data_store/realm/schemas/account/v20/discover.cljs @@ -0,0 +1,14 @@ +(ns status-im.data-store.realm.schemas.account.v20.discover + (:require [taoensso.timbre :as log])) + +(def schema {:name :discover + :primaryKey :message-id + :properties {:message-id "string" + :name {:type "string" :optional true} + :status "string" + :whisper-id "string" + :photo-path {:type "string" :optional true} + :created-at {:type "int" :default 0}}}) + +(defn migration [_ _] + (log/debug "migrating discover schema")) diff --git a/src/status_im/protocol/discoveries.cljs b/src/status_im/protocol/discoveries.cljs index 1f4e458cec..ad8b3d59f2 100644 --- a/src/status_im/protocol/discoveries.cljs +++ b/src/status_im/protocol/discoveries.cljs @@ -84,12 +84,11 @@ {:pre [(valid? :contact-request/message message)]} (debug :send-command-request!) (d/add-pending-message! - web3 - (assoc message :type :contact-request - :requires-ack? true - :topics [f/status-topic]))) - -(defonce watched-hashtag-topics (atom nil)) + web3 + (assoc message + :type :contact-request + :requires-ack? true + :topics [f/status-topic]))) (s/def :discoveries/hashtags (s/every string? :kind-of set?)) diff --git a/src/status_im/protocol/handlers.cljs b/src/status_im/protocol/handlers.cljs index 496158b61d..052cafb892 100644 --- a/src/status_im/protocol/handlers.cljs +++ b/src/status_im/protocol/handlers.cljs @@ -80,38 +80,38 @@ ::init-whisper (fn [{:keys [web3 public-key groups updates-public-key updates-private-key status contacts pending-messages]}] (protocol/init-whisper! - {:web3 web3 - :identity public-key - :groups groups - :callback #(re-frame/dispatch [:incoming-message %1 %2]) - :ack-not-received-s-interval 125 - :default-ttl 120 - :send-online-s-interval 180 - :ttl-config {:public-group-message 2400} - :max-attempts-number 3 - :delivery-loop-ms-interval 500 - :profile-keypair {:public updates-public-key - :private updates-private-key} - :hashtags (handlers/get-hashtags status) - :pending-messages pending-messages - :contacts (keep (fn [{:keys [whisper-identity - public-key - private-key]}] - (when (and public-key private-key) - {:identity whisper-identity - :keypair {:public public-key - :private private-key}})) - contacts) - :post-error-callback #(re-frame/dispatch [::post-error %])}))) + {:web3 web3 + :identity public-key + :groups groups + :callback #(re-frame/dispatch [:incoming-message %1 %2]) + :ack-not-received-s-interval 125 + :default-ttl 120 + :send-online-s-interval 180 + :ttl-config {:public-group-message 2400} + :max-attempts-number 3 + :delivery-loop-ms-interval 500 + :profile-keypair {:public updates-public-key + :private updates-private-key} + :hashtags (mapv name (handlers/get-hashtags status)) + :pending-messages pending-messages + :contacts (keep (fn [{:keys [whisper-identity + public-key + private-key]}] + (when (and public-key private-key) + {:identity whisper-identity + :keypair {:public public-key + :private private-key}})) + contacts) + :post-error-callback #(re-frame/dispatch [::post-error %])}))) (re-frame/reg-fx ::web3-get-syncing (fn [web3] (when web3 (.getSyncing - (.-eth web3) - (fn [error sync] - (re-frame/dispatch [:update-sync-state error sync])))))) + (.-eth web3) + (fn [error sync] + (re-frame/dispatch [:update-sync-state error sync])))))) (re-frame/reg-fx ::save-processed-messages diff --git a/src/status_im/ui/screens/db.cljs b/src/status_im/ui/screens/db.cljs index a18c6766f3..84b7a0f4a1 100644 --- a/src/status_im/ui/screens/db.cljs +++ b/src/status_im/ui/screens/db.cljs @@ -32,10 +32,10 @@ :group/contact-groups {} :group/selected-contacts #{} :chats {} - :current-chat-id constants/console-chat-id + :current-chat-id constants/console-chat-id :selected-participants #{} :discoveries {} - :discover-search-tags '() + :discover-search-tags #{} :discover-current-dapp {} :tags [] :sync-state :done @@ -164,9 +164,9 @@ :chat/chat-ui-props :chat/chat-list-ui-props :chat/layout-height - :chat/expandable-view-height-to-value + :chat/expandable-view-height-to-value :chat/message-data - :chat/message-status + :chat/message-status :chat/selected-participants :chat/chat-loaded-callbacks :chat/public-group-topic @@ -182,7 +182,6 @@ :discoveries/tags :discoveries/current-tag :discoveries/request-discoveries-timer - :discoveries/new-discover :wallet/wallet :wallet/wallet.transactions :wallet/wallet-selected-asset diff --git a/src/status_im/ui/screens/discover/all_dapps/views.cljs b/src/status_im/ui/screens/discover/all_dapps/views.cljs index daf0224eeb..72a23271a2 100644 --- a/src/status_im/ui/screens/discover/all_dapps/views.cljs +++ b/src/status_im/ui/screens/discover/all_dapps/views.cljs @@ -57,7 +57,7 @@ (repeat (- columns extras) {:name ""}))))) (defview main [] - (letsubs [all-dapps [:get-all-dapps] + (letsubs [all-dapps [:discover/all-dapps] tabs-hidden? [:tabs-hidden?]] (let [columns 3] (when (seq all-dapps) diff --git a/src/status_im/ui/screens/discover/db.cljs b/src/status_im/ui/screens/discover/db.cljs index fce6007238..23c3e637cf 100644 --- a/src/status_im/ui/screens/discover/db.cljs +++ b/src/status_im/ui/screens/discover/db.cljs @@ -3,8 +3,7 @@ ;; {id (string) descovery (map)} (s/def :discoveries/discoveries (s/nilable map?)) -(s/def :discoveries/discover-search-tags (s/nilable sequential?)) +(s/def :discoveries/discover-search-tags (s/nilable set?)) (s/def :discoveries/tags (s/nilable vector?)) (s/def :discoveries/current-tag (s/nilable map?)) (s/def :discoveries/request-discoveries-timer (s/nilable int?)) -(s/def :discoveries/new-discover (s/nilable map?)) \ No newline at end of file diff --git a/src/status_im/ui/screens/discover/events.cljs b/src/status_im/ui/screens/discover/events.cljs index 2c49d6ee9a..d55411362c 100644 --- a/src/status_im/ui/screens/discover/events.cljs +++ b/src/status_im/ui/screens/discover/events.cljs @@ -1,158 +1,186 @@ (ns status-im.ui.screens.discover.events - (:require [re-frame.core :refer [after dispatch enrich]] - [status-im.utils.utils :refer [first-index]] - [status-im.utils.handlers :refer [register-handler get-hashtags]] + (:require [re-frame.core :as re-frame] [status-im.protocol.core :as protocol] - [status-im.ui.screens.navigation :as nav] - [status-im.data-store.discover :as discoveries] - [status-im.utils.handlers :as u] - [status-im.utils.datetime :as time] - [status-im.utils.random :as random] - [taoensso.timbre :as log] - [status-im.utils.handlers :as handlers])) + [status-im.ui.screens.discover.navigation] + [status-im.utils.handlers :as handlers] + [clojure.string :as string])) (def request-discoveries-interval-s 600) +(def maximum-number-of-discoveries 1000) -(register-handler :init-discoveries - (fn [db _] - (-> db - (assoc :tags []) - (assoc :discoveries {})))) +;; EFFECTS -(defmethod nav/preload-data! :discover - [db _] - (-> db - (assoc-in [:toolbar-search :show] nil) - (assoc :tags (discoveries/get-all-tags)) - (assoc :discoveries (->> (discoveries/get-all :desc) - (map (fn [{:keys [message-id] :as discover}] - [message-id discover])) - (into {}))))) +(re-frame/reg-fx + ::send-portions + (fn [{:keys [current-public-key web3 contacts to discoveries]}] + (protocol/send-discoveries-response! + {:web3 web3 + :discoveries discoveries + :message {:from current-public-key + :to to}}))) -;; todo(goranjovic): at the moment we do nothing when a status without hashtags is posted -;; but we probably should post a special "delete" status that removes any previous -;; hashtag statuses in that scenario. In any case, that's the reason why this event -;; gets even the statuses without a hashtag - it may need to do stuff with them as well. -(register-handler :broadcast-status - (u/side-effect! - (fn [{:keys [current-public-key web3] - :accounts/keys [accounts current-account-id] - :contacts/keys [contacts]} - [_ status]] - (if-let [hashtags (seq (handlers/get-hashtags status))] - (let [{:keys [name photo-path]} (get accounts current-account-id) - message-id (random/id) - message {:message-id message-id - :from current-public-key - :payload {:message-id message-id - :status status - :hashtags (vec hashtags) - :profile {:name name - :profile-image photo-path}}}] - (doseq [id (u/identities contacts)] - (protocol/send-status! - {:web3 web3 - :message (assoc message :to id)})) - (dispatch [:status-received message])))))) +(re-frame/reg-fx + ::request-discoveries + (fn [{:keys [identities web3 current-public-key message-id]}] + (doseq [id identities] + (when-not (protocol/message-pending? web3 :discoveries-request id) + (protocol/send-discoveries-request! + {:web3 web3 + :message {:from current-public-key + :to id + :message-id message-id}}))))) -(register-handler :status-received - (u/side-effect! - (fn [{:keys [discoveries]} [_ {:keys [from payload]}]] - (when (and (not (discoveries/exists? (:message-id payload))) - (not (get discoveries (:message-id payload)))) - (let [{:keys [message-id status hashtags profile]} payload - {:keys [name profile-image]} profile - discover {:message-id message-id - :name name - :photo-path profile-image - :status status - :whisper-id from - :tags (map #(hash-map :name %) hashtags) - :created-at (time/now-ms)}] - (dispatch [:add-discover discover])))))) +(re-frame/reg-fx + ::broadcast-status + (fn [{:keys [identities web3 message]}] + (doseq [id identities] + (protocol/send-status! + {:web3 web3 + :message (assoc message :to id)})))) -(register-handler :start-requesting-discoveries - (fn [{:keys [request-discoveries-timer] :as db}] - (when request-discoveries-timer - (js/clearInterval request-discoveries-timer)) - (dispatch [:request-discoveries]) - (assoc db :request-discoveries-timer - (js/setInterval #(dispatch [:request-discoveries]) - (* request-discoveries-interval-s 1000))))) +;; HELPER-FN -(register-handler :request-discoveries - (u/side-effect! - (fn [{:keys [current-public-key web3] - :contacts/keys [contacts]}] - (doseq [id (u/identities contacts)] - (when-not (protocol/message-pending? web3 :discoveries-request id) - (protocol/send-discoveries-request! - {:web3 web3 - :message {:from current-public-key - :to id - :message-id (random/id)}})))))) +(defn send-portions-when-contact-exists + [{:keys [current-public-key web3 discoveries] + :contacts/keys [contacts]} + to] + (when (get contacts to) + {::send-portions {:current-public-key current-public-key + :web3 web3 + :contacts contacts + :to to + :discoveries (mapv #(dissoc % :tags) (vals discoveries))}})) -(register-handler :discoveries-send-portions - (u/side-effect! - (fn [{:keys [current-public-key web3] - :contacts/keys [contacts]} [_ to]] - (when (get contacts to) - (protocol/send-discoveries-response! - {:web3 web3 - :discoveries (discoveries/get-all :asc) - :message {:from current-public-key - :to to}}))))) +(defn add-discover [db {:keys [message-id] :as discover}] + (assoc-in db [:discoveries message-id] discover)) -(register-handler :discoveries-request-received - (u/side-effect! - (fn [_ [_ {:keys [from]}]] - (dispatch [:discoveries-send-portions from])))) +(defn add-discovers [db discovers] + (reduce add-discover db discovers)) -(register-handler :discoveries-response-received - (u/side-effect! - (fn [{:keys [discoveries] - :contacts/keys [contacts]} [_ {:keys [payload from]}]] - (when (get contacts from) - (when-let [data (:data payload)] - (doseq [{:keys [message-id] :as discover} data] - (when (and (not (discoveries/exists? message-id)) - (not (get discoveries message-id))) - (let [discover (assoc discover :created-at (time/now-ms))] - (dispatch [:add-discover discover]))))))))) +(defn new-discover? [discoveries {:keys [message-id]}] + (not (get discoveries message-id))) -(defn add-discover - [db [_ discover]] - (assoc db :new-discover discover)) -(defn save-discover! - [{:keys [new-discover]} _] - (discoveries/save new-discover)) +;; EVENTS -(defn reload-tags! - [db _] - (assoc db :tags (discoveries/get-all-tags) - :discoveries (->> (discoveries/get-all :desc) - (map (fn [{:keys [message-id] :as discover}] - [message-id discover])) - (into {})))) +(defn navigate-to-discover-search-results [db search-tags] + {:db (assoc db :discover-search-tags search-tags) + :dispatch [:navigate-to :discover-search-results]}) -(register-handler :add-discover - (u/handlers-> - add-discover - save-discover! - reload-tags!)) +(handlers/register-handler-fx + :discover/search-tags-results-view + (fn [{:keys [db]} [_ search-text]] + (navigate-to-discover-search-results db (reduce (fn [acc tag] + (conj acc (-> tag + (string/replace #"#" "") + string/lower-case + keyword))) + #{} + (re-seq #"[^ !?,;:.]+" search-text))))) -(register-handler :remove-old-discoveries! - (u/side-effect! - (fn [_ _] - (discoveries/delete :created-at :asc 1000 200)))) +(handlers/register-handler-fx + :discover/search-tag-results-view + (fn [{:keys [db]} [_ tag]] + (navigate-to-discover-search-results db #{(keyword tag)}))) -(handlers/register-handler-db - :show-discovery - (fn [db [_ tags view-id]] - (-> db - (assoc :discover-search-tags tags) - (nav/navigate-to view-id)))) +(handlers/register-handler-fx + :discover/popular-tags-view + (fn [{:keys [db]} [_ popular-tags]] + {:db (assoc db :discover-search-tags (into #{} popular-tags)) + :dispatch [:navigate-to :discover-all-hashtags]})) + +(handlers/register-handler-fx + :broadcast-status + [(re-frame/inject-cofx :random-id)] + (fn [{{:keys [current-public-key web3] + :accounts/keys [accounts current-account-id] + :contacts/keys [contacts]} :db + random-id :random-id} + [_ status]] + (when-let [hashtags (seq (handlers/get-hashtags status))] + (let [{:keys [name photo-path]} (get accounts current-account-id) + message {:message-id random-id + :from current-public-key + :payload {:message-id random-id + :status status + :hashtags (vec hashtags) + :profile {:name name + :profile-image photo-path}}}] + + {::broadcast-status {:web3 web3 + :message message + :identities (handlers/identities contacts)} + :dispatch [:status-received message]})))) + +(handlers/register-handler-fx + :init-discoveries + [(re-frame/inject-cofx :data-store/discoveries)] + (fn [{:keys [data-store/discoveries db]} _] + {:db (assoc db :discoveries discoveries) + :dispatch [:request-discoveries]})) + +(handlers/register-handler-fx + :request-discoveries + [(re-frame/inject-cofx :random-id)] + (fn [{{:keys [current-public-key web3] + :contacts/keys [contacts]} :db + random-id :random-id} [this-event]] + ;; this event calls itself at regular intervals + ;; TODO (yenda): this was previously using setInterval explicitly, with + ;; dispatch-later it is using it implicitly. setInterval is + ;; problematic for such long period of time and will cause a warning + ;; for Android in latest versions of react-nativexb + {::request-discoveries {:current-public-key current-public-key + :web3 web3 + :identities (handlers/identities contacts) + :message-id random-id} + :dispatch-later [{:ms (* request-discoveries-interval-s 1000) + :dispatch [this-event]}]})) + +(handlers/register-handler-fx + :discoveries-send-portions + (fn [{:keys [db]} [_ to]] + (send-portions-when-contact-exists db to))) + +(handlers/register-handler-fx + :discoveries-request-received + (fn [{:keys [db]} [_ {:keys [from]}]] + (send-portions-when-contact-exists db from))) + +(handlers/register-handler-fx + :discoveries-response-received + [(re-frame/inject-cofx :now)] + (fn [{{:keys [discoveries] + :contacts/keys [contacts] :as db} :db + now :now} + [_ {:keys [payload from]}]] + (when (get contacts from) + (when-let [discovers (some->> (:data payload) + (filter #(new-discover? discoveries %)) + (map #(assoc % + :created-at now + :tags (handlers/get-hashtags (:status %)))))] + {:db (add-discovers db discovers) + :data-store.discover/save-all [discovers maximum-number-of-discoveries]})))) + +(handlers/register-handler-fx + :status-received + [(re-frame/inject-cofx :now)] + (fn [{{:keys [discoveries] :as db} :db + now :now} + [_ {{:keys [message-id status profile] :as payload} :payload + from :from}]] + (when (new-discover? discoveries payload) + (let [{:keys [name profile-image]} profile + discover {:message-id message-id + :name name + :photo-path profile-image + :status status + :tags (handlers/get-hashtags status) + :whisper-id from + :created-at now}] + {:db (add-discover db discover) + :data-store.discover/save-all [[discover] maximum-number-of-discoveries]})))) (handlers/register-handler-fx :show-status-author-profile diff --git a/src/status_im/ui/screens/discover/navigation.cljs b/src/status_im/ui/screens/discover/navigation.cljs new file mode 100644 index 0000000000..b771e0d893 --- /dev/null +++ b/src/status_im/ui/screens/discover/navigation.cljs @@ -0,0 +1,7 @@ +(ns status-im.ui.screens.discover.navigation + (:require [status-im.ui.screens.navigation :as navigation] + [status-im.data-store.discover :as discoveries])) + +(defmethod navigation/preload-data! :discover + [db _] + (assoc-in db [:toolbar-search :show] nil)) diff --git a/src/status_im/ui/screens/discover/popular_hashtags/views.cljs b/src/status_im/ui/screens/discover/popular_hashtags/views.cljs index 79f0bc330d..f94c1ed31b 100644 --- a/src/status_im/ui/screens/discover/popular_hashtags/views.cljs +++ b/src/status_im/ui/screens/discover/popular_hashtags/views.cljs @@ -10,7 +10,7 @@ (defn render-tag [tag] [react/touchable-highlight - {:on-press #(re-frame/dispatch [:show-discovery [tag] :discover-search-results])} + {:on-press #(re-frame/dispatch [:discover/search-tag-results-view tag])} [react/view styles/tag-view [react/text {:style styles/tag-title :font :default} @@ -24,16 +24,15 @@ :shows-horizontal-scroll-indicator false :default-separator? false}]]) -(defview discover-all-hashtags [] - (letsubs [current-account [:get-current-account] - popular-tags [:get-popular-tags 10] - contacts [:get-contacts] - {:keys [discoveries]} [:get-popular-discoveries 10]] ;uses the tags passed via :discover-search-tags state +(defview discover-all-popular-hashtags [] + (letsubs [current-account [:get-current-account] + contacts [:get-contacts] + {:keys [discoveries tags]} [:discover/all-popular-hashtags]] [react/view styles/all-recent-container [toolbar/toolbar {} toolbar/default-nav-back [toolbar/content-title (i18n/label :t/popular-tags)]] - [tags-menu (map :name popular-tags)] + [tags-menu (map name tags)] [react/scroll-view styles/list-container [react/view styles/status-list-outer [react/view styles/status-list-inner diff --git a/src/status_im/ui/screens/discover/recent_statuses/views.cljs b/src/status_im/ui/screens/discover/recent_statuses/views.cljs index a30320e772..c344089a70 100644 --- a/src/status_im/ui/screens/discover/recent_statuses/views.cljs +++ b/src/status_im/ui/screens/discover/recent_statuses/views.cljs @@ -7,7 +7,7 @@ [status-im.i18n :as i18n])) (defview discover-all-recent [] - (letsubs [discoveries [:get-recent-discoveries] + (letsubs [discoveries [:discover/recent-discoveries] tabs-hidden? [:tabs-hidden?] current-account [:get-current-account] contacts [:get-contacts]] @@ -22,8 +22,8 @@ (let [discoveries (map-indexed vector discoveries)] (for [[i {:keys [message-id] :as message}] discoveries] ^{:key (str "message-recent-" message-id)} - [components/discover-list-item-full - {:message message - :show-separator? (not= (inc i) (count discoveries)) - :contacts contacts - :current-account current-account}]))]]])])) + [components/discover-list-item-full + {:message message + :show-separator? (not= (inc i) (count discoveries)) + :contacts contacts + :current-account current-account}]))]]])])) diff --git a/src/status_im/ui/screens/discover/search_results/views.cljs b/src/status_im/ui/screens/discover/search_results/views.cljs index 8c325b8e74..121b23831f 100644 --- a/src/status_im/ui/screens/discover/search_results/views.cljs +++ b/src/status_im/ui/screens/discover/search_results/views.cljs @@ -10,27 +10,26 @@ ;; TOOD(oskarth): Refactor this, very similar to discover-all-hashtags view (defview discover-search-results [] - (letsubs [{:keys [discoveries total]} [:get-popular-discoveries 250] - tags [:get :discover-search-tags] - contacts [:get-contacts] - current-account [:get-current-account]] - [react/view styles/discover-tag-container - [toolbar/toolbar {} - toolbar/default-nav-back - [toolbar/content-title (str "#" (first tags) " " total)]] - (if (empty? discoveries) - [react/view styles/empty-view - [vi/icon :icons/group-big {:style contacts-styles/empty-contacts-icon}] - [react/text {:style contacts-styles/empty-contacts-text} - (i18n/label :t/no-statuses-found)]] - [react/scroll-view styles/list-container - [react/view styles/status-list-outer - [react/view styles/status-list-inner - (let [discoveries (map-indexed vector discoveries)] - (for [[i {:keys [message-id] :as message}] discoveries] - ^{:key (str "message-hashtag-" message-id)} - [components/discover-list-item-full - {:message message - :show-separator? (not= (inc i) (count discoveries)) - :contacts contacts - :current-account current-account}]))]]])])) + (letsubs [{:keys [discoveries tags total]} [:discover/search-results 250] + contacts [:get-contacts] + current-account [:get-current-account]] + [react/view styles/discover-tag-container + [toolbar/toolbar {} + toolbar/default-nav-back + [toolbar/content-title (str "#" (name (first tags)) " " total)]] + (if (empty? discoveries) + [react/view styles/empty-view + [vi/icon :icons/group-big {:style contacts-styles/empty-contacts-icon}] + [react/text {:style contacts-styles/empty-contacts-text} + (i18n/label :t/no-statuses-found)]] + [react/scroll-view styles/list-container + [react/view styles/status-list-outer + [react/view styles/status-list-inner + (let [discoveries (map-indexed vector discoveries)] + (for [[i {:keys [message-id] :as message}] discoveries] + ^{:key (str "message-hashtag-" message-id)} + [components/discover-list-item-full + {:message message + :show-separator? (not= (inc i) (count discoveries)) + :contacts contacts + :current-account current-account}]))]]])])) diff --git a/src/status_im/ui/screens/discover/subs.cljs b/src/status_im/ui/screens/discover/subs.cljs index 3cc345f856..faa3beb069 100644 --- a/src/status_im/ui/screens/discover/subs.cljs +++ b/src/status_im/ui/screens/discover/subs.cljs @@ -2,19 +2,11 @@ (:require [re-frame.core :refer [reg-sub]] [status-im.utils.datetime :as time])) -(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 +(defn- calculate-priority [now-ms 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)) + seen-online-recently? (< (- now-ms (get contact :last-online)) time/hour) me? (= current-public-key whisper-id)] (+ created-at ; message is newer => priority is higher @@ -23,67 +15,94 @@ (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] - (let [tags' (or tags [current-tag])] - (filter #(some (->> (:tags %) - (map :name) - (into (hash-set))) - tags') - (vals discoveries)))) +(defn- get-discoveries-by-tags [discoveries-by-tags search-tags] + (reduce (fn [acc search-tag] + (concat acc (get discoveries-by-tags search-tag []))) + [] + search-tags)) -(reg-sub - :get-popular-discoveries - :<- [:get-discoveries] - :<- [:get-current-tag] - :<- [:get-discover-search-tags] +(reg-sub :discover/discoveries :discoveries) + +(reg-sub :discover/discoveries-with-priority + :<- [:discover/discoveries] :<- [: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)}))) + :<- [:get :current-public-key] + (fn [[discoveries chats contacts current-public-key]] + (let [now-ms (time/now-ms)] + (map #(assoc % :priority (calculate-priority now-ms chats current-public-key contacts %)) (vals discoveries))))) -(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)] - [tag {:discovery (first results) - :total (count results)}]))))) +(reg-sub :discover/search-tags :discover-search-tags) -(reg-sub - :get-recent-discoveries - :<- [:get-discoveries] +(reg-sub :discover/tags + :<- [:discover/discoveries] + (fn [discoveries] + (reduce (fn [acc {:keys [tags]}] + (into acc tags)) + #{} + (vals discoveries)))) + + +;; TODO(yenda) this is not really the most recent discoveries +;; it's just all off them +(reg-sub :discover/recent-discoveries + :<- [:discover/discoveries] (fn [discoveries] (sort-by :created-at > (vals discoveries)))) -(reg-sub - :get-popular-tags - :<- [:get-tags] - (fn [tags [_ limit]] - (take limit tags))) +(reg-sub :discover/discoveries-by-tags + :<- [:discover/discoveries-with-priority] + (fn [discoveries] + (reduce (fn [discoveries-by-tags {:keys [tags] :as discovery}] + (reduce (fn [discoveries-by-tags tag] + (update discoveries-by-tags tag conj discovery)) + discoveries-by-tags + tags)) + {} + discoveries))) -(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 :discover/most-popular-hashtags + :<- [:discover/discoveries-by-tags] + (fn [discoveries] + (->> discoveries + (sort-by (comp count val) >) + (take 10)))) -(reg-sub - :get-all-dapps - :<- [:get-contact-groups] +(reg-sub :discover/popular-hashtags-preview + :<- [:discover/most-popular-hashtags] + (fn [most-popular-hashtags] + (->> most-popular-hashtags + (map (fn [[tag discoveries]] {:tag tag + :total (count discoveries) + :discovery (first (sort-by :priority > discoveries))}))))) + +(reg-sub :discover/all-popular-hashtags + :<- [:discover/most-popular-hashtags] + (fn [most-popular-hashtags] + (let [tags (map first most-popular-hashtags) + discoveries (apply concat (map second most-popular-hashtags))] + {:tags tags + :discoveries (sort-by :priority > (distinct discoveries))}))) + + +(reg-sub :discover/search-results + :<- [:discover/discoveries-by-tags] + :<- [:discover/search-tags] + :<- [:chats] :<- [:get-contacts] - (fn [[groups contacts]] - (let [dapp-ids (into #{} (map :identity) (get-in groups ["dapps" :contacts]))] - (select-keys contacts dapp-ids)))) + :<- [:get :current-public-key] + (fn [[discoveries search-tags chats contacts current-public-key] [_ limit]] + (let [discoveries (->> (get-discoveries-by-tags discoveries search-tags) + (sort-by :priority >))] + {:discoveries (take limit discoveries) + :tags search-tags + :total (count discoveries)}))) + +(reg-sub :discover/all-dapps + (fn [db] + (let [dapp? (->> (get-in db [:group/contact-groups "dapps" :contacts]) + (map :identity) + set)] + (->> (:contacts/contacts db) + (filter #(-> % key dapp?)) + (into {}))))) diff --git a/src/status_im/ui/screens/discover/views.cljs b/src/status_im/ui/screens/discover/views.cljs index 752d73e343..e118fc6148 100644 --- a/src/status_im/ui/screens/discover/views.cljs +++ b/src/status_im/ui/screens/discover/views.cljs @@ -39,16 +39,15 @@ :search-placeholder (i18n/label :t/search-tags) :on-search-submit (fn [text] (when-not (string/blank? text) - (let [tags (get-hashtags text)] - (re-frame/dispatch [:show-discovery tags :discover-search-results]))))}]) + (re-frame/dispatch [:discover/search-tags-results-view text])))}]) -(defn top-status-for-popular-hashtag [{:keys [tag item current-account contacts]}] - (let [{:keys [discovery total]} item] +(defn top-status-for-popular-hashtag [{:keys [popular-hashtag current-account contacts]}] + (let [{:keys [tag discovery total]} popular-hashtag] [react/view styles/popular-list-container [react/view styles/row [react/view {} [react/touchable-highlight - {:on-press #(re-frame/dispatch [:show-discovery [tag] :discover-search-results])} + {:on-press #(re-frame/dispatch [:discover/search-tag-results-view tag])} [react/view {} [react/text {:style styles/tag-name :font :medium} @@ -62,21 +61,19 @@ :current-account current-account :contacts contacts}]])) -(defn popular-hashtags-preview [{:keys [popular-discoveries popular-tags contacts current-account]}] - (let [has-content? (seq popular-tags) - tags (map :name popular-tags)] +(defn popular-hashtags-preview [{:keys [popular-hashtags contacts current-account]}] + (let [has-content? (seq popular-hashtags)] [react/view styles/popular-container - [components/title :t/popular-tags :t/all #(re-frame/dispatch [:show-discovery tags :discover-all-hashtags]) has-content?] + [components/title :t/popular-tags :t/all #(re-frame/dispatch [:navigate-to :discover-all-popular-hashtags]) has-content?] (if has-content? [carousel/carousel {:pageStyle styles/carousel-page-style :gap 8 :sneak 16 - :count (count popular-tags)} - (for [[tag item] popular-discoveries] - [top-status-for-popular-hashtag {:tag tag - :item item - :contacts contacts - :current-account current-account}])] + :count (count popular-hashtags)} + (for [popular-hashtag popular-hashtags] + [top-status-for-popular-hashtag {:popular-hashtag popular-hashtag + :contacts contacts + :current-account current-account}])] [empty-section :empty-hashtags :t/no-hashtags-discovered-title :t/no-hashtags-discovered-body])])) (defn recent-statuses-preview [{:keys [current-account contacts discoveries]}] @@ -147,20 +144,18 @@ search-text [:get-in [:toolbar-search :text]] contacts [:get-contacts] current-account [:get-current-account] - discoveries [:get-recent-discoveries] - all-dapps [:get-all-dapps] - popular-tags [:get-popular-tags 10] - popular-discoveries [:get-top-discovery-per-tag 10]] + discoveries [:discover/recent-discoveries] + all-dapps [:discover/all-dapps] + popular-hashtags [:discover/popular-hashtags-preview]] [react/view styles/discover-container [toolbar-view (and current-view? (= show-search :discover)) search-text] [react/scroll-view styles/list-container [recent-statuses-preview {:contacts contacts - :current-account current-account - :discoveries discoveries}] - [popular-hashtags-preview {:popular-tags popular-tags - :popular-discoveries popular-discoveries - :contacts contacts - :current-account current-account}] + :current-account current-account + :discoveries discoveries}] + [popular-hashtags-preview {:popular-hashtags popular-hashtags + :contacts contacts + :current-account current-account}] [all-dapps/preview all-dapps] [public-chats-teaser]]])) diff --git a/src/status_im/ui/screens/events.cljs b/src/status_im/ui/screens/events.cljs index f1b3ccac9f..dbb2ca199d 100644 --- a/src/status_im/ui/screens/events.cljs +++ b/src/status_im/ui/screens/events.cljs @@ -22,7 +22,7 @@ status-im.ui.screens.wallet.settings.events status-im.ui.screens.wallet.transactions.events status-im.ui.screens.wallet.choose-recipient.events - [re-frame.core :refer [dispatch reg-fx reg-cofx] :as re-frame] + [re-frame.core :as re-frame] [status-im.native-module.core :as status] [status-im.ui.components.react :as react] [status-im.ui.components.permissions :as permissions] @@ -36,7 +36,7 @@ [status-im.utils.config :as config] [status-im.utils.crypt :as crypt] [status-im.utils.notifications :as notifications] - [status-im.utils.handlers :refer [register-handler-db register-handler-fx]] + [status-im.utils.handlers :as handlers] [status-im.utils.instabug :as inst] [status-im.utils.platform :as platform] [status-im.utils.types :as types] @@ -60,21 +60,21 @@ {:chat-id chat-id} jail-response]]) :when event] - (dispatch event)))}))) + (re-frame/dispatch event)))}))) ;;;; COFX -(reg-cofx +(re-frame/reg-cofx :now (fn [coeffects _] (assoc coeffects :now (time/now-ms)))) -(reg-cofx +(re-frame/reg-cofx :random-id (fn [coeffects _] (assoc coeffects :random-id (random/id)))) -(reg-cofx +(re-frame/reg-cofx :random-id-seq (fn [coeffects _] (assoc coeffects :random-id-seq @@ -83,7 +83,7 @@ ;;;; FX -(reg-fx +(re-frame/reg-fx :call-jail (fn [{:keys [callback-events-creator] :as opts}] (status/call-jail @@ -92,103 +92,103 @@ (assoc :callback (fn [jail-response] (doseq [event (callback-events-creator jail-response)] - (dispatch event)))))))) + (re-frame/dispatch event)))))))) -(reg-fx +(re-frame/reg-fx :call-jail-function call-jail-function) -(reg-fx +(re-frame/reg-fx :call-jail-function-n (fn [opts-seq] (doseq [opts opts-seq] (call-jail-function opts)))) -(reg-fx +(re-frame/reg-fx :http-post (fn [{:keys [action data success-event-creator failure-event-creator]}] (utils/http-post action data - #(dispatch (success-event-creator %)) - #(dispatch (failure-event-creator %))))) + #(re-frame/dispatch (success-event-creator %)) + #(re-frame/dispatch (failure-event-creator %))))) (defn- http-get [{:keys [url response-validator success-event-creator failure-event-creator]}] (if response-validator (utils/http-get url response-validator - #(dispatch (success-event-creator %)) - #(dispatch (failure-event-creator %))) + #(re-frame/dispatch (success-event-creator %)) + #(re-frame/dispatch (failure-event-creator %))) (utils/http-get url - #(dispatch (success-event-creator %)) - #(dispatch (failure-event-creator %))))) + #(re-frame/dispatch (success-event-creator %)) + #(re-frame/dispatch (failure-event-creator %))))) -(reg-fx +(re-frame/reg-fx :http-get http-get) -(reg-fx +(re-frame/reg-fx :http-get-n (fn [calls] (doseq [call calls] (http-get call)))) -(reg-fx +(re-frame/reg-fx ::init-store (fn [] (data-store/init))) -(reg-fx +(re-frame/reg-fx ::initialize-crypt-fx (fn [] (crypt/gen-random-bytes - 1024 - (fn [{:keys [error buffer]}] - (if error - (log/error "Failed to generate random bytes to initialize sjcl crypto") - (->> (.toString buffer "hex") - (.toBits (.. dependencies/eccjs -sjcl -codec -hex)) - (.addEntropy (.. dependencies/eccjs -sjcl -random)))))))) + 1024 + (fn [{:keys [error buffer]}] + (if error + (log/error "Failed to generate random bytes to initialize sjcl crypto") + (->> (.toString buffer "hex") + (.toBits (.. dependencies/eccjs -sjcl -codec -hex)) + (.addEntropy (.. dependencies/eccjs -sjcl -random)))))))) (defn move-to-internal-storage [config] (status/move-to-internal-storage - #(status/start-node config))) + #(status/start-node config))) -(reg-fx +(re-frame/reg-fx :initialize-geth-fx (fn [config] (status/should-move-to-internal-storage? - (fn [should-move?] - (if should-move? - (dispatch [:request-permissions - [:read-external-storage] - #(move-to-internal-storage config) - #(dispatch [:move-to-internal-failure-message])]) - (status/start-node config)))))) + (fn [should-move?] + (if should-move? + (re-frame/dispatch [:request-permissions + [:read-external-storage] + #(move-to-internal-storage config) + #(re-frame/dispatch [:move-to-internal-failure-message])]) + (status/start-node config)))))) -(reg-fx +(re-frame/reg-fx ::status-module-initialized-fx (fn [] (status/module-initialized!))) -(reg-fx +(re-frame/reg-fx ::request-permissions-fx (fn [[permissions then else]] (permissions/request-permissions permissions then else))) -(reg-fx +(re-frame/reg-fx ::testfairy-alert (fn [] (when config/testfairy-enabled? (utils/show-popup - (i18n/label :testfairy-title) - (i18n/label :testfairy-message))))) + (i18n/label :testfairy-title) + (i18n/label :testfairy-message))))) -(reg-fx +(re-frame/reg-fx ::get-fcm-token-fx (fn [] (notifications/get-fcm-token))) -(reg-fx +(re-frame/reg-fx :show-error (fn [content] (utils/show-popup "Error" content))) @@ -206,17 +206,17 @@ ;;;; Handlers -(register-handler-db +(handlers/register-handler-db :set (fn [db [_ k v]] (assoc db k v))) -(register-handler-db +(handlers/register-handler-db :set-in (fn [db [_ path v]] (assoc-in db path v))) -(register-handler-fx +(handlers/register-handler-fx :initialize-app (fn [_ _] {::testfairy-alert nil @@ -227,7 +227,7 @@ [:initialize-crypt] [:initialize-geth]]})) -(register-handler-fx +(handlers/register-handler-fx :initialize-db (fn [{{:keys [status-module-initialized? status-node-started? network-status network] @@ -242,7 +242,7 @@ :status-node-started? status-node-started? :network network)})) -(register-handler-db +(handlers/register-handler-db :initialize-account-db (fn [{:keys [accounts/accounts contacts/contacts networks/networks network network-status view-id navigation-stack chats @@ -271,7 +271,7 @@ console-contact (assoc :contacts/contacts {console-chat-id console-contact}))))) -(register-handler-fx +(handlers/register-handler-fx :initialize-account (fn [_ [_ address events-after]] {:dispatch-n (cond-> [[:initialize-account-db address] @@ -281,18 +281,16 @@ [:initialize-chats] [:load-contacts] [:load-contact-groups] - [:init-discoveries] [:initialize-debugging {:address address}] [:send-account-update-if-needed] - [:start-requesting-discoveries] - [:remove-old-discoveries!] + [:init-discoveries] [:update-wallet] [:update-transactions] [:get-fcm-token]] (seq events-after) (into events-after))})) -(register-handler-fx +(handlers/register-handler-fx :check-console-chat (fn [{{:accounts/keys [accounts] :as db} :db} [_ open-console?]] (let [view (if (empty? accounts) @@ -307,12 +305,12 @@ (when open-console? [[:navigate-to-chat console-chat-id]]))}))))) -(register-handler-fx +(handlers/register-handler-fx :initialize-crypt (fn [_ _] {::initialize-crypt-fx nil})) -(register-handler-fx +(handlers/register-handler-fx :initialize-geth (fn [{db :db} _] (let [{:accounts/keys [current-account-id accounts]} db @@ -323,12 +321,12 @@ (get-in default-networks [default-network :config]))] {:initialize-geth-fx network-config}))) -(register-handler-fx +(handlers/register-handler-fx :webview-geo-permissions-granted (fn [{{:keys [webview-bridge]} :db} _] (.geoPermissionsGranted webview-bridge))) -(register-handler-fx +(handlers/register-handler-fx :get-fcm-token (fn [_ _] {::get-fcm-token-fx nil})) @@ -345,66 +343,66 @@ (defn handle-jail-signal [{:keys [chat_id data]}] (let [{:keys [event data]} (types/json->clj data)] (case event - "local-storage" (dispatch [:set-local-storage {:chat-id chat_id + "local-storage" (re-frame/dispatch [:set-local-storage {:chat-id chat_id :data data}]) - "show-suggestions" (dispatch [:show-suggestions-from-jail {:chat-id chat_id + "show-suggestions" (re-frame/dispatch [:show-suggestions-from-jail {:chat-id chat_id :markup data}]) - "send-message" (dispatch [:send-message-from-jail {:chat-id chat_id + "send-message" (re-frame/dispatch [:send-message-from-jail {:chat-id chat_id :message data}]) "handler-result" (let [orig-params (:origParams data)] ;; TODO(janherich): figure out and fix chat_id from event - (dispatch [:command-handler! (:chat-id orig-params) + (re-frame/dispatch [:command-handler! (:chat-id orig-params) (restore-command-ref-keyword orig-params) {:result {:returned (dissoc data :origParams)}}])) (log/debug "Unknown jail signal " event)))) -(register-handler-fx +(handlers/register-handler-fx :signal-event (fn [_ [_ event-str]] (log/debug :event-str event-str) (inst/log (str "Signal event: " event-str)) (let [{:keys [type event]} (types/json->clj event-str)] (case type - "transaction.queued" (dispatch [:transaction-queued event]) - "transaction.failed" (dispatch [:transaction-failed event]) - "node.started" (dispatch [:status-node-started]) - "node.stopped" (dispatch [:status-node-stopped]) - "module.initialized" (dispatch [:status-module-initialized]) - "request_geo_permissions" (dispatch [:request-permissions [:geolocation] - #(dispatch [:webview-geo-permissions-granted])]) + "transaction.queued" (re-frame/dispatch [:transaction-queued event]) + "transaction.failed" (re-frame/dispatch [:transaction-failed event]) + "node.started" (re-frame/dispatch [:status-node-started]) + "node.stopped" (re-frame/dispatch [:status-node-stopped]) + "module.initialized" (re-frame/dispatch [:status-module-initialized]) + "request_geo_permissions" (re-frame/dispatch [:request-permissions [:geolocation] + #(re-frame/dispatch [:webview-geo-permissions-granted])]) "jail.signal" (handle-jail-signal event) (log/debug "Event " type " not handled"))))) -(register-handler-fx +(handlers/register-handler-fx :status-module-initialized (fn [{:keys [db]} _] {:db (assoc db :status-module-initialized? true) ::status-module-initialized-fx nil})) -(register-handler-fx +(handlers/register-handler-fx :status-node-started (fn [{{:node/keys [after-start] :as db} :db}] (merge {:db (assoc db :status-node-started? true)} (when after-start {:dispatch-n [after-start]})))) -(register-handler-fx +(handlers/register-handler-fx :status-node-stopped (fn [{{:node/keys [after-stop]} :db}] (when after-stop {:dispatch-n [after-stop]}))) -(register-handler-fx +(handlers/register-handler-fx :app-state-change (fn [_ [_ state]])) ;; TODO(rasom): let's not remove this handler, it will be used for ;; pausing node on entering background on android -(register-handler-fx +(handlers/register-handler-fx :request-permissions (fn [_ [_ permissions then else]] {::request-permissions-fx [permissions then else]})) -(register-handler-fx +(handlers/register-handler-fx :request-geolocation-update (fn [_ _] {:dispatch [:request-permissions [:geolocation] @@ -412,8 +410,8 @@ (let [watch-id (atom nil)] (.getCurrentPosition react/geolocation - #(dispatch [:update-geolocation (js->clj % :keywordize-keys true)]) - #(dispatch [:update-geolocation (js->clj % :keywordize-keys true)]) + #(re-frame/dispatch [:update-geolocation (js->clj % :keywordize-keys true)]) + #(re-frame/dispatch [:update-geolocation (js->clj % :keywordize-keys true)]) (clj->js {:enableHighAccuracy true :timeout 20000 :maximumAge 1000})) (when platform/android? (reset! watch-id @@ -423,9 +421,9 @@ (.clearWatch react/geolocation @watch-id) - (dispatch [:update-geolocation (js->clj % :keywordize-keys true)])))))))]})) + (re-frame/dispatch [:update-geolocation (js->clj % :keywordize-keys true)])))))))]})) -(register-handler-db +(handlers/register-handler-db :update-geolocation (fn [db [_ geolocation]] (assoc db :geolocation geolocation))) diff --git a/src/status_im/ui/screens/views.cljs b/src/status_im/ui/screens/views.cljs index b3059b1fc3..ab65b58bcd 100644 --- a/src/status_im/ui/screens/views.cljs +++ b/src/status_im/ui/screens/views.cljs @@ -101,7 +101,7 @@ :profile profile :edit-my-profile edit-my-profile :discover-all-recent discover-recent/discover-all-recent - :discover-all-hashtags discover-popular/discover-all-hashtags + :discover-all-popular-hashtags discover-popular/discover-all-popular-hashtags :discover-search-results discover-search/discover-search-results :discover-dapp-details discover-dapp-details/dapp-details :discover-all-dapps discover-all-dapps/main diff --git a/src/status_im/utils/handlers.cljs b/src/status_im/utils/handlers.cljs index 9e5c888374..9dde6099a1 100644 --- a/src/status_im/utils/handlers.cljs +++ b/src/status_im/utils/handlers.cljs @@ -97,7 +97,7 @@ (defn get-hashtags [status] (if status - (let [hashtags (map #(string/lower-case (subs % 1)) + (let [hashtags (map #(keyword (string/lower-case (subs % 1))) (re-seq #"#[^ !?,;:.]+" status))] (set (or hashtags []))) #{}))