diff --git a/.carve_ignore b/.carve_ignore index 697d7c3630a..4eef8e06712 100644 --- a/.carve_ignore +++ b/.carve_ignore @@ -95,7 +95,6 @@ react-native.fs/unlink react-native.fs/file-exists? status-im.ui.components.colors/white status-im.ui.components.colors/black -status-im.transport.core-test/messages status-im.ui.components.core/animated-header status-im.ui.components.core/safe-area-provider status-im.ui.components.core/safe-area-consumer diff --git a/.zprintrc b/.zprintrc index 9f4c2bd0c57..4f582f97290 100644 --- a/.zprintrc +++ b/.zprintrc @@ -32,6 +32,7 @@ "letsubs" :binding "with-let" "let" "reg-event-fx" :arg1-pair + "reg-fx" :arg1-pair "testing" :arg1-body "deftest-sub" :arg1-body "wait-for" :arg1-body diff --git a/src/status_im/chat/models/input.cljs b/src/status_im/chat/models/input.cljs index 695caa33171..ccfeca0dd6a 100644 --- a/src/status_im/chat/models/input.cljs +++ b/src/status_im/chat/models/input.cljs @@ -5,11 +5,11 @@ [goog.object :as object] [re-frame.core :as re-frame] [status-im.chat.models.mentions :as mentions] - [status-im.chat.models.message :as chat.message] [status-im.chat.models.message-content :as message-content] [status-im.data-store.messages :as data-store-messages] [status-im2.constants :as constants] [status-im2.contexts.chat.composer.link-preview.events :as link-preview] + [status-im2.contexts.chat.messages.transport.events :as messages.transport] [taoensso.timbre :as log] [utils.i18n :as i18n] [utils.re-frame :as rf] @@ -205,7 +205,7 @@ (rf/merge cofx (clean-input (:current-chat-id db)) (link-preview/reset-unfurled) - (chat.message/send-messages messages))))) + (messages.transport/send-chat-messages messages))))) (rf/defn send-audio-message [{:keys [db] :as cofx} audio-path duration current-chat-id] @@ -214,25 +214,26 @@ (when-not (string/blank? audio-path) (rf/merge {:db (assoc-in db [:chat/inputs current-chat-id :metadata :responding-to-message] nil)} - (chat.message/send-message - (merge - {:chat-id current-chat-id - :content-type constants/content-type-audio - :audio-path audio-path - :audio-duration-ms duration - :text (i18n/label :t/update-to-listen-audio {"locale" "en"})} - (when message-id - {:response-to message-id}))))))) + (messages.transport/send-chat-messages + [(merge + {:chat-id current-chat-id + :content-type constants/content-type-audio + :audio-path audio-path + :audio-duration-ms duration + :text (i18n/label :t/update-to-listen-audio {"locale" "en"})} + (when message-id + {:response-to message-id}))]))))) (rf/defn send-sticker-message [cofx {:keys [hash packID pack]} current-chat-id] (when-not (or (string/blank? hash) (and (string/blank? packID) (string/blank? pack))) - (chat.message/send-message cofx - {:chat-id current-chat-id - :content-type constants/content-type-sticker - :sticker {:hash hash - :pack (int (if (string/blank? packID) pack packID))} - :text (i18n/label :t/update-to-see-sticker {"locale" "en"})}))) + (messages.transport/send-chat-messages + cofx + [{:chat-id current-chat-id + :content-type constants/content-type-sticker + :sticker {:hash hash + :pack (int (if (string/blank? packID) pack packID))} + :text (i18n/label :t/update-to-see-sticker {"locale" "en"})}]))) (rf/defn send-edited-message [{:keys [db] diff --git a/src/status_im/chat/models/message.cljs b/src/status_im/chat/models/message.cljs index 6b9cc62c1aa..df1ca7a1242 100644 --- a/src/status_im/chat/models/message.cljs +++ b/src/status_im/chat/models/message.cljs @@ -5,7 +5,6 @@ [react-native.platform :as platform] [status-im.chat.models.loading :as chat.loading] [status-im.data-store.messages :as data-store.messages] - [status-im.transport.message.protocol :as protocol] [status-im.utils.deprecated-types :as types] [status-im2.contexts.chat.messages.delete-message.events :as delete-message] [status-im2.contexts.chat.messages.list.events :as message-list] @@ -21,12 +20,6 @@ [db chat-id clock-value] (>= (get-in db [:chats chat-id :deleted-at-clock-value]) clock-value)) -(defn add-timeline-message - [acc chat-id message-id message] - (-> acc - (update-in [:db :messages chat-id] assoc message-id message) - (update-in [:db :message-lists chat-id] message-list/add message))) - (defn hide-message "Hide chat message, rebuild message-list" [{:keys [db]} chat-id message-id] @@ -145,14 +138,6 @@ :on-error #(log/error "failed to re-send message" %)}]} (update-message-status chat-id message-id :sending))) -(rf/defn send-message - [cofx message] - (protocol/send-chat-messages cofx [message])) - -(rf/defn send-messages - [cofx messages] - (protocol/send-chat-messages cofx messages)) - (rf/defn handle-removed-messages {:events [::handle-removed-messages]} [{:keys [db] :as cofx} removed-messages] diff --git a/src/status_im/chat/models/reactions.cljs b/src/status_im/chat/models/reactions.cljs index 3e78ad87b53..93825664847 100644 --- a/src/status_im/chat/models/reactions.cljs +++ b/src/status_im/chat/models/reactions.cljs @@ -2,7 +2,6 @@ (:require [re-frame.core :as re-frame] [status-im.data-store.reactions :as data-store.reactions] - [status-im.transport.message.protocol :as message.protocol] [status-im2.constants :as constants] [taoensso.timbre :as log] [utils.re-frame :as rf] @@ -63,23 +62,6 @@ (let [reactions-w-chat-id (map #(assoc % :chat-id chat-id) reactions)] {:db (update db :reactions (process-reactions (:chats db)) reactions-w-chat-id)}))) - -;; Send reactions - - -(rf/defn send-emoji-reaction - {:events [:models.reactions/send-emoji-reaction]} - [{{:keys [current-chat-id]} :db :as cofx} reaction] - (message.protocol/send-reaction cofx - (update reaction :chat-id #(or % current-chat-id)))) - -(rf/defn send-retract-emoji-reaction - {:events [:models.reactions/send-emoji-reaction-retraction]} - [{{:keys [current-chat-id]} :db :as cofx} reaction] - (message.protocol/send-retract-reaction cofx - (update reaction :chat-id #(or % current-chat-id)))) - - (defn message-reactions [current-public-key reactions] (reduce diff --git a/src/status_im/events.cljs b/src/status_im/events.cljs index b5b98d3339b..92f20190338 100644 --- a/src/status_im/events.cljs +++ b/src/status_im/events.cljs @@ -32,9 +32,7 @@ status-im.pairing.core status-im.profile.core status-im.search.core - status-im.signals.core status-im.stickers.core - status-im.transport.core status-im.ui.components.invite.events [status-im.ui.components.react :as react] status-im.ui.screens.notifications-settings.events @@ -194,9 +192,9 @@ (rf/merge cofx (cond (= :chat view-id) - {:async-storage-set {:chat-id (get-in cofx [:db :current-chat-id]) - :key-uid (get-in cofx [:db :profile/profile :key-uid])} - :db (assoc db :screens/was-focused-once? true)} + {:effects.async-storage/set {:chat-id (get-in cofx [:db :current-chat-id]) + :key-uid (get-in cofx [:db :profile/profile :key-uid])} + :db (assoc db :screens/was-focused-once? true)} (not (get db :screens/was-focused-once?)) {:db (assoc db :screens/was-focused-once? true)}) diff --git a/src/status_im/keycard/change_pin.cljs b/src/status_im/keycard/change_pin.cljs index b88cdf3e96b..48e20046745 100644 --- a/src/status_im/keycard/change_pin.cljs +++ b/src/status_im/keycard/change_pin.cljs @@ -141,14 +141,14 @@ (let [pin (get-in db [:keycard :pin :original]) puk-restore? (get-in db [:keycard :pin :puk-restore?])] (rf/merge cofx - {:db (assoc-in db - [:keycard :pin] - {:status nil - :login pin - :confirmation [] - :error-label nil}) - :utils/show-popup {:title "" - :content (i18n/label :t/pin-changed)}} + {:db (assoc-in db + [:keycard :pin] + {:status nil + :login pin + :confirmation [] + :error-label nil}) + :effects.utils/show-popup {:title "" + :content (i18n/label :t/pin-changed)}} (common/hide-connection-sheet) (if puk-restore? (navigation/navigate-to :multiaccounts nil) @@ -160,14 +160,14 @@ {:events [:keycard.callback/on-change-puk-success]} [{:keys [db] :as cofx}] (rf/merge cofx - {:db (assoc-in db - [:keycard :pin] - {:status nil - :puk-original [] - :puk-confirmation [] - :error-label nil}) - :utils/show-popup {:title "" - :content (i18n/label :t/puk-changed)}} + {:db (assoc-in db + [:keycard :pin] + {:status nil + :puk-original [] + :puk-confirmation [] + :error-label nil}) + :effects.utils/show-popup {:title "" + :content (i18n/label :t/puk-changed)}} (common/hide-connection-sheet) (navigation/set-stack-root :profile-stack [:my-profile :keycard-settings]))) @@ -175,13 +175,13 @@ {:events [:keycard.callback/on-change-pairing-success]} [{:keys [db] :as cofx}] (rf/merge cofx - {:db (assoc-in db - [:keycard :pin] - {:status nil - :pairing-code nil - :error-label nil}) - :utils/show-popup {:title "" - :content (i18n/label :t/pairing-changed)}} + {:db (assoc-in db + [:keycard :pin] + {:status nil + :pairing-code nil + :error-label nil}) + :effects.utils/show-popup {:title "" + :content (i18n/label :t/pairing-changed)}} (common/hide-connection-sheet) (navigation/set-stack-root :profile-stack [:my-profile :keycard-settings]))) diff --git a/src/status_im/keycard/common.cljs b/src/status_im/keycard/common.cljs index f7f2802a38a..3bce5616995 100644 --- a/src/status_im/keycard/common.cljs +++ b/src/status_im/keycard/common.cljs @@ -293,14 +293,14 @@ (rf/defn show-wrong-keycard-alert [_] (log/debug "show-wrong-keycard-alert") - {:utils/show-popup {:title (i18n/label :t/wrong-card) - :content (i18n/label :t/wrong-card-text)}}) + {:effects.utils/show-popup {:title (i18n/label :t/wrong-card) + :content (i18n/label :t/wrong-card-text)}}) (rf/defn unauthorized-operation [cofx] (rf/merge cofx - {:utils/show-popup {:title "" - :content (i18n/label :t/keycard-unauthorized-operation)}} + {:effects.utils/show-popup {:title "" + :content (i18n/label :t/keycard-unauthorized-operation)}} (clear-on-card-connected) (navigation/set-stack-root :profile-stack [:my-profile :keycard-settings]))) diff --git a/src/status_im/keycard/core.cljs b/src/status_im/keycard/core.cljs index db2a9e0c247..b8b28ec6049 100644 --- a/src/status_im/keycard/core.cljs +++ b/src/status_im/keycard/core.cljs @@ -24,12 +24,12 @@ (rf/defn show-keycard-has-multiaccount-alert [{:keys [db] :as cofx}] (rf/merge cofx - {:db (assoc-in db [:keycard :setup-step] nil) - :utils/show-confirmation {:title nil - :content (i18n/label - :t/keycard-has-multiaccount-on-it) - :cancel-button-text "" - :confirm-button-text :t/okay}})) + {:db (assoc-in db [:keycard :setup-step] nil) + :effects.utils/show-confirmation {:title nil + :content (i18n/label + :t/keycard-has-multiaccount-on-it) + :cancel-button-text "" + :confirm-button-text :t/okay}})) (rf/defn load-pin-screen [{:keys [db] :as cofx}] @@ -548,10 +548,11 @@ (rf/defn show-no-keycard-applet-alert [_] - {:utils/show-confirmation {:title (i18n/label :t/no-keycard-applet-on-card) - :content (i18n/label :t/keycard-applet-install-instructions) - :cancel-button-text "" - :confirm-button-text :t/okay}}) + {:effects.utils/show-confirmation {:title (i18n/label :t/no-keycard-applet-on-card) + :content (i18n/label + :t/keycard-applet-install-instructions) + :cancel-button-text "" + :confirm-button-text :t/okay}}) ;; NOTE: Maybe replaced by multiple events based on on flow to make it easier to maintain. ;; Because there are many execution paths it is harder to follow all possible states. diff --git a/src/status_im/keycard/onboarding.cljs b/src/status_im/keycard/onboarding.cljs index 74ec69ed3e4..bbd16b8f756 100644 --- a/src/status_im/keycard/onboarding.cljs +++ b/src/status_im/keycard/onboarding.cljs @@ -35,8 +35,8 @@ (do (log/debug (str "Cannot start keycard installation from state: " card-state)) (rf/merge cofx - {:utils/show-popup {:title (i18n/label :t/error) - :content (i18n/label :t/something-went-wrong)}} + {:effects.utils/show-popup {:title (i18n/label :t/error) + :content (i18n/label :t/something-went-wrong)}} (navigation/navigate-to :keycard-authentication-method nil)))))) (rf/defn load-preparing-screen diff --git a/src/status_im/keycard/recovery.cljs b/src/status_im/keycard/recovery.cljs index f37297296d6..36c8fdf10cd 100644 --- a/src/status_im/keycard/recovery.cljs +++ b/src/status_im/keycard/recovery.cljs @@ -221,12 +221,12 @@ (rf/defn on-backup-success [{:keys [db] :as cofx} backup-type] (rf/merge cofx - {:utils/show-popup {:title (i18n/label (if (= backup-type :recovery-card) - :t/keycard-access-reset - :t/keycard-backup-success-title)) - :content (i18n/label (if (= backup-type :recovery-card) - :t/keycard-can-use-with-new-passcode - :t/keycard-backup-success-body))}} + {:effects.utils/show-popup {:title (i18n/label (if (= backup-type :recovery-card) + :t/keycard-access-reset + :t/keycard-backup-success-title)) + :content (i18n/label (if (= backup-type :recovery-card) + :t/keycard-can-use-with-new-passcode + :t/keycard-backup-success-body))}} (cond (multiaccounts.model/logged-in? db) (navigation/set-stack-root :profile-stack [:my-profile :keycard-settings]) @@ -373,4 +373,3 @@ cofx {:on-card-connected :keycard/load-recovering-key-screen :handler (common/dispatch-event :keycard/import-multiaccount)})) - diff --git a/src/status_im/keycard/unpair.cljs b/src/status_im/keycard/unpair.cljs index f8ccb1524df..f663f31ff11 100644 --- a/src/status_im/keycard/unpair.cljs +++ b/src/status_im/keycard/unpair.cljs @@ -83,7 +83,7 @@ :error-label nil :on-verified nil})) :keycard/persist-pairings (dissoc pairings (keyword instance-uid)) - :utils/show-popup {:title "" + :effects.utils/show-popup {:title "" :content (i18n/label :t/card-unpaired)}} (common/clear-on-card-connected) (remove-pairing-from-multiaccount nil) @@ -100,7 +100,7 @@ :error-label nil :on-verified nil}) :keycard/get-application-info nil - :utils/show-popup {:title "" + :effects.utils/show-popup {:title "" :content (i18n/label :t/something-went-wrong)}} (common/clear-on-card-connected) (navigation/navigate-to :keycard-settings nil))) @@ -139,15 +139,14 @@ :error-label nil :on-verified nil})) :keycard/persist-pairings (dissoc pairings (keyword instance-uid)) - :utils/show-popup {:title (i18n/label (if keys-removed-from-card? + :effects.utils/show-popup {:title (i18n/label (if keys-removed-from-card? :t/profile-deleted-title :t/database-reset-title)) :content (i18n/label (if keys-removed-from-card? :t/profile-deleted-keycard :t/database-reset-content)) :on-dismiss #(re-frame/dispatch [:logout])}} - ;;should be reimplemented - ;;:key-storage/delete-profile {:key-uid key-uid + ;;should be reimplemented :key-storage/delete-profile {:key-uid key-uid ;;:on-success #(log/debug "[keycard] remove account ok") ;; :on-error #(log/warn "[keycard] remove account: " %)} (common/clear-on-card-connected) diff --git a/src/status_im/mailserver/core.cljs b/src/status_im/mailserver/core.cljs index 835de8ca61c..320b523dff5 100644 --- a/src/status_im/mailserver/core.cljs +++ b/src/status_im/mailserver/core.cljs @@ -194,7 +194,7 @@ {:events [:mailserver.ui/request-error-pressed]} [{:keys [db]}] (let [mailserver-error (:mailserver/request-error db)] - {:utils/show-confirmation + {:effects.utils/show-confirmation {:title (i18n/label :t/mailserver-request-error-title) :content (i18n/label :t/mailserver-request-error-content {:error mailserver-error}) @@ -290,8 +290,7 @@ [{:method "mailservers_addMailserver" :params [(mailserver->rpc mailserver current-fleet)] :on-success (fn [] - ;; we naively logout if the user is connected to - ;; the edited mailserver + ;; we naively logout if the user is connected to the edited mailserver (when current (re-frame/dispatch [:multiaccounts.logout.ui/logout-confirmed])) @@ -413,3 +412,17 @@ (rf/merge cofx {:db (dissoc db :mailserver.edit/mailserver)} (navigation/navigate-to :edit-mailserver nil))) + +(defn add-mailservers + [db mailservers] + (reduce (fn [db {:keys [fleet id name] :as mailserver}] + (let [updated-mailserver + (-> mailserver + (update :id keyword) + (assoc :name (if (seq name) name id)) + (dissoc :fleet))] + (assoc-in db + [:mailserver/mailservers (keyword fleet) (keyword id)] + updated-mailserver))) + db + mailservers)) diff --git a/src/status_im/multiaccounts/logout/core.cljs b/src/status_im/multiaccounts/logout/core.cljs index 4df946aec79..8d0491ba685 100644 --- a/src/status_im/multiaccounts/logout/core.cljs +++ b/src/status_im/multiaccounts/logout/core.cljs @@ -31,7 +31,7 @@ (rf/merge cofx {:set-root :progress :chat.ui/clear-inputs nil - :shell/reset-state nil + :effects.shell/reset-state nil :hide-popover nil ::logout nil :profile.settings/webview-debug-changed false diff --git a/src/status_im/network/core.cljs b/src/status_im/network/core.cljs index 463758209ad..461e94cfa8c 100644 --- a/src/status_im/network/core.cljs +++ b/src/status_im/network/core.cljs @@ -89,7 +89,7 @@ (rf/defn connect-failure {:events [::connect-failure]} [_ reason] - {:utils/show-popup + {:effects.utils/show-popup {:title (i18n/label :t/error) :content (str reason)}}) diff --git a/src/status_im/pairing/core.cljs b/src/status_im/pairing/core.cljs index 7e0d6d60215..9feb6c9485c 100644 --- a/src/status_im/pairing/core.cljs +++ b/src/status_im/pairing/core.cljs @@ -165,9 +165,9 @@ (if (< (count (filter :enabled? (vals (get-in cofx [:db :pairing/installations])))) (inc config/max-installations)) {:pairing/enable-installation [installation-id]} - {:utils/show-popup {:title (i18n/label :t/pairing-maximum-number-reached-title) + {:effects.utils/show-popup {:title (i18n/label :t/pairing-maximum-number-reached-title) - :content (i18n/label :t/pairing-maximum-number-reached-content)}})) + :content (i18n/label :t/pairing-maximum-number-reached-content)}})) (rf/defn disable-fx {:events [:pairing.ui/disable-installation-pressed]} diff --git a/src/status_im/qr_scanner/core.cljs b/src/status_im/qr_scanner/core.cljs index 445368c4041..2aa447bfa21 100644 --- a/src/status_im/qr_scanner/core.cljs +++ b/src/status_im/qr_scanner/core.cljs @@ -49,8 +49,8 @@ [{:keys [db] :as cofx} {:keys [chat-id]}] (if-not (own-public-key? db chat-id) {:dispatch [:chat.ui/start-chat chat-id]} - {:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code) - :content (i18n/label :t/can-not-add-yourself)}})) + {:effects.utils/show-popup {:title (i18n/label :t/unable-to-read-this-code) + :content (i18n/label :t/can-not-add-yourself)}})) (rf/defn handle-group-chat [cofx params] @@ -71,9 +71,9 @@ (navigation/navigate-back)) :else - {:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code) - :content (i18n/label :t/ens-name-not-found) - :on-dismiss #(re-frame/dispatch [:pop-to-root :shell-stack])}}))) + {:effects.utils/show-popup {:title (i18n/label :t/unable-to-read-this-code) + :content (i18n/label :t/ens-name-not-found) + :on-dismiss #(re-frame/dispatch [:pop-to-root :shell-stack])}}))) (rf/defn handle-eip681 [cofx data] @@ -103,9 +103,9 @@ (log/info "Unable to find matcher for scanned value" {:type type :event ::match-scanned-value}) - {:dispatch [:navigate-back] - :utils/show-popup {:title (i18n/label :t/unable-to-read-this-code) - :on-dismiss #(re-frame/dispatch [:pop-to-root :shell-stack])}}))) + {:dispatch [:navigate-back] + :effects.utils/show-popup {:title (i18n/label :t/unable-to-read-this-code) + :on-dismiss #(re-frame/dispatch [:pop-to-root :shell-stack])}}))) (rf/defn on-scan {:events [::on-scan-success]} diff --git a/src/status_im/signing/keycard.cljs b/src/status_im/signing/keycard.cljs index 7ec9a53fb4e..ca0e1e28cc5 100644 --- a/src/status_im/signing/keycard.cljs +++ b/src/status_im/signing/keycard.cljs @@ -78,9 +78,9 @@ [{:keys [db]} data typed? result] (let [{:keys [result error]} (types/json->clj result)] (if error - {:dispatch [:signing.ui/cancel-is-pressed] - :utils/show-popup {:title (i18n/label :t/sign-request-failed) - :content (:message error)}} + {:dispatch [:signing.ui/cancel-is-pressed] + :effects.utils/show-popup {:title (i18n/label :t/sign-request-failed) + :content (:message error)}} {:db (update db :keycard assoc :hash result diff --git a/src/status_im/transport/core.cljs b/src/status_im/transport/core.cljs index ee389e212d5..e69de29bb2d 100644 --- a/src/status_im/transport/core.cljs +++ b/src/status_im/transport/core.cljs @@ -1,58 +0,0 @@ -(ns ^{:doc "API to init and stop whisper messaging"} status-im.transport.core - (:require - [re-frame.core :as re-frame] - [status-im.pairing.core :as pairing] - [status-im.stickers.core :as stickers] - status-im.transport.shh - [status-im2.common.universal-links :as universal-links] - [taoensso.timbre :as log] - [utils.re-frame :as rf])) - -(rf/defn set-node-info - {:events [:transport.callback/node-info-fetched]} - [{:keys [db]} node-info] - {:db (assoc db :node-info node-info)}) - -(rf/defn fetch-node-info-fx - [_] - {:json-rpc/call [{:method "admin_nodeInfo" - :on-success #(re-frame/dispatch [:transport.callback/node-info-fetched %]) - :on-error #(log/error "node-info: failed error" %)}]}) - -(defn add-mailservers - [db mailservers] - (reduce (fn [db {:keys [fleet id name] :as mailserver}] - (let [updated-mailserver - (-> mailserver - (update :id keyword) - (assoc :name (if (seq name) name id)) - (dissoc :fleet))] - (assoc-in db - [:mailserver/mailservers (keyword fleet) (keyword id)] - updated-mailserver))) - db - mailservers)) - -(rf/defn start-messenger - "We should only start receiving messages/processing topics once all the - initializiation is completed, otherwise we might receive messages/topics - when the state has not been properly initialized." - [_] - {:json-rpc/call [{:method "wakuext_startMessenger" - :on-success #(re-frame/dispatch [::messenger-started %]) - :on-error #(log/error "failed to start messenger")}]}) - -(rf/defn messenger-started - {:events [::messenger-started]} - [{:keys [db] :as cofx} {:keys [mailservers] :as response}] - (log/info "Messenger started") - (let [new-account? (get db :onboarding/new-account?)] - (rf/merge cofx - {:db (-> db - (assoc :messenger/started? true) - (add-mailservers mailservers))} - (fetch-node-info-fx) - (pairing/init) - (stickers/load-packs) - (when-not new-account? - (universal-links/process-stored-event))))) diff --git a/src/status_im/transport/message/protocol.cljs b/src/status_im/transport/message/protocol.cljs deleted file mode 100644 index e3cb8323e10..00000000000 --- a/src/status_im/transport/message/protocol.cljs +++ /dev/null @@ -1,59 +0,0 @@ -(ns ^{:doc "Protocol API and protocol utils"} status-im.transport.message.protocol - (:require - [clojure.set :as set] - [re-frame.core :as re-frame] - [taoensso.timbre :as log] - [utils.re-frame :as rf])) - -(defn- link-preview->rpc - [preview] - (update preview - :thumbnail - (fn [thumbnail] - (set/rename-keys thumbnail {:data-uri :dataUri})))) - -(defn build-message - [msg] - (-> msg - (update :link-previews #(map link-preview->rpc %)) - (set/rename-keys - {:album-id :albumId - :audio-duration-ms :audioDurationMs - :audio-path :audioPath - :chat-id :chatId - :community-id :communityId - :content-type :contentType - :ens-name :ensName - :image-height :imageHeight - :image-path :imagePath - :image-width :imageWidth - :link-previews :linkPreviews - :response-to :responseTo - :sticker :sticker - :text :text}))) - -(rf/defn send-chat-messages - [_ messages] - {:json-rpc/call [{:method "wakuext_sendChatMessages" - :params [(mapv build-message messages)] - :js-response true - :on-success #(re-frame/dispatch [:transport/message-sent %]) - :on-error #(do - (log/warn "failed to send a message" %) - (js/alert (str "failed to send a message: " %)))}]}) - -(rf/defn send-reaction - [_ {:keys [message-id chat-id emoji-id]}] - {:json-rpc/call [{:method "wakuext_sendEmojiReaction" - :params [chat-id message-id emoji-id] - :js-response true - :on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %]) - :on-error #(log/error "failed to send a reaction" %)}]}) - -(rf/defn send-retract-reaction - [_ {:keys [emoji-reaction-id]}] - {:json-rpc/call [{:method "wakuext_sendEmojiReactionRetraction" - :params [emoji-reaction-id] - :js-response true - :on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %]) - :on-error #(log/error "failed to send a reaction retraction" %)}]}) diff --git a/src/status_im/transport/shh.cljs b/src/status_im/transport/shh.cljs deleted file mode 100644 index d7e7751464a..00000000000 --- a/src/status_im/transport/shh.cljs +++ /dev/null @@ -1,35 +0,0 @@ -(ns ^{:doc "Whisper API and events for managing keys and posting messages"} status-im.transport.shh - (:require - [re-frame.core :as re-frame] - [status-im2.common.json-rpc.events :as json-rpc] - [taoensso.timbre :as log])) - -(defn generate-sym-key-from-password - [{:keys [password on-success on-error]}] - (json-rpc/call {:method "waku_generateSymKeyFromPassword" - :params [password] - :on-success on-success - :on-error on-error})) - -(defn get-sym-key - [{:keys [sym-key-id on-success on-error]}] - (json-rpc/call {:method "waku_getSymKey" - :params [sym-key-id] - :on-success on-success - :on-error on-error})) - -(defn log-error - [error] - (log/error :shh/get-new-sym-key-error error)) - -(re-frame/reg-fx - :shh/generate-sym-key-from-password - (fn [{:keys [password on-success]}] - (generate-sym-key-from-password - {:password password - :on-success (fn [sym-key-id] - (get-sym-key {:sym-key-id sym-key-id - :on-success (fn [sym-key] - (on-success sym-key sym-key-id)) - :on-error log-error})) - :on-error log-error}))) diff --git a/src/status_im/transport/utils.cljs b/src/status_im/transport/utils.cljs deleted file mode 100644 index 64e51295b3d..00000000000 --- a/src/status_im/transport/utils.cljs +++ /dev/null @@ -1,18 +0,0 @@ -(ns ^{:doc "Utils for transport layer"} status-im.transport.utils - (:require - [clojure.string :as string])) - -(defn extract-enode-id - [enode] - (-> enode - (string/split #"/") - (get 2 "") - (string/split #":") - (get 0 "") - (string/split "@") - (get 0))) - -(defn extract-url-components - [address] - (when address - (rest (re-matches #"enode://(.*?)@(.*):(.*)" address)))) diff --git a/src/status_im/ui/screens/privacy_and_security_settings/events.cljs b/src/status_im/ui/screens/privacy_and_security_settings/events.cljs index fb8cf70e1f6..36260447391 100644 --- a/src/status_im/ui/screens/privacy_and_security_settings/events.cljs +++ b/src/status_im/ui/screens/privacy_and_security_settings/events.cljs @@ -56,7 +56,7 @@ {:events [::on-delete-profile-success]} [cofx] (log/info "[delete-profile] on-success") - {:utils/show-popup + {:effects.utils/show-popup {:title (i18n/label :t/profile-deleted-title) :content (i18n/label :t/profile-deleted-content) :on-dismiss #(re-frame/dispatch [:logout])}}) diff --git a/src/status_im/utils/logging/core.cljs b/src/status_im/utils/logging/core.cljs index b1f485e00be..3886fac6589 100644 --- a/src/status_im/utils/logging/core.cljs +++ b/src/status_im/utils/logging/core.cljs @@ -7,7 +7,6 @@ [react-native.mail :as react-native-mail] [react-native.platform :as platform] [status-im.bottom-sheet.events :as bottom-sheet] - [status-im.transport.utils :as transport.utils] [status-im.ui.components.react :as react] [status-im.utils.build :as build] [status-im.utils.deprecated-types :as types] @@ -38,6 +37,11 @@ {:json-rpc/call [{:method "web3_clientVersion" :on-success #(re-frame/dispatch [:logging/store-web3-client-version %])}]}) +(defn extract-url-components + [address] + (when address + (rest (re-matches #"enode://(.*?)@(.*):(.*)" address)))) + (defn email-body "logs attached" [{:keys [:web3-node-version :mailserver/current-id @@ -46,7 +50,7 @@ build-version (str build/version " (" build-number ")") separator (string/join (take 40 (repeat "-"))) [enode-id ip-address port] - (transport.utils/extract-url-components (:enode node-info))] + (extract-url-components (:enode node-info))] (string/join "\n" (concat [(i18n/label :t/report-bug-email-template @@ -68,7 +72,7 @@ (mapcat (fn [{:keys [enode]}] (let [[enode-id ip-address port] - (transport.utils/extract-url-components enode)] + (extract-url-components enode)] [(str "id: " enode-id) (str "ip: " ip-address) (str "port: " port) @@ -151,15 +155,15 @@ (rf/defn show-client-error {:events [:show-client-error]} [_] - {:utils/show-popup {:title (i18n/label :t/cant-report-bug) - :content (i18n/label :t/mail-should-be-configured)}}) + {:effects.utils/show-popup {:title (i18n/label :t/cant-report-bug) + :content (i18n/label :t/mail-should-be-configured)}}) (rf/defn show-logs-dialog {:events [:shake-event]} [{:keys [db]}] (when-not (:logging/dialog-shown? db) {:db (assoc db :logging/dialog-shown? true) - :utils/show-confirmation + :effects.utils/show-confirmation (cond-> {:title (i18n/label :t/send-logs) :content (i18n/label :t/send-logs-to {:email report-email}) diff --git a/src/status_im/wallet/accounts/core.cljs b/src/status_im/wallet/accounts/core.cljs index c557ebf7310..79b759b14b9 100644 --- a/src/status_im/wallet/accounts/core.cljs +++ b/src/status_im/wallet/accounts/core.cljs @@ -359,8 +359,8 @@ (let [deleted-address (:address account) dapps-address (get-in cofx [:db :profile/profile :dapps-address])] (if (= (string/lower-case dapps-address) (string/lower-case deleted-address)) - {:utils/show-popup {:title (i18n/label :t/warning) - :content (i18n/label :t/account-is-used)}} + {:effects.utils/show-popup {:title (i18n/label :t/warning) + :content (i18n/label :t/account-is-used)}} {:key-storage/delete-imported-key {:key-uid (get-in db [:profile/profile :key-uid]) :address (:address account) @@ -379,8 +379,8 @@ (assoc-in [:add-account :scanned-address] address) (assoc-in [:add-account :address] address))} (when-not address - {:utils/show-popup {:title (i18n/label :t/error) - :content (i18n/label :t/invalid-address-qr-code)}})) + {:effects.utils/show-popup {:title (i18n/label :t/error) + :content (i18n/label :t/invalid-address-qr-code)}})) (navigation/navigate-back)))) (re-frame/reg-fx @@ -392,4 +392,3 @@ {:events [:wallet-legacy.accounts/share]} [_ address] {:list.selection/open-share {:message (eip55/address->checksum address)}}) - diff --git a/src/status_im/wallet/core.cljs b/src/status_im/wallet/core.cljs index 2606db2396b..35697f44b19 100644 --- a/src/status_im/wallet/core.cljs +++ b/src/status_im/wallet/core.cljs @@ -246,8 +246,8 @@ assets (get visible-tokens chain) tokens (->> (vals all-tokens) (remove #(or (:hidden? %) - ;;if not scan-all-tokens? remove not - ;;visible tokens + ;;if not scan-all-tokens? remove + ;;not visible tokens (and (not scan-all-tokens?) (not (get assets (:symbol %)))))) (reduce (fn [acc {:keys [address symbol]}] @@ -822,8 +822,8 @@ (rf/defn get-buy-crypto-preference {:events [::get-buy-crypto]} [_] - {:async-storage-get {:keys [:buy-crypto-hidden] - :cb #(re-frame/dispatch [::store-buy-crypto-preference %])}}) + {:effects.async-storage/get {:keys [:buy-crypto-hidden] + :cb #(re-frame/dispatch [::store-buy-crypto-preference %])}}) (rf/defn wallet-will-focus {:events [::wallet-stack]} @@ -844,8 +844,8 @@ (rf/defn hide-buy-crypto {:events [::hide-buy-crypto]} [{:keys [db]}] - {:db (assoc db :wallet-legacy/buy-crypto-hidden true) - :async-storage-set {:buy-crypto-hidden true}}) + {:db (assoc db :wallet-legacy/buy-crypto-hidden true) + :effects.async-storage/set {:buy-crypto-hidden true}}) (rf/defn store-buy-crypto {:events [::store-buy-crypto-preference]} @@ -1023,8 +1023,8 @@ (rf/defn switch-transactions-management-enabled {:events [:multiaccounts.ui/switch-transactions-management-enabled]} [{:keys [db]} enabled?] - {:async-storage-set {:transactions-management-enabled? enabled?} - :db (assoc db :wallet-legacy/transactions-management-enabled? enabled?)}) + {:effects.async-storage/set {:transactions-management-enabled? enabled?} + :db (assoc db :wallet-legacy/transactions-management-enabled? enabled?)}) (re-frame/reg-fx :wallet-legacy/initialize-transactions-management-enabled @@ -1072,9 +1072,8 @@ true])})) 2000))) -(re-frame/reg-fx - ;;TODO: this could be replaced by a single API call on status-go side - :wallet-legacy/initialize-wallet +;;TODO: this could be replaced by a single API call on status-go side +(re-frame/reg-fx :wallet-legacy/initialize-wallet (fn [[network-id network callback]] (-> (js/Promise.all (clj->js diff --git a/src/status_im/wallet/custom_tokens/core.cljs b/src/status_im/wallet/custom_tokens/core.cljs index ee4dfdbd81a..4b01249ccbe 100644 --- a/src/status_im/wallet/custom_tokens/core.cljs +++ b/src/status_im/wallet/custom_tokens/core.cljs @@ -65,8 +65,8 @@ (rf/defn not-supported {:events [:wallet-legacy.custom-token/not-supported]} [{:keys [db]}] - {:db (assoc-in db [:wallet-legacy/custom-token-screen :in-progress?] nil) - :utils/show-popup {:content (i18n/label :t/contract-isnt-supported)}}) + {:db (assoc-in db [:wallet-legacy/custom-token-screen :in-progress?] nil) + :effects.utils/show-popup {:content (i18n/label :t/contract-isnt-supported)}}) (rf/defn add-custom-token {:events [:wallet-legacy.custom-token.ui/add-pressed]} diff --git a/src/status_im2/common/alert/events.cljs b/src/status_im2/common/alert/effects.cljs similarity index 75% rename from src/status_im2/common/alert/events.cljs rename to src/status_im2/common/alert/effects.cljs index e12e03e8b55..a511308b53f 100644 --- a/src/status_im2/common/alert/events.cljs +++ b/src/status_im2/common/alert/effects.cljs @@ -1,8 +1,8 @@ -(ns status-im2.common.alert.events +(ns status-im2.common.alert.effects (:require - [re-frame.core :as re-frame] [react-native.core :as rn] - [utils.i18n :as i18n])) + [utils.i18n :as i18n] + [utils.re-frame :as rf])) (defn show-popup ([title content] @@ -26,8 +26,7 @@ (when on-dismiss {:cancelable false}))))) -(re-frame/reg-fx - :utils/show-popup +(rf/reg-fx :effects.utils/show-popup (fn [{:keys [title content on-dismiss]}] (show-popup title content on-dismiss))) @@ -50,8 +49,7 @@ (or extra-options nil)) {:cancelable false})) -(re-frame/reg-fx - :utils/show-confirmation +(rf/reg-fx :effects.utils/show-confirmation (fn [{:keys [title content confirm-button-text on-accept on-cancel cancel-button-text extra-options]}] (show-confirmation {:title title :content content @@ -60,18 +58,3 @@ :on-accept on-accept :on-cancel on-cancel :extra-options extra-options}))) - -(defn show-question - ([title content on-accept] - (show-question title content on-accept nil)) - ([title content on-accept on-cancel] - (rn/alert - title - content - (vector (merge {:text (i18n/label :t/no) - :accessibility-label :no-button} - (when on-cancel {:onPress on-cancel})) - {:text (i18n/label :t/yes) - :onPress on-accept - :accessibility-label :yes-button}) - nil))) diff --git a/src/status_im2/common/async_storage.cljs b/src/status_im2/common/async_storage.cljs deleted file mode 100644 index a1a66b2538d..00000000000 --- a/src/status_im2/common/async_storage.cljs +++ /dev/null @@ -1,8 +0,0 @@ -(ns status-im2.common.async-storage - (:require - [re-frame.core :as re-frame] - react-native.async-storage)) - -(re-frame/reg-fx :async-storage-set (react-native.async-storage/set-item-factory)) -(re-frame/reg-fx :async-storage-get - (fn [{ks :keys cb :cb}] (react-native.async-storage/get-items ks cb))) diff --git a/src/status_im2/common/async_storage/effects.cljs b/src/status_im2/common/async_storage/effects.cljs new file mode 100644 index 00000000000..9943a2ecca1 --- /dev/null +++ b/src/status_im2/common/async_storage/effects.cljs @@ -0,0 +1,11 @@ +(ns status-im2.common.async-storage.effects + (:require + [react-native.async-storage :as async-storage] + [utils.re-frame :as rf])) + +(rf/reg-fx :effects.async-storage/set + (async-storage/set-item-factory)) + +(rf/reg-fx :effects.async-storage/get + (fn [{ks :keys cb :cb}] + (async-storage/get-items ks cb))) diff --git a/src/status_im2/common/biometric/events.cljs b/src/status_im2/common/biometric/events.cljs index 7508e197a07..30fbe694cc6 100644 --- a/src/status_im2/common/biometric/events.cljs +++ b/src/status_im2/common/biometric/events.cljs @@ -51,7 +51,7 @@ (i18n/label :t/grant-face-id-permissions) (i18n/label :t/biometric-auth-error {:code code}))] (when handle-error? - {:utils/show-popup + {:effects.utils/show-popup {:title (i18n/label :t/biometric-auth-login-error-title) :content content}}))) diff --git a/src/status_im2/common/font/effects.cljs b/src/status_im2/common/font/effects.cljs new file mode 100644 index 00000000000..894016653ed --- /dev/null +++ b/src/status_im2/common/font/effects.cljs @@ -0,0 +1,8 @@ +(ns status-im2.common.font.effects + (:require + utils.image-server + [utils.re-frame :as rf])) + +(rf/reg-fx :effects.font/get-font-file-for-initials-avatar + (fn [callback] + (utils.image-server/get-font-file-ready callback))) diff --git a/src/status_im2/common/font.cljs b/src/status_im2/common/font/events.cljs similarity index 60% rename from src/status_im2/common/font.cljs rename to src/status_im2/common/font/events.cljs index cc26cf71016..863ef38e7df 100644 --- a/src/status_im2/common/font.cljs +++ b/src/status_im2/common/font/events.cljs @@ -1,15 +1,9 @@ -(ns status-im2.common.font +(ns status-im2.common.font.events (:require [clojure.string :as string] - [re-frame.core :as re-frame] - utils.image-server + status-im2.common.font.effects [utils.re-frame :as rf])) -(re-frame/reg-fx - :font/get-font-file-for-initials-avatar - (fn [callback] - (utils.image-server/get-font-file-ready callback))) - (rf/defn init-abs-root-path {:events [:font/init-font-file-for-initials-avatar]} [{:keys [db]} initials-avatar-font-file] diff --git a/src/status_im2/common/pairing/events.cljs b/src/status_im2/common/pairing/events.cljs new file mode 100644 index 00000000000..114c5ba7fbe --- /dev/null +++ b/src/status_im2/common/pairing/events.cljs @@ -0,0 +1,65 @@ +(ns status-im2.common.pairing.events + (:require + [quo.foundations.colors :as colors] + [status-im2.constants :as constants] + [status-im2.contexts.communities.discover.events] + [taoensso.timbre :as log] + [utils.re-frame :as rf])) + +(rf/defn handle-local-pairing-signals + [{:keys [db]} {:keys [type action data error] :as event}] + (log/info "local pairing signal received" + {:event event}) + (let [{:keys [account password]} data + role (get-in db [:syncing :role]) + receiver? (= role constants/local-pairing-role-receiver) + sender? (= role constants/local-pairing-role-sender) + connection-success? (and (= type + constants/local-pairing-event-connection-success) + (= action + constants/local-pairing-action-connect)) + error-on-pairing? (contains? constants/local-pairing-event-errors type) + completed-pairing? (and (= type + constants/local-pairing-event-transfer-success) + (= action + constants/local-pairing-action-pairing-installation)) + received-account? (and (= type + constants/local-pairing-event-received-account) + (= action + constants/local-pairing-action-pairing-account) + (and (some? account) (some? password))) + multiaccount-data (when received-account? + (merge account {:password password})) + navigate-to-syncing-devices? (and (or connection-success? error-on-pairing?) receiver?) + user-in-syncing-devices-screen? (or (= (:view-id db) :syncing-progress) + (= (:view-id db) :syncing-progress-intro)) + user-in-sign-in-intro-screen? (= (:view-id db) :sign-in-intro)] + (merge {:db (cond-> db + connection-success? + (assoc-in [:syncing :pairing-status] :connected) + + received-account? + (assoc-in [:syncing :profile] multiaccount-data) + + error-on-pairing? + (assoc-in [:syncing :pairing-status] :error) + + completed-pairing? + (assoc-in [:syncing :pairing-status] :completed))} + (cond + (and navigate-to-syncing-devices? (not user-in-syncing-devices-screen?)) + {:dispatch (if user-in-sign-in-intro-screen? + [:navigate-to-within-stack [:syncing-progress-intro :sign-in-intro]] + [:navigate-to :syncing-progress])} + + (and completed-pairing? sender?) + {:dispatch [:syncing/clear-states]} + + (and completed-pairing? receiver?) + {:dispatch [:profile.login/local-paired-user]} + + (and error-on-pairing? (some? error)) + {:dispatch [:toasts/upsert + {:icon :i/alert + :icon-color colors/danger-50 + :text error}]})))) diff --git a/src/status_im2/common/scan_qr_code/style.cljs b/src/status_im2/common/scan_qr_code/style.cljs index c4eeed23279..5c66a9f1adc 100644 --- a/src/status_im2/common/scan_qr_code/style.cljs +++ b/src/status_im2/common/scan_qr_code/style.cljs @@ -38,10 +38,11 @@ :padding-horizontal screen-padding :margin-vertical 12}) -(def header-text +(defn header-text + [bottom-padding?] {:padding-horizontal screen-padding :padding-top 12 - :padding-bottom 8 + :padding-bottom (when bottom-padding? 8) :color colors/white}) (def header-sub-text @@ -53,7 +54,7 @@ :margin-top 20}) (def scan-qr-code-container - {:margin-top 19}) + {:margin-top 20}) (def qr-view-finder {:margin-horizontal screen-padding diff --git a/src/status_im2/common/scan_qr_code/view.cljs b/src/status_im2/common/scan_qr_code/view.cljs index 66658cac194..374255ec567 100644 --- a/src/status_im2/common/scan_qr_code/view.cljs +++ b/src/status_im2/common/scan_qr_code/view.cljs @@ -35,13 +35,14 @@ [quo/text {:size :heading-1 :weight :semi-bold - :style style/header-text} + :style (style/header-text (when subtitle true))} title] - [quo/text - {:size :paragraph-1 - :weight :regular - :style style/header-sub-text} - subtitle]]) + (when subtitle + [quo/text + {:size :paragraph-1 + :weight :regular + :style style/header-sub-text} + subtitle])]) (defn get-labels-and-on-press-method [] @@ -109,21 +110,22 @@ [white-border :bottom-right]]]) (defn- viewfinder - [qr-view-finder] + [qr-view-finder helper-text?] (let [layout-size (+ (:width qr-view-finder) 2)] [rn/view {:style (style/viewfinder-container qr-view-finder)} [white-square layout-size] - [quo/text - {:size :paragraph-2 - :weight :regular - :style style/viewfinder-text} - (i18n/label :t/ensure-qr-code-is-in-focus-to-scan)]])) + (when helper-text? + [quo/text + {:size :paragraph-2 + :weight :regular + :style style/viewfinder-text} + (i18n/label :t/ensure-qr-code-is-in-focus-to-scan)])])) (defn- scan-qr-code-tab - [qr-view-finder] + [qr-view-finder helper-text?] (if (and @camera-permission-granted? (boolean (not-empty qr-view-finder))) - [viewfinder qr-view-finder] + [viewfinder qr-view-finder helper-text?] [camera-permission-view])) (defn- check-qr-code-and-navigate @@ -223,7 +225,7 @@ [:<> [rn/view {:style style/scan-qr-code-container}] [qr-scan-hole-area qr-view-finder]]) - [scan-qr-code-tab @qr-view-finder] + [scan-qr-code-tab @qr-view-finder (when subtitle true)] [rn/view {:style style/flex-spacer}] (when show-camera? [quo.theme/provider {:theme :light} diff --git a/src/status_im/signals/core.cljs b/src/status_im2/common/signals/events.cljs similarity index 57% rename from src/status_im/signals/core.cljs rename to src/status_im2/common/signals/events.cljs index b9a919ae770..b1b88e6dde4 100644 --- a/src/status_im/signals/core.cljs +++ b/src/status_im2/common/signals/events.cljs @@ -1,13 +1,12 @@ -(ns status-im.signals.core +(ns status-im2.common.signals.events (:require - [quo.foundations.colors :as colors] [status-im.chat.models.message :as models.message] [status-im.ethereum.subscriptions :as ethereum.subscriptions] [status-im.mailserver.core :as mailserver] - [status-im.transport.message.core :as transport.message] [status-im.visibility-status-updates.core :as visibility-status-updates] - [status-im2.constants :as constants] + [status-im2.common.pairing.events :as pairing] [status-im2.contexts.chat.messages.link-preview.events :as link-preview] + [status-im2.contexts.chat.messages.transport.events :as messages.transport] [status-im2.contexts.communities.discover.events] [status-im2.contexts.profile.login.events :as profile.login] [status-im2.contexts.push-notifications.local.events :as local-notifications] @@ -29,64 +28,6 @@ [{:keys [db]} peer-stats] {:db (assoc db :peer-stats peer-stats :peers-count (count (:peers peer-stats)))}) -(rf/defn handle-local-pairing-signals - [{:keys [db]} {:keys [type action data error] :as event}] - (log/info "local pairing signal received" - {:event event}) - (let [{:keys [account password]} data - role (get-in db [:syncing :role]) - receiver? (= role constants/local-pairing-role-receiver) - sender? (= role constants/local-pairing-role-sender) - connection-success? (and (= type - constants/local-pairing-event-connection-success) - (= action - constants/local-pairing-action-connect)) - error-on-pairing? (contains? constants/local-pairing-event-errors type) - completed-pairing? (and (= type - constants/local-pairing-event-transfer-success) - (= action - constants/local-pairing-action-pairing-installation)) - received-account? (and (= type - constants/local-pairing-event-received-account) - (= action - constants/local-pairing-action-pairing-account) - (and (some? account) (some? password))) - multiaccount-data (when received-account? - (merge account {:password password})) - navigate-to-syncing-devices? (and (or connection-success? error-on-pairing?) receiver?) - user-in-syncing-devices-screen? (or (= (:view-id db) :syncing-progress) - (= (:view-id db) :syncing-progress-intro)) - user-in-sign-in-intro-screen? (= (:view-id db) :sign-in-intro)] - (merge {:db (cond-> db - connection-success? - (assoc-in [:syncing :pairing-status] :connected) - - received-account? - (assoc-in [:syncing :profile] multiaccount-data) - - error-on-pairing? - (assoc-in [:syncing :pairing-status] :error) - - completed-pairing? - (assoc-in [:syncing :pairing-status] :completed))} - (cond - (and navigate-to-syncing-devices? (not user-in-syncing-devices-screen?)) - {:dispatch (if user-in-sign-in-intro-screen? - [:navigate-to-within-stack [:syncing-progress-intro :sign-in-intro]] - [:navigate-to :syncing-progress])} - - (and completed-pairing? sender?) - {:dispatch [:syncing/clear-states]} - - (and completed-pairing? receiver?) - {:dispatch [:profile.login/local-paired-user]} - - (and error-on-pairing? (some? error)) - {:dispatch [:toasts/upsert - {:icon :i/alert - :icon-color colors/danger-50 - :text error}]})))) - (rf/defn process {:events [:signals/signal-received]} [{:keys [db] :as cofx} event-str] @@ -101,18 +42,18 @@ "backup.performed" {:db (assoc-in db [:profile/profile :last-backup] (.-lastBackup event-js))} - "envelope.sent" (transport.message/update-envelopes-status cofx - (:ids - (js->clj event-js - :keywordize-keys - true)) - :sent) - "envelope.expired" (transport.message/update-envelopes-status cofx - (:ids - (js->clj event-js - :keywordize-keys - true)) - :not-sent) + "envelope.sent" (messages.transport/update-envelopes-status cofx + (:ids + (js->clj event-js + :keywordize-keys + true)) + :sent) + "envelope.expired" (messages.transport/update-envelopes-status cofx + (:ids + (js->clj event-js + :keywordize-keys + true)) + :not-sent) "message.delivered" (let [{:keys [chatID messageID]} (js->clj event-js :keywordize-keys true)] @@ -126,9 +67,9 @@ "discovery.summary" (summary cofx (js->clj event-js :keywordize-keys true)) "mediaserver.started" {:db (assoc db :mediaserver/port (.-port event-js))} "wakuv2.peerstats" (wakuv2-peer-stats cofx (js->clj event-js :keywordize-keys true)) - "messages.new" (transport.message/sanitize-messages-and-process-response cofx - event-js - true) + "messages.new" (messages.transport/sanitize-messages-and-process-response cofx + event-js + true) "wallet" (ethereum.subscriptions/new-wallet-event cofx (js->clj event-js :keywordize-keys @@ -141,7 +82,7 @@ "status.updates.timedout" (visibility-status-updates/handle-visibility-status-updates cofx (js->clj event-js :keywordize-keys true)) - "localPairing" (handle-local-pairing-signals + "localPairing" (pairing/handle-local-pairing-signals cofx (js->clj event-js :keywordize-keys true)) "curated.communities.update" (rf/dispatch [:fetched-contract-communities diff --git a/src/status_im2/common/universal_links.cljs b/src/status_im2/common/universal_links.cljs index 047a8bf49ac..6e98509e434 100644 --- a/src/status_im2/common/universal_links.cljs +++ b/src/status_im2/common/universal_links.cljs @@ -44,8 +44,8 @@ (when chat-id (if-not (own-public-key? db chat-id) {:dispatch [:chat.ui/start-chat chat-id]} - {:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code) - :content (i18n/label :t/can-not-add-yourself)}}))) + {:effects.utils/show-popup {:title (i18n/label :t/unable-to-read-this-code) + :content (i18n/label :t/can-not-add-yourself)}}))) (rf/defn handle-community-requests [cofx {:keys [community-id]}] diff --git a/src/status_im2/constants.cljs b/src/status_im2/constants.cljs index cf315771f63..b0e20c11da5 100644 --- a/src/status_im2/constants.cljs +++ b/src/status_im2/constants.cljs @@ -372,7 +372,9 @@ ;; wallet (def ^:const mainnet-chain-id 1) (def ^:const optimism-chain-id 10) +(def ^:const optimism-test-chain-id 420) (def ^:const arbitrum-chain-id 42161) +(def ^:const arbitrum-test-chain-id 421613) (def ^:const goerli-chain-id 5) (def ^:const mainnet-short-name "eth") diff --git a/src/status_im2/contexts/add_new_contact/effects.cljs b/src/status_im2/contexts/add_new_contact/effects.cljs new file mode 100644 index 00000000000..2627b7df1c1 --- /dev/null +++ b/src/status_im2/contexts/add_new_contact/effects.cljs @@ -0,0 +1,22 @@ +(ns status-im2.contexts.add-new-contact.effects + (:require + [native-module.core :as native-module] + [status-im.ethereum.ens :as ens] + [status-im2.constants :as constants] + [utils.re-frame :as rf] + [utils.transforms :as transforms])) + +(rf/reg-fx :effects.contacts/decompress-public-key + (fn [{:keys [compressed-key on-success on-error]}] + (native-module/compressed-key->public-key + compressed-key + constants/deserialization-key + (fn [resp] + (let [{:keys [error]} (transforms/json->clj resp)] + (if error + (on-error error) + (on-success (str "0x" (subs resp 5))))))))) + +(rf/reg-fx :effects.contacts/resolve-public-key-from-ens + (fn [{:keys [chain-id ens on-success on-error]}] + (ens/pubkey chain-id ens on-success on-error))) diff --git a/src/status_im2/contexts/add_new_contact/events.cljs b/src/status_im2/contexts/add_new_contact/events.cljs index 3ec4487614d..cb7d91976b8 100644 --- a/src/status_im2/contexts/add_new_contact/events.cljs +++ b/src/status_im2/contexts/add_new_contact/events.cljs @@ -1,17 +1,13 @@ (ns status-im2.contexts.add-new-contact.events (:require [clojure.string :as string] - [native-module.core :as native-module] - [re-frame.core :as re-frame] - [status-im.ethereum.ens :as ens] - [status-im2.constants :as constants] + status-im2.contexts.add-new-contact.effects [status-im2.contexts.contacts.events :as data-store.contacts] [status-im2.navigation.events :as navigation] [utils.ens.stateofus :as stateofus] [utils.ethereum.chain :as chain] [utils.re-frame :as rf] [utils.string :as utils.string] - [utils.transforms :as transforms] [utils.validators :as validators])) (defn init-contact @@ -108,14 +104,14 @@ :empty {:db (dissoc db :contacts/new-identity)} (:valid :invalid) {:db (assoc db :contacts/new-identity contact)} :decompress-key {:db (assoc db :contacts/new-identity contact) - :contacts/decompress-public-key + :effects.contacts/decompress-public-key {:compressed-key id :on-success (dispatcher :contacts/set-new-identity-success input) :on-error (dispatcher :contacts/set-new-identity-error input)}} :resolve-ens {:db (assoc db :contacts/new-identity contact) - :contacts/resolve-public-key-from-ens + :effects.contacts/resolve-public-key-from-ens {:chain-id (chain/chain-id db) :ens ens :on-success @@ -123,22 +119,7 @@ :on-error (dispatcher :contacts/set-new-identity-error input)}}))) -(re-frame/reg-fx - :contacts/decompress-public-key - (fn [{:keys [compressed-key on-success on-error]}] - (native-module/compressed-key->public-key - compressed-key - constants/deserialization-key - (fn [resp] - (let [{:keys [error]} (transforms/json->clj resp)] - (if error - (on-error error) - (on-success (str "0x" (subs resp 5))))))))) - -(re-frame/reg-fx - :contacts/resolve-public-key-from-ens - (fn [{:keys [chain-id ens on-success on-error]}] - (ens/pubkey chain-id ens on-success on-error))) + (rf/defn build-contact {:events [:contacts/build-contact]} diff --git a/src/status_im2/contexts/add_new_contact/events_test.cljs b/src/status_im2/contexts/add_new_contact/events_test.cljs index 9130b02687a..8ee2b402ea8 100644 --- a/src/status_im2/contexts/add_new_contact/events_test.cljs +++ b/src/status_im2/contexts/add_new_contact/events_test.cljs @@ -115,7 +115,7 @@ :ens ens-stateofus-eth :public-key nil ; not yet... :state :resolve-ens})) - :contacts/resolve-public-key-from-ens + :effects.contacts/resolve-public-key-from-ens {:chain-id 1 :ens ens-stateofus-eth :on-success [:contacts/set-new-identity-success ens] @@ -131,7 +131,7 @@ :type :compressed-key :public-key nil ; not yet... :state :decompress-key})) - :contacts/decompress-public-key + :effects.contacts/decompress-public-key {:compressed-key user-ckey :on-success [:contacts/set-new-identity-success user-ckey] :on-error [:contacts/set-new-identity-error user-ckey]}}))) diff --git a/src/status_im2/contexts/add_new_contact/scan/scan_profile_qr_page.cljs b/src/status_im2/contexts/add_new_contact/scan/scan_profile_qr_page.cljs new file mode 100644 index 00000000000..f7f6973d3eb --- /dev/null +++ b/src/status_im2/contexts/add_new_contact/scan/scan_profile_qr_page.cljs @@ -0,0 +1,20 @@ +(ns status-im2.contexts.add-new-contact.scan.scan-profile-qr-page + (:require [react-native.core :as rn] + [react-native.hooks :as hooks] + [status-im2.common.scan-qr-code.view :as scan-qr-code] + [utils.debounce :as debounce] + [utils.i18n :as i18n])) + +(defn- f-internal-view + [] + (let [{:keys [keyboard-shown]} (hooks/use-keyboard)] + [:<> + (when keyboard-shown + (rn/dismiss-keyboard!)) + [scan-qr-code/view + {:title (i18n/label :t/scan-qr) + :on-success-scan #(debounce/debounce-and-dispatch [:contacts/set-new-identity % %] 300)}]])) + +(defn view + [] + [:f> f-internal-view]) diff --git a/src/status_im2/contexts/add_new_contact/views.cljs b/src/status_im2/contexts/add_new_contact/views.cljs index 7c0eb9c8209..052f1f2ffae 100644 --- a/src/status_im2/contexts/add_new_contact/views.cljs +++ b/src/status_im2/contexts/add_new_contact/views.cljs @@ -4,7 +4,6 @@ [react-native.clipboard :as clipboard] [react-native.core :as rn] [reagent.core :as reagent] - [status-im.qr-scanner.core :as qr-scanner] [status-im2.contexts.add-new-contact.style :as style] [utils.address :as address] [utils.debounce :as debounce] @@ -96,8 +95,7 @@ {:type :outline :icon-only? true :size 40 - :on-press #(rf/dispatch [::qr-scanner/scan-code - {:handler :contacts/qr-code-scanned}])} + :on-press #(rf/dispatch [:open-modal :scan-profile-qr-code])} :i/scan]]]) (finally (rf/dispatch [:contacts/clear-new-identity])))) diff --git a/src/status_im2/contexts/chat/composer/actions/view.cljs b/src/status_im2/contexts/chat/composer/actions/view.cljs index 927116dbac3..c9d24d37931 100644 --- a/src/status_im2/contexts/chat/composer/actions/view.cljs +++ b/src/status_im2/contexts/chat/composer/actions/view.cljs @@ -7,7 +7,7 @@ [react-native.platform :as platform] [react-native.reanimated :as reanimated] [reagent.core :as reagent] - [status-im2.common.alert.events :as alert] + [status-im2.common.alert.effects :as alert.effects] [status-im2.common.device-permissions :as device-permissions] [status-im2.constants :as constants] [status-im2.contexts.chat.composer.actions.style :as style] @@ -146,7 +146,7 @@ :on-denied #(js/setTimeout (fn [] - (alert/show-popup + (alert.effects/show-popup (i18n/label :t/audio-recorder-error) (i18n/label :t/audio-recorder-permissions-error) @@ -198,9 +198,9 @@ (reanimated/get-shared-value height)]) (rf/dispatch [:open-modal :photo-selector {:insets insets}])) :on-denied (fn [] - (alert/show-popup (i18n/label :t/error) - (i18n/label - :t/external-storage-denied)))})) + (alert.effects/show-popup (i18n/label :t/error) + (i18n/label + :t/external-storage-denied)))})) (defn image-button [props animations insets edit] @@ -246,6 +246,6 @@ [:f> send-button props state animations window-height images edit send-btn-opacity scroll-to-bottom-fn] (when (and (not edit) (not images)) - ;; TODO(alwx): needs to be replaced with an `audio-button` later. - ;; See https://github.com/status-im/status-mobile/issues/16084 for more details. + ;; TODO(alwx): needs to be replaced with an `audio-button` later. See + ;; https://github.com/status-im/status-mobile/issues/16084 for more details. [:f> disabled-audio-button audio-btn-opacity])])) diff --git a/src/status_im2/contexts/chat/effects.cljs b/src/status_im2/contexts/chat/effects.cljs new file mode 100644 index 00000000000..5904b997b2c --- /dev/null +++ b/src/status_im2/contexts/chat/effects.cljs @@ -0,0 +1,18 @@ +(ns status-im2.contexts.chat.effects + (:require + [react-native.async-storage :as async-storage] + [status-im2.contexts.shell.jump-to.constants :as shell.constants] + [utils.re-frame :as rf])) + +(rf/reg-fx :effects.chat/open-last-chat + (fn [key-uid] + (async-storage/get-item + :chat-id + (fn [chat-id] + (when chat-id + (async-storage/get-item + :key-uid + (fn [stored-key-uid] + (when (= stored-key-uid key-uid) + (rf/dispatch [:chat/navigate-to-chat chat-id + shell.constants/open-screen-without-animation]))))))))) diff --git a/src/status_im2/contexts/chat/events.cljs b/src/status_im2/contexts/chat/events.cljs index 9819f370a69..78c8072407e 100644 --- a/src/status_im2/contexts/chat/events.cljs +++ b/src/status_im2/contexts/chat/events.cljs @@ -3,7 +3,6 @@ [clojure.set :as set] [quo.foundations.colors :as colors] [re-frame.core :as re-frame] - [react-native.async-storage :as async-storage] [reagent.core :as reagent] [status-im.chat.models.loading :as loading] [status-im.data-store.chats :as chats-store] @@ -11,11 +10,11 @@ [status-im2.config :as config] [status-im2.constants :as constants] [status-im2.contexts.chat.composer.link-preview.events :as link-preview] + status-im2.contexts.chat.effects [status-im2.contexts.chat.messages.delete-message-for-me.events :as delete-for-me] [status-im2.contexts.chat.messages.delete-message.events :as delete-message] [status-im2.contexts.chat.messages.list.state :as chat.state] [status-im2.contexts.contacts.events :as contacts-store] - [status-im2.contexts.shell.jump-to.constants :as shell.constants] [status-im2.navigation.events :as navigation] [taoensso.timbre :as log] [utils.datetime :as datetime] @@ -172,11 +171,11 @@ (chat.state/reset-visible-item) (rf/merge cofx (merge - {:db (-> db - (dissoc :current-chat-id) - (assoc-in [:chat/inputs chat-id :focused?] false)) - :async-storage-set {:chat-id nil - :key-uid nil}} + {:db (-> db + (dissoc :current-chat-id) + (assoc-in [:chat/inputs chat-id :focused?] false)) + :effects.async-storage/set {:chat-id nil + :key-uid nil}} (let [community-id (get-in db [:chats chat-id :community-id])] ;; When navigating back from community chat to community, update switcher card ;; A close chat event is also called while opening any chat. @@ -431,21 +430,7 @@ [{:keys [db]} value] {:db (assoc db :lightbox/scale value)}) -(re-frame/reg-fx - :chat/open-last-chat - (fn [key-uid] - (async-storage/get-item - :chat-id - (fn [chat-id] - (when chat-id - (async-storage/get-item - :key-uid - (fn [stored-key-uid] - (when (= stored-key-uid key-uid) - (re-frame/dispatch [:chat/navigate-to-chat chat-id - shell.constants/open-screen-without-animation]))))))))) - (rf/defn check-last-chat {:events [:chat/check-last-chat]} [{:keys [db]}] - {:chat/open-last-chat (get-in db [:profile/profile :key-uid])}) + {:effects.chat/open-last-chat (get-in db [:profile/profile :key-uid])}) diff --git a/src/status_im2/contexts/chat/messages/content/reactions/view.cljs b/src/status_im2/contexts/chat/messages/content/reactions/view.cljs index b733356d149..e64789ac5cc 100644 --- a/src/status_im2/contexts/chat/messages/content/reactions/view.cljs +++ b/src/status_im2/contexts/chat/messages/content/reactions/view.cljs @@ -9,11 +9,8 @@ (defn- on-press [{:keys [own message-id emoji-id emoji-reaction-id]}] (if own - (rf/dispatch [:models.reactions/send-emoji-reaction-retraction - {:message-id message-id - :emoji-id emoji-id - :emoji-reaction-id emoji-reaction-id}]) - (rf/dispatch [:models.reactions/send-emoji-reaction + (rf/dispatch [:reactions/send-emoji-reaction-retraction emoji-reaction-id]) + (rf/dispatch [:reactions/send-emoji-reaction {:message-id message-id :emoji-id emoji-id}]))) diff --git a/src/status_im2/contexts/chat/messages/drawers/view.cljs b/src/status_im2/contexts/chat/messages/drawers/view.cljs index 7918ddcf877..1ee71beb226 100644 --- a/src/status_im2/contexts/chat/messages/drawers/view.cljs +++ b/src/status_im2/contexts/chat/messages/drawers/view.cljs @@ -192,11 +192,8 @@ :on-press (fn [] (if emoji-reaction-id - (rf/dispatch [:models.reactions/send-emoji-reaction-retraction - {:message-id message-id - :emoji-id id - :emoji-reaction-id emoji-reaction-id}]) - (rf/dispatch [:models.reactions/send-emoji-reaction + (rf/dispatch [:reactions/send-emoji-reaction-retraction emoji-reaction-id]) + (rf/dispatch [:reactions/send-emoji-reaction {:message-id message-id :emoji-id id}])) (rf/dispatch [:hide-bottom-sheet]))}])])) diff --git a/src/status_im/transport/message/core.cljs b/src/status_im2/contexts/chat/messages/transport/events.cljs similarity index 87% rename from src/status_im/transport/message/core.cljs rename to src/status_im2/contexts/chat/messages/transport/events.cljs index e1cc24c3cd2..c0780c49577 100644 --- a/src/status_im/transport/message/core.cljs +++ b/src/status_im2/contexts/chat/messages/transport/events.cljs @@ -1,5 +1,6 @@ -(ns ^{:doc "Definition of the StatusMessage protocol"} status-im.transport.message.core +(ns status-im2.contexts.chat.messages.transport.events (:require + [clojure.set :as set] [clojure.string :as string] [status-im.browser.core :as browser] [status-im.chat.models.message :as models.message] @@ -20,6 +21,7 @@ [status-im2.contexts.chat.messages.pin.events :as messages.pin] [status-im2.contexts.contacts.events :as models.contact] [status-im2.contexts.shell.activity-center.events :as activity-center] + [taoensso.timbre :as log] [utils.re-frame :as rf])) (rf/defn process-next @@ -347,3 +349,58 @@ cofx (conj set-hash-fxs #(sanitize-messages-and-process-response % response-js false))))) + +(defn- link-preview->rpc + [preview] + (update preview + :thumbnail + (fn [thumbnail] + (set/rename-keys thumbnail {:data-uri :dataUri})))) + +(defn build-message + [msg] + (-> msg + (update :link-previews #(map link-preview->rpc %)) + (set/rename-keys + {:album-id :albumId + :audio-duration-ms :audioDurationMs + :audio-path :audioPath + :chat-id :chatId + :community-id :communityId + :content-type :contentType + :ens-name :ensName + :image-height :imageHeight + :image-path :imagePath + :image-width :imageWidth + :link-previews :linkPreviews + :response-to :responseTo + :sticker :sticker + :text :text}))) + +(rf/defn send-chat-messages + [_ messages] + {:json-rpc/call [{:method "wakuext_sendChatMessages" + :params [(mapv build-message messages)] + :js-response true + :on-success #(rf/dispatch [:transport/message-sent %]) + :on-error #(do + (log/warn "failed to send a message" %) + (js/alert (str "failed to send a message: " %)))}]}) + +(rf/defn send-emoji-reaction + {:events [:reactions/send-emoji-reaction]} + [{{:keys [current-chat-id]} :db} {:keys [message-id emoji-id]}] + {:json-rpc/call [{:method "wakuext_sendEmojiReaction" + :params [current-chat-id message-id emoji-id] + :js-response true + :on-success #(rf/dispatch [:sanitize-messages-and-process-response %]) + :on-error #(log/error "failed to send a reaction" %)}]}) + +(rf/defn send-retract-emoji-reaction + {:events [:reactions/send-emoji-reaction-retraction]} + [_ emoji-reaction-id] + {:json-rpc/call [{:method "wakuext_sendEmojiReactionRetraction" + :params [emoji-reaction-id] + :js-response true + :on-success #(rf/dispatch [:sanitize-messages-and-process-response %]) + :on-error #(log/error "failed to send a reaction retraction" %)}]}) diff --git a/src/status_im2/contexts/chat/photo_selector/effects.cljs b/src/status_im2/contexts/chat/photo_selector/effects.cljs new file mode 100644 index 00000000000..c4c3294f85e --- /dev/null +++ b/src/status_im2/contexts/chat/photo_selector/effects.cljs @@ -0,0 +1,94 @@ +(ns status-im2.contexts.chat.photo-selector.effects + (:require + [clojure.string :as string] + [react-native.cameraroll :as cameraroll] + [react-native.core :as rn] + [react-native.image-resizer :as image-resizer] + [react-native.permissions :as permissions] + [react-native.platform :as platform] + [taoensso.timbre :as log] + [utils.i18n :as i18n] + [utils.re-frame :as rf])) + +(def ^:private maximum-image-size-px 2000) + +(rf/reg-fx :effects.camera-roll/request-permissions-and-get-photos + (fn [[num end-cursor album]] + (permissions/request-permissions + {:permissions [:read-external-storage] + :on-allowed + (fn [] + (cameraroll/get-photos + (merge {:first num + :assetType "Photos" + :groupTypes (if (= album (i18n/label :t/recent)) "All" "Albums") + :groupName (if (not= album (i18n/label :t/recent)) album "") + :include ["imageSize"]} + (when end-cursor + {:after end-cursor})) + #(rf/dispatch [:on-camera-roll-get-photos (:edges %) (:page_info %) end-cursor])))}))) + +(defn- resize-photo + [uri callback] + (rn/image-get-size + uri + (fn [width height] + (let [resize? (> (max width height) maximum-image-size-px)] + (image-resizer/resize + uri + (if resize? maximum-image-size-px width) + (if resize? maximum-image-size-px height) + 60 + (fn [^js resized-image] + (let [path (.-path resized-image) + path (if (string/starts-with? path "file") path (str "file://" path))] + (callback {:resized-uri path + :width width + :height height}))) + #(log/error "could not resize image" %)))))) + +(rf/reg-fx :effects.camera-roll/image-selected + (fn [[image chat-id]] + (resize-photo (:uri image) #(rf/dispatch [:photo-selector/image-selected chat-id image %])))) + +(defn- get-albums + [callback] + (let [albums (atom {:smart-album [] + :my-albums []})] + ;; Get the "recent" album first + (cameraroll/get-photos + {:first 1 :groupTypes "All" :assetType "Photos"} + (fn [res-recent] + (swap! albums assoc + :smart-album + {:title (i18n/label :t/recent) + :uri (get-in (first (:edges res-recent)) [:node :image :uri])}) + ;; Get albums, then loop over albums and get each one's cover (first photo) + (cameraroll/get-albums + {:assetType "Photos"} + (fn [res-albums] + (let [response-count (count res-albums)] + (if (pos? response-count) + (doseq [album res-albums] + (cameraroll/get-photos + {:first 1 :groupTypes "Albums" :groupName (:title album) :assetType "Photos"} + (fn [res] + (let [uri (get-in (first (:edges res)) [:node :image :uri])] + (swap! albums update :my-albums conj (merge album {:uri uri})) + (when (= (count (:my-albums @albums)) response-count) + (swap! albums update :my-albums #(sort-by :title %)) + (callback @albums)))))) + (callback @albums))))))))) + +(rf/reg-fx :effects.camera-roll/get-albums + (fn [] + (get-albums #(rf/dispatch [:on-camera-roll-get-albums %])))) + +(defn get-photos-count-ios-fx + [cb] + (cameraroll/get-photos-count-ios cb)) + +(rf/reg-fx :effects.camera-roll/get-photos-count-ios + (fn [] + (when platform/ios? + (get-photos-count-ios-fx #(rf/dispatch [:on-camera-roll-get-images-count-ios %]))))) diff --git a/src/status_im2/contexts/chat/photo_selector/events.cljs b/src/status_im2/contexts/chat/photo_selector/events.cljs index b552cd98a84..ecdd92fb544 100644 --- a/src/status_im2/contexts/chat/photo_selector/events.cljs +++ b/src/status_im2/contexts/chat/photo_selector/events.cljs @@ -1,104 +1,10 @@ (ns status-im2.contexts.chat.photo-selector.events (:require - [clojure.string :as string] - [re-frame.core :as re-frame] - [react-native.cameraroll :as cameraroll] - [react-native.core :as rn] - [react-native.image-resizer :as image-resizer] - [react-native.permissions :as permissions] - [react-native.platform :as platform] [status-im2.constants :as constants] - [taoensso.timbre :as log] + status-im2.contexts.chat.photo-selector.effects [utils.i18n :as i18n] [utils.re-frame :as rf])) -(def maximum-image-size-px 2000) - -(defn- resize-photo - [uri callback] - (rn/image-get-size - uri - (fn [width height] - (let [resize? (> (max width height) maximum-image-size-px)] - (image-resizer/resize - uri - (if resize? maximum-image-size-px width) - (if resize? maximum-image-size-px height) - 60 - (fn [^js resized-image] - (let [path (.-path resized-image) - path (if (string/starts-with? path "file") path (str "file://" path))] - (callback {:resized-uri path - :width width - :height height}))) - #(log/error "could not resize image" %)))))) - -(re-frame/reg-fx - :camera-roll-request-permissions-and-get-photos - (fn [[num end-cursor album]] - (permissions/request-permissions - {:permissions [:read-external-storage] - :on-allowed - (fn [] - (cameraroll/get-photos - (merge {:first num - :assetType "Photos" - :groupTypes (if (= album (i18n/label :t/recent)) "All" "Albums") - :groupName (if (not= album (i18n/label :t/recent)) album "") - :include ["imageSize"]} - (when end-cursor - {:after end-cursor})) - #(re-frame/dispatch [:on-camera-roll-get-photos (:edges %) (:page_info %) end-cursor])))}))) - -(re-frame/reg-fx - :camera-roll-image-selected - (fn [[image chat-id]] - (resize-photo (:uri image) #(re-frame/dispatch [:photo-selector/image-selected chat-id image %])))) - -(defn get-albums - [callback] - (let [albums (atom {:smart-album [] - :my-albums []})] - ;; Get the "recent" album first - (cameraroll/get-photos - {:first 1 :groupTypes "All" :assetType "Photos"} - (fn [res-recent] - (swap! albums assoc - :smart-album - {:title (i18n/label :t/recent) - :uri (get-in (first (:edges res-recent)) [:node :image :uri])}) - ;; Get albums, then loop over albums and get each one's cover (first photo) - (cameraroll/get-albums - {:assetType "Photos"} - (fn [res-albums] - (let [response-count (count res-albums)] - (if (pos? response-count) - (doseq [album res-albums] - (cameraroll/get-photos - {:first 1 :groupTypes "Albums" :groupName (:title album) :assetType "Photos"} - (fn [res] - (let [uri (get-in (first (:edges res)) [:node :image :uri])] - (swap! albums update :my-albums conj (merge album {:uri uri})) - (when (= (count (:my-albums @albums)) response-count) - (swap! albums update :my-albums #(sort-by :title %)) - (callback @albums)))))) - (callback @albums))))))))) - -(defn get-photos-count-ios-fx - [cb] - (cameraroll/get-photos-count-ios cb)) - -(re-frame/reg-fx - :camera-roll-get-albums - (fn [] - (get-albums #(re-frame/dispatch [:on-camera-roll-get-albums %])))) - -(re-frame/reg-fx - :camera-roll-get-photos-count-ios - (fn [] - (when platform/ios? - (get-photos-count-ios-fx #(re-frame/dispatch [:on-camera-roll-get-images-count-ios %]))))) - (rf/defn on-camera-roll-get-albums {:events [:on-camera-roll-get-albums]} [{:keys [db]} albums] @@ -113,12 +19,12 @@ (rf/defn camera-roll-get-albums {:events [:photo-selector/camera-roll-get-albums]} [_] - {:camera-roll-get-albums nil}) + {:effects.camera-roll/get-albums nil}) (rf/defn camera-roll-get-ios-photo-count {:events [:photo-selector/camera-roll-get-ios-photo-count]} [_] - {:camera-roll-get-photos-count-ios nil}) + {:effects.camera-roll/get-photos-count-ios nil}) (rf/defn camera-roll-select-album {:events [:chat.ui/camera-roll-select-album]} @@ -150,9 +56,10 @@ (rf/defn get-photos-for-selected-album {:events [:photo-selector/get-photos-for-selected-album]} [{:keys [db]} end-cursor] - {:camera-roll-request-permissions-and-get-photos [21 end-cursor - (or (:camera-roll/selected-album db) - (i18n/label :t/recent))]}) + {:effects.camera-roll/request-permissions-and-get-photos + [21 end-cursor + (or (:camera-roll/selected-album db) + (i18n/label :t/recent))]}) (rf/defn camera-roll-loading-more {:events [:photo-selector/camera-roll-loading-more]} @@ -166,4 +73,4 @@ images (get-in db [:chat/inputs current-chat-id :metadata :sending-image])] (when (and (< (count images) constants/max-album-photos) (not (some #(= (:uri image) (:uri %)) images))) - {:camera-roll-image-selected [image current-chat-id]}))) + {:effects.camera-roll/image-selected [image current-chat-id]}))) diff --git a/src/status_im2/contexts/onboarding/events.cljs b/src/status_im2/contexts/onboarding/events.cljs index b9ea1f9ddc3..9aa07ea822d 100644 --- a/src/status_im2/contexts/onboarding/events.cljs +++ b/src/status_im2/contexts/onboarding/events.cljs @@ -114,7 +114,7 @@ {:events [:onboarding/seed-phrase-validated]} [{:keys [db]} seed-phrase key-uid] (if (contains? (:profile/profiles-overview db) key-uid) - {:utils/show-confirmation + {:effects.utils/show-confirmation {:title (i18n/label :t/multiaccount-exists-title) :content (i18n/label :t/multiaccount-exists-content) :confirm-button-text (i18n/label :t/unlock) diff --git a/src/status_im2/contexts/profile/create/effects.cljs b/src/status_im2/contexts/profile/create/effects.cljs new file mode 100644 index 00000000000..2d9a9f00bf0 --- /dev/null +++ b/src/status_im2/contexts/profile/create/effects.cljs @@ -0,0 +1,9 @@ +(ns status-im2.contexts.profile.create.effects + (:require + [native-module.core :as native-module] + [utils.re-frame :as rf])) + +(rf/reg-fx :effects.profile/create-and-login + (fn [request] + ;;"node.login" signal will be triggered as a callback + (native-module/create-account-and-login request))) diff --git a/src/status_im2/contexts/profile/create/events.cljs b/src/status_im2/contexts/profile/create/events.cljs index 7728d3ee50e..d23026da8d2 100644 --- a/src/status_im2/contexts/profile/create/events.cljs +++ b/src/status_im2/contexts/profile/create/events.cljs @@ -1,21 +1,15 @@ (ns status-im2.contexts.profile.create.events (:require [native-module.core :as native-module] - [re-frame.core :as re-frame] [status-im2.contexts.profile.config :as profile.config] + status-im2.contexts.profile.create.effects [utils.re-frame :as rf] [utils.security.core :as security])) -(re-frame/reg-fx - ::create-profile-and-login - (fn [request] - ;;"node.login" signal will be triggered as a callback - (native-module/create-account-and-login request))) - (rf/defn create-profile-and-login {:events [:profile.create/create-and-login]} [_ {:keys [display-name password image-path color]}] - {::create-profile-and-login + {:effects.profile/create-and-login (assoc (profile.config/create) :displayName display-name :password (native-module/sha3 (security/safe-unmask-data password)) diff --git a/src/status_im2/contexts/profile/login/effects.cljs b/src/status_im2/contexts/profile/login/effects.cljs new file mode 100644 index 00000000000..2f211dfbe7d --- /dev/null +++ b/src/status_im2/contexts/profile/login/effects.cljs @@ -0,0 +1,11 @@ +(ns status-im2.contexts.profile.login.effects + (:require + [native-module.core :as native-module] + [status-im2.contexts.profile.config :as profile.config] + [utils.re-frame :as rf])) + +(rf/reg-fx :effects.profile/login + (fn [[key-uid hashed-password]] + ;;"node.login" signal will be triggered as a callback + (native-module/login-account + (assoc (profile.config/login) :keyUid key-uid :password hashed-password)))) diff --git a/src/status_im2/contexts/profile/login/events.cljs b/src/status_im2/contexts/profile/login/events.cljs index bf1c803e5c8..173e97baa73 100644 --- a/src/status_im2/contexts/profile/login/events.cljs +++ b/src/status_im2/contexts/profile/login/events.cljs @@ -9,14 +9,18 @@ [status-im.data-store.switcher-cards :as switcher-cards-store] [status-im.data-store.visibility-status-updates :as visibility-status-updates-store] [status-im.group-chats.core :as group-chats] + [status-im.mailserver.core :as mailserver] [status-im.mobile-sync-settings.core :as mobile-network] - [status-im.transport.core :as transport] + [status-im.pairing.core :as pairing] + [status-im.stickers.core :as stickers] [status-im2.common.keychain.events :as keychain] [status-im2.common.log :as logging] + [status-im2.common.universal-links :as universal-links] [status-im2.config :as config] [status-im2.contexts.chat.messages.link-preview.events :as link-preview] [status-im2.contexts.contacts.events :as contacts] [status-im2.contexts.profile.config :as profile.config] + status-im2.contexts.profile.login.effects [status-im2.contexts.profile.rpc :as profile.rpc] [status-im2.contexts.profile.settings.events :as profile.settings.events] [status-im2.contexts.push-notifications.events :as notifications] @@ -27,36 +31,29 @@ [utils.re-frame :as rf] [utils.security.core :as security])) -(re-frame/reg-fx - ::login - (fn [[key-uid hashed-password]] - ;;"node.login" signal will be triggered as a callback - (native-module/login-account - (assoc (profile.config/login) :keyUid key-uid :password hashed-password)))) - (rf/defn login {:events [:profile.login/login]} [{:keys [db]}] (let [{:keys [key-uid password]} (:profile/login db)] - {:db (assoc-in db [:profile/login :processing] true) - ::login [key-uid (native-module/sha3 (security/safe-unmask-data password))]})) + {:db (assoc-in db [:profile/login :processing] true) + :effects.profile/login [key-uid (native-module/sha3 (security/safe-unmask-data password))]})) (rf/defn biometrics-login {:events [:profile.login/biometrics-login]} [{:keys [db]}] (let [{:keys [key-uid password]} (:profile/login db)] - {:db (assoc-in db [:profile/login :processing] true) - ::login [key-uid (security/safe-unmask-data password)]})) + {:db (assoc-in db [:profile/login :processing] true) + :effects.profile/login [key-uid (security/safe-unmask-data password)]})) (rf/defn login-local-paired-user {:events [:profile.login/local-paired-user]} [{:keys [db]}] (let [{:keys [key-uid password]} (get-in db [:syncing :profile]) masked-password (security/mask-data password)] - {:db (-> db - (assoc-in [:onboarding/profile :password] masked-password) - (assoc-in [:onboarding/profile :syncing?] true)) - ::login [key-uid password]})) + {:db (-> db + (assoc-in [:onboarding/profile :password] masked-password) + (assoc-in [:onboarding/profile :syncing?] true)) + :effects.profile/login [key-uid password]})) (rf/defn redirect-to-root [{:keys [db] :as cofx}] @@ -116,7 +113,10 @@ network-id (str (get-in networks [current-network :config :NetworkId]))] (rf/merge cofx - (cond-> {:wallet-legacy/initialize-transactions-management-enabled nil + (cond-> {:json-rpc/call [{:method "wakuext_startMessenger" + :on-success #(re-frame/dispatch [:messenger-started %]) + :on-error #(log/error "failed to start messenger")}] + :wallet-legacy/initialize-transactions-management-enabled nil :wallet-legacy/initialize-wallet [network-id current-network-config @@ -128,7 +128,6 @@ (assoc :chat/open-last-chat (get-in db [:profile/profile :key-uid])) notifications-enabled? (assoc :effects/push-notifications-enable nil)) - (transport/start-messenger) (contacts/initialize-contacts) (browser/initialize-browser) (mobile-network/on-network-status-change) @@ -139,6 +138,28 @@ (visibility-status-updates-store/fetch-visibility-status-updates-rpc) (switcher-cards-store/fetch-switcher-cards-rpc)))) +(rf/defn messenger-started + {:events [:messenger-started]} + [{:keys [db] :as cofx} {:keys [mailservers] :as response}] + (log/info "Messenger started") + (let [new-account? (get db :onboarding-2/new-account?)] + (rf/merge cofx + {:db (-> db + (assoc :messenger/started? true) + (mailserver/add-mailservers mailservers)) + :json-rpc/call [{:method "admin_nodeInfo" + :on-success #(re-frame/dispatch [:node-info-fetched %]) + :on-error #(log/error "node-info: failed error" %)}]} + (pairing/init) + (stickers/load-packs) + (when-not new-account? + (universal-links/process-stored-event))))) + +(rf/defn set-node-info + {:events [:node-info-fetched]} + [{:keys [db]} node-info] + {:db (assoc db :node-info node-info)}) + (rf/defn login-node-signal [{{:onboarding/keys [recovered-account? new-account?] :as db} :db :as cofx} {:keys [settings account ensUsernames error]}] diff --git a/src/status_im2/contexts/profile/recover/effects.cljs b/src/status_im2/contexts/profile/recover/effects.cljs new file mode 100644 index 00000000000..ecfb3653c46 --- /dev/null +++ b/src/status_im2/contexts/profile/recover/effects.cljs @@ -0,0 +1,9 @@ +(ns status-im2.contexts.profile.recover.effects + (:require + [native-module.core :as native-module] + [utils.re-frame :as rf])) + +(rf/reg-fx :effects.profile/restore-and-login + (fn [request] + ;;"node.login" signal will be triggered as a callback + (native-module/restore-account-and-login request))) diff --git a/src/status_im2/contexts/profile/recover/events.cljs b/src/status_im2/contexts/profile/recover/events.cljs index f2e5ebb90ae..ff8b295f8cb 100644 --- a/src/status_im2/contexts/profile/recover/events.cljs +++ b/src/status_im2/contexts/profile/recover/events.cljs @@ -1,24 +1,18 @@ (ns status-im2.contexts.profile.recover.events (:require [native-module.core :as native-module] - [re-frame.core :as re-frame] [status-im2.contexts.profile.config :as profile.config] + status-im2.contexts.profile.recover.effects [utils.re-frame :as rf] [utils.security.core :as security])) -(re-frame/reg-fx - ::restore-profile-and-login - (fn [request] - ;;"node.login" signal will be triggered as a callback - (native-module/restore-account-and-login request))) - (rf/defn recover-profile-and-login {:events [:profile.recover/recover-and-login]} [{:keys [db]} {:keys [display-name password image-path color seed-phrase]}] {:db (assoc db :onboarding/recovered-account? true) - ::restore-profile-and-login + :effects.profile/restore-and-login (merge (profile.config/create) {:displayName display-name :mnemonic (security/safe-unmask-data seed-phrase) diff --git a/src/status_im2/contexts/push_notifications/local/effects.cljs b/src/status_im2/contexts/push_notifications/local/effects.cljs index 66b864eab86..7ebd59d8a9e 100644 --- a/src/status_im2/contexts/push_notifications/local/effects.cljs +++ b/src/status_im2/contexts/push_notifications/local/effects.cljs @@ -6,14 +6,14 @@ [utils.re-frame :as rf])) (rf/reg-fx :effects/push-notifications-local-present-ios - (fn [{:keys [title message user-info body-type]}] - (when (not= body-type "message") - (pn-ios/present-local-notification title - message - (bean/->js (merge user-info - {:notificationType - "local-notification"})))))) + (fn [{:keys [title message user-info body-type]}] + (when (not= body-type "message") + (pn-ios/present-local-notification title + message + (bean/->js (merge user-info + {:notificationType + "local-notification"})))))) (rf/reg-fx :effects/push-notifications-local-present-android - (fn [notification] - (native-module.pn/present-local-notification notification))) + (fn [notification] + (native-module.pn/present-local-notification notification))) diff --git a/src/status_im2/contexts/quo_preview/record_audio/record_audio.cljs b/src/status_im2/contexts/quo_preview/record_audio/record_audio.cljs index ce63ab8dd42..ca10f936544 100644 --- a/src/status_im2/contexts/quo_preview/record_audio/record_audio.cljs +++ b/src/status_im2/contexts/quo_preview/record_audio/record_audio.cljs @@ -4,7 +4,7 @@ [react-native.core :as rn] [react-native.permissions :as permissions] [reagent.core :as reagent] - [status-im2.common.alert.events :as alert] + [status-im2.common.alert.effects :as alert.effects] [status-im2.constants :as constants] [status-im2.contexts.quo-preview.preview :as preview] [utils.i18n :as i18n] @@ -35,7 +35,7 @@ :on-denied #(js/setTimeout (fn [] - (alert/show-popup + (alert.effects/show-popup (i18n/label :t/audio-recorder-error) (i18n/label :t/audio-recorder-permissions-error))) diff --git a/src/status_im2/contexts/shell/jump_to/effects.cljs b/src/status_im2/contexts/shell/jump_to/effects.cljs new file mode 100644 index 00000000000..d662d5c3b28 --- /dev/null +++ b/src/status_im2/contexts/shell/jump_to/effects.cljs @@ -0,0 +1,32 @@ +(ns status-im2.contexts.shell.jump-to.effects + (:require + [status-im2.config :as config] + [status-im2.contexts.shell.jump-to.animation :as animation] + [status-im2.contexts.shell.jump-to.constants :as shell.constants] + [status-im2.contexts.shell.jump-to.state :as state] + [status-im2.contexts.shell.jump-to.utils :as shell.utils] + [utils.re-frame :as rf])) + +(rf/reg-fx :effects.shell/change-tab + (fn [stack-id] + (when (some #(= stack-id %) shell.constants/stacks-ids) + (animation/bottom-tab-on-press stack-id false)))) + +(rf/reg-fx :effects.shell/navigate-to-jump-to + (fn [] + (animation/close-home-stack false) + (when-not config/shell-navigation-disabled? + (some-> ^js @state/jump-to-list-ref + (.scrollToOffset #js {:y 0 :animated false}))))) + +;; Note - pop-to-root resets currently opened screens to `close-screen-without-animation`. +;; This might take some time. So don't directly merge the effect of `pop-to-root` and +;; `navigate-to` for the floating screen. Because it might close even the currently opened screen. +;; https://github.com/status-im/status-mobile/pull/16438#issuecomment-1623954774 +(rf/reg-fx :effects.shell/pop-to-root + (fn [] + (shell.utils/reset-floating-screens))) + +(rf/reg-fx :effects.shell/reset-state + (fn [] + (reset! state/floating-screens-state {}))) diff --git a/src/status_im2/contexts/shell/jump_to/events.cljs b/src/status_im2/contexts/shell/jump_to/events.cljs index 1b7f8567108..be6dd63cb15 100644 --- a/src/status_im2/contexts/shell/jump_to/events.cljs +++ b/src/status_im2/contexts/shell/jump_to/events.cljs @@ -1,48 +1,15 @@ (ns status-im2.contexts.shell.jump-to.events (:require - [re-frame.core :as re-frame] [status-im.data-store.switcher-cards :as switcher-cards-store] [status-im.utils.core :as utils] [status-im2.config :as config] [status-im2.constants :as constants] - [status-im2.contexts.shell.jump-to.animation :as animation] [status-im2.contexts.shell.jump-to.constants :as shell.constants] - [status-im2.contexts.shell.jump-to.state :as state] + status-im2.contexts.shell.jump-to.effects [status-im2.contexts.shell.jump-to.utils :as shell.utils] [status-im2.navigation.state :as navigation.state] [utils.re-frame :as rf])) -;;;; Effects - -;; Navigation -(re-frame/reg-fx - :shell/change-tab-fx - (fn [stack-id] - (when (some #(= stack-id %) shell.constants/stacks-ids) - (animation/bottom-tab-on-press stack-id false)))) - -(re-frame/reg-fx - :shell/navigate-to-jump-to-fx - (fn [] - (animation/close-home-stack false) - (when-not config/shell-navigation-disabled? - (some-> ^js @state/jump-to-list-ref - (.scrollToOffset #js {:y 0 :animated false}))))) - -;; Note - pop-to-root resets currently opened screens to `close-screen-without-animation`. -;; This might take some time. So don't directly merge the effect of `pop-to-root` and -;; `navigate-to` for the floating screen. Because it might close even the currently opened screen. -;; https://github.com/status-im/status-mobile/pull/16438#issuecomment-1623954774 -(re-frame/reg-fx - :shell/pop-to-root-fx - (fn [] - (shell.utils/reset-floating-screens))) - -(re-frame/reg-fx - :shell/reset-state - (fn [] - (reset! state/floating-screens-state {}))) - ;;;; Events ;; Switcher @@ -105,13 +72,13 @@ [:shell/switcher-cards (:card-id card-data)] switcher-card)} (when config/shell-navigation-disabled? - {:shell/change-tab-fx (cond - (#{shell.constants/one-to-one-chat-card - shell.constants/private-group-chat-card} - card-type) - :chats-stack + {:effects.shell/change-tab (cond + (#{shell.constants/one-to-one-chat-card + shell.constants/private-group-chat-card} + card-type) + :chats-stack - :else :communities-stack)})) + :else :communities-stack)})) (switcher-cards-store/upsert-switcher-card-rpc switcher-card))))) (rf/defn close-switcher-card @@ -152,7 +119,7 @@ shell.constants/close-screen-without-animation)) :dispatch [:set-view-id :shell]}) - {:shell/navigate-to-jump-to-fx nil}))) + {:effects.shell/navigate-to-jump-to nil}))) (rf/defn change-shell-status-bar-style {:events [:change-shell-status-bar-style]} @@ -246,10 +213,10 @@ (conj {:ms (* 2 shell.constants/shell-animation-time) :dispatch [:shell/add-switcher-card screen-id id]}))} (when (and id (not hidden-screen?)) - {:shell/change-tab-fx (if (or (= screen-id shell.constants/community-screen) - community-id) - :communities-stack - :chats-stack)}))) + {:effects.shell/change-tab (if (or (= screen-id shell.constants/community-screen) + community-id) + :communities-stack + :chats-stack)}))) (rf/defn floating-screen-closed {:events [:shell/floating-screen-closed]} diff --git a/src/status_im2/contexts/wallet/account/tabs/view.cljs b/src/status_im2/contexts/wallet/account/tabs/view.cljs index 5a78ddd47fa..2d50eff0496 100644 --- a/src/status_im2/contexts/wallet/account/tabs/view.cljs +++ b/src/status_im2/contexts/wallet/account/tabs/view.cljs @@ -1,34 +1,28 @@ (ns status-im2.contexts.wallet.account.tabs.view (:require - [quo.theme] [react-native.core :as rn] - [status-im2.common.resources :as resources] [status-im2.contexts.wallet.account.tabs.about.view :as about] [status-im2.contexts.wallet.account.tabs.dapps.view :as dapps] [status-im2.contexts.wallet.common.activity-tab.view :as activity] [status-im2.contexts.wallet.common.collectibles-tab.view :as collectibles] [status-im2.contexts.wallet.common.empty-tab.view :as empty-tab] - [status-im2.contexts.wallet.common.temp :as temp] [status-im2.contexts.wallet.common.token-value.view :as token-value] - [utils.i18n :as i18n])) + [utils.i18n :as i18n] + [utils.re-frame :as rf])) -(defn- view-internal - [{:keys [selected-tab theme]}] - (case selected-tab - :assets [rn/flat-list - {:render-fn token-value/view - :data temp/tokens - :content-container-style {:padding-horizontal 8}}] - :collectibles [collectibles/view] - :activity [activity/view] - :permissions [empty-tab/view - {:title (i18n/label :t/no-permissions) - :description (i18n/label :t/no-collectibles-description) - :image (resources/get-image - (quo.theme/theme-value :no-permissions-light - :no-permissions-dark - theme))}] - :dapps [dapps/view] - [about/view])) - -(def view (quo.theme/with-theme view-internal)) +(defn view + [{:keys [selected-tab]}] + (let [tokens (filter identity (rf/sub [:wallet/account-token-values]))] + (case selected-tab + :assets [rn/flat-list + {:render-fn token-value/view + :data tokens + :content-container-style {:padding-horizontal 8}}] + :collectibles [collectibles/view] + :activity [activity/view] + :permissions [empty-tab/view + {:title (i18n/label :t/no-permissions) + :description (i18n/label :t/no-collectibles-description) + :placeholder? true}] + :dapps [dapps/view] + [about/view]))) diff --git a/src/status_im2/contexts/wallet/collectible/view.cljs b/src/status_im2/contexts/wallet/collectible/view.cljs index afaf95e0eeb..de1b7facb09 100644 --- a/src/status_im2/contexts/wallet/collectible/view.cljs +++ b/src/status_im2/contexts/wallet/collectible/view.cljs @@ -10,7 +10,7 @@ [utils.re-frame :as rf])) (defn header - [{:keys [name description collection-image-url]}] + [{:keys [name description] :as _collectible-details} collection-image-url] [rn/view {:style style/header} [quo/text {:weight :semi-bold @@ -112,9 +112,11 @@ (defn view [] - (let [collectible-details (rf/sub [:wallet/last-collectible-details]) - {:keys [name description preview-url traits id]} collectible-details - chain-id (get-in id [:contract-id :chain-id])] + (let [collectible (rf/sub [:wallet/last-collectible-details]) + {:keys [collectible-data preview-url + collection-data]} collectible + {:keys [traits description]} collectible-data + chain-id (rf/sub [:wallet/last-collectible-chain-id])] [scroll-page/scroll-page {:navigate-back? true :height 148 @@ -129,7 +131,7 @@ [rn/image {:source preview-url :style style/preview}]] - [header collectible-details] + [header collectible-data (:image-url collection-data)] [cta-buttons] [tabs] [info chain-id] diff --git a/src/status_im2/contexts/wallet/common/utils.cljs b/src/status_im2/contexts/wallet/common/utils.cljs index 70abc3104ca..c7a6f9cb73b 100644 --- a/src/status_im2/contexts/wallet/common/utils.cljs +++ b/src/status_im2/contexts/wallet/common/utils.cljs @@ -1,6 +1,7 @@ (ns status-im2.contexts.wallet.common.utils (:require [clojure.string :as string] [status-im2.constants :as constants] + [utils.money :as money] [utils.number])) (defn get-first-name @@ -23,7 +24,7 @@ (let [path (get-derivation-path number-of-accounts)] (format-derivation-path path))) -(defn- calculate-raw-balance +(defn calculate-raw-balance [raw-balance decimals] (if-let [n (utils.number/parse-int raw-balance nil)] (/ n (Math/pow 10 (utils.number/parse-int decimals))) @@ -36,6 +37,12 @@ (map #(calculate-raw-balance (:raw-balance %) decimals)) (reduce +))) +(defn token-value-in-chain + [{:keys [balances-per-chain decimals]} chain-id] + (let [balance-in-chain (get balances-per-chain chain-id)] + (when balance-in-chain + (calculate-raw-balance (:raw-balance balance-in-chain) decimals)))) + (defn calculate-balance [tokens-in-account] (->> tokens-in-account @@ -52,3 +59,7 @@ (= (:related-chain-id %) chain-id)) networks))) (keys balances-per-chain)))) + +(defn calculate-fiat-change + [fiat-value change-pct-24hour] + (money/bignumber (* fiat-value (/ change-pct-24hour (+ 100 change-pct-24hour))))) diff --git a/src/status_im2/contexts/wallet/events.cljs b/src/status_im2/contexts/wallet/events.cljs index 63547567445..c397856d48c 100644 --- a/src/status_im2/contexts/wallet/events.cljs +++ b/src/status_im2/contexts/wallet/events.cljs @@ -215,9 +215,10 @@ (def collectibles-request-batch-size 1000) (defn displayable-collectible? - [{:keys [image-url animation-url]}] - (or (not (string/blank? animation-url)) - (not (string/blank? image-url)))) + [collectible] + (let [{:keys [image-url animation-url]} (:collectible-data collectible)] + (or (not (string/blank? animation-url)) + (not (string/blank? image-url))))) (defn store-collectibles [{:keys [db]} [collectibles]] @@ -243,28 +244,47 @@ (rf/reg-event-fx :wallet/store-last-collectible-details store-last-collectible-details) +(def collectible-data-types + {:unique-id 0 + :header 1 + :details 2 + :community-header 3}) + +(def fetch-type + {:never-fetch 0 + :always-fetch 1 + :fetch-if-not-cached 2 + :fetch-if-cache-old 3}) + +(def max-cache-age-seconds 3600) + (rf/reg-event-fx :wallet/request-collectibles (fn [{:keys [db]} [{:keys [start-at-index new-request?]}]] (let [request-id 0 collectibles-filter nil + data-type (collectible-data-types :header) + fetch-criteria {:fetch-type (fetch-type :fetch-if-not-cached) + :max-cache-age-seconds max-cache-age-seconds} request-params [request-id [(chain/chain-id db)] (map :address (:profile/wallet-accounts db)) collectibles-filter start-at-index - collectibles-request-batch-size]] - {:json-rpc/call [{:method "wallet_filterOwnedCollectiblesAsync" - :params request-params - :on-success #() - :on-error (fn [error] - (log/error "failed to request collectibles" - {:event :wallet/request-collectibles - :error error - :params request-params}))}] - :fx (if new-request? - [[:dispatch [:wallet/clear-stored-collectibles]]] - [])}))) + collectibles-request-batch-size + data-type + fetch-criteria]] + {:fx [[:json-rpc/call + [{:method "wallet_getOwnedCollectiblesAsync" + :params request-params + :on-success #() + :on-error (fn [error] + (log/error "failed to request collectibles" + {:event :wallet/request-collectibles + :error error + :params request-params}))}]] + (when new-request? + [:dispatch [:wallet/clear-stored-collectibles]])]}))) (rf/reg-event-fx :wallet/owned-collectibles-filtering-done (fn [_ [{:keys [message]}]] @@ -283,14 +303,16 @@ (fn [_ [collectible-id]] (let [request-id 0 collectible-id-converted (cske/transform-keys csk/->PascalCaseKeyword collectible-id) - request-params [request-id [collectible-id-converted]]] - {:json-rpc/call [{:method "wallet_getCollectiblesDetailsAsync" - :params request-params - :on-error (fn [error] - (log/error "failed to request collectible" - {:event :wallet/get-collectible-details - :error error - :params request-params}))}]}))) + data-type (collectible-data-types :details) + request-params [request-id [collectible-id-converted] data-type]] + {:fx [[:json-rpc/call + [{:method "wallet_getCollectiblesByUniqueIDAsync" + :params request-params + :on-error (fn [error] + (log/error "failed to request collectible" + {:event :wallet/get-collectible-details + :error error + :params request-params}))}]]]}))) (rf/reg-event-fx :wallet/get-collectible-details-done (fn [_ [{:keys [message]}]] diff --git a/src/status_im2/contexts/wallet/events_test.cljs b/src/status_im2/contexts/wallet/events_test.cljs index b4035753059..88f7831e794 100644 --- a/src/status_im2/contexts/wallet/events_test.cljs +++ b/src/status_im2/contexts/wallet/events_test.cljs @@ -23,24 +23,27 @@ (deftest store-collectibles (testing "(displayable-collectible?) helper function" - (let [expected-results [[true {:image-url "https://..." :animation-url "https://..."}] - [true {:image-url "" :animation-url "https://..."}] - [true {:image-url nil :animation-url "https://..."}] - [true {:image-url "https://..." :animation-url ""}] - [true {:image-url "https://..." :animation-url nil}] - [false {:image-url "" :animation-url nil}] - [false {:image-url nil :animation-url nil}] - [false {:image-url nil :animation-url ""}] - [false {:image-url "" :animation-url ""}]]] + (let [expected-results [[true + {:collectible-data {:image-url "https://..." :animation-url "https://..."}}] + [true {:collectible-data {:image-url "" :animation-url "https://..."}}] + [true {:collectible-data {:image-url nil :animation-url "https://..."}}] + [true {:collectible-data {:image-url "https://..." :animation-url ""}}] + [true {:collectible-data {:image-url "https://..." :animation-url nil}}] + [false {:collectible-data {:image-url "" :animation-url nil}}] + [false {:collectible-data {:image-url nil :animation-url nil}}] + [false {:collectible-data {:image-url nil :animation-url ""}}] + [false {:collectible-data {:image-url "" :animation-url ""}}]]] (doseq [[result collection] expected-results] (is (= result (events/displayable-collectible? collection)))))) (testing "save-collectibles-request-details" (let [db {:wallet {}} - collectibles [{:image-url "https://..." :animation-url "https://..."} - {:image-url "" :animation-url "https://..."} - {:image-url "" :animation-url nil}] - expected-db {:wallet {:collectibles [{:image-url "https://..." :animation-url "https://..."} - {:image-url "" :animation-url "https://..."}]}} + collectibles [{:collectible-data {:image-url "https://..." :animation-url "https://..."}} + {:collectible-data {:image-url "" :animation-url "https://..."}} + {:collectible-data {:image-url "" :animation-url nil}}] + expected-db {:wallet {:collectibles [{:collectible-data + {:image-url "https://..." :animation-url "https://..."}} + {:collectible-data + {:image-url "" :animation-url "https://..."}}]}} effects (events/store-collectibles {:db db} [collectibles]) result-db (:db effects)] (is (= result-db expected-db))))) diff --git a/src/status_im2/core.cljs b/src/status_im2/core.cljs index 5c6fbe9a2bc..216ca25a14d 100644 --- a/src/status_im2/core.cljs +++ b/src/status_im2/core.cljs @@ -2,7 +2,6 @@ (:require ;; NOTE: Do NOT sort i18n-resources because it MUST be loaded first. [status-im2.setup.i18n-resources :as i18n-resources] - #_{:clj-kondo/ignore [:unsorted-required-namespaces]} [native-module.core :as native-module] [re-frame.core :as re-frame] diff --git a/src/status_im2/events.cljs b/src/status_im2/events.cljs index 9091d85fc31..8715692f494 100644 --- a/src/status_im2/events.cljs +++ b/src/status_im2/events.cljs @@ -2,10 +2,12 @@ (:require [status-im.bottom-sheet.events] [status-im.keycard.core :as keycard] - status-im2.common.async-storage - status-im2.common.font + status-im2.common.alert.effects + status-im2.common.async-storage.effects + status-im2.common.font.events [status-im2.common.json-rpc.events] status-im2.common.password-authentication.events + status-im2.common.signals.events status-im2.common.theme.events [status-im2.common.toasts.events] [status-im2.contexts.add-new-contact.events] @@ -26,14 +28,14 @@ (rf/defn start-app {:events [:app-started]} [cofx] - (rf/merge cofx - {:db db/app-db - :theme/init-theme nil - :network/listen-to-network-info nil - :biometric/get-supported-biometric-type nil - ;;app starting flow continues in get-profiles-overview - :profile/get-profiles-overview #(rf/dispatch - [:profile/get-profiles-overview-success %]) - :font/get-font-file-for-initials-avatar #(rf/dispatch - [:font/init-font-file-for-initials-avatar %])} - (keycard/init))) + (rf/merge + cofx + {:db db/app-db + :theme/init-theme nil + :network/listen-to-network-info nil + :biometric/get-supported-biometric-type nil + ;;app starting flow continues in get-profiles-overview + :profile/get-profiles-overview #(rf/dispatch [:profile/get-profiles-overview-success %]) + :effects.font/get-font-file-for-initials-avatar + #(rf/dispatch [:font/init-font-file-for-initials-avatar %])} + (keycard/init))) diff --git a/src/status_im2/navigation/core.cljs b/src/status_im2/navigation/core.cljs index 86fda6baac3..2623e961ea3 100644 --- a/src/status_im2/navigation/core.cljs +++ b/src/status_im2/navigation/core.cljs @@ -5,11 +5,11 @@ [react-native.gesture :as gesture] [react-native.navigation :as navigation] [status-im2.common.theme.core :as theme] + [status-im2.navigation.effects :as effects] [status-im2.navigation.options :as options] - [status-im2.navigation.roots :as roots] [status-im2.navigation.state :as state] [status-im2.navigation.view :as views] - [taoensso.timbre :as log])) + [utils.re-frame :as rf])) (navigation/set-lazy-component-registrator (fn [screen-key] @@ -33,150 +33,26 @@ (re-frame/dispatch [:chat/check-last-chat]))) (rn/hide-splash-screen))) -(defn set-view-id - [view-id] - (when (get views/screens view-id) - (re-frame/dispatch [:set-view-id view-id]))) - -(re-frame/reg-fx - :set-view-id-fx - (fn [view-id] - (re-frame/dispatch [:screens/on-will-focus view-id]) - (when-let [{:keys [on-focus]} (get views/screens view-id)] - (when on-focus - (re-frame/dispatch on-focus))))) - (navigation/reg-component-did-appear-listener (fn [view-id] (when (get views/screens view-id) - ;;NOTE when back from the background on Android, this event happens for all screens, but we need - ;;only for active one + ;;NOTE when back from the background on Android, this event happens for all screens, but we + ;;need only for active one (when (and @state/curr-modal (= @state/curr-modal view-id)) - (set-view-id view-id)) + (effects/set-view-id view-id)) (when-not @state/curr-modal - (set-view-id view-id) + (effects/set-view-id view-id) (reset! state/pushed-screen-id view-id))))) -(defn dissmissModal - ([] (dissmissModal nil)) - ([comp-id] - (reset! state/dissmissing true) - (navigation/dismiss-modal (name (or comp-id (last @state/modals)))))) - -(defn dismiss-all-modals - [] - (when @state/curr-modal - (reset! state/curr-modal false) - (reset! state/dissmissing true) - (doseq [modal @state/modals] - (navigation/dismiss-modal (name modal))) - (reset! state/modals []))) - -;; ROOT -(re-frame/reg-fx - :set-root - (fn [root-id] - (let [root (get (roots/roots) root-id)] - (dismiss-all-modals) - (re-frame/dispatch [:profile.settings/switch-theme - (get roots/themes root-id) - root-id]) - (reset! state/root-id (or (get-in root [:root :stack :id]) root-id)) - (navigation/set-root root)))) - -;; NAVIGATE-TO -(defn navigate - [component] - (let [{:keys [options]} (get views/screens component)] - (dismiss-all-modals) - (navigation/push - (name @state/root-id) - {:component {:id component - :name component - :options (merge (options/default-root) - (options/statusbar-and-navbar) - options - (if (:topBar options) - (options/merge-top-bar (options/topbar-options) options) - {:topBar {:visible false}}))}}))) - -;; NAVIGATE-TO-WITHIN-STACK -(defn navigate-to-within-stack - [[component comp-id]] - (let [{:keys [options]} (get views/screens component)] - (navigation/push - (name comp-id) - {:component {:id component - :name component - :options (merge (options/statusbar-and-navbar) - options - (if (:topBar options) - (options/merge-top-bar (options/topbar-options) options) - {:topBar {:visible false}}))}}))) - -(re-frame/reg-fx :navigate-to navigate) - -(re-frame/reg-fx :navigate-to-within-stack navigate-to-within-stack) - -(re-frame/reg-fx :navigate-replace-fx - (fn [view-id] - (navigation/pop (name @state/root-id)) - (navigate view-id))) - -(re-frame/reg-fx :navigate-back - (fn [] - (if @state/curr-modal - (dissmissModal) - (navigation/pop (name @state/root-id))))) - -(re-frame/reg-fx :navigate-back-within-stack - (fn [comp-id] - (navigation/pop (name comp-id)))) - -(re-frame/reg-fx :navigate-back-to - (fn [comp-id] - (navigation/pop-to (name comp-id)))) - -(re-frame/reg-fx :dismiss-modal - (fn [comp-id] - (dissmissModal (name comp-id)))) - -(defn pop-to-root - [root-id] - (navigation/pop-to-root root-id) - (dismiss-all-modals)) - -(re-frame/reg-fx :pop-to-root-fx pop-to-root) - -;; MODAL -(defn open-modal - [component] - (let [{:keys [options]} (get views/screens component) - sheet? (:sheet? options)] - (if @state/dissmissing - (reset! state/dissmissing component) - (do - (reset! state/curr-modal true) - (swap! state/modals conj component) - (navigation/show-modal - {:stack {:children [{:component - {:name component - :id component - :options (merge (options/default-root) - (options/statusbar-and-navbar) - options - (when sheet? - options/sheet-options))}}]}}))))) - -(re-frame/reg-fx :open-modal-fx open-modal) +;;;; Modal (navigation/reg-button-pressed-listener (fn [id] (if (= "dismiss-modal" id) (do (when-let [event (get-in views/screens [(last @state/modals) :on-dissmiss])] - (re-frame/dispatch event)) - (dissmissModal)) + (rf/dispatch event)) + (effects/dismiss-modal)) (when-let [handler (get-in views/screens [(keyword id) :right-handler])] (handler))))) @@ -185,112 +61,38 @@ (if (> (count @state/modals) 1) (let [new-modals (butlast @state/modals)] (reset! state/modals (vec new-modals)) - (set-view-id (last new-modals))) + (effects/set-view-id (last new-modals))) (do (reset! state/modals []) (reset! state/curr-modal false) - (set-view-id @state/pushed-screen-id))) + (effects/set-view-id @state/pushed-screen-id))) (let [component @state/dissmissing] (reset! state/dissmissing false) (when (keyword? component) - (open-modal component))))) + (effects/open-modal component))))) -;; OVERLAY -(def dissmiss-overlay navigation/dissmiss-overlay) +;;;; Toast -(defn show-overlay - ([component] (show-overlay component {})) - ([component opts] - (dissmiss-overlay component) - (navigation/show-overlay - {:component {:name component - :id component - :options (merge (options/statusbar) - {:layout {:componentBackgroundColor :transparent - :orientation ["portrait"]} - :overlay {:interceptTouchOutside true}} - opts)}}))) +(navigation/register-component + "toasts" + ; `:flex 0` is the same as `flex: 0 0 auto` in CSS. + ; We need this to override the HOC default layout which is + ; flex 1. If we don't override this property, this HOC + ; will catch all touches/gestures while the toast is shown, + ; preventing the user doing any action in the app + #(gesture/gesture-handler-root-hoc views/toasts + #js {:flex 0}) + (fn [] views/toasts)) -;; toast -(navigation/register-component "toasts" - ; `:flex 0` is the same as `flex: 0 0 auto` in CSS. - ; We need this to override the HOC default layout which is - ; flex 1. If we don't override this property, this HOC - ; will catch all touches/gestures while the toast is shown, - ; preventing the user doing any action in the app - #(gesture/gesture-handler-root-hoc views/toasts - #js {:flex 0}) - (fn [] views/toasts)) +;;;; Bottom sheet -(re-frame/reg-fx :show-toasts - (fn [] - (show-overlay "toasts" - {:overlay {:interceptTouchOutside false} - :layout {:componentBackgroundColor :transparent - :orientation ["portrait"]}}))) -(re-frame/reg-fx :hide-toasts (fn [] (dissmiss-overlay "toasts"))) - -;; bottom sheet -(navigation/register-component "bottom-sheet" - (fn [] (gesture/gesture-handler-root-hoc views/bottom-sheet)) - (fn [] views/bottom-sheet)) - -(re-frame/reg-fx :show-bottom-sheet (fn [] (show-overlay "bottom-sheet"))) -(re-frame/reg-fx :hide-bottom-sheet (fn [] (dissmiss-overlay "bottom-sheet"))) - -;; MERGE OPTIONS -(re-frame/reg-fx - :merge-options - (fn [{:keys [id options]}] - (navigation/merge-options id options))) +(navigation/register-component + "bottom-sheet" + (fn [] (gesture/gesture-handler-root-hoc views/bottom-sheet)) + (fn [] views/bottom-sheet)) ;; LEGACY (should be removed in status 2.0) -(defn get-screen-component - [component] - (let [{:keys [options]} (get views/screens component)] - {:component {:id component - :name component - :options (merge (options/statusbar-and-navbar) - options - (options/merge-top-bar (options/topbar-options) options))}})) - -(re-frame/reg-fx - :set-stack-root-fx - (fn [[stack component]] - ;; We don't have bottom tabs as separate stacks anymore,. So the old way of pushing screens in - ;; specific tabs will not work. Disabled set-stack-root for :shell-stack as it is not working - ;; and currently only being used for browser and some rare keycard flows after login - (when-not (= @state/root-id :shell-stack) - (log/debug :set-stack-root-fx stack component) - (navigation/set-stack-root - (name stack) - (if (vector? component) - (mapv get-screen-component component) - (get-screen-component component)))))) - -(re-frame/reg-fx :show-popover (fn [] (show-overlay "popover"))) -(re-frame/reg-fx :hide-popover (fn [] (dissmiss-overlay "popover"))) -(re-frame/reg-fx :show-visibility-status-popover - (fn [] (show-overlay "visibility-status-popover"))) -(re-frame/reg-fx :hide-visibility-status-popover - (fn [] (dissmiss-overlay "visibility-status-popover"))) -(re-frame/reg-fx :show-bottom-sheet-overlay-old (fn [] (show-overlay "bottom-sheet-old"))) -(re-frame/reg-fx :dismiss-bottom-sheet-overlay-old (fn [] (dissmiss-overlay "bottom-sheet-old"))) -(re-frame/reg-fx :show-wallet-connect-sheet (fn [] (show-overlay "wallet-connect-sheet"))) -(re-frame/reg-fx :hide-wallet-connect-sheet (fn [] (dissmiss-overlay "wallet-connect-sheet"))) -(re-frame/reg-fx :show-wallet-connect-success-sheet - (fn [] (show-overlay "wallet-connect-success-sheet"))) -(re-frame/reg-fx :hide-wallet-connect-success-sheet - (fn [] (dissmiss-overlay "wallet-connect-success-sheet"))) -(re-frame/reg-fx :show-wallet-connect-app-management-sheet - (fn [] (show-overlay "wallet-connect-app-management-sheet"))) -(re-frame/reg-fx :hide-wallet-connect-app-management-sheet - (fn [] (dissmiss-overlay "wallet-connect-app-management-sheet"))) -(re-frame/reg-fx :show-signing-sheet (fn [] (show-overlay "signing-sheet"))) -(re-frame/reg-fx :hide-signing-sheet (fn [] (dissmiss-overlay "signing-sheet"))) -(re-frame/reg-fx :show-select-acc-sheet (fn [] (show-overlay "select-acc-sheet"))) -(re-frame/reg-fx :hide-select-acc-sheet (fn [] (dissmiss-overlay "select-acc-sheet"))) (defonce _ diff --git a/src/status_im2/navigation/effects.cljs b/src/status_im2/navigation/effects.cljs new file mode 100644 index 00000000000..29a42902966 --- /dev/null +++ b/src/status_im2/navigation/effects.cljs @@ -0,0 +1,248 @@ +(ns status-im2.navigation.effects + (:require + [react-native.navigation :as navigation] + [status-im2.navigation.options :as options] + [status-im2.navigation.roots :as roots] + [status-im2.navigation.state :as state] + [status-im2.navigation.view :as views] + [taoensso.timbre :as log] + [utils.re-frame :as rf])) + +(rf/reg-fx :set-view-id-fx + (fn [view-id] + (rf/dispatch [:screens/on-will-focus view-id]) + (when-let [{:keys [on-focus]} (get views/screens view-id)] + (when on-focus + (rf/dispatch on-focus))))) + +(defn set-view-id + [view-id] + (when (get views/screens view-id) + (rf/dispatch [:set-view-id view-id]))) + +(defn- dismiss-all-modals + [] + (when @state/curr-modal + (reset! state/curr-modal false) + (reset! state/dissmissing true) + (doseq [modal @state/modals] + (navigation/dismiss-modal (name modal))) + (reset! state/modals []))) + +;;;; Root + +(rf/reg-fx :set-root + (fn [root-id] + (let [root (get (roots/roots) root-id)] + (dismiss-all-modals) + (rf/dispatch [:profile.settings/switch-theme + (get roots/themes root-id) + root-id]) + (reset! state/root-id (or (get-in root [:root :stack :id]) root-id)) + (navigation/set-root root)))) + +;;;; Navigate to + +(defn- navigate + [component] + (let [{:keys [options]} (get views/screens component)] + (dismiss-all-modals) + (navigation/push + (name @state/root-id) + {:component {:id component + :name component + :options (merge (options/default-root) + (options/statusbar-and-navbar) + options + (if (:topBar options) + (options/merge-top-bar (options/topbar-options) options) + {:topBar {:visible false}}))}}))) + +(rf/reg-fx :navigate-to navigate) + +;;;; Navigate to within stack + +(defn- navigate-to-within-stack + [[component comp-id]] + (let [{:keys [options]} (get views/screens component)] + (navigation/push + (name comp-id) + {:component {:id component + :name component + :options (merge (options/statusbar-and-navbar) + options + (if (:topBar options) + (options/merge-top-bar (options/topbar-options) options) + {:topBar {:visible false}}))}}))) + +(rf/reg-fx :navigate-to-within-stack navigate-to-within-stack) + +(rf/reg-fx :navigate-replace-fx + (fn [view-id] + (navigation/pop (name @state/root-id)) + (navigate view-id))) + +(defn dismiss-modal + ([] (dismiss-modal nil)) + ([comp-id] + (reset! state/dissmissing true) + (navigation/dismiss-modal (name (or comp-id (last @state/modals)))))) + +(rf/reg-fx :navigate-back + (fn [] + (if @state/curr-modal + (dismiss-modal) + (navigation/pop (name @state/root-id))))) + +(rf/reg-fx :navigate-back-within-stack + (fn [comp-id] + (navigation/pop (name comp-id)))) + +(rf/reg-fx :navigate-back-to + (fn [comp-id] + (navigation/pop-to (name comp-id)))) + +(rf/reg-fx :dismiss-modal + (fn [comp-id] + (dismiss-modal (name comp-id)))) + +(defn- pop-to-root + [root-id] + (navigation/pop-to-root root-id) + (dismiss-all-modals)) + +(rf/reg-fx :pop-to-root-fx pop-to-root) + +;;;; Modal + +(defn open-modal + [component] + (let [{:keys [options]} (get views/screens component) + sheet? (:sheet? options)] + (if @state/dissmissing + (reset! state/dissmissing component) + (do + (reset! state/curr-modal true) + (swap! state/modals conj component) + (navigation/show-modal + {:stack {:children [{:component + {:name component + :id component + :options (merge (options/default-root) + (options/statusbar-and-navbar) + options + (when sheet? + options/sheet-options))}}]}}))))) + +(rf/reg-fx :open-modal-fx open-modal) + +;;;; Overlay + +(defn show-overlay + ([component] (show-overlay component {})) + ([component opts] + (navigation/dissmiss-overlay component) + (navigation/show-overlay + {:component {:name component + :id component + :options (merge (options/statusbar) + {:layout {:componentBackgroundColor :transparent + :orientation ["portrait"]} + :overlay {:interceptTouchOutside true}} + opts)}}))) + +(rf/reg-fx :show-toasts + (fn [] + (show-overlay "toasts" + {:overlay {:interceptTouchOutside false} + :layout {:componentBackgroundColor :transparent + :orientation ["portrait"]}}))) + +(rf/reg-fx :hide-toasts + (fn [] (navigation/dissmiss-overlay "toasts"))) + +;;;; Bottom sheet + +(rf/reg-fx :show-bottom-sheet + (fn [] (show-overlay "bottom-sheet"))) + +(rf/reg-fx :hide-bottom-sheet + (fn [] (navigation/dissmiss-overlay "bottom-sheet"))) + +;;;; Merge options + +(rf/reg-fx :merge-options + (fn [{:keys [id options]}] + (navigation/merge-options id options))) + +;;;; Legacy (should be removed in status 2.0) + +(defn- get-screen-component + [component] + (let [{:keys [options]} (get views/screens component)] + {:component {:id component + :name component + :options (merge (options/statusbar-and-navbar) + options + (options/merge-top-bar (options/topbar-options) options))}})) + +(rf/reg-fx :set-stack-root-fx + (fn [[stack component]] + ;; We don't have bottom tabs as separate stacks anymore,. So the old way of pushing screens in + ;; specific tabs will not work. Disabled set-stack-root for :shell-stack as it is not working + ;; and currently only being used for browser and some rare keycard flows after login + (when-not (= @state/root-id :shell-stack) + (log/debug :set-stack-root-fx stack component) + (navigation/set-stack-root + (name stack) + (if (vector? component) + (mapv get-screen-component component) + (get-screen-component component)))))) + +(rf/reg-fx :show-popover + (fn [] (show-overlay "popover"))) + +(rf/reg-fx :hide-popover + (fn [] (navigation/dissmiss-overlay "popover"))) + +(rf/reg-fx :show-visibility-status-popover + (fn [] (show-overlay "visibility-status-popover"))) + +(rf/reg-fx :hide-visibility-status-popover + (fn [] (navigation/dissmiss-overlay "visibility-status-popover"))) + +(rf/reg-fx :show-bottom-sheet-overlay-old + (fn [] (show-overlay "bottom-sheet-old"))) + +(rf/reg-fx :dismiss-bottom-sheet-overlay-old + (fn [] (navigation/dissmiss-overlay "bottom-sheet-old"))) + +(rf/reg-fx :show-wallet-connect-sheet + (fn [] (show-overlay "wallet-connect-sheet"))) + +(rf/reg-fx :hide-wallet-connect-sheet + (fn [] (navigation/dissmiss-overlay "wallet-connect-sheet"))) + +(rf/reg-fx :show-wallet-connect-success-sheet + (fn [] (show-overlay "wallet-connect-success-sheet"))) + +(rf/reg-fx :hide-wallet-connect-success-sheet + (fn [] (navigation/dissmiss-overlay "wallet-connect-success-sheet"))) + +(rf/reg-fx :show-wallet-connect-app-management-sheet + (fn [] (show-overlay "wallet-connect-app-management-sheet"))) + +(rf/reg-fx :hide-wallet-connect-app-management-sheet + (fn [] (navigation/dissmiss-overlay "wallet-connect-app-management-sheet"))) + +(rf/reg-fx :show-signing-sheet + (fn [] (show-overlay "signing-sheet"))) + +(rf/reg-fx :hide-signing-sheet + (fn [] (navigation/dissmiss-overlay "signing-sheet"))) + +(rf/reg-fx :show-select-acc-sheet + (fn [] (show-overlay "select-acc-sheet"))) + +(rf/reg-fx :hide-select-acc-sheet + (fn [] (navigation/dissmiss-overlay "select-acc-sheet"))) diff --git a/src/status_im2/navigation/events.cljs b/src/status_im2/navigation/events.cljs index 5d72d033be9..b8b8cd9aa64 100644 --- a/src/status_im2/navigation/events.cljs +++ b/src/status_im2/navigation/events.cljs @@ -60,12 +60,12 @@ (rf/defn pop-to-root {:events [:pop-to-root]} [{:keys [db]} tab] - {:pop-to-root-fx tab - :db (-> db - (dissoc :shell/floating-screens) - (dissoc :shell/loaded-screens) - (assoc :view-id (or @shell.state/selected-stack-id :shell))) - :shell/pop-to-root-fx nil}) + {:pop-to-root-fx tab + :db (-> db + (dissoc :shell/floating-screens) + (dissoc :shell/loaded-screens) + (assoc :view-id (or @shell.state/selected-stack-id :shell))) + :effects.shell/pop-to-root nil}) (rf/defn init-root {:events [:init-root]} @@ -80,8 +80,8 @@ (rf/defn change-tab {:events [:navigate-change-tab]} [{:keys [db]} stack-id] - {:db (assoc db :view-id stack-id) - :shell/change-tab-fx stack-id}) + {:db (assoc db :view-id stack-id) + :effects.shell/change-tab stack-id}) (rf/defn navigate-replace {:events [:navigate-replace]} diff --git a/src/status_im2/navigation/screens.cljs b/src/status_im2/navigation/screens.cljs index fa08f335405..8f3ef893364 100644 --- a/src/status_im2/navigation/screens.cljs +++ b/src/status_im2/navigation/screens.cljs @@ -2,6 +2,7 @@ (:require [status-im.ui.screens.screens :as old-screens] [status-im2.config :as config] + [status-im2.contexts.add-new-contact.scan.scan-profile-qr-page :as scan-profile-qr-page] [status-im2.contexts.add-new-contact.views :as add-new-contact] [status-im2.contexts.chat.camera.view :as camera-screen] [status-im2.contexts.chat.group-details.view :as group-details] @@ -315,7 +316,13 @@ :options (merge options/dark-screen {:modalPresentationStyle :overCurrentContext}) - :component scan-address/view}] + :component scan-address/view} + + {:name :scan-profile-qr-code + :options (merge + options/dark-screen + {:modalPresentationStyle :overCurrentContext}) + :component scan-profile-qr-page/view}] (when js/goog.DEBUG [{:name :dev-component-preview diff --git a/src/status_im2/setup/global_error.cljs b/src/status_im2/setup/global_error.cljs index a880bf7ed8e..f02876ae0ec 100644 --- a/src/status_im2/setup/global_error.cljs +++ b/src/status_im2/setup/global_error.cljs @@ -2,7 +2,7 @@ (:require [clojure.string :as string] [re-frame.core :as re-frame] - [status-im2.common.alert.events :as alert] + [status-im2.common.alert.effects :as alert.effects] [utils.i18n :as i18n])) ;; Error handling code based on https://gist.github.com/pesterhazy/e6846be1b6712a9038537022d131ce46 @@ -62,7 +62,7 @@ (if js/goog.DEBUG (some-> orig-handler (.call nil e isFatal)) - (alert/show-confirmation + (alert.effects/show-confirmation {:title "Error" :content (.-message e) :confirm-button-text (i18n/label :t/send-logs) diff --git a/src/status_im2/subs/wallet/collectibles.cljs b/src/status_im2/subs/wallet/collectibles.cljs index c2ad6bc2658..c2bd40c012c 100644 --- a/src/status_im2/subs/wallet/collectibles.cljs +++ b/src/status_im2/subs/wallet/collectibles.cljs @@ -15,7 +15,7 @@ :<- [:wallet] (fn [wallet] (map (fn [collectible] - (assoc collectible :preview-url (preview-url collectible))) + (assoc collectible :preview-url (preview-url (:collectible-data collectible)))) (:collectibles wallet)))) (re-frame/reg-sub @@ -23,4 +23,10 @@ :<- [:wallet] (fn [wallet] (let [last-collectible (:last-collectible-details wallet)] - (assoc last-collectible :preview-url (preview-url last-collectible))))) + (assoc last-collectible :preview-url (preview-url (:collectible-data last-collectible)))))) + +(re-frame/reg-sub + :wallet/last-collectible-chain-id + :<- [:wallet/last-collectible-details] + (fn [collectible] + (get-in collectible [:id :contract-id :chain-id]))) diff --git a/src/status_im2/subs/wallet/wallet.cljs b/src/status_im2/subs/wallet/wallet.cljs index a3e712b5381..2f7fe983bae 100644 --- a/src/status_im2/subs/wallet/wallet.cljs +++ b/src/status_im2/subs/wallet/wallet.cljs @@ -99,3 +99,29 @@ :<- [:wallet/current-viewing-account-address] (fn [[accounts current-viewing-account-address]] (remove #(= (:address %) current-viewing-account-address) accounts))) + +(defn- calc-token-value + [{:keys [market-values-per-currency] :as item} chain-id] + (let [crypto-value (utils/token-value-in-chain item chain-id) + market-values (:usd market-values-per-currency) + {:keys [price change-pct-24hour]} market-values + fiat-change (utils/calculate-fiat-change crypto-value change-pct-24hour)] + (when crypto-value + {:token (keyword (string/lower-case (:symbol item))) + :state :default + :status (cond + (pos? change-pct-24hour) :positive + (neg? change-pct-24hour) :negative + :else :empty) + :customization-color :blue + :values {:crypto-value crypto-value + :fiat-value (utils/prettify-balance (* crypto-value price)) + :percentage-change (.toFixed change-pct-24hour 2) + :fiat-change (utils/prettify-balance fiat-change)}}))) + +(rf/reg-sub + :wallet/account-token-values + :<- [:wallet/current-viewing-account] + :<- [:chain-id] + (fn [[current-account chain-id]] + (mapv #(calc-token-value % chain-id) (:tokens current-account)))) diff --git a/src/test_helpers/integration.clj b/src/test_helpers/integration.clj index b2fd1e3b38b..58c91db3aa7 100644 --- a/src/test_helpers/integration.clj +++ b/src/test_helpers/integration.clj @@ -19,6 +19,6 @@ (do ~@body) (do (test-helpers.integration/create-multiaccount!) - (rf-test/wait-for [:status-im.transport.core/messenger-started] + (rf-test/wait-for [:messenger-started] (test-helpers.integration/assert-messenger-started) ~@body))))