mirror of
https://github.com/status-im/status-react.git
synced 2025-01-11 03:26:31 +00:00
[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
This commit is contained in:
parent
1b563a59cc
commit
5c359886e5
@ -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 []
|
||||
|
@ -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))))
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
|
31
src/status_im/data_store/realm/schemas/account/v20/core.cljs
Normal file
31
src/status_im/data_store/realm/schemas/account/v20/core.cljs
Normal file
@ -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))
|
@ -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"))
|
@ -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?))
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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?))
|
@ -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
|
||||
|
7
src/status_im/ui/screens/discover/navigation.cljs
Normal file
7
src/status_im/ui/screens/discover/navigation.cljs
Normal file
@ -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))
|
@ -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
|
||||
|
@ -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}]))]]])]))
|
||||
|
@ -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}]))]]])]))
|
||||
|
@ -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 {})))))
|
||||
|
@ -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]]]))
|
||||
|
@ -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)))
|
||||
|
@ -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
|
||||
|
@ -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 [])))
|
||||
#{}))
|
||||
|
Loading…
x
Reference in New Issue
Block a user