Compare commits

..
73 changed files with 1580 additions and 1659 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.13'
library 'status-jenkins-lib@v1.9.12'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.13'
library 'status-jenkins-lib@v1.9.12'
import groovy.json.JsonBuilder
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.13'
library 'status-jenkins-lib@v1.9.12'
pipeline {
agent { label 'linux' }
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.13'
library 'status-jenkins-lib@v1.9.12'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.13'
library 'status-jenkins-lib@v1.9.12'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.13'
library 'status-jenkins-lib@v1.9.12'
pipeline {
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.13'
library 'status-jenkins-lib@v1.9.12'
pipeline {
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.13'
library 'status-jenkins-lib@v1.9.12'
pipeline {
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.13'
library 'status-jenkins-lib@v1.9.12'
pipeline {
agent { label 'macos' }
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.13'
library 'status-jenkins-lib@v1.9.12'
pipeline {
agent { label params.AGENT_LABEL }
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.13'
library 'status-jenkins-lib@v1.9.12'
pipeline {
agent { label 'linux' }
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.13'
library 'status-jenkins-lib@v1.9.12'
pipeline {
agent {
+1
View File
@@ -219,6 +219,7 @@ PLATFORMS
arm64-darwin-22
arm64-darwin-23
x86_64-darwin-22
x86_64-darwin-23
DEPENDENCIES
activesupport (>= 6.1.7.3, < 7.1.0)
+1 -1
View File
@@ -1490,7 +1490,7 @@ SPEC CHECKSUMS:
FBLazyVector: 56e0e498dbb513b96c40bac6284729ba4e62672d
FBReactNativeSpec: 146c741a3f40361f6bc13a4ba284678cbedb5881
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: c0eca6ffed0a6fde1965ef26dcc7bf528f052af4
glog: 36c15c01d70ed395c6e4f3619f98a23ee415b07a
hermes-engine: 1d1835b2cc54c381909d94d1b3c8e0a2f1a94a0e
HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352
Keycard: ac6df4d91525c3c82635ac24d4ddd9a80aca5fc8
@@ -253,11 +253,6 @@ class AccountManager(private val reactContext: ReactApplicationContext) : ReactC
utils.executeRunnableStatusGoMethod({ Statusgo.initializeApplication(request) }, callback)
}
@ReactMethod
private fun acceptTerms(callback: Callback) {
Log.d(TAG, "acceptTerms")
utils.executeRunnableStatusGoMethod({ Statusgo.acceptTerms() }, callback)
}
@ReactMethod
fun logout() {
@@ -204,14 +204,6 @@ RCT_EXPORT_METHOD(initializeApplication:(NSString *)request
callback(@[result]);
}
RCT_EXPORT_METHOD(acceptTerms:(RCTResponseSenderBlock)callback) {
#if DEBUG
NSLog(@"acceptTerms() method called");
#endif
NSString *result = StatusgoAcceptTerms();
callback(@[result]);
}
RCT_EXPORT_METHOD(openAccounts:(RCTResponseSenderBlock)callback) {
#if DEBUG
NSLog(@"OpenAccounts() method called");
@@ -761,26 +761,6 @@ void _Logout(const FunctionCallbackInfo<Value>& args) {
}
void _AcceptTerms(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
if (args.Length() != 0) {
// Throw an Error that is passed back to JavaScript
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8Literal(isolate, "Wrong number of arguments for AcceptTerms")));
return;
}
// Check the argument types
// Call exported Go function, which returns a C string
char *c = AcceptTerms();
Local<String> ret = String::NewFromUtf8(isolate, c).ToLocalChecked();
args.GetReturnValue().Set(ret);
delete c;
}
void _HashMessage(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
@@ -2018,7 +1998,6 @@ void init(Local<Object> exports) {
NODE_SET_METHOD(exports, "multiAccountStoreAccount", _MultiAccountStoreAccount);
NODE_SET_METHOD(exports, "initKeystore", _InitKeystore);
NODE_SET_METHOD(exports, "initializeApplication", _InitializeApplication);
NODE_SET_METHOD(exports, "acceptTerms", _AcceptTerms);
NODE_SET_METHOD(exports, "fleets", _Fleets);
NODE_SET_METHOD(exports, "stopCPUProfiling", _StopCPUProfiling);
NODE_SET_METHOD(exports, "encodeTransfer", _EncodeTransfer);
+1 -3
View File
@@ -32,9 +32,7 @@ showXcrunLogs() {
}
# find the first connected iPhone's UUID
#DEVICE_UUID=$(idevice_id -l)
# hardcoding Sid's iPhone
DEVICE_UUID="00008120-0002681E0E04201E"
DEVICE_UUID=$(idevice_id -l)
# Check if any device is connected
if [ -z "${DEVICE_UUID}" ]; then
+7 -10
View File
@@ -95,8 +95,7 @@
;; otherwise sometimes you'll get weird errors when
;; instrumenting functions.
:static-fns false
:infer-externs true
:reader-features #{:mobile}}
:infer-externs true}
;; if you want to use a real device, set your local ip
;; in the SHADOW_HOST env variable to make sure that
;; it will use the right interface
@@ -130,8 +129,7 @@
:static-fns true
:fn-invoke-direct true
:optimizations :advanced
:js-options {:js-provider :closure}
:reader-features #{:mobile}}}}
:js-options {:js-provider :closure}}}}
;; the tests are ran with node, react-native dependencies are mocked
;; by using node --require override.js, which uses the node-library
;; produced by the target :mocks below and redefines node require
@@ -171,13 +169,12 @@
{;; needed because we override require and it
;; messes with source-map which reports callstack
;; exceeded exceptions instead of real issues
:source-map false
:source-map false
;; needed because we use deref in tests
:static-fns false
:optimizations :simple
:warnings {:fn-deprecated false}
:infer-externs true
:reader-features #{:mobile}}}
:static-fns false
:optimizations :simple
:warnings {:fn-deprecated false}
:infer-externs true}}
;; mock.js-dependencies is mocking the react-native libraries
;; we build it as a node library so that it can be required by
-6
View File
@@ -79,12 +79,6 @@
(types/clj->json request)
#(callback (types/json->clj %))))
(defn accept-terms
([]
(native-utils/promisify-native-module-call accept-terms))
([callback]
(.acceptTerms ^js (account-manager) callback)))
(defn prepare-dir-and-update-config
[key-uid config callback]
(log/debug "[native-module] prepare-dir-and-update-config")
@@ -5,7 +5,6 @@
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im.common.confirmation-drawer.style :as style]
[status-im.constants :as constants]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@@ -36,12 +35,11 @@
close-button-text]}]
(let [extra-action-selected? (reagent/atom false)]
(fn []
(let [{:keys [group-chat chat-id public-key color chat-type
(let [{:keys [group-chat chat-id public-key color
profile-picture name]} context
id (or chat-id public-key)
theme (quo.theme/use-theme)
[primary-name _] (when-not (or group-chat
(= chat-type constants/public-chat-type))
[primary-name _] (when-not group-chat
(rf/sub [:contacts/contact-two-names-by-identity id]))
display-name (cond
(= primary-name "Unknown")
+16 -20
View File
@@ -232,11 +232,12 @@
:sub-label nil
:chevron? false})))
;; TODO(OmarBasem): Requires design input.
(defn edit-name-image-entry
[chat-id]
[]
(entry {:icon :i/edit
:label (i18n/label :t/edit-name-and-image)
:on-press #(rf/dispatch [:open-modal :screen/group-update chat-id])
:on-press #(js/alert "TODO: to be implemented, requires design input")
:danger? false
:accessibility-label :edit-name-and-image
:sub-label nil
@@ -358,7 +359,7 @@
(rf/dispatch [:chats-list/load-chat chat-id])
(rf/dispatch [:pin-message/load-pin-messages chat-id])
(rf/dispatch [:hide-bottom-sheet])
(rf/dispatch [:navigate-to :screen/group-details chat-id]))
(rf/dispatch [:navigate-to :group-details chat-id]))
:danger? false
:accessibility-label :group-details
:sub-label nil
@@ -368,17 +369,18 @@
[chat-id admin?]
(entry {:icon :i/add-user
:label (i18n/label (if admin? :t/manage-members :t/add-members))
:on-press #(rf/dispatch [:open-modal :screen/group-add-manage-members chat-id])
:on-press #(rf/dispatch [:open-modal :group-add-manage-members chat-id])
:danger? false
:accessibility-label :manage-members
:sub-label nil
:chevron? false}))
;; TODO(OmarBasem): to be implemented.
(defn edit-group-entry
[chat-id]
[]
(entry {:icon :i/edit
:label (i18n/label :t/edit-name-and-image)
:on-press #(rf/dispatch [:open-modal :screen/group-update chat-id])
:on-press #(js/alert "TODO: to be implemented")
:danger? false
:accessibility-label :edit-group
:sub-label nil
@@ -396,11 +398,10 @@
:chevron? false}))
(defn destructive-actions
[{:keys [group-chat chat-type] :as item} inside-chat?]
[{:keys [group-chat] :as item} inside-chat?]
[(when (not group-chat)
(close-chat-entry item inside-chat? (not= chat-type constants/public-chat-type)))
(when-not (= chat-type constants/public-chat-type)
(clear-history-entry item group-chat))
(close-chat-entry item inside-chat? (not group-chat)))
(clear-history-entry item group-chat)
(when group-chat
(leave-group-entry item nil))])
@@ -424,7 +425,8 @@
(when inside-chat?
(add-manage-members-entry chat-id admin?))
(when (and admin? inside-chat?)
(edit-group-entry chat-id))
(when config/show-not-implemented-features?
(edit-group-entry)))
(when (and admin? inside-chat?)
(when config/show-not-implemented-features?
(group-privacy-entry)))]))
@@ -436,11 +438,6 @@
(notification-actions item inside-chat? true)
(destructive-actions item inside-chat?)]])
(defn public-chat-actions
[item inside-chat?]
[quo/action-drawer
[(destructive-actions item inside-chat?)]])
(defn private-group-chat-actions
[item inside-chat?]
[quo/action-drawer
@@ -476,8 +473,6 @@
[one-to-one-actions chat inside-chat?]
constants/private-group-chat-type
[private-group-chat-actions chat inside-chat?]
constants/public-chat-type
[public-chat-actions chat inside-chat?]
constants/community-chat-type
[communities-chat-actions/actions chat inside-chat? hide-show-members?]
nil))
@@ -485,12 +480,13 @@
(chat-actions chat inside-chat? nil)))
(defn group-details-actions
[{:keys [chat-id admins] :as group}]
[{:keys [admins] :as group}]
(let [current-pub-key (rf/sub [:multiaccount/public-key])
admin? (get admins current-pub-key)]
[quo/action-drawer
[(when admin?
[(edit-name-image-entry chat-id)])
[(when config/show-not-implemented-features?
(edit-name-image-entry))])
[(when config/show-not-implemented-features?
(notifications-entry admin?))]
(destructive-actions group false)]]))
-1
View File
@@ -566,7 +566,6 @@
(def ^:const bridge-name-erc-1155-transfer "ERC1155Transfer")
(def ^:const bridge-name-hop "Hop")
(def ^:const bridge-name-paraswap "Paraswap")
(def ^:const bridge-name-celer "CBridge")
(def ^:const bridge-assets #{"ETH" "USDT" "USDC" "DAI"})
@@ -14,13 +14,10 @@
(defn centralized-metrics-interceptor
[context]
(when (push-event? (interceptor/get-coeffect context :db))
(when-let [event (tracking/metrics-event (interceptor/get-coeffect context :event))]
(log/debug "tracking event" event)
(if (or (seq? event) (vector? event))
(doseq [e event]
(native-module/add-centralized-metric e))
(native-module/add-centralized-metric event))))
(when-let [event (tracking/tracked-event (interceptor/get-coeffect context :event))]
(log/debug "tracking event" event)
(when (push-event? (interceptor/get-coeffect context :db))
(native-module/add-centralized-metric event)))
context)
(def interceptor
@@ -15,7 +15,7 @@
(deftest centralized-metrics-interceptor-test
(testing "processes context correctly"
(with-redefs [tracking/metrics-event (fn [_] {:metric "mocked-event"})
(with-redefs [tracking/tracked-event (fn [_] {:metric "mocked-event"})
events/push-event? (fn [_] true)]
(let [context {:coeffects {:event [:some-event]
:db {:centralized-metrics/enabled? true}}}]
@@ -1,9 +1,7 @@
(ns status-im.contexts.centralized-metrics.tracking
(:require
[clojure.string]
[legacy.status-im.utils.build :as build]
[react-native.platform :as platform]
[status-im.navigation.screens :as screens]))
[react-native.platform :as platform]))
(defn key-value-event
[event-name event-value]
@@ -21,54 +19,47 @@
[view-id]
(key-value-event "navigation" {:viewId view-id}))
(defn screen-event
[screen event-data]
(let [screen-id (:name screen)
view-id (get-in screen [:metrics :alias-id] screen-id)]
{:metric
{:eventName "navigation"
:platform platform/os
:appVersion build/app-short-version
:eventValue (assoc event-data :viewId (name view-id))}}))
(def ^:const app-started-event "app-started")
(def ^:const view-ids-to-track
#{;; Tabs
:communities-stack
:chats-stack
:wallet-stack})
:wallet-stack
;; Onboarding
:screen/onboarding.intro
:screen/onboarding.new-to-status
:screen/onboarding.sync-or-recover-profile
:screen/onboarding.enter-seed-phrase
:screen/onboarding.create-profile
:screen/onboarding.create-profile-password
:screen/onboarding.enable-biometrics
:screen/onboarding.generating-keys
:screen/onboarding.enable-notifications
:screen/onboarding.preparing-status
:screen/onboarding.sign-in-intro
:screen/onboarding.sign-in
:screen/onboarding.syncing-progress
:screen/onboarding.syncing-progress-intro
:screen/onboarding.syncing-results
:screen/onboarding.welcome})
(defn track-view-id-event
[view-id]
(if-let [screen (get screens/screens-by-name view-id)]
(when (get-in screen [:metrics :track?])
(screen-event screen {}))
(when (contains? view-ids-to-track view-id)
(navigation-event (name view-id)))))
(when (contains? view-ids-to-track view-id)
(navigation-event (name view-id))))
(defn navigated-to-collectibles-tab-event
[location]
(key-value-event "navigated-to-collectibles-tab" {:location location}))
(defn metrics-event
[[rf-event-name rf-event-parameter]]
(case rf-event-name
(defn tracked-event
[[event-name second-parameter]]
(case event-name
:profile/get-profiles-overview-success
(user-journey-event app-started-event)
:centralized-metrics/toggle-centralized-metrics
(key-value-event "events.metrics-enabled" {:enabled rf-event-parameter})
(key-value-event "events.metrics-enabled" {:enabled second-parameter})
:set-view-id
(track-view-id-event rf-event-parameter)
:wallet/select-account-tab
(when (= rf-event-parameter :collectibles)
(navigated-to-collectibles-tab-event :account))
:wallet/select-home-tab
(when (= rf-event-parameter :collectibles)
(navigated-to-collectibles-tab-event :home))
(track-view-id-event second-parameter)
nil))
@@ -52,7 +52,7 @@
{:eventName "navigation"
:platform platform-os
:appVersion app-version
:eventValue {:viewId "onboarding.create-profile-info"}}}
:eventValue {:viewId "onboarding.create-profile"}}}
(tracking/track-view-id-event :screen/onboarding.create-profile)))
(is (nil? (tracking/track-view-id-event :unknown-stack)))))
@@ -63,23 +63,17 @@
:platform platform-os
:appVersion app-version
:eventValue {:action tracking/app-started-event}}}
(tracking/metrics-event [:profile/get-profiles-overview-success])))
(tracking/tracked-event [:profile/get-profiles-overview-success])))
(is (= {:metric
{:eventName "events.metrics-enabled"
:platform platform-os
:appVersion app-version
:eventValue {:enabled true}}}
(tracking/metrics-event [:centralized-metrics/toggle-centralized-metrics true])))
(tracking/tracked-event [:centralized-metrics/toggle-centralized-metrics true])))
(is (= {:metric
{:eventName "navigation"
:platform platform-os
:appVersion app-version
:eventValue {:viewId "wallet-stack"}}}
(tracking/metrics-event [:set-view-id :wallet-stack])))
(is (nil? (tracking/metrics-event [:unknown-event])))
(is (= {:metric
{:eventName "navigation"
:platform platform-os
:appVersion app-version
:eventValue {:viewId "onboarding.intro"}}}
(tracking/metrics-event [:set-view-id :screen/onboarding.intro])))))
(tracking/tracked-event [:set-view-id :wallet-stack])))
(is (nil? (tracking/tracked-event [:unknown-event])))))
+4 -4
View File
@@ -9,7 +9,7 @@
[status-im.constants :as constants]
[status-im.contexts.chat.contacts.events :as contacts-store]
status-im.contexts.chat.effects
status-im.contexts.chat.group.events
status-im.contexts.chat.group-create.events
[status-im.contexts.chat.messenger.composer.link-preview.events :as link-preview]
status-im.contexts.chat.messenger.messages.content.reactions.events
[status-im.contexts.chat.messenger.messages.delete-message-for-me.events :as delete-for-me]
@@ -33,8 +33,8 @@
(multi-user-chat? (get-chat cofx chat-id))))
(defn public-chat?
([{:keys [chat-type]}]
(= chat-type constants/public-chat-type))
([chat]
(:public? chat))
([cofx chat-id]
(public-chat? (get-chat cofx chat-id))))
@@ -52,7 +52,7 @@
(defn group-chat?
([chat]
(and (multi-user-chat? chat)
(not (:public? chat))))
(not (public-chat? chat))))
([cofx chat-id]
(group-chat? (get-chat cofx chat-id))))
@@ -1,27 +0,0 @@
(ns status-im.contexts.chat.group.create.view
(:require
[clojure.string :as string]
[quo.foundations.colors :as colors]
[status-im.constants :as constants]
[status-im.contexts.chat.group.common.group-edit :as group-edit]
[status-im.contexts.profile.utils :as profile.utils]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn view
[{:keys [close]}]
(let [contacts (rf/sub [:selected-group-contacts])
contact-string (string/join ", " (map profile.utils/displayed-name contacts))
default-group-name (subs contact-string
0
(min (count contact-string) constants/max-group-chat-name-length))
profile (rf/sub [:profile/profile-with-image])
contacts (conj contacts profile)]
[group-edit/view
{:default-group-name default-group-name
:default-group-color (rand-nth colors/account-colors)
:contacts contacts
:submit-button-label (i18n/label :t/create-group-chat)
:submit-event :group-chat/create
:back-button-icon :i/arrow-left
:close close}]))
@@ -1,23 +0,0 @@
(ns status-im.contexts.chat.group.update.view
(:require
[status-im.contexts.chat.group.common.group-edit :as group-edit]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn view
[{:keys [close]}]
(let [chat-id (rf/sub [:get-screen-params :screen/group-update])
{:keys [chat-name color image]} (rf/sub [:chats/chat-by-id chat-id])
contacts (rf/sub [:contacts/contacts-by-chat chat-id])]
[group-edit/view
{:default-group-name chat-name
:default-group-color color
:default-group-image image
:contacts contacts
:submit-button-label (i18n/label :t/update-group-chat)
:submit-event :group-chat/edit
:back-button-icon :i/close
:chat-id chat-id
:close close
:on-success close
:editing-group? true}]))
@@ -1,12 +1,12 @@
(ns status-im.contexts.chat.group.events
(ns status-im.contexts.chat.group-create.events
(:require [clojure.string :as string]
[legacy.status-im.data-store.chats :as data-store.chats]
[oops.core :as oops]
[re-frame.core :as rf]
[status-im.common.avatar-picture-picker.view :as avatar-picture-picker]
[taoensso.timbre :as log]))
[status-im.common.avatar-picture-picker.view :as avatar-picture-picker]))
(rf/reg-event-fx :group-chat/create
(fn [{:keys [db]} [{:keys [group-name group-color group-image]}]]
(fn [{:keys [db]} [group-name color image]]
(let [selected-contacts (:group/selected-contacts db)]
{:json-rpc/call [{:method "wakuext_createGroupChatWithMembers"
:params [nil group-name (into [] selected-contacts)]
@@ -17,23 +17,25 @@
(oops/oget :id))]
(rf/dispatch [:chat-updated response])
(rf/dispatch [:group-chat/edit
{:chat-id chat-id
:group-name group-name
:group-color group-color
:group-image group-image}])))}]})))
{:chat-id chat-id
:group-name group-name
:color color
:image image}])))}]})))
(rf/reg-event-fx :group-chat/edit-success
(fn [{:keys [db]} [{:keys [chat-id name color image]}]]
(let [new-chat {:name name :color color :image image}]
{:db (update-in db [:chats chat-id] #(merge % new-chat))})))
(rf/reg-event-fx :group-chat/edit
(fn [_ [{:keys [chat-id group-name group-color group-image on-success]}]]
(fn [_ [{:keys [chat-id group-name color image]}]]
{:json-rpc/call [{:method "chat_editChat"
:params ["" chat-id group-name (name group-color)
{:imagePath (when group-image
(string/replace-first group-image #"file://" ""))
:params ["" chat-id group-name (name color)
{:imagePath (when image (string/replace-first image #"file://" ""))
:x 0
:y 0
:width avatar-picture-picker/crop-size
:height avatar-picture-picker/crop-size}]
:js-response true
:on-error #(log/error "failed to edit group" {:error %})
:on-success (fn [response]
(rf/dispatch [:chat-updated response true])
(when on-success (on-success)))}]}))
:on-success #(rf/dispatch [:group-chat/edit-success
(data-store.chats/<-rpc-js %)])}]}))
@@ -1,4 +1,4 @@
(ns status-im.contexts.chat.group.common.style
(ns status-im.contexts.chat.group-create.style
(:require [quo.foundations.colors :as colors]))
(def avatar {:width 88 :margin-top 12 :margin-left 20})
@@ -1,11 +1,13 @@
(ns status-im.contexts.chat.group.common.group-edit
(:require [quo.core :as quo]
(ns status-im.contexts.chat.group-create.view
(:require [clojure.string :as string]
[quo.core :as quo]
[quo.foundations.colors :as colors]
[quo.theme]
[react-native.core :as rn]
[status-im.common.avatar-picture-picker.view :as avatar-picture-picker]
[status-im.common.floating-button-page.view :as floating-button-page]
[status-im.constants :as constants]
[status-im.contexts.chat.group.common.style :as style]
[status-im.contexts.chat.group-create.style :as style]
[status-im.contexts.profile.utils :as profile.utils]
[utils.debounce :as debounce]
utils.emojilib
@@ -39,28 +41,35 @@
:i/camera]]))
(defn view
[{:keys [default-group-name default-group-color default-group-image contacts
submit-button-label submit-event back-button-icon chat-id close on-success editing-group?]}]
[]
(let [theme (quo.theme/use-theme)
{window-width :width} (rn/get-window)
profile (rf/sub [:profile/profile-with-image])
contacts (rf/sub [:selected-group-contacts])
contacts-count (count contacts)
[group-name set-group-name] (rn/use-state default-group-name)
default-value (rn/use-memo
(fn []
(let [contact-string (string/join ", "
(map
profile.utils/displayed-name
contacts))]
(subs contact-string
0
(min (count contact-string)
constants/max-group-chat-name-length))))
[])
[group-name set-group-name] (rn/use-state default-value)
[error-message
set-error-message] (rn/use-state nil)
group-name-empty? (not (and (string? group-name) (not-empty group-name)))
[group-color set-group-color] (rn/use-state default-group-color)
[group-image set-group-image] (rn/use-state default-group-image)
on-submit (rn/use-callback #(debounce/throttle-and-dispatch
[submit-event
{:group-name group-name
:group-color group-color
:group-image (when (not= group-image
default-group-image)
group-image)
:chat-id chat-id
:on-success on-success}]
[group-color set-group-color] (rn/use-state (rand-nth colors/account-colors))
[group-image set-group-image] (rn/use-state nil)
create-group-on-press (rn/use-callback #(debounce/throttle-and-dispatch
[:group-chat/create group-name group-color
group-image]
300)
[group-name group-color group-image])
back-on-press (rn/use-callback #(rf/dispatch [:navigate-back]))
on-change-text (rn/use-callback
(fn [text]
(if (boolean (re-find utils.emojilib/emoji-regex text))
@@ -68,13 +77,7 @@
{:check (i18n/label
:t/emojis)}))
(set-error-message nil))
(set-group-name text)))
disabled? (or group-name-empty?
error-message
(and editing-group?
(= group-name default-group-name)
(= group-color default-group-color)
(= group-image default-group-image)))]
(set-group-name text)))]
[floating-button-page/view
{:customization-color group-color
:gradient-cover? true
@@ -82,13 +85,13 @@
:header [quo/page-nav
{:background :photo
:type :no-title
:icon-name back-button-icon
:on-press close}]
:icon-name :i/arrow-left
:on-press back-on-press}]
:footer [quo/button
{:customization-color group-color
:disabled? disabled?
:on-press on-submit}
submit-button-label]}
:disabled? (boolean (or group-name-empty? error-message))
:on-press create-group-on-press}
(i18n/label :t/create-group-chat)]}
[:<>
[avatar
{:customization-color group-color
@@ -96,7 +99,7 @@
:set-group-image set-group-image}]
[quo/title-input
{:on-change-text on-change-text
:default-value default-group-name
:default-value default-value
:container-style {:padding-horizontal 20 :padding-top 12 :padding-bottom (if error-message 0 16)}
:placeholder (i18n/label :t/name-your-group)
:max-length constants/max-group-chat-name-length}]
@@ -123,9 +126,9 @@
:padding-left (responsiveness/iphone-11-Pro-20-pixel-from-width
window-width)}}]]
[quo/divider-label
(i18n/label :t/n-m-people {:n contacts-count :m constants/max-group-chat-participants})]
(i18n/label :t/n-m-people {:n (inc contacts-count) :m constants/max-group-chat-participants})]
[rn/view {:style style/tags}
(for [contact contacts]
(for [contact (conj contacts profile)]
^{:key contact}
[quo/context-tag
{:container-style style/tag
@@ -1,4 +1,4 @@
(ns status-im.contexts.chat.group.details.style
(ns status-im.contexts.chat.group-details.style
(:require
[quo.foundations.colors :as colors]))
@@ -1,4 +1,4 @@
(ns status-im.contexts.chat.group.details.view
(ns status-im.contexts.chat.group-details.view
(:require
[quo.core :as quo]
[quo.foundations.colors :as colors]
@@ -11,7 +11,7 @@
[status-im.common.contact-list.view :as contact-list]
[status-im.common.home.actions.view :as actions]
[status-im.constants :as constants]
[status-im.contexts.chat.group.details.style :as style]
[status-im.contexts.chat.group-details.style :as style]
[status-im.feature-flags :as ff]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@@ -54,7 +54,7 @@
(let [theme (quo.theme/use-theme)
selected-participants (rf/sub [:group-chat/selected-participants])
deselected-members (rf/sub [:group-chat/deselected-members])
chat-id (rf/sub [:get-screen-params :screen/group-add-manage-members])
chat-id (rf/sub [:get-screen-params :group-add-manage-members])
{:keys [admins] :as group} (rf/sub [:chats/chat-by-id chat-id])
current-pk (rf/sub [:multiaccount/public-key])
admin? (get admins current-pk)]
@@ -123,9 +123,9 @@
[_]
[rn/view {:style {:height 8}}])
(defn view
(defn group-details
[]
(let [chat-id (rf/sub [:get-screen-params :screen/group-details])
(let [chat-id (rf/sub [:get-screen-params :group-details])
{:keys [admins chat-id chat-name color muted contacts image]
:as group} (rf/sub [:chats/chat-by-id chat-id])
members (rf/sub [:contacts/group-members-sections chat-id])
@@ -176,8 +176,7 @@
:icon :i/add-user
:label (i18n/label (if admin? :t/manage-members :t/add-members))
:counter-value (count contacts)
:on-press #(rf/dispatch [:open-modal
:screen/group-add-manage-members
:on-press #(rf/dispatch [:open-modal :group-add-manage-members
chat-id])}]}]
[rn/section-list
{:key-fn :title
@@ -237,17 +237,11 @@
(defn chat-item
[{:keys [chat-id group-chat color name last-message timestamp muted image
chat-type unviewed-messages-count]
unviewed-messages-count]
:as item}]
(let [[primary-name secondary-name]
(cond
group-chat
(if group-chat
[name ""]
(= chat-type constants/public-chat-type)
[(str "#" name) ""]
:else
(rf/sub [:contacts/contact-two-names-by-identity chat-id]))
{:keys [ens-verified added?] :as contact} (when-not group-chat
(rf/sub [:contacts/contact-by-address chat-id]))
@@ -149,7 +149,7 @@
:on-press (fn []
(if one-contact-selected?
(rf/dispatch [:chat.ui/start-chat public-key])
(rf/dispatch [:open-modal :screen/group-create])))}
(rf/dispatch [:open-modal :group-create])))}
(if one-contact-selected?
(i18n/label :t/chat-with {:selected-user primary-name})
(i18n/label :t/setup-group-chat))]])]))
@@ -12,13 +12,10 @@
(defn view
[{:keys [contact-id]}]
(let [customization-color (rf/sub [:profile/customization-color])
[primary-name _] (rf/sub [:contacts/contact-two-names-by-identity contact-id])
{:keys [contact-request-state
community-id
chat-name]} (rf/sub [:chats/current-chat-chat-view])
community-id]} (rf/sub [:chats/current-chat-chat-view])
chat-type (rf/sub [:chats/chat-type])
[primary-name _] (if (= chat-type :public-chat)
[(str "#" chat-name) ""]
(rf/sub [:contacts/contact-two-names-by-identity contact-id]))
community-chat? (= chat-type :community-chat)
joined (when community-chat?
(rf/sub [:communities/community-joined community-id]))
@@ -11,93 +11,66 @@
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn- show-terms-of-use
[]
(rf/dispatch [:show-bottom-sheet {:content terms/terms-of-use :shell? true}]))
(defn- show-privacy-policy
[]
(rf/dispatch [:show-bottom-sheet {:content privacy/privacy-statement :shell? true}]))
(defn- terms
[terms-accepted? set-terms-accepted?]
[rn/view {:style style/terms-privacy-container}
[rn/view
{:accessibility-label :terms-privacy-checkbox-container}
[quo/selectors
{:type :checkbox
:blur? true
:checked? terms-accepted?
:on-change #(set-terms-accepted? not)}]]
[rn/view {:style style/text-container}
[quo/text
{:style style/plain-text
:size :paragraph-2}
(str (i18n/label :t/accept-status-tos-prefix) " ")]
[quo/text
{:on-press show-terms-of-use
:style style/highlighted-text
:size :paragraph-2
:weight :medium}
(i18n/label :t/terms-of-service)]
[quo/text
{:style style/plain-text
:size :paragraph-2}
" " (i18n/label :t/and) " "]
[quo/text
{:on-press show-privacy-policy
:style style/highlighted-text
:size :paragraph-2
:weight :medium}
(i18n/label :t/intro-privacy-policy)]]])
(defn- explore-new-status
[]
(rf/dispatch [:profile/explore-new-status]))
(defn- sync-or-recover-profile
[]
(when-let [blur-show-fn @overlay/blur-show-fn-atom]
(blur-show-fn))
(rf/dispatch [:open-modal :screen/onboarding.sync-or-recover-profile]))
(defn- create-profile
[]
(when-let [blur-show-fn @overlay/blur-show-fn-atom]
(blur-show-fn))
(rf/dispatch [:open-modal :screen/onboarding.new-to-status]))
(defn view
[]
(let [[terms-accepted? set-terms-accepted?] (rn/use-state false)
has-profiles-and-unaccepted-terms? (rf/sub [:profile/has-profiles-and-unaccepted-terms?])]
(let [[terms-accepted? set-terms-accepted?] (rn/use-state false)]
[rn/view {:style style/page-container}
[background/view false]
[quo/bottom-actions
(cond->
{:container-style (style/bottom-actions-container (safe-area/get-bottom))
:actions :two-vertical-actions
:description :top
:description-top-text [terms terms-accepted? set-terms-accepted?]}
has-profiles-and-unaccepted-terms?
(assoc
:actions :one-action
:button-one-label (i18n/label :t/explore-the-new-status)
:button-one-props {:disabled? (not terms-accepted?)
:accessibility-label :explore-new-status
:on-press explore-new-status})
(not has-profiles-and-unaccepted-terms?)
(assoc
:actions :two-vertical-actions
:button-one-label (i18n/label :t/sync-or-recover-profile)
:button-one-props {:type :dark-grey
:disabled? (not terms-accepted?)
:accessibility-label :already-use-status-button
:on-press sync-or-recover-profile}
:button-two-label (i18n/label :t/create-profile)
:button-two-props {:accessibility-label :new-to-status-button
:disabled? (not terms-accepted?)
:on-press create-profile}))]
{:container-style (style/bottom-actions-container (safe-area/get-bottom))
:actions :two-vertical-actions
:description :top
:description-top-text [rn/view
{:style style/terms-privacy-container}
[rn/view
{:accessibility-label :terms-privacy-checkbox-container}
[quo/selectors
{:type :checkbox
:blur? true
:checked? terms-accepted?
:on-change #(set-terms-accepted? not)}]]
[rn/view {:style style/text-container}
[quo/text
{:style style/plain-text
:size :paragraph-2}
(str (i18n/label :t/accept-status-tos-prefix) " ")]
[quo/text
{:on-press #(rf/dispatch [:show-bottom-sheet
{:content terms/terms-of-use
:shell? true}])
:style style/highlighted-text
:size :paragraph-2
:weight :medium}
(i18n/label :t/terms-of-service)]
[quo/text
{:style style/plain-text
:size :paragraph-2}
" " (i18n/label :t/and) " "]
[quo/text
{:on-press #(rf/dispatch [:show-bottom-sheet
{:content privacy/privacy-statement
:shell? true}])
:style style/highlighted-text
:size :paragraph-2
:weight :medium}
(i18n/label :t/intro-privacy-policy)]]]
:button-one-label (i18n/label :t/sync-or-recover-profile)
:button-one-props {:type :dark-grey
:disabled? (not terms-accepted?)
:accessibility-label :already-use-status-button
:on-press (fn []
(when-let [blur-show-fn @overlay/blur-show-fn-atom]
(blur-show-fn))
(rf/dispatch
[:open-modal
:screen/onboarding.sync-or-recover-profile]))}
:button-two-label (i18n/label :t/create-profile)
:button-two-props {:accessibility-label :new-to-status-button
:disabled? (not terms-accepted?)
:on-press
(fn []
(when-let [blur-show-fn @overlay/blur-show-fn-atom]
(blur-show-fn))
(rf/dispatch
[:open-modal :screen/onboarding.new-to-status]))}}]
[overlay/view]]))
@@ -1,5 +0,0 @@
(ns status-im.contexts.profile.data-store)
(defn accepted-terms?
[accounts]
(some :hasAcceptedTerms accounts))
@@ -1,14 +0,0 @@
(ns status-im.contexts.profile.effects
(:require
[native-module.core :as native-module]
[promesa.core :as promesa]
[taoensso.timbre :as log]
[utils.re-frame :as rf]))
(rf/reg-fx :effects.profile/accept-terms
(fn [{:keys [on-success]}]
(-> (native-module/accept-terms)
(promesa/then (fn []
(rf/call-continuation on-success)))
(promesa/catch (fn [error]
(log/error "Failed to accept terms" {:error error}))))))
+20 -28
View File
@@ -4,12 +4,10 @@
[legacy.status-im.multiaccounts.update.core :as multiaccounts.update]
[native-module.core :as native-module]
[status-im.config :as config]
[status-im.contexts.profile.data-store :as profile.data-store]
[status-im.contexts.profile.edit.accent-colour.events]
[status-im.contexts.profile.edit.bio.events]
[status-im.contexts.profile.edit.header.events]
[status-im.contexts.profile.edit.name.events]
status-im.contexts.profile.effects
status-im.contexts.profile.login.events
[status-im.contexts.profile.rpc :as profile.rpc]
[utils.re-frame :as rf]))
@@ -44,27 +42,26 @@
(rf/reg-event-fx
:profile/get-profiles-overview-success
(fn [{:keys [db]} [{:keys [accounts] {:keys [userConfirmed enabled]} :centralizedMetricsInfo}]]
(let [db-with-settings (assoc db
:centralized-metrics/user-confirmed? userConfirmed
:centralized-metrics/enabled? enabled)
profiles (reduce-profiles accounts)
{:keys [key-uid]} (first (sort-by :timestamp > (vals profiles)))
new-db (cond-> db-with-settings
(seq profiles)
(assoc :profile/profiles-overview profiles)
key-uid
(update :profile/login #(select-profile % key-uid)))]
{:db new-db
:fx (if (profile.data-store/accepted-terms? accounts)
[[:dispatch [:update-theme-and-init-root :screen/profile.profiles]]
(when (and key-uid userConfirmed)
[:effects.biometric/check-if-available
{:key-uid key-uid
:on-success (fn [auth-method]
(rf/dispatch [:profile.login/check-biometric-success key-uid
auth-method]))}])]
[[:dispatch [:update-theme-and-init-root :screen/onboarding.intro]]])})))
(let [db-with-settings (assoc db
:centralized-metrics/user-confirmed? userConfirmed
:centralized-metrics/enabled? enabled)]
(if (seq accounts)
(let [profiles (reduce-profiles accounts)
{:keys [key-uid]} (first (sort-by :timestamp > (vals profiles)))]
{:db (if key-uid
(-> db-with-settings
(assoc :profile/profiles-overview profiles)
(update :profile/login #(select-profile % key-uid)))
db-with-settings)
:fx [[:dispatch [:update-theme-and-init-root :screen/profile.profiles]]
(when (and key-uid userConfirmed)
[:effects.biometric/check-if-available
{:key-uid key-uid
:on-success (fn [auth-method]
(rf/dispatch [:profile.login/check-biometric-success key-uid
auth-method]))}])]})
{:db db-with-settings
:fx [[:dispatch [:update-theme-and-init-root :screen/onboarding.intro]]]}))))
(rf/reg-event-fx
:profile/update-setting-from-backup
@@ -85,8 +82,3 @@
:messages-from-contacts-only
(not (get-in db [:profile/profile :messages-from-contacts-only]))
{})))
(rf/reg-event-fx :profile/explore-new-status
(fn []
{:fx [[:effects.profile/accept-terms
{:on-success [:navigate-to :screen/profile.profiles]}]]}))
@@ -10,17 +10,14 @@
[]
[rn/view {:style style/bridge-send-wrapper}
[input-amount/view
{:current-screen-id :screen/wallet.bridge-input-amount
:button-one-label (i18n/label :t/review-bridge)
:button-one-props {:icon-left :i/bridge}
:enabled-from-chain-ids (rf/sub
[:wallet/bridge-from-chain-ids])
:from-enabled-networks (rf/sub [:wallet/bridge-from-networks])
:on-confirm (fn [amount]
(rf/dispatch [:wallet/set-token-amount-to-bridge
{:amount amount
:stack-id :screen/wallet.bridge-input-amount}]))
:on-navigate-back (fn []
(rf/dispatch-sync [:wallet/stop-and-clean-suggested-routes])
(rf/dispatch [:wallet/clean-disabled-from-networks])
(rf/dispatch [:wallet/clean-send-amount]))}]])
{:current-screen-id :screen/wallet.bridge-input-amount
:button-one-label (i18n/label :t/review-bridge)
:button-one-props {:icon-left :i/bridge}
:on-confirm (fn [amount]
(rf/dispatch [:wallet/set-token-amount-to-bridge
{:amount amount
:stack-id :screen/wallet.bridge-input-amount}]))
:on-navigate-back (fn []
(rf/dispatch-sync [:wallet/stop-and-clean-suggested-routes])
(rf/dispatch [:wallet/clean-disabled-from-networks])
(rf/dispatch [:wallet/clean-send-amount]))}]])
@@ -43,18 +43,10 @@
(defn flush-collectibles
[{:keys [db]}]
(let [collectibles-per-account (get-in db [:wallet :ui :collectibles :fetched])
updated-accounts (move-collectibles-to-accounts (get-in db [:wallet :accounts])
collectibles-per-account)
has-collectibles? (some (fn [account]
(pos? (count (:collectibles account))))
(vals updated-accounts))]
(let [collectibles-per-account (get-in db [:wallet :ui :collectibles :fetched])]
{:db (-> db
(update-in [:wallet :ui :collectibles] dissoc :pending-requests :fetched)
(assoc-in [:wallet :accounts] updated-accounts))
:fx [[:dispatch
[:centralized-metrics/track :metric/wallet-collectibles-fetched
{:has-collectibles? has-collectibles?}]]]}))
(update-in [:wallet :accounts] move-collectibles-to-accounts collectibles-per-account))}))
(rf/reg-event-fx :wallet/flush-collectibles-fetched flush-collectibles)
@@ -77,13 +77,12 @@
(defn token-value-drawer
[token watch-only? entry-point]
(let [token-symbol (:token token)
token-data (rf/sub [:wallet/token-by-symbol token-symbol])
token-data (first (rf/sub [:wallet/current-viewing-account-tokens-filtered
{:query token-symbol}]))
selected-account (rf/sub [:wallet/current-viewing-account-address])
token-owners (rf/sub [:wallet/operable-addresses-with-token-symbol token-symbol])
testnet-mode? (rf/sub [:profile/test-networks-enabled?])
account-owns-token? (rf/sub [:wallet/current-account-owns-token token-symbol])
receive-token-symbol (if (= token-symbol "SNT") "ETH" "SNT")
token-owned? (if selected-account account-owns-token? (seq token-owners))
asset-to-receive (rf/sub [:wallet/token-by-symbol receive-token-symbol])
params (cond-> {:start-flow? true
:owners token-owners
@@ -104,12 +103,11 @@
(action-hide))]
(not watch-only?)
(concat [(action-buy)
(when token-owned?
(when (seq token-owners)
(action-send params entry-point))
(action-receive selected-account)
(when token-owned?
(action-swap params))
(when token-owned?
(action-swap params)
(when (seq token-owners)
(action-bridge (assoc params
:bridge-disabled?
(send-utils/bridge-disabled? token-symbol))))]))]]))
@@ -27,12 +27,18 @@
[balance]
(cut-fiat-balance balance 2))
(defn prettify-balance
[currency-symbol balance]
(defn prepend-curency-symbol-to-fiat-balance
[fiat-balance currency-symbol]
(let [formatted-symbol (if (> (count currency-symbol) 1)
(str currency-symbol " ")
currency-symbol)]
(str formatted-symbol (cut-fiat-balance-to-two-decimals balance))))
(str formatted-symbol fiat-balance)))
(defn prettify-balance
[currency-symbol fiat-balance]
(-> fiat-balance
cut-fiat-balance-to-two-decimals
(prepend-curency-symbol-to-fiat-balance currency-symbol)))
(defn get-derivation-path
[number-of-accounts]
@@ -104,11 +110,15 @@
:else (number/remove-trailing-zeroes
(.toFixed token-units standardized-decimals-count)))))
(defn add-token-symbol-to-crypto-balance
[crypto-balance token-symbol]
(str crypto-balance " " (string/upper-case token-symbol)))
(defn prettify-crypto-balance
[token-symbol crypto-balance conversion-rate]
(str (cut-crypto-decimals-to-fit-usd-cents crypto-balance conversion-rate)
" "
(string/upper-case token-symbol)))
(-> crypto-balance
(cut-crypto-decimals-to-fit-usd-cents conversion-rate)
(add-token-symbol-to-crypto-balance token-symbol)))
(defn get-standard-crypto-format
"For full details: https://github.com/status-im/status-mobile/issues/18225"
@@ -495,7 +505,9 @@
:TokenIDTo token-id-to
:SlippagePercentage slippage-percentage))
(= bridge-name constants/bridge-name-celer)
(not (or (= bridge-name constants/bridge-name-erc-721-transfer)
(= bridge-name constants/bridge-name-transfer)
(= bridge-name constants/bridge-name-hop)))
(assoc :CbridgeTx
(assoc tx-data
:ChainID to-chain-id
@@ -1,10 +1,8 @@
(ns status-im.contexts.wallet.common.utils.networks
(:require
[clojure.string :as string]
[quo.foundations.resources :as resources]
[status-im.constants :as constants]
[utils.money :as money]
[utils.number]))
(:require [clojure.string :as string]
[quo.foundations.resources :as resources]
[status-im.constants :as constants]
[utils.number]))
(def ^:private last-comma-followed-by-text-to-end-regex #",\s(?=[^,]+$)")
@@ -65,21 +63,12 @@
(defn network-list
[{:keys [balances-per-chain]} networks]
(->> balances-per-chain
keys
(map (fn [chain-id]
(first (filter #(or (= (:chain-id %) chain-id)
(= (:related-chain-id %) chain-id))
networks))))
set))
(defn network-list-with-positive-balance
"Same as `network-list`, but only returns the networks that have a positive token balance"
[{:keys [balances-per-chain] :as token} networks]
(as-> balances-per-chain $
(filter #(-> % second :raw-balance (money/greater-than 0)) $)
(assoc token :balances-per-chain $)
(network-list $ networks)))
(into #{}
(mapv (fn [chain-id]
(first (filter #(or (= (:chain-id %) chain-id)
(= (:related-chain-id %) chain-id))
networks)))
(keys balances-per-chain))))
(defn get-default-chain-ids-by-mode
[{:keys [test-networks-enabled? is-goerli-enabled?]}]
+1 -2
View File
@@ -10,5 +10,4 @@
;; Note: we set it to nil by default to differentiate when the user logs
;; in and the device is offline, versus re-fetching when offline and
;; tokens already exist in the app-db.
:tokens-loading nil
:active-tab :assets}})
:tokens-loading nil}})
@@ -59,10 +59,6 @@
(fn [{:keys [db]} [tab]]
{:db (assoc-in db [:wallet :ui :account-page :active-tab] tab)}))
(rf/reg-event-fx :wallet/select-home-tab
(fn [{:keys [db]} [tab]]
{:db (assoc-in db [:wallet :ui :active-tab] tab)}))
(rf/reg-event-fx :wallet/clear-account-tab
(fn [{:keys [db]}]
{:db (assoc-in db [:wallet :ui :account-page :active-tab] nil)}))
+10 -12
View File
@@ -41,8 +41,6 @@
(when (ff/enabled? ::ff/wallet.home-activity)
{:id :activity :label (i18n/label :t/activity) :accessibility-label :activity-tab})])
(defn- change-tab [id] (rf/dispatch [:wallet/select-home-tab id]))
(defn- render-cards
[cards ref]
[rn/flat-list
@@ -66,15 +64,15 @@
(defn view
[]
(let [selected-tab (rf/sub [:wallet/home-tab])
account-list-ref (rn/use-ref-atom nil)
tokens-loading? (rf/sub [:wallet/home-tokens-loading?])
networks (rf/sub [:wallet/selected-network-details])
account-cards-data (rf/sub [:wallet/account-cards-data])
cards (conj account-cards-data (new-account-card-data))
[init-loaded? set-init-loaded] (rn/use-state false)
{:keys [formatted-balance]} (rf/sub [:wallet/aggregated-token-values-and-balance])
theme (quo.theme/use-theme)]
(let [[selected-tab set-selected-tab] (rn/use-state (:id (first tabs-data)))
account-list-ref (rn/use-ref-atom nil)
tokens-loading? (rf/sub [:wallet/home-tokens-loading?])
networks (rf/sub [:wallet/selected-network-details])
account-cards-data (rf/sub [:wallet/account-cards-data])
cards (conj account-cards-data (new-account-card-data))
[init-loaded? set-init-loaded] (rn/use-state false)
{:keys [formatted-balance]} (rf/sub [:wallet/aggregated-token-values-and-balance])
theme (quo.theme/use-theme)]
(rn/use-effect (fn []
(when (and @account-list-ref (pos? (count cards)))
(.scrollToOffset ^js @account-list-ref
@@ -106,7 +104,7 @@
(when (ff/enabled? ::ff/wallet.graph)
[quo/wallet-graph {:time-frame :empty}])
[render-cards cards account-list-ref]
[render-tabs tabs-data change-tab selected-tab]]
[render-tabs tabs-data set-selected-tab selected-tab]]
:content-container-style style/list-container
:sticky-header-indices [0]
:data []
@@ -104,7 +104,7 @@
:wallet/wallet-send-tx-type :tx/send
:wallet/wallet-send-fee-fiat-formatted "$5,00"
:wallet/sending-collectible? false
:wallet/total-amount (money/bignumber "250")})
:wallet/total-amount-in-to-chains (money/bignumber "250")})
(h/describe "Send > input amount screen"
(h/setup-restorable-re-frame)
@@ -0,0 +1,74 @@
(ns status-im.contexts.wallet.send.input-amount.controlled-input-logic
(:require
[clojure.string :as string]
[status-im.contexts.wallet.common.utils :as wallet-utils]
[utils.money :as money]))
(def ^:private default-max-limit 12)
(def ^:private not-digits-or-dot-pattern
#"[^0-9+\.]")
(def ^:private dot ".")
(defn- can-add-character?
[input-value character max-length]
(let [length-overflow? (>= (count input-value) max-length)
extra-dot? (and (= character dot) (string/includes? input-value dot))
extra-leading-zero? (and (= input-value "0") (= "0" (str character)))
non-numeric? (re-find not-digits-or-dot-pattern (str character))]
(not (or non-numeric? extra-dot? extra-leading-zero? length-overflow?))))
(defn- normalize-value-as-numeric
[value character]
(cond
(and (string/blank? value) (= character dot))
(str "0" character)
(and (= value "0") (not= character dot))
(str character)
:else
(str value character)))
(defn add-character
([input-value character]
(add-character input-value character default-max-limit))
([input-value character max-length]
(if (can-add-character? input-value character max-length)
(normalize-value-as-numeric input-value character)
input-value)))
(defn delete-last
([input-value]
(delete-last input-value ""))
([input-value default-value]
(let [new-value (subs input-value 0 (dec (count input-value)))]
(if (string/blank? new-value)
default-value
new-value))))
(defn upper-limit-exceeded?
[input-value upper-limit]
(and upper-limit
(when (money/bignumber? (money/bignumber input-value))
(money/greater-than (money/bignumber input-value) (money/bignumber upper-limit)))))
(defn lower-limit-exceeded?
[input-value lower-limit]
(and lower-limit
(when (money/bignumber? (money/bignumber input-value))
(money/less-than (money/bignumber input-value) (money/bignumber lower-limit)))))
(defn value-out-of-limits?
[input-value upper-limit lower-limit]
(or (upper-limit-exceeded? input-value upper-limit)
(lower-limit-exceeded? input-value lower-limit)))
(defn value-numeric
[input-value]
(or (parse-double input-value) 0))
(defn empty-value?
[input-value]
(or (string/blank? input-value) (<= (value-numeric input-value) 0)))
@@ -0,0 +1,497 @@
(ns status-im.contexts.wallet.send.input-amount.controller
(:require
[clojure.string :as string]
[status-im.constants :as constants]
[status-im.contexts.wallet.common.utils :as utils]
[status-im.contexts.wallet.send.input-amount.controlled-input-logic :as controlled-input-logic]
[utils.money :as money]
[utils.number :as number]
[utils.re-frame :as rf]))
;; notes
;; token-by-symbol and token looks very similar but they have difference in market values data
;; inside token structure :total-balance and :available-balance are same, not sure if they have
;; different
;; meaning
;; subs
(rf/reg-sub :layers/ui
:<- [:layers]
:-> :ui)
(rf/reg-sub :ui/send
:<- [:layers/ui]
:-> :send)
(rf/reg-sub :ui/send-input-amount-screen
:<- [:ui/send]
:-> :input-amount-screen)
(rf/reg-sub :send-input-amount-screen/controller
:<- [:ui/send-input-amount-screen]
:-> :controller)
(rf/reg-sub :send-input-amount-screen/currency-information
:<- [:wallet/wallet-send-token]
:<- [:profile/currency]
:<- [:profile/currency-symbol]
:<- [:profile/profile]
(fn [[{token-symbol :symbol
:as
token}
currency
currency-symbol
{fiat-currency :currency}]]
{:usd-conversion-rate (utils/token-usd-price token)
:currency currency
:fiat-currency fiat-currency
:currency-symbol currency-symbol
:token-symbol token-symbol
:conversion-rate (-> token
:market-values-per-currency
currency
:price)
:token-decimals (-> token
utils/token-usd-price
utils/one-cent-value
utils/calc-max-crypto-decimals)
:token token}))
(rf/reg-sub :send-input-amount-screen/max-decimals
:<- [:send-input-amount-screen/controller]
:<- [:send-input-amount-screen/currency-information]
:<- [:wallet/wallet-send-receiver-preferred-networks]
(fn [[{:keys [crypto-currency?]}
{:keys [token-decimals]}]]
(if crypto-currency? token-decimals 2)))
(rf/reg-sub :send-input-amount-screen/enabled-from-chain-ids
:<- [:wallet/wallet-send-tx-type]
:<- [:wallet/wallet-send-enabled-from-chain-ids]
:<- [:wallet/bridge-from-chain-ids]
(fn [[tx-type send-chain-ids bridge-chain-ids]]
(if (= tx-type :tx/bridge)
bridge-chain-ids
send-chain-ids)))
(rf/reg-sub :send-input-amount-screen/from-enabled-networks
:<- [:wallet/wallet-send-tx-type]
:<- [:wallet/wallet-send-enabled-networks]
:<- [:wallet/bridge-from-networks]
(fn [[tx-type send-enabled-networks bridge-enabled-networks]]
(if (= tx-type :tx/bridge)
bridge-enabled-networks
send-enabled-networks)))
(defn- every-network-value-is-zero?
[sender-network-values]
(every? (fn [{:keys [total-amount]}]
(and
total-amount
(money/bignumber? total-amount)
(money/equal-to total-amount
(money/bignumber "0"))))
sender-network-values))
(rf/reg-sub :send-input-amount-screen/routes-information
:<- [:wallet/wallet-send-route]
:<- [:wallet/wallet-send-sender-network-values]
:<- [:wallet/wallet-send-receiver-network-values]
:<- [:wallet/wallet-send-suggested-routes]
:<- [:wallet/wallet-send-loading-suggested-routes?]
:<- [:wallet/wallet-send-tx-type]
(fn [[route
sender-network-values
receiver-network-values
suggested-routes
loading-routes?
tx-type]]
(let [token-not-supported-in-receiver-networks? (and (not= tx-type :tx/bridge)
(->> receiver-network-values
(remove #(= (:type %) :add))
(every? #(= (:type %) :not-available))))
routes (when suggested-routes
(or (:best suggested-routes) []))]
{:route route
:sender-network-values sender-network-values
:receiver-network-values receiver-network-values
:suggested-routes suggested-routes
:loading-routes? loading-routes?
:routes routes
:token-not-supported-in-receiver-networks? token-not-supported-in-receiver-networks?
:no-routes-found? (and
(every-network-value-is-zero?
sender-network-values)
(not (nil? routes))
(not loading-routes?)
(not token-not-supported-in-receiver-networks?))})))
(rf/reg-sub :send-input-amount-screen/networks-information
:<- [:wallet/wallet-send-token]
:<- [:wallet/wallet-send-receiver-networks]
:<- [:wallet/wallet-send-receiver-preferred-networks]
(fn [[{token-networks :networks}
receiver-networks
receiver-preferred-networks]]
{:token-networks token-networks
:receiver-networks receiver-networks
:sending-to-unpreferred-networks? (not (every? (fn [receiver-selected-network]
(contains?
(set receiver-preferred-networks)
receiver-selected-network))
receiver-networks))}))
(rf/reg-sub :send-input-amount-screen/token-by-symbol
:<- [:send-input-amount-screen/enabled-from-chain-ids]
:<- [:send-input-amount-screen/currency-information]
(fn [[enabled-from-chain-ids {:keys [token-symbol]}]]
(rf/sub [:wallet/token-by-symbol
(str token-symbol)
enabled-from-chain-ids])))
(rf/reg-sub :send-input-amount-screen/total-balance
:<- [:send-input-amount-screen/token-by-symbol]
(fn [{:keys [total-balance]}]
total-balance))
(rf/reg-sub :send-input-amount-screen/upper-limit
:<- [:send-input-amount-screen/controller]
:<- [:send-input-amount-screen/currency-information]
:<- [:send-input-amount-screen/total-balance]
(fn [[{:keys [crypto-currency?]}
{:keys [usd-conversion-rate conversion-rate]}
total-balance]]
(if crypto-currency?
(utils/cut-crypto-decimals-to-fit-usd-cents
total-balance
usd-conversion-rate)
(-> (money/crypto->fiat
total-balance
conversion-rate)
utils/cut-fiat-balance-to-two-decimals))))
(rf/reg-sub
:send-input-amount-screen/amount-in-crypto
:<- [:send-input-amount-screen/controller]
:<- [:send-input-amount-screen/currency-information]
(fn [[{:keys [crypto-currency? token-input-value]}
{:keys [conversion-rate token-decimals]}]]
(if crypto-currency?
token-input-value
(number/remove-trailing-zeroes
(.toFixed (/ token-input-value conversion-rate)
token-decimals)))))
(defn- fiat->crypto
[value conversion-rate]
(-> value
(money/fiat->crypto conversion-rate)
(utils/cut-crypto-decimals-to-fit-usd-cents conversion-rate)))
(defn- crypto->fiat
[value conversion-rate]
(-> value
(money/crypto->fiat conversion-rate)
(utils/cut-fiat-balance-to-two-decimals)))
(rf/reg-sub :send-input-amount-screen/token-input-converted-value
:<- [:send-input-amount-screen/controller]
:<- [:send-input-amount-screen/currency-information]
(fn [[{:keys [crypto-currency? token-input-value]}
{:keys [conversion-rate]}]]
(if crypto-currency?
(crypto->fiat token-input-value conversion-rate)
(fiat->crypto token-input-value conversion-rate))))
(rf/reg-sub :send-input-amount-screen/token-input-converted-value-prettified
:<- [:send-input-amount-screen/controller]
:<- [:send-input-amount-screen/token-input-converted-value]
:<- [:send-input-amount-screen/currency-information]
(fn [[{:keys [crypto-currency?]}
token-input-converted-value
{:keys [currency-symbol token-symbol]}]]
(if crypto-currency?
(utils/prepend-curency-symbol-to-fiat-balance token-input-converted-value currency-symbol)
(utils/add-token-symbol-to-crypto-balance token-input-converted-value
(or (clj->js token-symbol) "")))))
(rf/reg-sub :send-input-amount-screen/upper-limit-prettified
:<- [:send-input-amount-screen/controller]
:<- [:send-input-amount-screen/currency-information]
:<- [:send-input-amount-screen/upper-limit]
(fn [[{:keys [crypto-currency?]}
{:keys [currency-symbol token-symbol conversion-rate]}
upper-limit]]
(if crypto-currency?
(utils/prettify-crypto-balance
(or (clj->js token-symbol) "")
(money/bignumber upper-limit)
conversion-rate)
(utils/prettify-balance currency-symbol
(money/bignumber upper-limit)))
))
(rf/reg-sub :send-input-amount-screen/value-out-of-limits?
:<- [:send-input-amount-screen/controller]
:<- [:send-input-amount-screen/upper-limit]
(fn [[{:keys [token-input-value]}
upper-limit]]
(controlled-input-logic/value-out-of-limits? token-input-value upper-limit 0)))
(rf/reg-sub :send-input-amount-screen/recipient-gets-amount
:<- [:send-input-amount-screen/currency-information]
:<- [:wallet/total-amount-in-to-chains]
(fn [[{:keys [conversion-rate token-symbol]}
total-amount-receiver]]
(utils/prettify-crypto-balance
token-symbol
total-amount-receiver
conversion-rate)))
(rf/reg-sub :send-input-amount-screen/owned-eth-balance-is-zero?
:<- [:send-input-amount-screen/enabled-from-chain-ids]
(fn [enabled-from-chain-ids]
(let [owned-eth-token (rf/sub [:wallet/token-by-symbol
(string/upper-case
constants/mainnet-short-name)
enabled-from-chain-ids])]
(money/equal-to (:total-balance owned-eth-token) 0))))
(rf/reg-sub :send-input-amount-screen/fee-formatted
:<- [:send-input-amount-screen/routes-information]
(fn [{:keys [route]}]
(let [native-currency-symbol (when-not (or (nil? route) (empty? route))
(get-in (first route)
[:from :native-currency-symbol]))]
(rf/sub [:wallet/wallet-send-fee-fiat-formatted native-currency-symbol]))))
(rf/reg-sub :send-input-amount-screen/upper-limit-exceeded?
:<- [:send-input-amount-screen/controller]
:<- [:send-input-amount-screen/upper-limit]
(fn [[{:keys [token-input-value]}
upper-limit]]
(controlled-input-logic/upper-limit-exceeded?
token-input-value
upper-limit)))
(rf/reg-sub :send-input-amount-screen/upper-limit-equals-input-value?
:<- [:send-input-amount-screen/controller]
:<- [:send-input-amount-screen/upper-limit]
(fn [[{:keys [token-input-value]}
upper-limit]]
(money/equal-to
(money/bignumber token-input-value)
(money/bignumber upper-limit))))
(rf/reg-sub :send-input-amount-screen/should-try-again?
:<- [:send-input-amount-screen/upper-limit-exceeded?]
:<- [:send-input-amount-screen/routes-information]
(fn [[upper-limit-exceeded?
{:keys [no-routes-found?]}]]
(and (not upper-limit-exceeded?) no-routes-found?)))
(rf/reg-sub :send-input-amount-screen/not-enough-asset?
:<- [:send-input-amount-screen/upper-limit-exceeded?]
:<- [:send-input-amount-screen/upper-limit-equals-input-value?]
:<- [:send-input-amount-screen/routes-information]
:<- [:send-input-amount-screen/currency-information]
:<- [:send-input-amount-screen/owned-eth-balance-is-zero?]
(fn [[upper-limit-exceeded?
upper-limit-equals-input-value?
{:keys [sender-network-values no-routes-found?]}
{:keys [token-symbol]}
owned-eth-balance-is-zero?]]
(and
(or no-routes-found? upper-limit-exceeded?)
(not-empty sender-network-values)
(if (= token-symbol
(string/upper-case
constants/mainnet-short-name))
upper-limit-equals-input-value?
owned-eth-balance-is-zero?))))
(rf/reg-sub :send-input-amount-screen/show-no-routes?
:<- [:send-input-amount-screen/upper-limit-exceeded?]
:<- [:send-input-amount-screen/routes-information]
:<- [:send-input-amount-screen/not-enough-asset?]
(fn [[upper-limit-exceeded?
{:keys [sender-network-values no-routes-found?]}
not-enough-asset?]]
(and
(or no-routes-found? upper-limit-exceeded?)
(not-empty sender-network-values)
(not not-enough-asset?))))
(comment
(rf/sub [:send-input-amount-screen/not-enough-asset?])
(rf/sub [:send-input-amount-screen/upper-limit-equals-input-value?])
(:no-routes-found? (rf/sub [:send-input-amount-screen/routes-information]))
(:sender-network-values (rf/sub [:send-input-amount-screen/currency-information]))
(rf/sub [:send-input-amount-screen/not-enough-asset?]))
(rf/reg-sub :send-input-amount-screen/view-subs
:<- [:send-input-amount-screen/currency-information]
:<- [:send-input-amount-screen/value-out-of-limits?]
:<- [:send-input-amount-screen/routes-information]
:<- [:send-input-amount-screen/networks-information]
:<- [:send-input-amount-screen/recipient-gets-amount]
:<- [:send-input-amount-screen/max-decimals]
:<- [:send-input-amount-screen/fee-formatted]
:<- [:wallet/current-viewing-account-address]
:<- [:send-input-amount-screen/not-enough-asset?]
:<- [:send-input-amount-screen/show-no-routes?]
(fn
[[{:keys [token-symbol] :as currency-information}
value-out-of-limits?
{:keys [route
sender-network-values
loading-routes?
token-not-supported-in-receiver-networks?
no-routes-found?]
:as routes-information}
{:keys [token-networks
receiver-networks]}
recipient-gets-amount
max-decimals
fee-formatted
current-address
not-enough-asset?
show-no-routes?]]
{:token-symbol token-symbol
:value-out-of-limits? value-out-of-limits?
:route route
:sender-network-values sender-network-values
:loading-routes? loading-routes?
:token-not-supported-in-receiver-networks? token-not-supported-in-receiver-networks?
:token-networks token-networks
:receiver-networks receiver-networks
:recipient-gets-amount recipient-gets-amount
:max-decimals max-decimals
:fee-formatted fee-formatted
:no-routes-found? no-routes-found?
:current-address current-address
:not-enough-asset? not-enough-asset?
:show-no-routes? show-no-routes?}))
(rf/reg-sub :send-input-amount-screen/token-input-subs
:<- [:send-input-amount-screen/controller]
:<- [:send-input-amount-screen/currency-information]
:<- [:send-input-amount-screen/token-input-converted-value]
:<- [:send-input-amount-screen/token-input-converted-value-prettified]
:<- [:send-input-amount-screen/value-out-of-limits?]
:<- [:send-input-amount-screen/upper-limit-prettified]
:<- [:send-input-amount-screen/from-enabled-networks]
(fn
[[{:keys [crypto-currency? token-input-value] :as controller}
{:keys [fiat-currency token-symbol] :as currency-information}
token-input-converted-value
token-input-converted-value-prettified
value-out-of-limits?
upper-limit-prettified
from-enabled-networks]]
{:crypto-currency? crypto-currency?
:fiat-currency fiat-currency
:token-symbol token-symbol
:upper-limit-prettified upper-limit-prettified
:input-value token-input-value
:value-out-of-limits? value-out-of-limits?
:token-input-converted-value token-input-converted-value
:token-input-converted-value-prettified token-input-converted-value-prettified
:from-enabled-networks from-enabled-networks}))
(rf/reg-sub :send-input-amount-screen/routes-subs
:<- [:send-input-amount-screen/controller]
:<- [:send-input-amount-screen/currency-information]
:<- [:send-input-amount-screen/amount-in-crypto]
:<- [:send-input-amount-screen/value-out-of-limits?]
:<- [:send-input-amount-screen/routes-information]
:<- [:send-input-amount-screen/token-by-symbol]
:<- [:send-input-amount-screen/upper-limit-exceeded?]
(fn
[[{:keys [token-input-value] :as controller}
{:keys [token] :as currency-information}
amount-in-crypto
value-out-of-limits?
{:keys [routes
token-not-supported-in-receiver-networks?]
:as routes-information}
token-by-symbol
upper-limit-exceeded?]]
{:token token
:valid-input? (not (or (controlled-input-logic/empty-value?
token-input-value)
value-out-of-limits?))
:upper-limit-exceeded? upper-limit-exceeded?
:amount-in-crypto amount-in-crypto
:routes routes
:token-not-supported-in-receiver-networks? token-not-supported-in-receiver-networks?
:token-by-symbol token-by-symbol}))
(rf/reg-sub :send-input-amount-screen/bottom-actions-subs
:<- [:send-input-amount-screen/controller]
:<- [:send-input-amount-screen/amount-in-crypto]
:<- [:send-input-amount-screen/value-out-of-limits?]
:<- [:send-input-amount-screen/routes-information]
:<- [:send-input-amount-screen/networks-information]
:<- [:send-input-amount-screen/token-by-symbol]
:<- [:send-input-amount-screen/should-try-again?]
(fn
[[{:keys [token-input-value] :as controller}
amount-in-crypto
value-out-of-limits?
{:keys [route loading-routes?]
:as routes-information}
{:keys [sending-to-unpreferred-networks?]}
token-by-symbol
should-try-again?]]
{:valid-input? (not (or (controlled-input-logic/empty-value?
token-input-value)
value-out-of-limits?))
:amount-in-crypto amount-in-crypto
:route route
:loading-routes? loading-routes?
:token-by-symbol token-by-symbol
:sending-to-unpreferred-networks? sending-to-unpreferred-networks?
:should-try-again? should-try-again?}))
;; events
(def token-input-value-path [:layers :ui :send :input-amount-screen :controller :token-input-value])
(rf/reg-event-fx :send-input-amount-screen/set-input-state
(fn [{:keys [db]} [f]]
{:db (update-in db [:layers :ui :send :input-amount-screen :controller :input-state] f)}))
(rf/reg-event-fx :send-input-amount-screen/set-token-input-value
(fn [{:keys [db]} [v]]
{:db (assoc-in db token-input-value-path v)}))
(rf/reg-event-fx :send-input-amount-screen/swap-between-fiat-and-crypto
(fn [{:keys [db]} [token-input-converted-value]]
{:db (update-in db [:layers :ui :send :input-amount-screen :controller :crypto-currency?] not)
:fx [[:dispatch
[:send-input-amount-screen/set-token-input-value token-input-converted-value]]]}))
(rf/reg-event-fx :send-input-amount-screen/token-input-add-character
(fn [{:keys [db]} [c max-decimals]]
(let [input-value (get-in db token-input-value-path)
new-text (str input-value c)
regex-pattern (str "^\\d*\\.?\\d{0," max-decimals "}$")
regex (re-pattern regex-pattern)]
(when (re-matches regex new-text)
{:db (update-in db token-input-value-path #(controlled-input-logic/add-character % c))}))))
(rf/reg-event-fx :send-input-amount-screen/token-input-delete-last
(fn [{:keys [db]}]
{:db (update-in db token-input-value-path controlled-input-logic/delete-last)}))
(rf/reg-event-fx :send-input-amount-screen/token-input-delete-all
(fn [{:keys [db]}]
{:db (assoc-in db token-input-value-path "")}))
@@ -1,16 +1,13 @@
(ns status-im.contexts.wallet.send.input-amount.view
(:require
[clojure.string :as string]
[quo.core :as quo]
[quo.foundations.colors :as colors]
[quo.theme]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
[status-im.common.controlled-input.utils :as controlled-input]
[status-im.constants :as constants]
[status-im.contexts.wallet.common.account-switcher.view :as account-switcher]
[status-im.contexts.wallet.common.asset-list.view :as asset-list]
[status-im.contexts.wallet.common.utils :as utils]
[status-im.contexts.wallet.send.input-amount.controller]
[status-im.contexts.wallet.send.input-amount.style :as style]
[status-im.contexts.wallet.send.routes.view :as routes]
[status-im.contexts.wallet.sheets.buy-token.view :as buy-token]
@@ -19,12 +16,10 @@
[status-im.setup.hot-reload :as hot-reload]
[utils.debounce :as debounce]
[utils.i18n :as i18n]
[utils.money :as money]
[utils.number :as number]
[utils.re-frame :as rf]))
(defn- estimated-fees
[{:keys [loading-routes? fees amount]}]
[{:keys [loading-routes? fees recipient-gets-amount]}]
[rn/view {:style style/estimated-fees-container}
(when (ff/enabled? ::ff/wallet.advanced-sending)
[rn/view {:style style/estimated-fees-content-container}
@@ -48,20 +43,12 @@
:status (if loading-routes? :loading :default)
:size :small
:title (i18n/label :t/recipient-gets)
:subtitle amount}]])
:subtitle recipient-gets-amount}]])
(defn- every-network-value-is-zero?
[sender-network-values]
(every? (fn [{:keys [total-amount]}]
(and
total-amount
(money/bignumber? total-amount)
(money/equal-to total-amount
(money/bignumber "0"))))
sender-network-values))
(defn select-asset-bottom-sheet
[clear-input!]
[]
(let [{preselected-token-symbol :symbol} (rf/sub [:wallet/wallet-send-token])]
[:<> ;; Need to be a `:<>` to keep `asset-list` scrollable.
[quo/drawer-top
@@ -73,7 +60,8 @@
:preselected-token-symbol preselected-token-symbol
:on-token-press (fn [token]
(rf/dispatch [:wallet/edit-token-to-send token])
(clear-input!))}]]))
#(rf/dispatch
[:send-input-amount-screen/token-input-delete-all]))}]]))
(defn- token-not-available
[token-symbol receiver-networks token-networks]
@@ -140,163 +128,122 @@
:else (rf/dispatch [:wallet/stop-and-clean-suggested-routes])))
(defn- get-fee-formatted
[route]
(when-let [native-currency-symbol (-> route first :from :native-currency-symbol)]
(rf/sub [:wallet/wallet-send-fee-fiat-formatted native-currency-symbol])))
(defn token-input
[]
(let [{:keys [crypto-currency?
upper-limit-prettified
input-value
value-out-of-limits?
token-input-converted-value
token-input-converted-value-prettified
fiat-currency
token-symbol
from-enabled-networks]} (rf/sub [:send-input-amount-screen/token-input-subs])
show-select-asset-sheet #(rf/dispatch
[:show-bottom-sheet
{:content (fn [] [select-asset-bottom-sheet])}])]
[quo/token-input
{:container-style style/input-container
:token-symbol token-symbol
:value input-value
:on-swap #(rf/dispatch [:send-input-amount-screen/swap-between-fiat-and-crypto
token-input-converted-value])
:on-token-press show-select-asset-sheet
:error? value-out-of-limits?
:currency-symbol (if crypto-currency? token-symbol fiat-currency)
:converted-value token-input-converted-value-prettified
:hint-component [quo/network-tags
{:networks (seq from-enabled-networks)
:title (i18n/label
:t/send-limit
{:limit upper-limit-prettified})
:status (when value-out-of-limits? :error)}]}]))
(defn routes-view
[current-screen-id]
(let [{:keys [valid-input?
upper-limit-exceeded?
amount-in-crypto
routes
token-not-supported-in-receiver-networks?
token
token-by-symbol]} (rf/sub [:send-input-amount-screen/routes-subs])
request-fetch-routes (fn [bounce-duration-ms]
(fetch-routes
{:amount amount-in-crypto
:valid-input? valid-input?
:bounce-duration-ms bounce-duration-ms
:token token
:reset-amounts-to-zero? (and upper-limit-exceeded?
(some? routes))}))]
[routes/view
{:token token-by-symbol
:send-amount-in-crypto amount-in-crypto
:valid-input? valid-input?
:token-not-supported-in-receiver-networks? token-not-supported-in-receiver-networks?
:current-screen-id current-screen-id
:request-fetch-routes request-fetch-routes}]))
(defn- insufficient-asset-amount?
[{:keys [token-symbol owned-eth-token input-state no-routes-found? limit-exceeded?
sender-network-values enough-assets?]}]
(let [eth-selected? (= token-symbol (string/upper-case constants/mainnet-short-name))
zero-owned-eth? (money/equal-to (:total-balance owned-eth-token) 0)
input-at-max-owned-amount? (money/equal-to
(controlled-input/value-bn input-state)
(controlled-input/upper-limit-bn input-state))
exceeded-input? (if eth-selected?
input-at-max-owned-amount?
zero-owned-eth?)]
(and (or no-routes-found? limit-exceeded?)
(seq sender-network-values)
(or exceeded-input? (not enough-assets?)))))
(defn bottom-actions
[on-confirm button-one-label button-one-props]
(let [{:keys [valid-input?
amount-in-crypto
route
loading-routes?
token-by-symbol
sending-to-unpreferred-networks?
should-try-again?]} (rf/sub [:send-input-amount-screen/bottom-actions-subs])]
[quo/bottom-actions
{:actions :one-action
:button-one-label (if should-try-again?
(i18n/label :t/try-again)
button-one-label)
:button-one-props (merge (when-not should-try-again? button-one-props)
{:disabled? (or loading-routes?
(and (not should-try-again?)
(or (nil? route)
(empty? route)
(not valid-input?))))
:on-press (cond
should-try-again?
#(rf/dispatch [:wallet/start-get-suggested-routes
{:amount amount-in-crypto
:updated-token token-by-symbol}])
sending-to-unpreferred-networks?
#(show-unpreferred-networks-alert on-confirm)
:else
#(on-confirm amount-in-crypto))}
(when should-try-again?
{:type :grey}))}])
)
(defn view
;; crypto-decimals, limit-crypto and initial-crypto-currency? args are needed
;; for component tests only
[{default-on-confirm :on-confirm
default-limit-crypto :limit-crypto
default-crypto-decimals :crypto-decimals
on-navigate-back :on-navigate-back
button-one-label :button-one-label
button-one-props :button-one-props
current-screen-id :current-screen-id
initial-crypto-currency? :initial-crypto-currency?
enabled-from-chain-ids :enabled-from-chain-ids
from-enabled-networks :from-enabled-networks
:or {initial-crypto-currency? true}}]
(let [view-id (rf/sub [:view-id])
active-screen? (= view-id current-screen-id)
bottom (safe-area/get-bottom)
[crypto-currency?
set-crypto-currency] (rn/use-state initial-crypto-currency?)
handle-on-confirm (fn [amount]
(rf/dispatch [:wallet/set-token-amount-to-send
{:amount amount
:stack-id current-screen-id}]))
{fiat-currency :currency} (rf/sub [:profile/profile])
{token-symbol :symbol
token-networks :networks
:as token} (rf/sub [:wallet/wallet-send-token])
send-from-locked-amounts (rf/sub [:wallet/wallet-send-from-locked-amounts])
{:keys [total-balance]
:as token-by-symbol} (rf/sub [:wallet/token-by-symbol
(str token-symbol)
enabled-from-chain-ids])
token-balance (or default-limit-crypto total-balance)
usd-conversion-rate (utils/token-usd-price token)
currency (rf/sub [:profile/currency])
conversion-rate (-> token
:market-values-per-currency
currency
:price)
token-decimals (-> token
utils/token-usd-price
utils/one-cent-value
utils/calc-max-crypto-decimals)
[input-state set-input-state] (rn/use-state controlled-input/init-state)
clear-input! #(set-input-state controlled-input/delete-all)
currency-symbol (rf/sub [:profile/currency-symbol])
loading-routes? (rf/sub [:wallet/wallet-send-loading-suggested-routes?])
route (rf/sub [:wallet/wallet-send-route])
on-confirm (or default-on-confirm handle-on-confirm)
crypto-decimals (or token-decimals default-crypto-decimals)
max-limit (if crypto-currency?
(utils/cut-crypto-decimals-to-fit-usd-cents
token-balance
usd-conversion-rate)
(utils/cut-fiat-balance-to-two-decimals
(money/crypto->fiat token-balance conversion-rate)))
input-value (controlled-input/input-value input-state)
valid-input? (not (or (controlled-input/empty-value? input-state)
(controlled-input/input-error input-state)))
amount-in-crypto (if crypto-currency?
input-value
(number/remove-trailing-zeroes
(.toFixed (/ input-value conversion-rate)
crypto-decimals)))
total-amount-receiver (rf/sub [:wallet/total-amount true])
amount-text (str (number/remove-trailing-zeroes
(.toFixed total-amount-receiver
(min token-decimals 6)))
" "
token-symbol)
show-select-asset-sheet #(rf/dispatch
[:show-bottom-sheet
{:content (fn []
[select-asset-bottom-sheet
clear-input!])}])
sender-network-values (rf/sub [:wallet/wallet-send-sender-network-values])
receiver-network-values (rf/sub [:wallet/wallet-send-receiver-network-values])
tx-type (rf/sub [:wallet/wallet-send-tx-type])
unsupported-token-in-receiver? (and (not= tx-type :tx/bridge)
(->> receiver-network-values
(remove #(= (:type %) :add))
(every? #(= (:type %) :not-available))))
suggested-routes (rf/sub [:wallet/wallet-send-suggested-routes])
routes (when suggested-routes
(or (:best suggested-routes) []))
no-routes-found? (and
(every-network-value-is-zero? sender-network-values)
(some? routes)
(not loading-routes?)
(not unsupported-token-in-receiver?))
receiver-networks (rf/sub [:wallet/wallet-send-receiver-networks])
receiver-preferred-networks (rf/sub [:wallet/wallet-send-receiver-preferred-networks])
receiver-preferred-network? (set receiver-preferred-networks)
sending-to-unpreferred-networks? (some (comp not receiver-preferred-network?)
receiver-networks)
input-error (controlled-input/input-error input-state)
limit-exceeded? (controlled-input/upper-limit-exceeded? input-state)
current-address (rf/sub [:wallet/current-viewing-account-address])
current-color (rf/sub [:wallet/current-viewing-account-color])
enough-assets? (rf/sub [:wallet/wallet-send-enough-assets?])
owned-eth-token (rf/sub [:wallet/token-by-symbol
(string/upper-case constants/mainnet-short-name)
enabled-from-chain-ids])
not-enough-asset? (insufficient-asset-amount?
{:enough-assets? enough-assets?
:token-symbol token-symbol
:owned-eth-token owned-eth-token
:input-state input-state
:no-routes-found? no-routes-found?
:limit-exceeded? limit-exceeded?
:sender-network-values sender-network-values})
should-try-again? (and (not limit-exceeded?)
no-routes-found?
(not not-enough-asset?))
show-no-routes? (and (or no-routes-found? limit-exceeded?)
(not-empty sender-network-values)
(not not-enough-asset?))
confirm-disabled? (or (nil? route)
(empty? route)
(not valid-input?))
fee-formatted (when (or (not confirm-disabled?) not-enough-asset?)
(get-fee-formatted route))
request-fetch-routes (fn [bounce-duration-ms]
(fetch-routes
{:amount amount-in-crypto
:valid-input? valid-input?
:bounce-duration-ms bounce-duration-ms
:token token
:reset-amounts-to-zero? (and limit-exceeded?
(some? routes))}))
swap-between-fiat-and-crypto (fn []
(if crypto-currency?
(set-input-state
#(controlled-input/->fiat % conversion-rate))
(set-input-state
#(controlled-input/->crypto % conversion-rate)))
(set-crypto-currency (not crypto-currency?)))]
[{on-confirm :on-confirm
on-navigate-back :on-navigate-back
button-one-label :button-one-label
button-one-props :button-one-props
current-screen-id :current-screen-id}]
(let [{:keys [value-out-of-limits?
route
sender-network-values
loading-routes?
token-not-supported-in-receiver-networks?
token-networks
receiver-networks
token-symbol
recipient-gets-amount
max-decimals
fee-formatted
no-routes-found?
current-address
not-enough-asset?
show-no-routes?]
:as state} (rf/sub [:send-input-amount-screen/view-subs])
view-id (rf/sub [:view-id])
active-screen? (= view-id current-screen-id)
bottom (safe-area/get-bottom)
on-navigate-back on-navigate-back]
(rn/use-effect
(fn []
(when active-screen?
@@ -310,125 +257,52 @@
(hot-reload/use-safe-unmount on-navigate-back)
(rn/use-effect
(fn []
(set-input-state #(controlled-input/set-upper-limit % max-limit)))
[max-limit])
(rn/use-effect
(fn []
(when input-error
(when value-out-of-limits?
(rf/dispatch [:wallet/stop-get-suggested-routes])
(debounce/clear-all)))
[input-error])
[value-out-of-limits?])
(rn/use-effect
(fn []
(clear-input!)
(rf/dispatch [:send-input-amount-screen/token-input-delete-all])
(rf/dispatch [:wallet/stop-and-clean-suggested-routes])
(rf/dispatch [:wallet/clean-disabled-from-networks]))
[current-address])
(rn/use-effect
(fn []
(request-fetch-routes 0))
[send-from-locked-amounts])
[rn/view
{:style style/screen
:accessibility-label (str "container"
(when (controlled-input/input-error input-state) "-error"))}
(when value-out-of-limits? "-error"))}
[account-switcher/view
{:icon-name :i/arrow-left
:on-press #(rf/dispatch [:navigate-back])
:switcher-type :select-account}]
[quo/token-input
{:container-style style/input-container
:token-symbol token-symbol
:value input-value
:on-swap swap-between-fiat-and-crypto
:on-token-press show-select-asset-sheet
:error? (controlled-input/input-error input-state)
:currency-symbol (if crypto-currency? token-symbol fiat-currency)
:converted-value (if crypto-currency?
(utils/prettify-balance
currency-symbol
(money/crypto->fiat input-value
conversion-rate))
(utils/prettify-crypto-balance
(or (clj->js token-symbol) "")
(money/fiat->crypto input-value
conversion-rate)
conversion-rate))
:hint-component [quo/network-tags
{:networks (seq from-enabled-networks)
:title (i18n/label
:t/send-limit
{:limit (if crypto-currency?
(utils/prettify-crypto-balance
(or (clj->js token-symbol) "")
(controlled-input/upper-limit-bn input-state)
conversion-rate)
(utils/prettify-balance currency-symbol
(controlled-input/upper-limit-bn
input-state)))})
:status (when (controlled-input/input-error input-state) :error)}]}]
[routes/view
{:token token-by-symbol
:send-amount-in-crypto amount-in-crypto
:valid-input? valid-input?
:token-not-supported-in-receiver-networks? unsupported-token-in-receiver?
:current-screen-id current-screen-id
:request-fetch-routes request-fetch-routes}]
[token-input]
[routes-view current-screen-id]
(when (and (not loading-routes?)
sender-network-values
unsupported-token-in-receiver?)
token-not-supported-in-receiver-networks?)
[token-not-available token-symbol receiver-networks token-networks])
(when not-enough-asset?
[not-enough-asset])
(when (or (and (not no-routes-found?) (or loading-routes? route))
not-enough-asset?)
(when (and (not no-routes-found?) (or loading-routes? route))
[estimated-fees
{:loading-routes? loading-routes?
:fees fee-formatted
:amount amount-text}])
(when show-no-routes?
[no-routes-found])
[quo/bottom-actions
{:actions :one-action
:button-one-label (if should-try-again?
(i18n/label :t/try-again)
button-one-label)
:button-one-props (merge (when-not should-try-again?
button-one-props)
{:disabled? (or not-enough-asset?
loading-routes?
(and (not should-try-again?)
confirm-disabled?))
:on-press (cond
should-try-again?
#(rf/dispatch [:wallet/start-get-suggested-routes
{:amount amount-in-crypto
:updated-token token-by-symbol}])
sending-to-unpreferred-networks?
#(show-unpreferred-networks-alert on-confirm)
:else
#(on-confirm amount-in-crypto))
:customization-color current-color}
(when should-try-again?
{:type :grey}))}]
{:loading-routes? loading-routes?
:fees fee-formatted
:recipient-gets-amount recipient-gets-amount}])
(cond
show-no-routes? [no-routes-found]
not-enough-asset? [not-enough-asset])
[bottom-actions on-confirm button-one-label button-one-props]
[quo/numbered-keyboard
{:container-style (style/keyboard-container bottom)
:left-action :dot
:delete-key? true
:on-press (fn [c]
(let [new-text (str input-value c)
max-decimals (if crypto-currency? crypto-decimals 2)
regex-pattern (str "^\\d*\\.?\\d{0," max-decimals "}$")
regex (re-pattern regex-pattern)]
(when (re-matches regex new-text)
(debounce/clear-all)
(set-input-state #(controlled-input/add-character % c)))))
(rf/dispatch [:send-input-amount-screen/token-input-add-character c
max-decimals]))
:on-delete (fn []
(debounce/clear-all)
(set-input-state controlled-input/delete-last)
(rf/dispatch [:send-input-amount-screen/token-input-delete-last])
(rf/dispatch-sync [:wallet/stop-and-clean-suggested-routes]))
:on-long-press-delete (fn []
(debounce/clear-all)
(set-input-state controlled-input/delete-all)
(rf/dispatch [:send-input-amount-screen/token-input-delete-all])
(rf/dispatch-sync [:wallet/stop-and-clean-suggested-routes]))}]]))
@@ -340,15 +340,11 @@
(let [token-symbol (:symbol token)
nav-current-screen-id (rf/sub [:view-id])
active-screen? (= nav-current-screen-id current-screen-id)
loading-routes? (rf/sub
[:wallet/wallet-send-loading-suggested-routes?])
sender-network-values (rf/sub
[:wallet/wallet-send-sender-network-values])
receiver-network-values (rf/sub
[:wallet/wallet-send-receiver-network-values])
loading-routes? (rf/sub [:wallet/wallet-send-loading-suggested-routes?])
sender-network-values (rf/sub [:wallet/wallet-send-sender-network-values])
receiver-network-values (rf/sub [:wallet/wallet-send-receiver-network-values])
network-links (rf/sub [:wallet/wallet-send-network-links])
disabled-from-chain-ids (rf/sub
[:wallet/wallet-send-disabled-from-chain-ids])
disabled-from-chain-ids (rf/sub [:wallet/wallet-send-disabled-from-chain-ids])
{token-balances-per-chain :balances-per-chain} (rf/sub [:wallet/wallet-send-token])
token-available-networks-for-suggested-routes
(send-utils/token-available-networks-for-suggested-routes
@@ -8,12 +8,14 @@
(defn view
[]
[input-amount/view
{:current-screen-id :screen/wallet.send-input-amount
:button-one-label (i18n/label :t/review-send)
:enabled-from-chain-ids (rf/sub [:wallet/wallet-send-enabled-from-chain-ids])
:from-enabled-networks (rf/sub [:wallet/wallet-send-enabled-networks])
:on-navigate-back (fn []
(rf/dispatch-sync [:wallet/stop-and-clean-suggested-routes])
(rf/dispatch [:wallet/clean-disabled-from-networks])
(rf/dispatch [:wallet/clean-from-locked-amounts])
(rf/dispatch [:wallet/clean-send-amount]))}])
{:current-screen-id :screen/wallet.send-input-amount
:button-one-label (i18n/label :t/review-send)
:on-confirm (fn [amount]
(rf/dispatch [:wallet/set-token-amount-to-send
{:amount amount
:stack-id :screen/wallet.send-input-amount}]))
:on-navigate-back (fn []
(rf/dispatch-sync [:wallet/stop-and-clean-suggested-routes])
(rf/dispatch [:wallet/clean-disabled-from-networks])
(rf/dispatch [:wallet/clean-from-locked-amounts])
(rf/dispatch [:wallet/clean-send-amount]))}])
@@ -221,9 +221,8 @@
bridge-to-network (when bridge-to-chain-id
(rf/sub [:wallet/network-details-by-chain-id
bridge-to-chain-id]))
loading-suggested-routes? (rf/sub
[:wallet/wallet-send-loading-suggested-routes?])
total-amount-receiver (rf/sub [:wallet/total-amount true])
loading-suggested-routes? (rf/sub [:wallet/wallet-send-loading-suggested-routes?])
total-amount-receiver (rf/sub [:wallet/total-amount-in-to-chains])
from-account-props {:customization-color account-color
:size 32
:emoji (:emoji account)
+8 -14
View File
@@ -17,7 +17,6 @@
(fn [{:keys [db]} [{:keys [network asset-to-receive open-new-screen?] :as data}]]
(let [{:keys [wallet]} db
test-networks-enabled? (get-in db [:profile/profile :test-networks-enabled?])
view-id (:view-id db)
account (swap-utils/wallet-account wallet)
asset-to-pay (if (get-in data [:asset-to-pay :networks])
(:asset-to-pay data)
@@ -31,13 +30,12 @@
{:db (-> db
(assoc-in [:wallet :ui :swap :asset-to-pay] asset-to-pay)
(assoc-in [:wallet :ui :swap :asset-to-receive] asset-to-receive)
(assoc-in [:wallet :ui :swap :network] network')
(assoc-in [:wallet :ui :swap :launch-screen] view-id))
(assoc-in [:wallet :ui :swap :network] network'))
:fx (if network'
[[:dispatch [:wallet/switch-current-viewing-account (:address account)]]
[:dispatch
(if open-new-screen?
[:open-modal :screen/wallet.setup-swap]
[:navigate-to :screen/wallet.setup-swap]
[:navigate-to-within-stack
[:screen/wallet.setup-swap :screen/wallet.swap-select-asset-to-pay]])]
[:dispatch [:wallet.swap/set-default-slippage]]]
@@ -206,6 +204,12 @@
(fn [{:keys [db]}]
{:db (update-in db [:wallet :ui] dissoc :swap)}))
(rf/reg-event-fx
:wallet/on-swap-done
(fn [_]
{:fx [[:dispatch [:wallet/select-account-tab :activity]]
[:dispatch [:wallet/clean-swap]]]}))
(rf/reg-event-fx :wallet/swap-transaction
(fn [{:keys [db]} [sha3-pwd]]
(let [wallet-address (get-in db
@@ -295,7 +299,6 @@
:screen/wallet.swap-set-spending-cap
:screen/wallet.swap-confirmation)])
(when-not approval-required?
(rf/dispatch [:wallet/end-swap-flow])
(debounce/debounce-and-dispatch
[:toasts/upsert
{:id :swap-transaction-pending
@@ -421,12 +424,3 @@
:last-request-uuid
:approved-amount
:approval-transaction-id)))})))
(rf/reg-event-fx :wallet/end-swap-flow
(fn [{:keys [db]}]
(let [launch-screen (get-in db [:wallet :ui :swap :launch-screen])
address (get-in db [:wallet :current-viewing-account-address])]
{:fx [(when (= launch-screen :wallet-stack)
[:dispatch [:wallet/navigate-to-account-within-stack address]])
[:dispatch [:wallet/fetch-activities-for-current-account]]
[:dispatch [:wallet/select-account-tab :activity]]]})))
@@ -26,7 +26,7 @@
(let [pay-token-symbol (:symbol token)
asset-to-receive (if (= pay-token-symbol "SNT") eth-token snt-token)]
(rf/dispatch [:wallet.swap/start
{:asset-to-pay {:symbol pay-token-symbol}
{:asset-to-pay token
:asset-to-receive asset-to-receive
:open-new-screen? false}])))]
[:<>
@@ -156,7 +156,7 @@
:valid-input? valid-pay-input?
:clean-approval-transaction? true}))
[pay-input-amount])]
(rn/use-unmount #(rf/dispatch [:wallet/clean-swap]))
(rn/use-unmount #(rf/dispatch [:wallet/on-swap-done]))
(rn/use-effect
(fn []
(request-fetch-swap-proposal))
@@ -50,10 +50,8 @@
data)
symbols (->> tokens
:by-symbol
vals
(map :symbol)
set
vec)]
keys
(remove utils.address/address?))]
{:fx [[:effects.wallet.tokens/fetch-market-values
{:symbols symbols
:currency constants/profile-default-currency
+8 -1
View File
@@ -2,6 +2,7 @@
(:require
[legacy.status-im.fleet.core :as fleet]
[react-native.core :as rn]
[status-im.common.controlled-input.utils :as controlled-input]
[status-im.contexts.shell.activity-center.events :as activity-center]
[status-im.contexts.wallet.db :as wallet]))
@@ -43,4 +44,10 @@
:stickers/packs-pending #{}
:settings/change-password {}
:keycard {}
:theme :light})
:theme :light
:layers {:ui
{:send
{:input-amount-screen
{:controller
{:crypto-currency? true
:token-input-value ""}}}}}})
File diff suppressed because it is too large Load Diff
@@ -1,10 +0,0 @@
(ns status-im.setup.interceptor-metrics
(:require
#?@(:mobile
[[re-frame.core :as re-frame]
[status-im.contexts.centralized-metrics.events :as centralized-metrics]])))
(defn setup-centralized-metrics-interceptor
[]
#?(:mobile
(re-frame/reg-global-interceptor centralized-metrics/interceptor)))
+2 -2
View File
@@ -2,13 +2,13 @@
(:require
[re-frame.core :as re-frame]
[re-frame.std-interceptors :as std-interceptors]
[status-im.setup.interceptor-metrics :as interceptor-metrics]
[status-im.contexts.centralized-metrics.events :as centralized-metrics]
[utils.re-frame :as rf]))
(defn register-global-interceptors
[]
(re-frame/reg-global-interceptor rf/debug-handlers-names)
(interceptor-metrics/setup-centralized-metrics-interceptor)
(re-frame/reg-global-interceptor centralized-metrics/interceptor)
(re-frame/reg-global-interceptor (re-frame/inject-cofx :now))
;; Interceptor `trim-v` removes the first element of the event vector.
+1 -6
View File
@@ -125,8 +125,7 @@
:<- [:contacts/blocked-set]
:<- [:contacts/contacts-raw]
:<- [:chat/inputs]
(fn [[{:keys [group-chat chat-id chat-name name] :as current-chat} my-public-key community
blocked-users-set contacts
(fn [[{:keys [group-chat chat-id] :as current-chat} my-public-key community blocked-users-set contacts
inputs]]
(when current-chat
(cond-> current-chat
@@ -141,9 +140,6 @@
(assoc :able-to-send-message? true
:member? true)
(not chat-name)
(assoc :chat-name name)
(not group-chat)
(assoc
:contact-request-state (get-in contacts [chat-id :contact-request-state])
@@ -168,7 +164,6 @@
(condp apply [current-chat]
chat.events/community-chat? :community-chat
chat.events/group-chat? :group-chat
chat.events/public-chat? :public-chat
:chat)))
(re-frame/reg-sub
-10
View File
@@ -8,7 +8,6 @@
[re-frame.core :as re-frame]
[status-im.common.pixel-ratio :as pixel-ratio]
[status-im.constants :as constants]
[status-im.contexts.profile.data-store :as profile.data-store]
[status-im.contexts.profile.utils :as profile.utils]
[utils.security.core :as security]))
@@ -18,15 +17,6 @@
(fn [{:keys [customization-color]}]
(or customization-color constants/profile-default-color)))
;; A profile can only be created without accepting terms in Status v1. In Status
;; v2, the terms may be unaccepted because we intentionally created a migration
;; resetting the flag in case the privacy policy changed.
(re-frame/reg-sub :profile/has-profiles-and-unaccepted-terms?
:<- [:profile/profiles-overview]
(fn [profiles-overview]
(and (seq profiles-overview)
(not (profile.data-store/accepted-terms? (vals profiles-overview))))))
(re-frame/reg-sub
:profile/currency
:<- [:profile/profile]
+2
View File
@@ -196,3 +196,5 @@
;;keycard
(reg-root-key-sub :keycard :keycard)
(reg-root-key-sub :layers :layers)
+9 -11
View File
@@ -75,15 +75,13 @@
{}
network-values))))
(re-frame/reg-sub
:wallet/total-amount
(re-frame/reg-sub :wallet/total-amount-in-to-chains
:<- [:wallet/wallet-send]
(fn [{:keys [from-values-by-chain to-values-by-chain]} [_ to-values?]]
(let [network-values (if to-values? to-values-by-chain from-values-by-chain)]
(reduce
(fn [acc amount]
(if (money/bignumber? amount)
(money/add acc amount)
acc))
(money/bignumber 0)
(vals network-values)))))
(fn [{:keys [to-values-by-chain]}]
(reduce
(fn [acc amount]
(if (money/bignumber? amount)
(money/add acc amount)
acc))
(money/bignumber 0)
(vals to-values-by-chain))))
+10 -26
View File
@@ -450,19 +450,17 @@
(map
(fn [token]
(assoc token
:bridge-disabled? (and (= tx-type :tx/bridge)
(send-utils/bridge-disabled? (:symbol
token)))
:networks (cond->>
(network-utils/network-list-with-positive-balance
token
networks)
chain-ids
(filter #(some #{(:chain-id %)} chain-ids)))
:bridge-disabled? (and (= tx-type :tx/bridge)
(send-utils/bridge-disabled? (:symbol
token)))
:networks (cond->> (network-utils/network-list token
networks)
chain-ids
(filter #(some #{(:chain-id %)} chain-ids)))
:available-balance (utils/calculate-total-token-balance token)
:total-balance (utils/calculate-total-token-balance
token
chain-ids))))
:total-balance (utils/calculate-total-token-balance
token
chain-ids))))
(filter (fn [{:keys [networks]}]
(pos? (count networks))))
(remove #(when hide-token-fn (hide-token-fn constants/swap-tokens-my %))))
@@ -577,26 +575,12 @@
tokens))
addresses-tokens)))
(rf/reg-sub
:wallet/current-account-owns-token
(fn [[_ token-symbol]]
[(rf/subscribe [:wallet/current-viewing-account-address])
(rf/subscribe [:wallet/operable-addresses-with-token-symbol token-symbol])])
(fn [[address addresses-with-token]]
(-> addresses-with-token set (contains? address))))
(rf/reg-sub
:wallet/account-tab
:<- [:wallet/ui]
(fn [ui]
(get-in ui [:account-page :active-tab])))
(rf/reg-sub
:wallet/home-tab
:<- [:wallet/ui]
(fn [ui]
(:active-tab ui)))
(rf/reg-sub
:wallet/aggregated-tokens
:<- [:wallet/accounts-without-watched-accounts]
-3
View File
@@ -70,9 +70,6 @@
{:initializeApplication
(fn [request callback]
(callback (.initializeApplication native-status request)))
:acceptTerms
(fn [callback]
(callback (.acceptTerms native-status)))
:createAccountAndLogin
(fn [request] (.createAccountAndLogin native-status request))
:restoreAccountAndLogin
+3 -3
View File
@@ -3,7 +3,7 @@
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
"owner": "status-im",
"repo": "status-go",
"version": "v3.5.0",
"commit-sha1": "39511298cdc8f50e7659ac8079d5bc8a4763ddc7",
"src-sha256": "1nn8gq9d91ix5mzndr306rq3n68rzj4drym3pfaxzaa73k4v9r07"
"version": "v3.3.0",
"commit-sha1": "43659f0c7e1a64102e7f8e38bd532b72714c5819",
"src-sha256": "01fpviw1g22f4ni3li2wnhyz0l517jfipvnyfysckds6yi94l0hf"
}
-2
View File
@@ -1002,7 +1002,6 @@
"expand-all": "Expand all",
"experienced-web3": "Experienced in Web3?",
"explore-the-decentralized-web": "Explore and interact with the decentralized web",
"explore-the-new-status": "Explore the new Status",
"export-account": "Export account",
"export-key": "Export private key",
"external-link": "External link",
@@ -2647,7 +2646,6 @@
"untrustworthy": "Untrustworthy",
"update": "Update",
"update-account-name": "Update account name",
"update-group-chat": "Update group chat",
"update-nickname-title": "Update nickname",
"update-to-listen-audio": "Update to latest version to listen to an audio message here!",
"update-to-see-image": "Update to latest version to see a nice image here!",