Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c3eabf2d3 | ||
|
|
ac186e27de | ||
|
|
917f10955a | ||
|
|
8638a2266d | ||
|
|
baab56946e | ||
|
|
d10a026908 | ||
|
|
2cb50fcbf6 |
@@ -36,6 +36,7 @@
|
||||
android:allowBackup="false"
|
||||
android:label="@string/app_name"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:theme="@style/Theme.AppSplash"
|
||||
android:name=".MainApplication"
|
||||
android:largeHeap="true"
|
||||
|
||||
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 92 B After Width: | Height: | Size: 9.8 KiB |
|
Before Width: | Height: | Size: 498 B After Width: | Height: | Size: 940 B |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 272 B After Width: | Height: | Size: 266 B |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 100 B After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 972 B After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 495 B After Width: | Height: | Size: 452 B |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 108 B After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 826 B After Width: | Height: | Size: 824 B |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 118 B After Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 826 B After Width: | Height: | Size: 825 B |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 123 KiB |
@@ -2,4 +2,5 @@
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_foreground"/>
|
||||
</adaptive-icon>
|
||||
<monochrome android:drawable="@mipmap/ic_launcher_monochrome" />
|
||||
</adaptive-icon>
|
||||
|
||||
@@ -2,4 +2,5 @@
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_foreground"/>
|
||||
</adaptive-icon>
|
||||
<monochrome android:drawable="@mipmap/ic_launcher_monochrome" />
|
||||
</adaptive-icon>
|
||||
|
||||
|
Before Width: | Height: | Size: 374 B After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 239 B After Width: | Height: | Size: 9.8 KiB |
|
Before Width: | Height: | Size: 678 B After Width: | Height: | Size: 737 B |
|
Before Width: | Height: | Size: 970 B After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 517 B After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 8.4 KiB |
|
Before Width: | Height: | Size: 905 B After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 25 KiB |
@@ -1115,7 +1115,7 @@ PODS:
|
||||
- React-perflogger (= 0.73.5)
|
||||
- ReactNativeAudioToolkit (2.0.3):
|
||||
- React
|
||||
- ReactNativeCameraKit (14.0.0-beta15):
|
||||
- ReactNativeCameraKit (14.0.0-beta13):
|
||||
- React-Core
|
||||
- ReactNativeNavigation (7.39.0):
|
||||
- HMSegmentedControl
|
||||
@@ -1485,7 +1485,7 @@ SPEC CHECKSUMS:
|
||||
FBLazyVector: 56e0e498dbb513b96c40bac6284729ba4e62672d
|
||||
FBReactNativeSpec: 146c741a3f40361f6bc13a4ba284678cbedb5881
|
||||
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
|
||||
glog: 36c15c01d70ed395c6e4f3619f98a23ee415b07a
|
||||
glog: 530710e7949eb12c82670bd09e946becf50a3c2a
|
||||
hermes-engine: 1d1835b2cc54c381909d94d1b3c8e0a2f1a94a0e
|
||||
HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352
|
||||
Keycard: ac6df4d91525c3c82635ac24d4ddd9a80aca5fc8
|
||||
@@ -1551,7 +1551,7 @@ SPEC CHECKSUMS:
|
||||
React-utils: 987a4526a2fc0acdfaf87888adfe0bf9d0452066
|
||||
ReactCommon: 2947b0bffd82ea0e58ca7928881152d4c6dae9af
|
||||
ReactNativeAudioToolkit: de9610f323e855ac6574be8c99621f3d57c5df06
|
||||
ReactNativeCameraKit: 71343efc1256720184ce980f164c7eedb78d5c16
|
||||
ReactNativeCameraKit: d95d3e19c514526a234d9f93c6db7e7f10eef9ea
|
||||
ReactNativeNavigation: 679d8c8bf3b8ae98d285bce810964d10da85dbdb
|
||||
RNCAsyncStorage: c913ede1fa163a71cea118ed4670bbaaa4b511bb
|
||||
RNCClipboard: 60fed4b71560d7bfe40e9d35dea9762b024da86d
|
||||
|
||||
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 429 B After Width: | Height: | Size: 848 B |
|
Before Width: | Height: | Size: 825 B After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 825 B After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 1013 B After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 629 B After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 413 KiB |
@@ -253,6 +253,11 @@ 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,6 +204,14 @@ 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,6 +761,26 @@ 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();
|
||||
@@ -1998,6 +2018,7 @@ 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);
|
||||
|
||||
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 64 KiB |
@@ -79,6 +79,12 @@
|
||||
(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")
|
||||
|
||||
@@ -6,20 +6,16 @@
|
||||
(h/describe "Wallet: Token Input"
|
||||
(h/test "Token label renders"
|
||||
(h/render-with-theme-provider [token-input/view
|
||||
{:token-symbol :snt
|
||||
:currency-symbol :snt
|
||||
:on-swap nil
|
||||
:error? false
|
||||
:value "1"
|
||||
:converted-value "10"}])
|
||||
{:token :snt
|
||||
:currency :eur
|
||||
:currency-symbol "€"
|
||||
:conversion 1}])
|
||||
(h/is-truthy (h/get-by-text "SNT")))
|
||||
|
||||
(h/test "Amount renders"
|
||||
(h/render-with-theme-provider [token-input/view
|
||||
{:token-symbol :snt
|
||||
:currency-symbol :snt
|
||||
:on-swap nil
|
||||
:error? false
|
||||
:value "1"
|
||||
:converted-value "€0.00"}])
|
||||
{:token :snt
|
||||
:currency :eur
|
||||
:currency-symbol "€"
|
||||
:conversion 1}])
|
||||
(h/is-truthy (h/get-by-text "€0.00"))))
|
||||
|
||||
@@ -4,14 +4,15 @@
|
||||
[:=>
|
||||
[:catn
|
||||
[:props
|
||||
[:map {:closed true}
|
||||
[:token-symbol [:maybe [:or :string :keyword]]]
|
||||
[:currency-symbol [:maybe [:or :string :keyword]]]
|
||||
[:hint-component {:optional true} [:maybe :schema.common/hiccup]]
|
||||
[:on-token-press {:optional true} [:maybe fn?]]
|
||||
[:on-swap [:maybe fn?]]
|
||||
[:container-style {:optional true} [:maybe :map]]
|
||||
[:error? [:maybe :boolean]]
|
||||
[:value [:maybe :string]]
|
||||
[:converted-value [:maybe :string]]]]]
|
||||
[:map
|
||||
[:token {:optional true} [:maybe [:or :string :keyword]]]
|
||||
[:currency {:optional true} [:maybe [:or :string :keyword]]]
|
||||
[:error? {:optional true} [:maybe :boolean]]
|
||||
[:title {:optional true} [:maybe :string]]
|
||||
[:conversion {:optional true} [:maybe :double]]
|
||||
[:show-keyboard? {:optional true} [:maybe :boolean]]
|
||||
[:networks {:optional true}
|
||||
[:maybe [:sequential [:map [:source [:maybe :schema.common/image-source]]]]]]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
|
||||
[:value {:optional true} [:maybe :string]]]]]
|
||||
:any])
|
||||
|
||||
@@ -25,11 +25,9 @@
|
||||
|
||||
(defn input-container
|
||||
[window-width]
|
||||
{:width (- window-width 120)
|
||||
:margin-left 8
|
||||
:margin-right 8
|
||||
:flex-direction :row
|
||||
:align-items :flex-end})
|
||||
{:width (- window-width 120)
|
||||
:margin-left 8
|
||||
:margin-right 8})
|
||||
|
||||
(def text-input-dimensions
|
||||
(-> typography/heading-1
|
||||
@@ -67,6 +65,6 @@
|
||||
:justify-content :space-between
|
||||
:align-items :center})
|
||||
|
||||
(defn converted-amount
|
||||
(defn fiat-amount
|
||||
[theme]
|
||||
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)})
|
||||
|
||||
@@ -1,15 +1,57 @@
|
||||
(ns quo.components.wallet.token-input.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[oops.core :as oops]
|
||||
[quo.components.buttons.button.view :as button]
|
||||
[quo.components.dividers.divider-line.view :as divider-line]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.tags.network-tags.view :as network-tag]
|
||||
[quo.components.utilities.token.view :as token]
|
||||
[quo.components.wallet.token-input.schema :as component-schema]
|
||||
[quo.components.wallet.token-input.style :as style]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[schema.core :as schema]))
|
||||
[schema.core :as schema]
|
||||
[utils.number :as number]))
|
||||
|
||||
(defn fiat-format
|
||||
[currency-symbol num-value conversion]
|
||||
(str currency-symbol (.toFixed (* num-value conversion) 2)))
|
||||
|
||||
(defn crypto-format
|
||||
[num-value conversion crypto-decimals token]
|
||||
(str (number/remove-trailing-zeroes
|
||||
(.toFixed (/ num-value conversion) (or crypto-decimals 2)))
|
||||
" "
|
||||
(string/upper-case (or (clj->js token) ""))))
|
||||
|
||||
(defn calc-value
|
||||
[{:keys [crypto? currency-symbol token value conversion crypto-decimals]}]
|
||||
(let [num-value (if (string? value)
|
||||
(or (parse-double value) 0)
|
||||
value)]
|
||||
(if crypto?
|
||||
(fiat-format currency-symbol num-value conversion)
|
||||
(crypto-format num-value conversion crypto-decimals token))))
|
||||
|
||||
(defn- data-info
|
||||
[{:keys [theme token crypto-decimals conversion networks title crypto? currency-symbol amount
|
||||
error?]}]
|
||||
[rn/view {:style style/data-container}
|
||||
[network-tag/view
|
||||
{:networks networks
|
||||
:title title
|
||||
:status (when error? :error)}]
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:style (style/fiat-amount theme)}
|
||||
(calc-value {:crypto? crypto?
|
||||
:currency-symbol currency-symbol
|
||||
:token token
|
||||
:value amount
|
||||
:conversion conversion
|
||||
:crypto-decimals crypto-decimals})]])
|
||||
|
||||
(defn- token-name-text
|
||||
[theme text]
|
||||
@@ -20,63 +62,91 @@
|
||||
(string/upper-case (or (clj->js text) ""))])
|
||||
|
||||
(defn input-section
|
||||
[{:keys [token-symbol on-token-press value error? on-swap currency-symbol]}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
window-width (:width (rn/get-window))]
|
||||
[rn/pressable
|
||||
{:style {:width "100%"
|
||||
:flex-direction :row}
|
||||
:on-press on-token-press}
|
||||
[token/view
|
||||
{:token token-symbol
|
||||
:size :size-32}]
|
||||
[rn/view {:style (style/input-container window-width)}
|
||||
[rn/text-input
|
||||
{:style (style/text-input theme error?)
|
||||
:placeholder-text-color (style/placeholder-text theme)
|
||||
:placeholder "0"
|
||||
:keyboard-type :numeric
|
||||
:editable false
|
||||
:value value}]
|
||||
[token-name-text theme currency-symbol]]
|
||||
[button/button
|
||||
{:icon true
|
||||
:icon-only? true
|
||||
:size 32
|
||||
:on-press #(when on-swap (on-swap))
|
||||
:type :outline
|
||||
:accessibility-label :reorder}
|
||||
:i/reorder]]))
|
||||
[{:keys [on-change-text value value-internal set-value-internal on-selection-change
|
||||
on-token-press]}]
|
||||
(let [input-ref (atom nil)
|
||||
set-ref #(reset! input-ref %)
|
||||
focus-input #(when-let [ref ^js @input-ref]
|
||||
(.focus ref))
|
||||
controlled-input? (some? value)
|
||||
handle-on-change-text (fn [v]
|
||||
(when-not controlled-input?
|
||||
(set-value-internal v))
|
||||
(when on-change-text
|
||||
(on-change-text v)))
|
||||
handle-selection-change (fn [^js e]
|
||||
(when on-selection-change
|
||||
(-> e
|
||||
(oops/oget "nativeEvent.selection")
|
||||
(js->clj :keywordize-keys true)
|
||||
(on-selection-change))))]
|
||||
(fn [{:keys [token customization-color show-keyboard? crypto? currency value error? selection
|
||||
handle-on-swap allow-selection?]
|
||||
:or {show-keyboard? true
|
||||
allow-selection? true}}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
window-width (:width (rn/get-window))]
|
||||
[rn/pressable
|
||||
{:style {:width "100%"
|
||||
:flex-direction :row}
|
||||
:on-press on-token-press}
|
||||
[token/view
|
||||
{:token token
|
||||
:size :size-32}]
|
||||
[rn/view {:style (style/input-container window-width)}
|
||||
[rn/pressable
|
||||
{:style style/text-input-container
|
||||
:on-press focus-input}
|
||||
[rn/text-input
|
||||
(cond-> {:style (style/text-input theme error?)
|
||||
:placeholder-text-color (style/placeholder-text theme)
|
||||
:auto-focus true
|
||||
:ref set-ref
|
||||
:placeholder "0"
|
||||
:keyboard-type :numeric
|
||||
:on-change-text handle-on-change-text
|
||||
:selection-color customization-color
|
||||
:show-soft-input-on-focus show-keyboard?
|
||||
:on-selection-change handle-selection-change
|
||||
:selection (clj->js selection)
|
||||
:editable allow-selection?}
|
||||
controlled-input? (assoc :value value)
|
||||
(not controlled-input?) (assoc :default-value value-internal))]
|
||||
[token-name-text theme (if crypto? token currency)]]]
|
||||
[button/button
|
||||
{:icon true
|
||||
:icon-only? true
|
||||
:size 32
|
||||
:on-press handle-on-swap
|
||||
:type :outline
|
||||
:accessibility-label :reorder}
|
||||
:i/reorder]]))))
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [token-symbol
|
||||
value
|
||||
on-token-press
|
||||
error?
|
||||
container-style
|
||||
on-swap
|
||||
converted-value
|
||||
hint-component
|
||||
currency-symbol]}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
width (:width (rn/get-window))]
|
||||
[{:keys [container-style value on-swap] :as props}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
width (:width (rn/get-window))
|
||||
[value-internal set-value-internal] (rn/use-state nil)
|
||||
[crypto? set-crypto] (rn/use-state true)
|
||||
handle-on-swap (rn/use-callback
|
||||
(fn []
|
||||
(set-crypto (not crypto?))
|
||||
(when on-swap (on-swap (not crypto?))))
|
||||
[crypto? on-swap])]
|
||||
[rn/view {:style (merge (style/main-container width) container-style)}
|
||||
[rn/view {:style style/amount-container}
|
||||
[input-section
|
||||
{:theme theme
|
||||
:token-symbol token-symbol
|
||||
:on-token-press on-token-press
|
||||
:value value
|
||||
:error? error?
|
||||
:on-swap on-swap
|
||||
:currency-symbol currency-symbol}]]
|
||||
(assoc props
|
||||
:value-internal value-internal
|
||||
:theme theme
|
||||
:set-value-internal set-value-internal
|
||||
:handle-on-swap handle-on-swap
|
||||
:crypto? crypto?)]]
|
||||
[divider-line/view {:container-style (style/divider theme)}]
|
||||
[rn/view {:style style/data-container}
|
||||
hint-component
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:style (style/converted-amount theme)}
|
||||
converted-value]]]))
|
||||
[data-info
|
||||
(assoc props
|
||||
:theme theme
|
||||
:crypto? crypto?
|
||||
:amount (or value value-internal))]]))
|
||||
|
||||
(def view (schema/instrument #'view-internal component-schema/?schema))
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
(ns status-im.common.controlled-input.utils
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[status-im.contexts.wallet.common.utils :as wallet-utils]
|
||||
[utils.money :as money]))
|
||||
[clojure.string :as string]))
|
||||
|
||||
(def init-state
|
||||
{:value ""
|
||||
@@ -16,7 +14,7 @@
|
||||
|
||||
(defn numeric-value
|
||||
[state]
|
||||
(money/bignumber (input-value state)))
|
||||
(or (parse-double (input-value state)) 0))
|
||||
|
||||
(defn input-error
|
||||
[state]
|
||||
@@ -28,29 +26,23 @@
|
||||
|
||||
(defn upper-limit
|
||||
[state]
|
||||
(money/bignumber (:upper-limit state)))
|
||||
(:upper-limit state))
|
||||
|
||||
(defn lower-limit
|
||||
[state]
|
||||
(money/bignumber (:lower-limit state)))
|
||||
(:lower-limit state))
|
||||
|
||||
(defn upper-limit-exceeded?
|
||||
[state]
|
||||
(let [num-value (numeric-value state)]
|
||||
(and
|
||||
(upper-limit state)
|
||||
(if (money/bignumber? num-value)
|
||||
(money/greater-than (numeric-value state) (upper-limit state))
|
||||
false))))
|
||||
(and
|
||||
(upper-limit state)
|
||||
(> (numeric-value state) (upper-limit state))))
|
||||
|
||||
(defn- lower-limit-exceeded?
|
||||
(defn lower-limit-exceeded?
|
||||
[state]
|
||||
(let [num-value (numeric-value state)]
|
||||
(and
|
||||
(lower-limit state)
|
||||
(if (money/bignumber? num-value)
|
||||
(money/less-than (numeric-value state) (lower-limit state))
|
||||
false))))
|
||||
(and
|
||||
(lower-limit state)
|
||||
(< (numeric-value state) (lower-limit state))))
|
||||
|
||||
(defn- recheck-errorness
|
||||
[state]
|
||||
@@ -83,11 +75,13 @@
|
||||
|
||||
(defn increase
|
||||
[state]
|
||||
(set-input-value state (str (money/add (numeric-value state) 1))))
|
||||
(let [new-val (inc (numeric-value state))]
|
||||
(set-input-value state (str new-val))))
|
||||
|
||||
(defn decrease
|
||||
[state]
|
||||
(set-input-value state (str (money/add (numeric-value state) -1))))
|
||||
(let [new-val (dec (numeric-value state))]
|
||||
(set-input-value state (str new-val))))
|
||||
|
||||
(def ^:private not-digits-or-dot-pattern
|
||||
#"[^0-9+\.]")
|
||||
@@ -136,29 +130,3 @@
|
||||
(defn empty-value?
|
||||
[state]
|
||||
(string/blank? (:value state)))
|
||||
|
||||
(defn- fiat->crypto
|
||||
[value conversion-rate]
|
||||
(-> value
|
||||
(money/fiat->crypto conversion-rate)
|
||||
(wallet-utils/cut-crypto-decimals-to-fit-usd-cents conversion-rate)))
|
||||
|
||||
(defn- crypto->fiat
|
||||
[value conversion-rate]
|
||||
(-> value
|
||||
(money/crypto->fiat conversion-rate)
|
||||
(wallet-utils/cut-fiat-balance-to-two-decimals)))
|
||||
|
||||
(defn ->crypto
|
||||
[state conversion-rate]
|
||||
(-> state
|
||||
(set-input-value (fiat->crypto (input-value state) conversion-rate))
|
||||
(set-upper-limit (fiat->crypto (upper-limit state) conversion-rate))
|
||||
(set-lower-limit (fiat->crypto (lower-limit state) conversion-rate))))
|
||||
|
||||
(defn ->fiat
|
||||
[state conversion-rate]
|
||||
(-> state
|
||||
(set-input-value (crypto->fiat (input-value state) conversion-rate))
|
||||
(set-upper-limit (crypto->fiat (upper-limit state) conversion-rate))
|
||||
(set-lower-limit (crypto->fiat (lower-limit state) conversion-rate))))
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
{:margin-top 11
|
||||
:margin-horizontal 20
|
||||
:gap 21
|
||||
:margin-bottom 15})
|
||||
:margin-bottom 8})
|
||||
|
||||
(def item-text
|
||||
{:margin-top 10
|
||||
@@ -12,3 +12,9 @@
|
||||
|
||||
(def info-text
|
||||
{:margin-top -5})
|
||||
|
||||
(def privacy-policy
|
||||
{:margin-top 4
|
||||
:margin-horizontal 20
|
||||
:margin-bottom 20
|
||||
:align-items :center})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
(ns status-im.common.metrics-confirmation-modal.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.metrics-confirmation-modal.style :as style]
|
||||
@@ -52,14 +53,36 @@
|
||||
(toggle-metrics false)
|
||||
(hide-bottom-sheet))
|
||||
|
||||
(declare view)
|
||||
|
||||
(defn- on-privacy-policy-press
|
||||
[]
|
||||
[settings?]
|
||||
(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content (fn []
|
||||
[quo.theme/provider :dark
|
||||
[privacy/privacy-statement]])
|
||||
:shell? true}]))
|
||||
{:content (fn []
|
||||
[quo.theme/provider :dark
|
||||
[privacy/privacy-statement]])
|
||||
:on-close (fn []
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content (fn []
|
||||
[quo.theme/provider :dark
|
||||
[view {:settings? settings?}]])
|
||||
:shell? true}]))
|
||||
:shell? true}]))
|
||||
|
||||
(defn- privacy-policy-text
|
||||
[settings?]
|
||||
[rn/view {:style style/privacy-policy}
|
||||
[quo/text
|
||||
[quo/text
|
||||
{:style {:color colors/white-opa-50}
|
||||
:size :paragraph-2}
|
||||
(i18n/label :t/more-details-in-privacy-policy-1)]
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:weight :bold
|
||||
:on-press #(on-privacy-policy-press settings?)}
|
||||
(i18n/label :t/more-details-in-privacy-policy-2)]]])
|
||||
|
||||
(defn view
|
||||
[{:keys [settings?]}]
|
||||
@@ -79,22 +102,18 @@
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:style style/info-text}
|
||||
(i18n/label :t/usage-data-shared-from-all-profiles)
|
||||
(i18n/label :t/more-details-in-privacy-policy-1)
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:weight :bold
|
||||
:on-press on-privacy-policy-press}
|
||||
(i18n/label :t/more-details-in-privacy-policy-2)]]
|
||||
(i18n/label :t/usage-data-shared-from-all-profiles)]
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:style style/info-text}
|
||||
(i18n/label :t/usage-data-shared-from-all-profiles)
|
||||
(i18n/label :t/sharing-usage-data-can-be-turned-off)])]
|
||||
[quo/bottom-actions
|
||||
{:actions :two-actions
|
||||
:blur? true
|
||||
:button-one-label (i18n/label :t/share-usage-data)
|
||||
:button-one-props {:on-press on-share-usage}
|
||||
:button-two-label (i18n/label (if settings? :t/do-not-share :t/not-now))
|
||||
:button-two-label (i18n/label :t/not-now)
|
||||
:button-two-props {:type :grey
|
||||
:on-press on-do-not-share}}]])
|
||||
:on-press on-do-not-share}}]
|
||||
[privacy-policy-text settings?]])
|
||||
|
||||
@@ -10,12 +10,13 @@
|
||||
{:flex 1
|
||||
:flex-direction :row
|
||||
:flex-wrap :wrap
|
||||
:align-self :center})
|
||||
:align-self :flex-start})
|
||||
|
||||
(def terms-privacy-container
|
||||
{:gap 8
|
||||
{:flex-direction :row
|
||||
:padding-horizontal 20
|
||||
:padding-vertical 8})
|
||||
:padding-vertical 8
|
||||
:gap 8})
|
||||
|
||||
(def plain-text
|
||||
{:color colors/white-opa-70})
|
||||
|
||||
@@ -11,68 +11,92 @@
|
||||
[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)]
|
||||
(let [[terms-accepted? set-terms-accepted?] (rn/use-state false)
|
||||
from-v1-without-terms-accepted? (rf/sub [:profile/from-status-v1-without-terms-accepted?])]
|
||||
[rn/view {:style style/page-container}
|
||||
[background/view false]
|
||||
[quo/bottom-actions
|
||||
{: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
|
||||
:flex-direction :row}
|
||||
[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 {:flex 1}}
|
||||
[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}
|
||||
" & "]
|
||||
[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-statement)]]]]
|
||||
: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]))}}]
|
||||
(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?]}
|
||||
from-v1-without-terms-accepted?
|
||||
(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 from-v1-without-terms-accepted?)
|
||||
(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}))]
|
||||
[overlay/view]]))
|
||||
|
||||
@@ -2,13 +2,9 @@
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.resources :as resources]
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.common.controlled-input.utils :as controlled-input]
|
||||
[status-im.contexts.preview.quo.preview :as preview]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[utils.money :as money]))
|
||||
[status-im.contexts.preview.quo.preview :as preview]))
|
||||
|
||||
(def networks
|
||||
[{:source (resources/get-network :arbitrum)}
|
||||
@@ -16,75 +12,47 @@
|
||||
{:source (resources/get-network :ethereum)}])
|
||||
|
||||
(def title "Max: 200 SNT")
|
||||
(def conversion-rate 3450.28)
|
||||
|
||||
(def descriptor
|
||||
[{:key :token-symbol
|
||||
[{:key :token
|
||||
:type :select
|
||||
:options [{:key :eth}
|
||||
{:key :snt}]}
|
||||
{:key :currency
|
||||
:type :select
|
||||
:options [{:key "$"}
|
||||
{:key "€"}]}
|
||||
:options [{:key :usd}
|
||||
{:key :eur}]}
|
||||
{:key :error?
|
||||
:type :boolean}
|
||||
{:key :allow-selection?
|
||||
:type :boolean}])
|
||||
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [state (reagent/atom {:token-symbol :eth
|
||||
:currency "$"
|
||||
:crypto? true
|
||||
:error? false})]
|
||||
(let [state (reagent/atom {:token :eth
|
||||
:currency :usd
|
||||
:conversion 0.02
|
||||
:networks networks
|
||||
:title title
|
||||
:customization-color :blue
|
||||
:show-keyboard? false
|
||||
:allow-selection? true})
|
||||
value (reagent/atom "")
|
||||
set-value (fn [v]
|
||||
(swap! value str v))
|
||||
delete (fn [_]
|
||||
(swap! value #(subs % 0 (dec (count %)))))]
|
||||
(fn []
|
||||
(let [{:keys [currency token-symbol crypto? error?]} @state
|
||||
[input-state set-input-state] (rn/use-state controlled-input/init-state)
|
||||
input-amount (controlled-input/input-value input-state)
|
||||
swap-between-fiat-and-crypto (fn []
|
||||
(if crypto?
|
||||
(set-input-state #(controlled-input/->fiat
|
||||
%
|
||||
conversion-rate))
|
||||
(set-input-state
|
||||
#(controlled-input/->crypto
|
||||
%
|
||||
conversion-rate))))
|
||||
converted-value (if crypto?
|
||||
(utils/prettify-balance currency
|
||||
(money/crypto->fiat
|
||||
input-amount
|
||||
conversion-rate))
|
||||
(utils/prettify-crypto-balance
|
||||
(or (clj->js token-symbol) "")
|
||||
(money/fiat->crypto input-amount
|
||||
conversion-rate)
|
||||
conversion-rate))]
|
||||
[preview/preview-container
|
||||
{:state state
|
||||
:descriptor descriptor
|
||||
:full-screen? true
|
||||
:component-container-style {:flex 1
|
||||
:justify-content :space-between}}
|
||||
[quo/token-input
|
||||
{:token-symbol token-symbol
|
||||
:currency-symbol (if crypto? token-symbol currency)
|
||||
:error? error?
|
||||
:value input-amount
|
||||
:converted-value converted-value
|
||||
:on-swap (fn []
|
||||
(swap! state assoc :crypto? (not crypto?))
|
||||
(swap-between-fiat-and-crypto))
|
||||
:hint-component [quo/network-tags
|
||||
{:networks networks
|
||||
:title title
|
||||
:status (when (:error? @state) :error)}]}]
|
||||
[quo/numbered-keyboard
|
||||
{:container-style {:padding-bottom (safe-area/get-top)}
|
||||
:left-action :dot
|
||||
:delete-key? true
|
||||
:on-press (fn [c]
|
||||
(set-input-state #(controlled-input/add-character % c)))
|
||||
|
||||
:on-delete (fn []
|
||||
(set-input-state controlled-input/delete-last))}]]))))
|
||||
[preview/preview-container
|
||||
{:state state
|
||||
:descriptor descriptor
|
||||
:full-screen? true
|
||||
:component-container-style {:flex 1
|
||||
:justify-content :space-between}}
|
||||
[quo/token-input (assoc @state :value @value)]
|
||||
[quo/numbered-keyboard
|
||||
{:container-style {:padding-bottom (safe-area/get-top)}
|
||||
:left-action :dot
|
||||
:delete-key? true
|
||||
:on-press set-value
|
||||
:on-delete delete}]])))
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
(ns status-im.contexts.profile.data-store)
|
||||
|
||||
(defn accepted-terms?
|
||||
[accounts]
|
||||
(some #(:hasAcceptedTerms %) accounts))
|
||||
@@ -0,0 +1,14 @@
|
||||
(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}))))))
|
||||
@@ -4,10 +4,12 @@
|
||||
[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]))
|
||||
@@ -42,26 +44,27 @@
|
||||
(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)]
|
||||
(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]]]}))))
|
||||
(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]]])})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:profile/update-setting-from-backup
|
||||
@@ -82,3 +85,8 @@
|
||||
: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]}]]}))
|
||||
|
||||
@@ -12,17 +12,14 @@
|
||||
[full-name]
|
||||
(first (string/split full-name #" ")))
|
||||
|
||||
(defn cut-fiat-balance-to-two-decimals
|
||||
[balance]
|
||||
(defn prettify-balance
|
||||
[currency-symbol balance]
|
||||
(let [valid-balance? (and balance
|
||||
(or (number? balance) (.-toFixed balance)))]
|
||||
(as-> balance $
|
||||
(if valid-balance? $ 0)
|
||||
(.toFixed $ 2))))
|
||||
|
||||
(defn prettify-balance
|
||||
[currency-symbol balance]
|
||||
(str currency-symbol (cut-fiat-balance-to-two-decimals balance)))
|
||||
(.toFixed $ 2)
|
||||
(str currency-symbol $))))
|
||||
|
||||
(defn get-derivation-path
|
||||
[number-of-accounts]
|
||||
@@ -50,8 +47,8 @@
|
||||
nil))
|
||||
|
||||
(defn calc-max-crypto-decimals
|
||||
[one-cent-value]
|
||||
(let [str-representation (str one-cent-value)
|
||||
[value]
|
||||
(let [str-representation (str value)
|
||||
decimal-part (second (clojure.string/split str-representation #"\."))
|
||||
exponent (extract-exponent str-representation)
|
||||
zeroes-count (count (take-while #(= \0 %) decimal-part))
|
||||
@@ -61,60 +58,29 @@
|
||||
(inc max-decimals)
|
||||
max-decimals)))
|
||||
|
||||
(defn token-usd-price
|
||||
[token]
|
||||
(get-in token [:market-values-per-currency :usd :price]))
|
||||
|
||||
(defn one-cent-value
|
||||
[token-price-in-usd]
|
||||
(if (pos? token-price-in-usd)
|
||||
(/ 0.01 token-price-in-usd)
|
||||
0))
|
||||
|
||||
(defn analyze-token-amount-for-price
|
||||
"For full details: https://github.com/status-im/status-mobile/issues/18225"
|
||||
[token-price-in-usd token-units]
|
||||
(if (or (nil? token-units)
|
||||
(not (money/bignumber? token-units))
|
||||
(money/equal-to token-units 0))
|
||||
{:zero-value? true}
|
||||
(let [cent-value (one-cent-value token-price-in-usd)]
|
||||
{:usd-cent-value cent-value
|
||||
:standardized-decimals-count (if (nil? token-price-in-usd)
|
||||
missing-price-decimals
|
||||
(calc-max-crypto-decimals cent-value))})))
|
||||
|
||||
(defn cut-crypto-decimals-to-fit-usd-cents
|
||||
[token-units token-price-in-usd]
|
||||
(let [{:keys [zero-value? usd-cent-value standardized-decimals-count]}
|
||||
(analyze-token-amount-for-price token-price-in-usd token-units)]
|
||||
(cond
|
||||
zero-value? "0"
|
||||
(< token-units usd-cent-value) "0"
|
||||
:else (number/remove-trailing-zeroes
|
||||
(.toFixed token-units standardized-decimals-count)))))
|
||||
|
||||
(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)))
|
||||
(defn get-crypto-decimals-count
|
||||
[{:keys [market-values-per-currency]}]
|
||||
(let [price (get-in market-values-per-currency [:usd :price])
|
||||
one-cent-value (if (pos? price) (/ 0.01 price) 0)]
|
||||
(calc-max-crypto-decimals one-cent-value)))
|
||||
|
||||
(defn get-standard-crypto-format
|
||||
"For full details: https://github.com/status-im/status-mobile/issues/18225"
|
||||
[token token-units]
|
||||
(let [token-price-in-usd (token-usd-price token)
|
||||
{:keys [zero-value? usd-cent-value standardized-decimals-count]}
|
||||
(analyze-token-amount-for-price token-price-in-usd token-units)]
|
||||
(cond
|
||||
zero-value?
|
||||
"0"
|
||||
[{:keys [market-values-per-currency]} token-units]
|
||||
(cond (or (nil? token-units)
|
||||
(money/equal-to token-units 0))
|
||||
"0"
|
||||
|
||||
(< token-units usd-cent-value)
|
||||
(str "<" (number/remove-trailing-zeroes (.toFixed usd-cent-value standardized-decimals-count)))
|
||||
(nil? (-> market-values-per-currency :usd :price))
|
||||
(number/remove-trailing-zeroes (.toFixed token-units missing-price-decimals))
|
||||
|
||||
:else
|
||||
(number/remove-trailing-zeroes (.toFixed token-units standardized-decimals-count)))))
|
||||
:else
|
||||
(let [price (-> market-values-per-currency :usd :price)
|
||||
one-cent-value (if (pos? price) (/ 0.01 price) 0)
|
||||
decimals-count (calc-max-crypto-decimals one-cent-value)]
|
||||
(if (< token-units one-cent-value)
|
||||
(str "<" (number/remove-trailing-zeroes (.toFixed one-cent-value decimals-count)))
|
||||
(number/remove-trailing-zeroes (.toFixed token-units decimals-count))))))
|
||||
|
||||
(defn get-market-value
|
||||
[currency {:keys [market-values-per-currency]}]
|
||||
@@ -320,6 +286,18 @@
|
||||
(let [counter (count address)]
|
||||
(str (subs address 0 6) "\u2026" (subs address (- counter 3) counter)))))
|
||||
|
||||
(defn make-limit-label-crypto
|
||||
[amount currency]
|
||||
(str amount
|
||||
" "
|
||||
(some-> currency
|
||||
name
|
||||
string/upper-case)))
|
||||
|
||||
(defn make-limit-label-fiat
|
||||
[amount currency-symbol]
|
||||
(str currency-symbol amount))
|
||||
|
||||
(defn get-account-name-error
|
||||
[s existing-account-names]
|
||||
(cond
|
||||
|
||||