Compare commits

..
Author SHA1 Message Date
Brian Sztamfater 984bc74b6d lint fixes 2023-12-05 02:31:24 -03:00
Brian Sztamfater 17cd163f25 some cleanup 2023-12-05 02:23:06 -03:00
Brian Sztamfater f3c967f26b improve flow 2023-12-05 01:13:05 -03:00
Brian Sztamfater 9f78eaa91d integrate select input screen to the flow, also calculate routes prior showing transaction confirmation screen 2023-12-04 21:46:33 -03:00
Brian Sztamfater 778b06abb2 some refactor 2023-12-04 20:48:48 -03:00
Brian Sztamfater 68d7eddb4d only allow ETH transfers for now 2023-12-04 20:48:48 -03:00
Brian Sztamfater c7165cf078 calculate fiat balances correctly and some other fixes 2023-12-04 20:48:46 -03:00
Brian Sztamfater 50dcf9d9b9 goerli as default suggested routes network 2023-12-04 20:48:22 -03:00
Brian Sztamfater 372bf83da5 some polishing 2023-12-04 20:48:21 -03:00
Brian Sztamfater 710829d248 fix endpoints integration 2023-12-04 20:47:45 -03:00
Brian Sztamfater 23fae29f9d try basic integration 2023-12-04 20:47:42 -03:00
Brian Sztamfater daf3e52281 some cleanup 2023-12-04 20:46:45 -03:00
Jamie Caprani 3338a4b1a1 chore 2023-12-04 20:03:28 -03:00
Jamie Caprani 9ead91c383 progress 2023-12-04 20:02:09 -03:00
Ajay Sivan fb84885af0 Add Test Networks Enabled option in settings 2023-12-04 19:59:06 -03:00
Ulises M 4aac04e931 Add utils.money/add version able to work with nils 2023-12-04 19:59:05 -03:00
Brian Sztamfater 90166e8762 some refactor 2023-12-01 13:38:57 -03:00
Brian Sztamfater d68fdb18f4 adjustment to summary info component 2023-12-01 13:38:57 -03:00
Brian Sztamfater e46f4d9081 adjust text color 2023-12-01 13:38:56 -03:00
Brian Sztamfater dd2fd3410b some refactor 2023-12-01 13:38:56 -03:00
Brian Sztamfater 085e2df34c localize strings 2023-12-01 13:38:55 -03:00
Brian Sztamfater 51bfd3567c most of the ui in place, polishing pending 2023-12-01 13:38:54 -03:00
Brian Sztamfater fb6d907cc5 some progress 2023-12-01 13:38:54 -03:00
Brian Sztamfater a88c5b7bf7 feat: transaction confirmation page ui 2023-12-01 13:38:52 -03:00
148 changed files with 2178 additions and 1944 deletions
+1
View File
@@ -95,6 +95,7 @@ react-native.fs/unlink
react-native.fs/file-exists?
status-im.ui.components.colors/white
status-im.ui.components.colors/black
status-im.transport.core-test/messages
status-im.ui.components.core/animated-header
status-im.ui.components.core/safe-area-provider
status-im.ui.components.core/safe-area-consumer
-1
View File
@@ -32,7 +32,6 @@
"letsubs" :binding
"with-let" "let"
"reg-event-fx" :arg1-pair
"reg-fx" :arg1-pair
"testing" :arg1-body
"deftest-sub" :arg1-body
"wait-for" :arg1-body
@@ -27,23 +27,18 @@ class StatusOkHttpClientFactory implements OkHttpClientFactory {
X509Certificate cert = null;
HandshakeCertificates clientCertificates;
String certPem = "";
// Get TLS PEM certificate from status-go
try {
// induce half second sleep because sometimes a cert is not immediately available
// TODO : remove sleep if App no longer crashes on Android 10 devices with
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
Thread.sleep(500);
certPem = getCertificatePem();
} catch(Exception e) {
Log.e(TAG, "Could not getImageTLSCert",e);
}
if (certPem.isEmpty()) {
Log.e(TAG, "Certificate is empty, cannot create OkHttpClient without a valid certificate");
return null;
}
// Convert PEM certificate string to X509Certificate object
// Get TLS PEM certificate from status-go
try {
// induce half second sleep because sometimes a cert is not immediately available
// TODO : remove sleep if App no longer crashes on Android 10 devices with
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
Thread.sleep(500);
certPem = StatusPackage.getImageTLSCert();
} catch(Exception e) {
Log.e(TAG, "Could not getImageTLSCert",e);
}
// Convert PEM certificate string to X509Certificate object
try {
// induce half second sleep because sometimes a cert is not immediately available
// TODO : remove sleep if App no longer crashes on Android 10 devices
@@ -79,17 +74,4 @@ class StatusOkHttpClientFactory implements OkHttpClientFactory {
return null;
}
}
private String getCertificatePem() {
try {
String certPem = StatusPackage.getImageTLSCert();
if (certPem == null || certPem.trim().isEmpty()) {
Log.e(TAG, "Certificate PEM string is null or empty");
return "";
}
return certPem;
} catch (Exception e) {
Log.e(TAG, "Could not getImageTLSCert", e);
return "";
}
}
}
+1 -1
View File
@@ -94,7 +94,7 @@
"process": "0.11.10",
"react-test-renderer": "18.0.0",
"rn-snoopy": "git+https://github.com/status-im/rn-snoopy.git#refs/tags/v2.0.2-status",
"shadow-cljs": "2.26.2"
"shadow-cljs": "2.25.0"
},
"binary": {
"module_name": "status_nodejs_addon",
+2 -3
View File
@@ -12,10 +12,9 @@
[metosin/malli "0.13.0"]
;; Dev dependencies
[refactor-nrepl "3.9.1"]
[cider/cider-nrepl "0.31.0"]
[refactor-nrepl "2.5.0"]
[cider/cider-nrepl "0.25.3"]
[cider/piggieback "0.4.1"]
[org.slf4j/slf4j-nop "2.0.9"]
[re-frisk-remote "1.6.0"]
;; Use the same version specified in the Nix dependency.
@@ -1,17 +0,0 @@
(ns quo.components.ios.drawer-bar.style
(:require
[quo.foundations.colors :as colors]
[quo.theme :as theme]))
(def handle-container
{:padding-vertical 8
:height 20
:align-items :center})
(defn handle
[{:keys [theme]}]
{:width 32
:height 4
:background-color (colors/theme-colors colors/neutral-100 colors/white theme)
:opacity (theme/theme-value 0.05 0.1 theme)
:border-radius 100})
@@ -1,12 +0,0 @@
(ns quo.components.ios.drawer-bar.view
(:require
[quo.components.ios.drawer-bar.style :as style]
[quo.theme :as quo.theme]
[react-native.core :as rn]))
(defn- view-internal
[props]
[rn/view {:style style/handle-container}
[rn/view {:style (style/handle props)}]])
(def view (quo.theme/with-theme view-internal))
@@ -13,7 +13,7 @@
(h/render [account/view])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor (colors/resolve-color :blue :light 5)})))
{:backgroundColor (colors/custom-color :blue 50 5)})))
(h/test "on-press-in changes state to :pressed with blur? enabled"
(h/render [account/view {:blur? true}])
@@ -21,26 +21,31 @@
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor colors/white-opa-5})))
(h/test "render with state :active"
(h/render [account/view {:state :active}])
(h/has-style (h/query-by-label-text :container)
{:backgroundColor (colors/resolve-color :blue :light 10)}))
(h/test "on-press-out changes state to :active"
(h/render [account/view])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/fire-event :on-press-out (h/get-by-label-text :container))
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor (colors/custom-color :blue 50 10)})))
(h/test "render with state :active and blur? enabled"
(h/render [account/view
{:blur? true
:state :active}])
(h/has-style (h/query-by-label-text :container)
{:backgroundColor colors/white-opa-10}))
(h/test "on-press-out changes state to :active with blur? enabled"
(h/render [account/view {:blur? true}])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/fire-event :on-press-out (h/get-by-label-text :container))
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor colors/white-opa-10})))
(h/test "render with state :selected"
(h/render [account/view {:state :selected}])
(h/is-truthy (h/query-by-label-text :check-icon)))
(h/test "on-press-out changes state to :selected"
(h/render [account/view {:selectable? true}])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/fire-event :on-press-out (h/get-by-label-text :container))
(h/wait-for #(h/is-truthy (h/query-by-label-text :check-icon))))
(h/test "calls on-press"
(h/test "on-press-out calls on-press"
(let [on-press (h/mock-fn)]
(h/render [account/view {:on-press on-press}])
(h/fire-event :on-press (h/get-by-label-text :container))
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/fire-event :on-press-out (h/get-by-label-text :container))
(h/was-called on-press)))
(h/test "renders token props if type :tag"
@@ -3,12 +3,12 @@
[quo.foundations.colors :as colors]))
(defn- background-color
[{:keys [state pressed? blur? customization-color]}]
(cond (or pressed? (= state :selected))
(if blur? colors/white-opa-5 (colors/resolve-color customization-color :light 5))
[{:keys [state blur? customization-color]}]
(cond (or (= state :pressed) (= state :selected))
(if blur? colors/white-opa-5 (colors/custom-color customization-color 50 5))
(= state :active)
(if blur? colors/white-opa-10 (colors/resolve-color customization-color :light 10))
(and pressed? blur?) colors/white-opa-10
(if blur? colors/white-opa-10 (colors/custom-color customization-color 50 10))
(and (= state :pressed) blur?) colors/white-opa-10
:else :transparent))
(defn container
+51 -31
View File
@@ -94,42 +94,62 @@
[icon/icon :i/check
{:color (if blur?
colors/white
(colors/resolve-color customization-color theme))}]])
(colors/theme-colors (colors/custom-color customization-color 50)
(colors/custom-color customization-color 60)
theme))}]])
(defn- internal-view
[_]
(let [pressed? (reagent/atom false)
on-press-in #(reset! pressed? true)
on-press-out #(reset! pressed? false)]
(fn [{:keys [type state blur? customization-color on-press]
(defn- f-internal-view
[]
(let [state (reagent/atom :default)
active-or-selected? (atom false)
timer (atom nil)
on-press-in (fn []
(when-not (= @state :selected)
(reset! timer (js/setTimeout #(reset! state :pressed) 100))))]
(fn [{:keys [type selectable? blur? customization-color on-press]
:or {customization-color :blue
type :default
state :default
blur? false}
:as props}]
[rn/pressable
{:style (style/container
{:state state
:blur? blur?
:customization-color customization-color
:pressed? @pressed?})
:on-press-in on-press-in
:on-press on-press
:on-press-out on-press-out
:accessibility-label :container}
[account-view props]
[rn/view {:style (when (= type :tag) style/token-tag-container)}
(cond
(#{:balance-neutral :balance-negative :balance-positive} type)
[balance-view props]
(let [on-press-out (fn []
(let [new-state (if @active-or-selected?
:default
(if (and (= type :default) selectable?)
:selected
:active))]
(when @timer (js/clearTimeout @timer))
(reset! timer nil)
(reset! active-or-selected? (or (= new-state :active)
(= new-state :selected)))
(reset! state new-state)
(when on-press
(on-press))))]
(rn/use-effect
#(cond (and selectable? (= type :default) (= @state :active)) (reset! state :selected)
(and (not selectable?) (= type :default) (= @state :selected)) (reset! state :active))
[selectable?])
[rn/pressable
{:style (style/container
{:state @state :blur? blur? :customization-color customization-color})
:on-press-in on-press-in
:on-press-out on-press-out
:accessibility-label :container}
[account-view props]
[rn/view {:style (when (= type :tag) style/token-tag-container)}
(when (or (= type :balance-neutral)
(= type :balance-negative)
(= type :balance-positive))
[balance-view props])
(when (= type :tag)
[token-tag props])
(when (= type :action)
[options-button props])
(when (and (= type :default)
(= @state :selected))
[check-icon props])]]))))
(= type :tag)
[token-tag props]
(= type :action)
[options-button props]
(and (= type :default) (= state :selected))
[check-icon props])]])))
(defn- internal-view
[props]
[:f> f-internal-view props])
(def view (quo.theme/with-theme internal-view))
+27 -18
View File
@@ -17,21 +17,30 @@
{:width size})))
(defn base-tag
[{:keys [id size disabled? border-color border-width background-color on-press
accessibility-label type labelled?]
:or {size 32}}
children]
[rn/touchable-without-feedback
(merge {:disabled disabled?
:accessibility-label accessibility-label}
(when on-press
{:on-press #(on-press id)}))
[rn/view
{:style (merge (style-container size
disabled?
border-color
border-width
background-color
labelled?
type))}
children]])
[_]
(fn
[{:keys [id
size
disabled?
border-color
border-width
background-color
on-press
accessibility-label
type
labelled?]
:or {size 32}} children]
[rn/touchable-without-feedback
(merge {:disabled disabled?
:accessibility-label accessibility-label}
(when on-press
{:on-press #(on-press id)}))
[rn/view
{:style (merge (style-container size
disabled?
border-color
border-width
background-color
labelled?
type))}
children]]))
+39 -30
View File
@@ -4,7 +4,7 @@
[quo.components.markdown.text :as text]
[quo.components.tags.base-tag :as base-tag]
[quo.foundations.colors :as colors]
[quo.theme]
[quo.theme :as theme]
[react-native.core :as rn]))
(def themes
@@ -66,45 +66,54 @@
text-color)
label])])
(defn tag-internal
(defn tag
"opts
{:type :icon/:emoji/:label
:label string
:size 32/24
:on-press fn
:blurred? true/false
:blurred? true/false
:resource icon/image
:labelled? true/false
:disabled? true/false}
opts
- `blurred` boolean: use to determine border color if the background is blurred
- `type` can be icon or emoji with or without a tag label
- `labelled` boolean: is true if tag has label else false"
[{:keys [id on-press disabled? size active accessibility-label label resource type
labelled? blurred? icon-color theme]
:or {size 32}}]
(let [state (cond
disabled? :disabled
active :active
:else :default)
{:keys [border-color
blurred-border-color
text-color]} (get-in themes [theme state])]
[rn/view {:style {:align-items :center}}
[base-tag/base-tag
{:id id
:size size
:border-width 1
:border-color (if blurred?
blurred-border-color
border-color)
:on-press on-press
:accessibility-label accessibility-label
:disabled? disabled?
:type type
:labelled? (if (= type :label) true labelled?)}
[tag-resources size type resource icon-color label text-color labelled?]]]))
(def tag (quo.theme/with-theme tag-internal))
[_ _]
(fn
[{:keys [id
on-press
disabled?
size
active
accessibility-label
label
resource
type
labelled?
blurred?
icon-color
override-theme]
:or {size 32}}]
(let [state (cond disabled? :disabled
active :active
:else :default)
{:keys [border-color blurred-border-color text-color]}
(get-in themes [(or override-theme (theme/get-theme)) state])]
[rn/view {:style {:align-items :center}}
[base-tag/base-tag
{:id id
:size size
:border-width 1
:border-color (if blurred?
blurred-border-color
border-color)
:on-press on-press
:accessibility-label accessibility-label
:disabled? disabled?
:type type
:labelled? (if (= type :label) true labelled?)}
[tag-resources size type resource icon-color label text-color labelled?]]])))
@@ -1,51 +0,0 @@
(ns quo.components.text-combinations.standard-title.component-spec
(:require [quo.components.text-combinations.standard-title.view :as standard-title]
[test-helpers.component :as h]))
(h/describe "Text combinations - Standard title"
(h/test "Default render"
(h/render [standard-title/view {:title "This is a title"}])
(h/is-truthy (h/get-by-text "This is a title")))
(h/test "Counter variant"
(h/render [standard-title/view
{:title "This is a title"
:right :counter
:counter-left 50
:counter-right 100}])
(h/is-truthy (h/get-by-text "50/100")))
(h/describe "Action variant"
(h/test "Default render"
(let [on-press-fn (h/mock-fn)]
(h/render [standard-title/view
{:title "This is a title"
:right :action
:on-press on-press-fn}])
(h/is-truthy (h/get-by-text "This is a title"))))
(h/test "Action fired"
(let [on-press-fn (h/mock-fn)]
(h/render [standard-title/view
{:title "This is a title"
:right :action
:on-press on-press-fn}])
(h/fire-event :on-press (h/get-by-label-text :standard-title-action))
(h/was-called-times on-press-fn 1))))
(h/describe "Tag variant"
(h/test "Default render"
(h/render [standard-title/view
{:title "This is a title"
:right :tag}])
(h/is-truthy (h/get-by-text "This is a title")))
(h/test "Tag callback fired"
(let [on-press-fn (h/mock-fn)]
(h/render [standard-title/view
{:title "This is a title"
:right :tag
:on-press on-press-fn}])
(h/fire-event :on-press (h/get-by-label-text :standard-title-tag))
(h/was-called-times on-press-fn 1)))))
@@ -1,24 +0,0 @@
(ns quo.components.text-combinations.standard-title.style
(:require [quo.foundations.colors :as colors]))
(def container
{:flex-direction :row
:justify-content :space-between})
(def right-container {:margin-left 20})
(def right-counter
{:padding-top 12
:padding-bottom 2})
(defn right-counter-text
[blur? theme]
{:color (if blur?
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
(colors/theme-colors colors/neutral-40 colors/neutral-50 theme))})
(defn right-tag-icon-color
[blur? theme]
(if blur?
(colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 theme)
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
@@ -1,68 +0,0 @@
(ns quo.components.text-combinations.standard-title.view
(:require [clojure.string :as string]
[quo.components.buttons.button.view :as button]
[quo.components.markdown.text :as text]
[quo.components.tags.tag :as tag]
[quo.components.text-combinations.standard-title.style :as style]
[quo.theme]
[react-native.core :as rn]
[utils.number]))
(defn- get-counter-number
[n]
(let [parsed-number (utils.number/parse-int n)]
(if (< n 10)
(str "0" parsed-number)
parsed-number)))
(defn- right-counter
[{:keys [blur? theme counter-left counter-right]}]
[rn/view {:style style/right-counter}
[text/text
{:size :paragraph-2
:weight :regular
:style (style/right-counter-text blur? theme)}
(str (get-counter-number counter-left)
"/"
(get-counter-number counter-right))]])
(defn- right-action
[{:keys [customization-color on-press icon]
:or {icon :i/placeholder}}]
[button/button
{:accessibility-label :standard-title-action
:size 32
:icon-only? true
:customization-color customization-color
:on-press on-press}
icon])
(defn- right-tag
[{:keys [theme blur? on-press icon label]
:or {icon :i/placeholder}}]
(let [labelled? (not (string/blank? label))]
[tag/tag
{:accessibility-label :standard-title-tag
:size 32
:type :icon
:resource icon
:on-press on-press
:labelled? labelled?
:label (when labelled? label)
:blurred? blur?
:icon-color (style/right-tag-icon-color blur? theme)}]))
(defn- view-internal
[{:keys [title right] :as props}]
[rn/view {:style style/container}
[text/text {:size :heading-1 :weight :semi-bold}
title]
(when right
[rn/view {:style style/right-container}
(case right
:counter [right-counter props]
:action [right-action props]
:tag [right-tag props]
nil)])])
(def view (quo.theme/with-theme view-internal))
@@ -20,13 +20,12 @@
(i18n/label :t/trip-accounts))])
(defn- row-icon
[customization-color profile-picture type secondary-color]
[profile-picture type secondary-color]
(case type
:default-keypair [user-avatar/user-avatar
{:size :xxs
:ring? false
:customization-color customization-color
:profile-picture profile-picture}]
{:size :xxs
:ring? false
:profile-picture profile-picture}]
:recovery-phrase [icons/icon
:i/seed
{:accessibility-label :recovery-phrase-icon
@@ -42,11 +41,10 @@
nil))
(defn- row-view
[{:keys [type theme secondary-color customization-color profile-picture title stored subtitle
on-press]}]
[{:keys [type theme secondary-color profile-picture title stored subtitle on-press]}]
[rn/view {:style (style/row-container type theme)}
[rn/view {:style style/icon-container}
[row-icon customization-color profile-picture type secondary-color]]
[row-icon profile-picture type secondary-color]]
[rn/view
{:style style/row-content-container}
[row-title type title]
@@ -70,19 +68,18 @@
{:color secondary-color}]])])
(defn- list-view
[{:keys [type stored customization-color profile-picture user-name theme secondary-color]}]
[{:keys [type stored profile-picture user-name theme secondary-color]}]
(let [stored-name (if (= :on-device stored)
(i18n/label :t/on-device)
(i18n/label :t/on-keycard))]
[row-view
{:type type
:stored stored
:customization-color customization-color
:profile-picture profile-picture
:title user-name
:subtitle stored-name
:theme theme
:secondary-color secondary-color}]))
{:type type
:stored stored
:profile-picture profile-picture
:title user-name
:subtitle stored-name
:theme theme
:secondary-color secondary-color}]))
(defn- card-view
[theme derivation-path secondary-color on-press]
@@ -108,13 +105,12 @@
(def view
"Create an account-origin UI component.
| key | values |
| ----------------------|------------------------------------------------|
| :type | :default-keypair :recovery-phrase :private-key
| :stored | :on-device :on-keycard
| :profile-picture | image source
| :customization-color | profile color
| :derivation-path | string
| :user-name | string
| :on-press | function"
| key | values |
| ------------------|------------------------------------------------|
| :type | :default-keypair :recovery-phrase :private-key
| :stored | :on-device :on-keycard
| :profile-picture | image source
| :derivation-path | string
| :user-name | string
| :on-press | function"
(quo.theme/with-theme view-internal))
@@ -4,7 +4,7 @@
(defn container
[networks? theme]
{:width 335
{:width "100%"
:height (if networks? 90 56)
:border-radius 16
:border-width 1
@@ -43,7 +43,7 @@
:align-items :flex-end}}
[rn/image
{:style style/token
:source (resources/get-token token)}]
:source (resources/get-token (keyword (string/lower-case token)))}]
[rn/text-input
(cond-> {:auto-focus true
:ref #(reset! input-ref %)
+1 -7
View File
@@ -66,7 +66,6 @@
quo.components.inputs.recovery-phrase.view
quo.components.inputs.search-input.view
quo.components.inputs.title-input.view
quo.components.ios.drawer-bar.view
quo.components.keycard.view
quo.components.links.link-preview.view
quo.components.links.url-preview-list.view
@@ -140,7 +139,6 @@
quo.components.tags.tiny-tag.view
quo.components.tags.token-tag.view
quo.components.text-combinations.channel-name.view
quo.components.text-combinations.standard-title.view
quo.components.text-combinations.view
quo.components.wallet.account-card.view
quo.components.wallet.account-origin.view
@@ -269,9 +267,6 @@
(def search-input quo.components.inputs.search-input.view/search-input)
(def title-input quo.components.inputs.title-input.view/view)
;;;; iOS
(def drawer-bar quo.components.ios.drawer-bar.view/view)
;;;; Numbered Keyboard
(def keyboard-key quo.components.numbered-keyboard.keyboard-key.view/view)
(def numbered-keyboard quo.components.numbered-keyboard.numbered-keyboard.view/view)
@@ -380,9 +375,8 @@
(def token-tag quo.components.tags.token-tag.view/view)
;;;; Text combinations
(def channel-name quo.components.text-combinations.channel-name.view/view)
(def standard-title quo.components.text-combinations.standard-title.view/view)
(def text-combinations quo.components.text-combinations.view/view)
(def channel-name quo.components.text-combinations.channel-name.view/view)
;;;; Wallet
(def account-card quo.components.wallet.account-card.view/view)
+17 -18
View File
@@ -5,11 +5,11 @@
[goog.object :as object]
[re-frame.core :as re-frame]
[status-im.chat.models.mentions :as mentions]
[status-im.chat.models.message :as chat.message]
[status-im.chat.models.message-content :as message-content]
[status-im.data-store.messages :as data-store-messages]
[status-im2.constants :as constants]
[status-im2.contexts.chat.composer.link-preview.events :as link-preview]
[status-im2.contexts.chat.messages.transport.events :as messages.transport]
[taoensso.timbre :as log]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
@@ -205,7 +205,7 @@
(rf/merge cofx
(clean-input (:current-chat-id db))
(link-preview/reset-unfurled)
(messages.transport/send-chat-messages messages)))))
(chat.message/send-messages messages)))))
(rf/defn send-audio-message
[{:keys [db] :as cofx} audio-path duration current-chat-id]
@@ -214,26 +214,25 @@
(when-not (string/blank? audio-path)
(rf/merge
{:db (assoc-in db [:chat/inputs current-chat-id :metadata :responding-to-message] nil)}
(messages.transport/send-chat-messages
[(merge
{:chat-id current-chat-id
:content-type constants/content-type-audio
:audio-path audio-path
:audio-duration-ms duration
:text (i18n/label :t/update-to-listen-audio {"locale" "en"})}
(when message-id
{:response-to message-id}))])))))
(chat.message/send-message
(merge
{:chat-id current-chat-id
:content-type constants/content-type-audio
:audio-path audio-path
:audio-duration-ms duration
:text (i18n/label :t/update-to-listen-audio {"locale" "en"})}
(when message-id
{:response-to message-id})))))))
(rf/defn send-sticker-message
[cofx {:keys [hash packID pack]} current-chat-id]
(when-not (or (string/blank? hash) (and (string/blank? packID) (string/blank? pack)))
(messages.transport/send-chat-messages
cofx
[{:chat-id current-chat-id
:content-type constants/content-type-sticker
:sticker {:hash hash
:pack (int (if (string/blank? packID) pack packID))}
:text (i18n/label :t/update-to-see-sticker {"locale" "en"})}])))
(chat.message/send-message cofx
{:chat-id current-chat-id
:content-type constants/content-type-sticker
:sticker {:hash hash
:pack (int (if (string/blank? packID) pack packID))}
:text (i18n/label :t/update-to-see-sticker {"locale" "en"})})))
(rf/defn send-edited-message
[{:keys [db]
+2 -2
View File
@@ -76,9 +76,9 @@
(rf/defn handle-mark-all-read-in-community-successful
{:events [::mark-all-read-in-community-successful]}
[{:keys [db] :as cofx} {:keys [chats] :as _messenger-response}]
[{:keys [db] :as cofx} chat-ids]
(rf/merge cofx
{:db (reduce mark-chat-all-read db (map :id chats))
{:db (reduce mark-chat-all-read db chat-ids)
:dispatch [:activity-center.notifications/fetch-unread-count]}))
(rf/defn handle-mark-all-read
+15
View File
@@ -5,6 +5,7 @@
[react-native.platform :as platform]
[status-im.chat.models.loading :as chat.loading]
[status-im.data-store.messages :as data-store.messages]
[status-im.transport.message.protocol :as protocol]
[status-im.utils.deprecated-types :as types]
[status-im2.contexts.chat.messages.delete-message.events :as delete-message]
[status-im2.contexts.chat.messages.list.events :as message-list]
@@ -20,6 +21,12 @@
[db chat-id clock-value]
(>= (get-in db [:chats chat-id :deleted-at-clock-value]) clock-value))
(defn add-timeline-message
[acc chat-id message-id message]
(-> acc
(update-in [:db :messages chat-id] assoc message-id message)
(update-in [:db :message-lists chat-id] message-list/add message)))
(defn hide-message
"Hide chat message, rebuild message-list"
[{:keys [db]} chat-id message-id]
@@ -138,6 +145,14 @@
:on-error #(log/error "failed to re-send message" %)}]}
(update-message-status chat-id message-id :sending)))
(rf/defn send-message
[cofx message]
(protocol/send-chat-messages cofx [message]))
(rf/defn send-messages
[cofx messages]
(protocol/send-chat-messages cofx messages))
(rf/defn handle-removed-messages
{:events [::handle-removed-messages]}
[{:keys [db] :as cofx} removed-messages]
+18
View File
@@ -2,6 +2,7 @@
(:require
[re-frame.core :as re-frame]
[status-im.data-store.reactions :as data-store.reactions]
[status-im.transport.message.protocol :as message.protocol]
[status-im2.constants :as constants]
[taoensso.timbre :as log]
[utils.re-frame :as rf]
@@ -62,6 +63,23 @@
(let [reactions-w-chat-id (map #(assoc % :chat-id chat-id) reactions)]
{:db (update db :reactions (process-reactions (:chats db)) reactions-w-chat-id)})))
;; Send reactions
(rf/defn send-emoji-reaction
{:events [:models.reactions/send-emoji-reaction]}
[{{:keys [current-chat-id]} :db :as cofx} reaction]
(message.protocol/send-reaction cofx
(update reaction :chat-id #(or % current-chat-id))))
(rf/defn send-retract-emoji-reaction
{:events [:models.reactions/send-emoji-reaction-retraction]}
[{{:keys [current-chat-id]} :db :as cofx} reaction]
(message.protocol/send-retract-reaction cofx
(update reaction :chat-id #(or % current-chat-id))))
(defn message-reactions
[current-public-key reactions]
(reduce
+1 -1
View File
@@ -14,6 +14,6 @@
(rf/merge cofx
(multiaccounts.update/multiaccount-update
:currency
currency
"USD"
{})
(prices/update-prices)))
+6 -4
View File
@@ -32,7 +32,9 @@
status-im.pairing.core
status-im.profile.core
status-im.search.core
status-im.signals.core
status-im.stickers.core
status-im.transport.core
status-im.ui.components.invite.events
[status-im.ui.components.react :as react]
status-im.ui.screens.notifications-settings.events
@@ -134,7 +136,7 @@
(rf/defn on-return-from-background
[{:keys [db now] :as cofx}]
(let [new-account? (get db :onboarding/new-account?)
(let [new-account? (get db :onboarding-2/new-account?)
app-in-background-since (get db :app-in-background-since)
signed-up? (get-in db [:profile/profile :signed-up?])
requires-bio-auth (and
@@ -192,9 +194,9 @@
(rf/merge cofx
(cond
(= :chat view-id)
{:effects.async-storage/set {:chat-id (get-in cofx [:db :current-chat-id])
:key-uid (get-in cofx [:db :profile/profile :key-uid])}
:db (assoc db :screens/was-focused-once? true)}
{:async-storage-set {:chat-id (get-in cofx [:db :current-chat-id])
:key-uid (get-in cofx [:db :profile/profile :key-uid])}
:db (assoc db :screens/was-focused-once? true)}
(not (get db :screens/was-focused-once?))
{:db (assoc db :screens/was-focused-once? true)})
+23 -23
View File
@@ -141,14 +141,14 @@
(let [pin (get-in db [:keycard :pin :original])
puk-restore? (get-in db [:keycard :pin :puk-restore?])]
(rf/merge cofx
{:db (assoc-in db
[:keycard :pin]
{:status nil
:login pin
:confirmation []
:error-label nil})
:effects.utils/show-popup {:title ""
:content (i18n/label :t/pin-changed)}}
{:db (assoc-in db
[:keycard :pin]
{:status nil
:login pin
:confirmation []
:error-label nil})
:utils/show-popup {:title ""
:content (i18n/label :t/pin-changed)}}
(common/hide-connection-sheet)
(if puk-restore?
(navigation/navigate-to :multiaccounts nil)
@@ -160,14 +160,14 @@
{:events [:keycard.callback/on-change-puk-success]}
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db (assoc-in db
[:keycard :pin]
{:status nil
:puk-original []
:puk-confirmation []
:error-label nil})
:effects.utils/show-popup {:title ""
:content (i18n/label :t/puk-changed)}}
{:db (assoc-in db
[:keycard :pin]
{:status nil
:puk-original []
:puk-confirmation []
:error-label nil})
:utils/show-popup {:title ""
:content (i18n/label :t/puk-changed)}}
(common/hide-connection-sheet)
(navigation/set-stack-root :profile-stack [:my-profile :keycard-settings])))
@@ -175,13 +175,13 @@
{:events [:keycard.callback/on-change-pairing-success]}
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db (assoc-in db
[:keycard :pin]
{:status nil
:pairing-code nil
:error-label nil})
:effects.utils/show-popup {:title ""
:content (i18n/label :t/pairing-changed)}}
{:db (assoc-in db
[:keycard :pin]
{:status nil
:pairing-code nil
:error-label nil})
:utils/show-popup {:title ""
:content (i18n/label :t/pairing-changed)}}
(common/hide-connection-sheet)
(navigation/set-stack-root :profile-stack [:my-profile :keycard-settings])))
+4 -4
View File
@@ -293,14 +293,14 @@
(rf/defn show-wrong-keycard-alert
[_]
(log/debug "show-wrong-keycard-alert")
{:effects.utils/show-popup {:title (i18n/label :t/wrong-card)
:content (i18n/label :t/wrong-card-text)}})
{:utils/show-popup {:title (i18n/label :t/wrong-card)
:content (i18n/label :t/wrong-card-text)}})
(rf/defn unauthorized-operation
[cofx]
(rf/merge cofx
{:effects.utils/show-popup {:title ""
:content (i18n/label :t/keycard-unauthorized-operation)}}
{:utils/show-popup {:title ""
:content (i18n/label :t/keycard-unauthorized-operation)}}
(clear-on-card-connected)
(navigation/set-stack-root :profile-stack [:my-profile :keycard-settings])))
+10 -11
View File
@@ -24,12 +24,12 @@
(rf/defn show-keycard-has-multiaccount-alert
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db (assoc-in db [:keycard :setup-step] nil)
:effects.utils/show-confirmation {:title nil
:content (i18n/label
:t/keycard-has-multiaccount-on-it)
:cancel-button-text ""
:confirm-button-text :t/okay}}))
{:db (assoc-in db [:keycard :setup-step] nil)
:utils/show-confirmation {:title nil
:content (i18n/label
:t/keycard-has-multiaccount-on-it)
:cancel-button-text ""
:confirm-button-text :t/okay}}))
(rf/defn load-pin-screen
[{:keys [db] :as cofx}]
@@ -548,11 +548,10 @@
(rf/defn show-no-keycard-applet-alert
[_]
{:effects.utils/show-confirmation {:title (i18n/label :t/no-keycard-applet-on-card)
:content (i18n/label
:t/keycard-applet-install-instructions)
:cancel-button-text ""
:confirm-button-text :t/okay}})
{:utils/show-confirmation {:title (i18n/label :t/no-keycard-applet-on-card)
:content (i18n/label :t/keycard-applet-install-instructions)
:cancel-button-text ""
:confirm-button-text :t/okay}})
;; NOTE: Maybe replaced by multiple events based on on flow to make it easier to maintain.
;; Because there are many execution paths it is harder to follow all possible states.
+2 -2
View File
@@ -35,8 +35,8 @@
(do
(log/debug (str "Cannot start keycard installation from state: " card-state))
(rf/merge cofx
{:effects.utils/show-popup {:title (i18n/label :t/error)
:content (i18n/label :t/something-went-wrong)}}
{:utils/show-popup {:title (i18n/label :t/error)
:content (i18n/label :t/something-went-wrong)}}
(navigation/navigate-to :keycard-authentication-method nil))))))
(rf/defn load-preparing-screen
+7 -6
View File
@@ -221,12 +221,12 @@
(rf/defn on-backup-success
[{:keys [db] :as cofx} backup-type]
(rf/merge cofx
{:effects.utils/show-popup {:title (i18n/label (if (= backup-type :recovery-card)
:t/keycard-access-reset
:t/keycard-backup-success-title))
:content (i18n/label (if (= backup-type :recovery-card)
:t/keycard-can-use-with-new-passcode
:t/keycard-backup-success-body))}}
{:utils/show-popup {:title (i18n/label (if (= backup-type :recovery-card)
:t/keycard-access-reset
:t/keycard-backup-success-title))
:content (i18n/label (if (= backup-type :recovery-card)
:t/keycard-can-use-with-new-passcode
:t/keycard-backup-success-body))}}
(cond
(multiaccounts.model/logged-in? db)
(navigation/set-stack-root :profile-stack [:my-profile :keycard-settings])
@@ -373,3 +373,4 @@
cofx
{:on-card-connected :keycard/load-recovering-key-screen
:handler (common/dispatch-event :keycard/import-multiaccount)}))
+5 -4
View File
@@ -83,7 +83,7 @@
:error-label nil
:on-verified nil}))
:keycard/persist-pairings (dissoc pairings (keyword instance-uid))
:effects.utils/show-popup {:title ""
:utils/show-popup {:title ""
:content (i18n/label :t/card-unpaired)}}
(common/clear-on-card-connected)
(remove-pairing-from-multiaccount nil)
@@ -100,7 +100,7 @@
:error-label nil
:on-verified nil})
:keycard/get-application-info nil
:effects.utils/show-popup {:title ""
:utils/show-popup {:title ""
:content (i18n/label :t/something-went-wrong)}}
(common/clear-on-card-connected)
(navigation/navigate-to :keycard-settings nil)))
@@ -139,14 +139,15 @@
:error-label nil
:on-verified nil}))
:keycard/persist-pairings (dissoc pairings (keyword instance-uid))
:effects.utils/show-popup {:title (i18n/label (if keys-removed-from-card?
:utils/show-popup {:title (i18n/label (if keys-removed-from-card?
:t/profile-deleted-title
:t/database-reset-title))
:content (i18n/label (if keys-removed-from-card?
:t/profile-deleted-keycard
:t/database-reset-content))
:on-dismiss #(re-frame/dispatch [:logout])}}
;;should be reimplemented :key-storage/delete-profile {:key-uid key-uid
;;should be reimplemented
;;:key-storage/delete-profile {:key-uid key-uid
;;:on-success #(log/debug "[keycard] remove account ok")
;; :on-error #(log/warn "[keycard] remove account: " %)}
(common/clear-on-card-connected)
+3 -16
View File
@@ -194,7 +194,7 @@
{:events [:mailserver.ui/request-error-pressed]}
[{:keys [db]}]
(let [mailserver-error (:mailserver/request-error db)]
{:effects.utils/show-confirmation
{:utils/show-confirmation
{:title (i18n/label :t/mailserver-request-error-title)
:content (i18n/label :t/mailserver-request-error-content
{:error mailserver-error})
@@ -290,7 +290,8 @@
[{:method "mailservers_addMailserver"
:params [(mailserver->rpc mailserver current-fleet)]
:on-success (fn []
;; we naively logout if the user is connected to the edited mailserver
;; we naively logout if the user is connected to
;; the edited mailserver
(when current
(re-frame/dispatch
[:multiaccounts.logout.ui/logout-confirmed]))
@@ -412,17 +413,3 @@
(rf/merge cofx
{:db (dissoc db :mailserver.edit/mailserver)}
(navigation/navigate-to :edit-mailserver nil)))
(defn add-mailservers
[db mailservers]
(reduce (fn [db {:keys [fleet id name] :as mailserver}]
(let [updated-mailserver
(-> mailserver
(update :id keyword)
(assoc :name (if (seq name) name id))
(dissoc :fleet))]
(assoc-in db
[:mailserver/mailservers (keyword fleet) (keyword id)]
updated-mailserver)))
db
mailservers))
+1 -2
View File
@@ -172,8 +172,7 @@
:use-mailservers? true
:recovered recovered}
config/default-multiaccount)
;; The address from which we derive any chat
;; account/encryption keys
;; The address from which we derive any chat account/encryption keys
eip1581-address
(assoc :eip1581-address eip1581-address)
save-mnemonic?
+1 -1
View File
@@ -31,7 +31,7 @@
(rf/merge cofx
{:set-root :progress
:chat.ui/clear-inputs nil
:effects.shell/reset-state nil
:shell/reset-state nil
:hide-popover nil
::logout nil
:profile.settings/webview-debug-changed false
+1 -1
View File
@@ -89,7 +89,7 @@
(rf/defn connect-failure
{:events [::connect-failure]}
[_ reason]
{:effects.utils/show-popup
{:utils/show-popup
{:title (i18n/label :t/error)
:content (str reason)}})
+2 -2
View File
@@ -165,9 +165,9 @@
(if (< (count (filter :enabled? (vals (get-in cofx [:db :pairing/installations]))))
(inc config/max-installations))
{:pairing/enable-installation [installation-id]}
{:effects.utils/show-popup {:title (i18n/label :t/pairing-maximum-number-reached-title)
{:utils/show-popup {:title (i18n/label :t/pairing-maximum-number-reached-title)
:content (i18n/label :t/pairing-maximum-number-reached-content)}}))
:content (i18n/label :t/pairing-maximum-number-reached-content)}}))
(rf/defn disable-fx
{:events [:pairing.ui/disable-installation-pressed]}
+8 -8
View File
@@ -49,8 +49,8 @@
[{:keys [db] :as cofx} {:keys [chat-id]}]
(if-not (own-public-key? db chat-id)
{:dispatch [:chat.ui/start-chat chat-id]}
{:effects.utils/show-popup {:title (i18n/label :t/unable-to-read-this-code)
:content (i18n/label :t/can-not-add-yourself)}}))
{:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code)
:content (i18n/label :t/can-not-add-yourself)}}))
(rf/defn handle-group-chat
[cofx params]
@@ -71,9 +71,9 @@
(navigation/navigate-back))
:else
{:effects.utils/show-popup {:title (i18n/label :t/unable-to-read-this-code)
:content (i18n/label :t/ens-name-not-found)
:on-dismiss #(re-frame/dispatch [:pop-to-root :shell-stack])}})))
{:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code)
:content (i18n/label :t/ens-name-not-found)
:on-dismiss #(re-frame/dispatch [:pop-to-root :shell-stack])}})))
(rf/defn handle-eip681
[cofx data]
@@ -103,9 +103,9 @@
(log/info "Unable to find matcher for scanned value"
{:type type
:event ::match-scanned-value})
{:dispatch [:navigate-back]
:effects.utils/show-popup {:title (i18n/label :t/unable-to-read-this-code)
:on-dismiss #(re-frame/dispatch [:pop-to-root :shell-stack])}})))
{:dispatch [:navigate-back]
:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code)
:on-dismiss #(re-frame/dispatch [:pop-to-root :shell-stack])}})))
(rf/defn on-scan
{:events [::on-scan-success]}
@@ -1,12 +1,13 @@
(ns status-im2.common.signals.events
(ns status-im.signals.core
(:require
[quo.foundations.colors :as colors]
[status-im.chat.models.message :as models.message]
[status-im.ethereum.subscriptions :as ethereum.subscriptions]
[status-im.mailserver.core :as mailserver]
[status-im.transport.message.core :as transport.message]
[status-im.visibility-status-updates.core :as visibility-status-updates]
[status-im2.common.pairing.events :as pairing]
[status-im2.constants :as constants]
[status-im2.contexts.chat.messages.link-preview.events :as link-preview]
[status-im2.contexts.chat.messages.transport.events :as messages.transport]
[status-im2.contexts.communities.discover.events]
[status-im2.contexts.profile.login.events :as profile.login]
[status-im2.contexts.push-notifications.local.events :as local-notifications]
@@ -28,6 +29,64 @@
[{:keys [db]} peer-stats]
{:db (assoc db :peer-stats peer-stats :peers-count (count (:peers peer-stats)))})
(rf/defn handle-local-pairing-signals
[{:keys [db]} {:keys [type action data error] :as event}]
(log/info "local pairing signal received"
{:event event})
(let [{:keys [account password]} data
role (get-in db [:syncing :role])
receiver? (= role constants/local-pairing-role-receiver)
sender? (= role constants/local-pairing-role-sender)
connection-success? (and (= type
constants/local-pairing-event-connection-success)
(= action
constants/local-pairing-action-connect))
error-on-pairing? (contains? constants/local-pairing-event-errors type)
completed-pairing? (and (= type
constants/local-pairing-event-transfer-success)
(= action
constants/local-pairing-action-pairing-installation))
received-account? (and (= type
constants/local-pairing-event-received-account)
(= action
constants/local-pairing-action-pairing-account)
(and (some? account) (some? password)))
multiaccount-data (when received-account?
(merge account {:password password}))
navigate-to-syncing-devices? (and (or connection-success? error-on-pairing?) receiver?)
user-in-syncing-devices-screen? (or (= (:view-id db) :syncing-progress)
(= (:view-id db) :syncing-progress-intro))
user-in-sign-in-intro-screen? (= (:view-id db) :sign-in-intro)]
(merge {:db (cond-> db
connection-success?
(assoc-in [:syncing :pairing-status] :connected)
received-account?
(assoc-in [:syncing :profile] multiaccount-data)
error-on-pairing?
(assoc-in [:syncing :pairing-status] :error)
completed-pairing?
(assoc-in [:syncing :pairing-status] :completed))}
(cond
(and navigate-to-syncing-devices? (not user-in-syncing-devices-screen?))
{:dispatch (if user-in-sign-in-intro-screen?
[:navigate-to-within-stack [:syncing-progress-intro :sign-in-intro]]
[:navigate-to :syncing-progress])}
(and completed-pairing? sender?)
{:dispatch [:syncing/clear-states]}
(and completed-pairing? receiver?)
{:dispatch [:profile.login/local-paired-user]}
(and error-on-pairing? (some? error))
{:dispatch [:toasts/upsert
{:icon :i/alert
:icon-color colors/danger-50
:text error}]}))))
(rf/defn process
{:events [:signals/signal-received]}
[{:keys [db] :as cofx} event-str]
@@ -42,18 +101,18 @@
"backup.performed" {:db (assoc-in db
[:profile/profile :last-backup]
(.-lastBackup event-js))}
"envelope.sent" (messages.transport/update-envelopes-status cofx
(:ids
(js->clj event-js
:keywordize-keys
true))
:sent)
"envelope.expired" (messages.transport/update-envelopes-status cofx
(:ids
(js->clj event-js
:keywordize-keys
true))
:not-sent)
"envelope.sent" (transport.message/update-envelopes-status cofx
(:ids
(js->clj event-js
:keywordize-keys
true))
:sent)
"envelope.expired" (transport.message/update-envelopes-status cofx
(:ids
(js->clj event-js
:keywordize-keys
true))
:not-sent)
"message.delivered" (let [{:keys [chatID messageID]} (js->clj event-js
:keywordize-keys
true)]
@@ -67,9 +126,9 @@
"discovery.summary" (summary cofx (js->clj event-js :keywordize-keys true))
"mediaserver.started" {:db (assoc db :mediaserver/port (.-port event-js))}
"wakuv2.peerstats" (wakuv2-peer-stats cofx (js->clj event-js :keywordize-keys true))
"messages.new" (messages.transport/sanitize-messages-and-process-response cofx
event-js
true)
"messages.new" (transport.message/sanitize-messages-and-process-response cofx
event-js
true)
"wallet" (ethereum.subscriptions/new-wallet-event cofx
(js->clj event-js
:keywordize-keys
@@ -82,7 +141,7 @@
"status.updates.timedout" (visibility-status-updates/handle-visibility-status-updates
cofx
(js->clj event-js :keywordize-keys true))
"localPairing" (pairing/handle-local-pairing-signals
"localPairing" (handle-local-pairing-signals
cofx
(js->clj event-js :keywordize-keys true))
"curated.communities.update" (rf/dispatch [:fetched-contract-communities
+3 -3
View File
@@ -78,9 +78,9 @@
[{:keys [db]} data typed? result]
(let [{:keys [result error]} (types/json->clj result)]
(if error
{:dispatch [:signing.ui/cancel-is-pressed]
:effects.utils/show-popup {:title (i18n/label :t/sign-request-failed)
:content (:message error)}}
{:dispatch [:signing.ui/cancel-is-pressed]
:utils/show-popup {:title (i18n/label :t/sign-request-failed)
:content (:message error)}}
{:db (update db
:keycard assoc
:hash result
+58
View File
@@ -0,0 +1,58 @@
(ns ^{:doc "API to init and stop whisper messaging"} status-im.transport.core
(:require
[re-frame.core :as re-frame]
[status-im.pairing.core :as pairing]
[status-im.stickers.core :as stickers]
status-im.transport.shh
[status-im2.common.universal-links :as universal-links]
[taoensso.timbre :as log]
[utils.re-frame :as rf]))
(rf/defn set-node-info
{:events [:transport.callback/node-info-fetched]}
[{:keys [db]} node-info]
{:db (assoc db :node-info node-info)})
(rf/defn fetch-node-info-fx
[_]
{:json-rpc/call [{:method "admin_nodeInfo"
:on-success #(re-frame/dispatch [:transport.callback/node-info-fetched %])
:on-error #(log/error "node-info: failed error" %)}]})
(defn add-mailservers
[db mailservers]
(reduce (fn [db {:keys [fleet id name] :as mailserver}]
(let [updated-mailserver
(-> mailserver
(update :id keyword)
(assoc :name (if (seq name) name id))
(dissoc :fleet))]
(assoc-in db
[:mailserver/mailservers (keyword fleet) (keyword id)]
updated-mailserver)))
db
mailservers))
(rf/defn start-messenger
"We should only start receiving messages/processing topics once all the
initializiation is completed, otherwise we might receive messages/topics
when the state has not been properly initialized."
[_]
{:json-rpc/call [{:method "wakuext_startMessenger"
:on-success #(re-frame/dispatch [::messenger-started %])
:on-error #(log/error "failed to start messenger")}]})
(rf/defn messenger-started
{:events [::messenger-started]}
[{:keys [db] :as cofx} {:keys [mailservers] :as response}]
(log/info "Messenger started")
(let [new-account? (get db :onboarding-2/new-account?)]
(rf/merge cofx
{:db (-> db
(assoc :messenger/started? true)
(add-mailservers mailservers))}
(fetch-node-info-fx)
(pairing/init)
(stickers/load-packs)
(when-not new-account?
(universal-links/process-stored-event)))))
@@ -1,6 +1,5 @@
(ns status-im2.contexts.chat.messages.transport.events
(ns ^{:doc "Definition of the StatusMessage protocol"} status-im.transport.message.core
(:require
[clojure.set :as set]
[clojure.string :as string]
[status-im.browser.core :as browser]
[status-im.chat.models.message :as models.message]
@@ -21,7 +20,6 @@
[status-im2.contexts.chat.messages.pin.events :as messages.pin]
[status-im2.contexts.contacts.events :as models.contact]
[status-im2.contexts.shell.activity-center.events :as activity-center]
[taoensso.timbre :as log]
[utils.re-frame :as rf]))
(rf/defn process-next
@@ -349,58 +347,3 @@
cofx
(conj set-hash-fxs
#(sanitize-messages-and-process-response % response-js false)))))
(defn- link-preview->rpc
[preview]
(update preview
:thumbnail
(fn [thumbnail]
(set/rename-keys thumbnail {:data-uri :dataUri}))))
(defn build-message
[msg]
(-> msg
(update :link-previews #(map link-preview->rpc %))
(set/rename-keys
{:album-id :albumId
:audio-duration-ms :audioDurationMs
:audio-path :audioPath
:chat-id :chatId
:community-id :communityId
:content-type :contentType
:ens-name :ensName
:image-height :imageHeight
:image-path :imagePath
:image-width :imageWidth
:link-previews :linkPreviews
:response-to :responseTo
:sticker :sticker
:text :text})))
(rf/defn send-chat-messages
[_ messages]
{:json-rpc/call [{:method "wakuext_sendChatMessages"
:params [(mapv build-message messages)]
:js-response true
:on-success #(rf/dispatch [:transport/message-sent %])
:on-error #(do
(log/warn "failed to send a message" %)
(js/alert (str "failed to send a message: " %)))}]})
(rf/defn send-emoji-reaction
{:events [:reactions/send-emoji-reaction]}
[{{:keys [current-chat-id]} :db} {:keys [message-id emoji-id]}]
{:json-rpc/call [{:method "wakuext_sendEmojiReaction"
:params [current-chat-id message-id emoji-id]
:js-response true
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])
:on-error #(log/error "failed to send a reaction" %)}]})
(rf/defn send-retract-emoji-reaction
{:events [:reactions/send-emoji-reaction-retraction]}
[_ emoji-reaction-id]
{:json-rpc/call [{:method "wakuext_sendEmojiReactionRetraction"
:params [emoji-reaction-id]
:js-response true
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])
:on-error #(log/error "failed to send a reaction retraction" %)}]})
@@ -0,0 +1,59 @@
(ns ^{:doc "Protocol API and protocol utils"} status-im.transport.message.protocol
(:require
[clojure.set :as set]
[re-frame.core :as re-frame]
[taoensso.timbre :as log]
[utils.re-frame :as rf]))
(defn- link-preview->rpc
[preview]
(update preview
:thumbnail
(fn [thumbnail]
(set/rename-keys thumbnail {:data-uri :dataUri}))))
(defn build-message
[msg]
(-> msg
(update :link-previews #(map link-preview->rpc %))
(set/rename-keys
{:album-id :albumId
:audio-duration-ms :audioDurationMs
:audio-path :audioPath
:chat-id :chatId
:community-id :communityId
:content-type :contentType
:ens-name :ensName
:image-height :imageHeight
:image-path :imagePath
:image-width :imageWidth
:link-previews :linkPreviews
:response-to :responseTo
:sticker :sticker
:text :text})))
(rf/defn send-chat-messages
[_ messages]
{:json-rpc/call [{:method "wakuext_sendChatMessages"
:params [(mapv build-message messages)]
:js-response true
:on-success #(re-frame/dispatch [:transport/message-sent %])
:on-error #(do
(log/warn "failed to send a message" %)
(js/alert (str "failed to send a message: " %)))}]})
(rf/defn send-reaction
[_ {:keys [message-id chat-id emoji-id]}]
{:json-rpc/call [{:method "wakuext_sendEmojiReaction"
:params [chat-id message-id emoji-id]
:js-response true
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
:on-error #(log/error "failed to send a reaction" %)}]})
(rf/defn send-retract-reaction
[_ {:keys [emoji-reaction-id]}]
{:json-rpc/call [{:method "wakuext_sendEmojiReactionRetraction"
:params [emoji-reaction-id]
:js-response true
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
:on-error #(log/error "failed to send a reaction retraction" %)}]})
+35
View File
@@ -0,0 +1,35 @@
(ns ^{:doc "Whisper API and events for managing keys and posting messages"} status-im.transport.shh
(:require
[re-frame.core :as re-frame]
[status-im2.common.json-rpc.events :as json-rpc]
[taoensso.timbre :as log]))
(defn generate-sym-key-from-password
[{:keys [password on-success on-error]}]
(json-rpc/call {:method "waku_generateSymKeyFromPassword"
:params [password]
:on-success on-success
:on-error on-error}))
(defn get-sym-key
[{:keys [sym-key-id on-success on-error]}]
(json-rpc/call {:method "waku_getSymKey"
:params [sym-key-id]
:on-success on-success
:on-error on-error}))
(defn log-error
[error]
(log/error :shh/get-new-sym-key-error error))
(re-frame/reg-fx
:shh/generate-sym-key-from-password
(fn [{:keys [password on-success]}]
(generate-sym-key-from-password
{:password password
:on-success (fn [sym-key-id]
(get-sym-key {:sym-key-id sym-key-id
:on-success (fn [sym-key]
(on-success sym-key sym-key-id))
:on-error log-error}))
:on-error log-error})))
+18
View File
@@ -0,0 +1,18 @@
(ns ^{:doc "Utils for transport layer"} status-im.transport.utils
(:require
[clojure.string :as string]))
(defn extract-enode-id
[enode]
(-> enode
(string/split #"/")
(get 2 "")
(string/split #":")
(get 0 "")
(string/split "@")
(get 0)))
(defn extract-url-components
[address]
(when address
(rest (re-matches #"enode://(.*?)@(.*):(.*)" address))))
@@ -14,7 +14,8 @@
transactions-management-enabled?
wakuv2-flag
current-fleet
webview-debug]}]
webview-debug
test-networks-enabled?]}]
(keep
identity
[{:size :small
@@ -95,6 +96,15 @@
[:profile.settings/change-webview-debug (not webview-debug)])
:accessory :switch
:active webview-debug}
{:size :small
:title "Test Networks Enabled"
:accessibility-label :test-networks-enabled
:container-margin-bottom 8
:on-press
#(re-frame/dispatch
[:profile.settings/change-test-networks-enabled (not test-networks-enabled?)])
:accessory :switch
:active test-networks-enabled?}
{:size :small
:title (i18n/label :t/waku-bloom-filter-mode)
:accessibility-label :waku-bloom-filter-mode-settings-switch
@@ -117,7 +127,8 @@
(views/defview advanced-settings
[]
(views/letsubs [{:keys [webview-debug]} [:profile/profile]
(views/letsubs [{:keys [webview-debug
test-networks-enabled?]} [:profile/profile]
network-name [:network-name]
waku-bloom-filter-mode [:waku/bloom-filter-mode]
wakuv2-flag [:waku/v2-flag]
@@ -133,6 +144,7 @@
:dev-mode? false
:wakuv2-flag wakuv2-flag
:waku-bloom-filter-mode waku-bloom-filter-mode
:webview-debug webview-debug})
:webview-debug webview-debug
:test-networks-enabled? test-networks-enabled?})
:key-fn (fn [_ i] (str i))
:render-fn render-item}]))
@@ -56,7 +56,7 @@
{:events [::on-delete-profile-success]}
[cofx]
(log/info "[delete-profile] on-success")
{:effects.utils/show-popup
{:utils/show-popup
{:title (i18n/label :t/profile-deleted-title)
:content (i18n/label :t/profile-deleted-content)
:on-dismiss #(re-frame/dispatch [:logout])}})
@@ -207,7 +207,7 @@
key-uid]
:as profile}
@(re-frame/subscribe [:profile/profile-with-image])
customization-color (or (:color @(re-frame/subscribe [:onboarding/profile]))
customization-color (or (:color @(re-frame/subscribe [:onboarding-2/profile]))
@(re-frame/subscribe [:profile/customization-color key-uid]))
on-share #(re-frame/dispatch [:show-popover
{:view :share-chat-key
+6 -10
View File
@@ -7,6 +7,7 @@
[react-native.mail :as react-native-mail]
[react-native.platform :as platform]
[status-im.bottom-sheet.events :as bottom-sheet]
[status-im.transport.utils :as transport.utils]
[status-im.ui.components.react :as react]
[status-im.utils.build :as build]
[status-im.utils.deprecated-types :as types]
@@ -37,11 +38,6 @@
{:json-rpc/call [{:method "web3_clientVersion"
:on-success #(re-frame/dispatch [:logging/store-web3-client-version %])}]})
(defn extract-url-components
[address]
(when address
(rest (re-matches #"enode://(.*?)@(.*):(.*)" address))))
(defn email-body
"logs attached"
[{:keys [:web3-node-version :mailserver/current-id
@@ -50,7 +46,7 @@
build-version (str build/version " (" build-number ")")
separator (string/join (take 40 (repeat "-")))
[enode-id ip-address port]
(extract-url-components (:enode node-info))]
(transport.utils/extract-url-components (:enode node-info))]
(string/join
"\n"
(concat [(i18n/label :t/report-bug-email-template
@@ -72,7 +68,7 @@
(mapcat
(fn [{:keys [enode]}]
(let [[enode-id ip-address port]
(extract-url-components enode)]
(transport.utils/extract-url-components enode)]
[(str "id: " enode-id)
(str "ip: " ip-address)
(str "port: " port)
@@ -155,15 +151,15 @@
(rf/defn show-client-error
{:events [:show-client-error]}
[_]
{:effects.utils/show-popup {:title (i18n/label :t/cant-report-bug)
:content (i18n/label :t/mail-should-be-configured)}})
{:utils/show-popup {:title (i18n/label :t/cant-report-bug)
:content (i18n/label :t/mail-should-be-configured)}})
(rf/defn show-logs-dialog
{:events [:shake-event]}
[{:keys [db]}]
(when-not (:logging/dialog-shown? db)
{:db (assoc db :logging/dialog-shown? true)
:effects.utils/show-confirmation
:utils/show-confirmation
(cond-> {:title (i18n/label :t/send-logs)
:content (i18n/label :t/send-logs-to
{:email report-email})
+5 -4
View File
@@ -359,8 +359,8 @@
(let [deleted-address (:address account)
dapps-address (get-in cofx [:db :profile/profile :dapps-address])]
(if (= (string/lower-case dapps-address) (string/lower-case deleted-address))
{:effects.utils/show-popup {:title (i18n/label :t/warning)
:content (i18n/label :t/account-is-used)}}
{:utils/show-popup {:title (i18n/label :t/warning)
:content (i18n/label :t/account-is-used)}}
{:key-storage/delete-imported-key
{:key-uid (get-in db [:profile/profile :key-uid])
:address (:address account)
@@ -379,8 +379,8 @@
(assoc-in [:add-account :scanned-address] address)
(assoc-in [:add-account :address] address))}
(when-not address
{:effects.utils/show-popup {:title (i18n/label :t/error)
:content (i18n/label :t/invalid-address-qr-code)}}))
{:utils/show-popup {:title (i18n/label :t/error)
:content (i18n/label :t/invalid-address-qr-code)}}))
(navigation/navigate-back))))
(re-frame/reg-fx
@@ -392,3 +392,4 @@
{:events [:wallet-legacy.accounts/share]}
[_ address]
{:list.selection/open-share {:message (eip55/address->checksum address)}})
+10 -27
View File
@@ -822,8 +822,8 @@
(rf/defn get-buy-crypto-preference
{:events [::get-buy-crypto]}
[_]
{:effects.async-storage/get {:keys [:buy-crypto-hidden]
:cb #(re-frame/dispatch [::store-buy-crypto-preference %])}})
{:async-storage-get {:keys [:buy-crypto-hidden]
:cb #(re-frame/dispatch [::store-buy-crypto-preference %])}})
(rf/defn wallet-will-focus
{:events [::wallet-stack]}
@@ -844,8 +844,8 @@
(rf/defn hide-buy-crypto
{:events [::hide-buy-crypto]}
[{:keys [db]}]
{:db (assoc db :wallet-legacy/buy-crypto-hidden true)
:effects.async-storage/set {:buy-crypto-hidden true}})
{:db (assoc db :wallet-legacy/buy-crypto-hidden true)
:async-storage-set {:buy-crypto-hidden true}})
(rf/defn store-buy-crypto
{:events [::store-buy-crypto-preference]}
@@ -1023,8 +1023,8 @@
(rf/defn switch-transactions-management-enabled
{:events [:multiaccounts.ui/switch-transactions-management-enabled]}
[{:keys [db]} enabled?]
{:effects.async-storage/set {:transactions-management-enabled? enabled?}
:db (assoc db :wallet-legacy/transactions-management-enabled? enabled?)})
{:async-storage-set {:transactions-management-enabled? enabled?}
:db (assoc db :wallet-legacy/transactions-management-enabled? enabled?)})
(re-frame/reg-fx
:wallet-legacy/initialize-transactions-management-enabled
@@ -1072,9 +1072,10 @@
true])}))
2000)))
;;TODO: this could be replaced by a single API call on status-go side
(re-frame/reg-fx :wallet-legacy/initialize-wallet
(fn [[network-id network callback]]
(re-frame/reg-fx
;;TODO: this could be replaced by a single API call on status-go side
:wallet-legacy/initialize-wallet
(fn [[network-id callback]]
(-> (js/Promise.all
(clj->js
[(js/Promise.
@@ -1082,24 +1083,6 @@
(json-rpc/call {:method "accounts_getAccounts"
:on-success resolve-fn
:on-error reject})))
(js/Promise.
(fn [resolve-fn _]
(json-rpc/call
{:method "wallet_addEthereumChain"
:params
[{:isTest false
:tokenOverrides []
:rpcUrl (get-in network [:config :UpstreamConfig :URL])
:chainColor "green"
:chainName (:name network)
:nativeCurrencyDecimals 10
:shortName "erc20"
:layer 1
:chainId (int network-id)
:enabled false
:fallbackURL (get-in network [:config :UpstreamConfig :URL])}]
:on-success resolve-fn
:on-error (fn [_] (resolve-fn nil))})))
(js/Promise.
(fn [resolve-fn _]
(json-rpc/call {:method "wallet_getTokens"
+2 -2
View File
@@ -65,8 +65,8 @@
(rf/defn not-supported
{:events [:wallet-legacy.custom-token/not-supported]}
[{:keys [db]}]
{:db (assoc-in db [:wallet-legacy/custom-token-screen :in-progress?] nil)
:effects.utils/show-popup {:content (i18n/label :t/contract-isnt-supported)}})
{:db (assoc-in db [:wallet-legacy/custom-token-screen :in-progress?] nil)
:utils/show-popup {:content (i18n/label :t/contract-isnt-supported)}})
(rf/defn add-custom-token
{:events [:wallet-legacy.custom-token.ui/add-pressed]}
@@ -1,8 +1,8 @@
(ns status-im2.common.alert.effects
(ns status-im2.common.alert.events
(:require
[re-frame.core :as re-frame]
[react-native.core :as rn]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
[utils.i18n :as i18n]))
(defn show-popup
([title content]
@@ -26,7 +26,8 @@
(when on-dismiss
{:cancelable false})))))
(rf/reg-fx :effects.utils/show-popup
(re-frame/reg-fx
:utils/show-popup
(fn [{:keys [title content on-dismiss]}]
(show-popup title content on-dismiss)))
@@ -49,7 +50,8 @@
(or extra-options nil))
{:cancelable false}))
(rf/reg-fx :effects.utils/show-confirmation
(re-frame/reg-fx
:utils/show-confirmation
(fn [{:keys [title content confirm-button-text on-accept on-cancel cancel-button-text extra-options]}]
(show-confirmation {:title title
:content content
@@ -58,3 +60,18 @@
:on-accept on-accept
:on-cancel on-cancel
:extra-options extra-options})))
(defn show-question
([title content on-accept]
(show-question title content on-accept nil))
([title content on-accept on-cancel]
(rn/alert
title
content
(vector (merge {:text (i18n/label :t/no)
:accessibility-label :no-button}
(when on-cancel {:onPress on-cancel}))
{:text (i18n/label :t/yes)
:onPress on-accept
:accessibility-label :yes-button})
nil)))
+8
View File
@@ -0,0 +1,8 @@
(ns status-im2.common.async-storage
(:require
[re-frame.core :as re-frame]
react-native.async-storage))
(re-frame/reg-fx :async-storage-set (react-native.async-storage/set-item-factory))
(re-frame/reg-fx :async-storage-get
(fn [{ks :keys cb :cb}] (react-native.async-storage/get-items ks cb)))
@@ -1,11 +0,0 @@
(ns status-im2.common.async-storage.effects
(:require
[react-native.async-storage :as async-storage]
[utils.re-frame :as rf]))
(rf/reg-fx :effects.async-storage/set
(async-storage/set-item-factory))
(rf/reg-fx :effects.async-storage/get
(fn [{ks :keys cb :cb}]
(async-storage/get-items ks cb)))
+1 -1
View File
@@ -51,7 +51,7 @@
(i18n/label :t/grant-face-id-permissions)
(i18n/label :t/biometric-auth-error {:code code}))]
(when handle-error?
{:effects.utils/show-popup
{:utils/show-popup
{:title (i18n/label :t/biometric-auth-login-error-title)
:content content}})))
@@ -1,8 +1,19 @@
(ns status-im2.common.bottom-sheet.style
(:require
[quo.foundations.colors :as colors]
[quo.theme :as theme]
[react-native.platform :as platform]))
(defn handle
[theme]
{:width 32
:height 4
:background-color (colors/theme-colors colors/neutral-100 colors/white theme)
:opacity (theme/theme-value 0.05 0.1 theme)
:border-radius 100
:align-self :center
:margin-vertical 8})
(defn sheet
[{:keys [top]} window-height selected-item]
{:position :absolute
+2 -3
View File
@@ -63,7 +63,7 @@
item-height (reagent/atom 0)]
(fn [{:keys [hide? insets theme]}
{:keys [content selected-item padding-bottom-override border-radius on-close shell?
gradient-cover? customization-color hide-handle?]
gradient-cover? customization-color]
:or {border-radius 12}}]
(let [{window-height :height} (rn/get-window)
bg-opacity (reanimated/use-shared-value 0)
@@ -122,8 +122,7 @@
[quo/gradient-cover
{:customization-color customization-color
:opacity 0.4}]])
(when-not hide-handle?
[quo/drawer-bar])
[rn/view {:style (style/handle theme)}]
[content]]]]]))))
(defn- internal-view
@@ -1,9 +1,15 @@
(ns status-im2.common.font.events
(ns status-im2.common.font
(:require
[clojure.string :as string]
status-im2.common.font.effects
[re-frame.core :as re-frame]
utils.image-server
[utils.re-frame :as rf]))
(re-frame/reg-fx
:font/get-font-file-for-initials-avatar
(fn [callback]
(utils.image-server/get-font-file-ready callback)))
(rf/defn init-abs-root-path
{:events [:font/init-font-file-for-initials-avatar]}
[{:keys [db]} initials-avatar-font-file]
-8
View File
@@ -1,8 +0,0 @@
(ns status-im2.common.font.effects
(:require
utils.image-server
[utils.re-frame :as rf]))
(rf/reg-fx :effects.font/get-font-file-for-initials-avatar
(fn [callback]
(utils.image-server/get-font-file-ready callback)))
-65
View File
@@ -1,65 +0,0 @@
(ns status-im2.common.pairing.events
(:require
[quo.foundations.colors :as colors]
[status-im2.constants :as constants]
[status-im2.contexts.communities.discover.events]
[taoensso.timbre :as log]
[utils.re-frame :as rf]))
(rf/defn handle-local-pairing-signals
[{:keys [db]} {:keys [type action data error] :as event}]
(log/info "local pairing signal received"
{:event event})
(let [{:keys [account password]} data
role (get-in db [:syncing :role])
receiver? (= role constants/local-pairing-role-receiver)
sender? (= role constants/local-pairing-role-sender)
connection-success? (and (= type
constants/local-pairing-event-connection-success)
(= action
constants/local-pairing-action-connect))
error-on-pairing? (contains? constants/local-pairing-event-errors type)
completed-pairing? (and (= type
constants/local-pairing-event-transfer-success)
(= action
constants/local-pairing-action-pairing-installation))
received-account? (and (= type
constants/local-pairing-event-received-account)
(= action
constants/local-pairing-action-pairing-account)
(and (some? account) (some? password)))
multiaccount-data (when received-account?
(merge account {:password password}))
navigate-to-syncing-devices? (and (or connection-success? error-on-pairing?) receiver?)
user-in-syncing-devices-screen? (or (= (:view-id db) :syncing-progress)
(= (:view-id db) :syncing-progress-intro))
user-in-sign-in-intro-screen? (= (:view-id db) :sign-in-intro)]
(merge {:db (cond-> db
connection-success?
(assoc-in [:syncing :pairing-status] :connected)
received-account?
(assoc-in [:syncing :profile] multiaccount-data)
error-on-pairing?
(assoc-in [:syncing :pairing-status] :error)
completed-pairing?
(assoc-in [:syncing :pairing-status] :completed))}
(cond
(and navigate-to-syncing-devices? (not user-in-syncing-devices-screen?))
{:dispatch (if user-in-sign-in-intro-screen?
[:navigate-to-within-stack [:syncing-progress-intro :sign-in-intro]]
[:navigate-to :syncing-progress])}
(and completed-pairing? sender?)
{:dispatch [:syncing/clear-states]}
(and completed-pairing? receiver?)
{:dispatch [:profile.login/local-paired-user]}
(and error-on-pairing? (some? error))
{:dispatch [:toasts/upsert
{:icon :i/alert
:icon-color colors/danger-50
:text error}]}))))
@@ -38,11 +38,10 @@
:padding-horizontal screen-padding
:margin-vertical 12})
(defn header-text
[bottom-padding?]
(def header-text
{:padding-horizontal screen-padding
:padding-top 12
:padding-bottom (when bottom-padding? 8)
:padding-bottom 8
:color colors/white})
(def header-sub-text
@@ -54,7 +53,7 @@
:margin-top 20})
(def scan-qr-code-container
{:margin-top 20})
{:margin-top 19})
(def qr-view-finder
{:margin-horizontal screen-padding
+15 -17
View File
@@ -35,14 +35,13 @@
[quo/text
{:size :heading-1
:weight :semi-bold
:style (style/header-text (when subtitle true))}
:style style/header-text}
title]
(when subtitle
[quo/text
{:size :paragraph-1
:weight :regular
:style style/header-sub-text}
subtitle])])
[quo/text
{:size :paragraph-1
:weight :regular
:style style/header-sub-text}
subtitle]])
(defn get-labels-and-on-press-method
[]
@@ -110,22 +109,21 @@
[white-border :bottom-right]]])
(defn- viewfinder
[qr-view-finder helper-text?]
[qr-view-finder]
(let [layout-size (+ (:width qr-view-finder) 2)]
[rn/view {:style (style/viewfinder-container qr-view-finder)}
[white-square layout-size]
(when helper-text?
[quo/text
{:size :paragraph-2
:weight :regular
:style style/viewfinder-text}
(i18n/label :t/ensure-qr-code-is-in-focus-to-scan)])]))
[quo/text
{:size :paragraph-2
:weight :regular
:style style/viewfinder-text}
(i18n/label :t/ensure-qr-code-is-in-focus-to-scan)]]))
(defn- scan-qr-code-tab
[qr-view-finder helper-text?]
[qr-view-finder]
(if (and @camera-permission-granted?
(boolean (not-empty qr-view-finder)))
[viewfinder qr-view-finder helper-text?]
[viewfinder qr-view-finder]
[camera-permission-view]))
(defn- check-qr-code-and-navigate
@@ -225,7 +223,7 @@
[:<>
[rn/view {:style style/scan-qr-code-container}]
[qr-scan-hole-area qr-view-finder]])
[scan-qr-code-tab @qr-view-finder (when subtitle true)]
[scan-qr-code-tab @qr-view-finder]
[rn/view {:style style/flex-spacer}]
(when show-camera?
[quo.theme/provider {:theme :light}
@@ -14,8 +14,11 @@
(defn authorize
[{:keys [on-enter-password biometric-auth? on-auth-success on-auth-fail on-close
auth-button-label theme blur? auth-button-icon-left]}]
(println auth-button-label "dasasdasdadsdas")
(biometric/get-supported-type
(fn [biometric-type]
(println biometric-type "biometric-type")
(if (and biometric-auth? biometric-type)
(biometric/authenticate
{:reason (i18n/label :t/biometric-auth-confirm-message)
@@ -30,8 +33,10 @@
:shell? blur?
:content (fn []
[enter-password/view
{:on-enter-password on-enter-password}])}]))})
{:button-label auth-button-label
:on-enter-password on-enter-password}])}]))})
(do
(println "222222")
(reset-password)
(rf/dispatch [:show-bottom-sheet
{:on-close on-close
+2 -2
View File
@@ -44,8 +44,8 @@
(when chat-id
(if-not (own-public-key? db chat-id)
{:dispatch [:chat.ui/start-chat chat-id]}
{:effects.utils/show-popup {:title (i18n/label :t/unable-to-read-this-code)
:content (i18n/label :t/can-not-add-yourself)}})))
{:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code)
:content (i18n/label :t/can-not-add-yourself)}})))
(rf/defn handle-community-requests
[cofx {:keys [community-id]}]
+1 -1
View File
@@ -74,7 +74,7 @@
(def default-multiaccount
{:preview-privacy? blank-preview?
:wallet-legacy/visible-tokens {:mainnet #{:SNT}}
:wallet-legacy/visible-tokens {:mainnet #{:SNT :ETH :DAI}}
:currency :usd
:appearance 0
:profile-pictures-show-to 2
-2
View File
@@ -372,9 +372,7 @@
;; wallet
(def ^:const mainnet-chain-id 1)
(def ^:const optimism-chain-id 10)
(def ^:const optimism-test-chain-id 420)
(def ^:const arbitrum-chain-id 42161)
(def ^:const arbitrum-test-chain-id 421613)
(def ^:const goerli-chain-id 5)
(def ^:const mainnet-short-name "eth")
@@ -1,22 +0,0 @@
(ns status-im2.contexts.add-new-contact.effects
(:require
[native-module.core :as native-module]
[status-im.ethereum.ens :as ens]
[status-im2.constants :as constants]
[utils.re-frame :as rf]
[utils.transforms :as transforms]))
(rf/reg-fx :effects.contacts/decompress-public-key
(fn [{:keys [compressed-key on-success on-error]}]
(native-module/compressed-key->public-key
compressed-key
constants/deserialization-key
(fn [resp]
(let [{:keys [error]} (transforms/json->clj resp)]
(if error
(on-error error)
(on-success (str "0x" (subs resp 5)))))))))
(rf/reg-fx :effects.contacts/resolve-public-key-from-ens
(fn [{:keys [chain-id ens on-success on-error]}]
(ens/pubkey chain-id ens on-success on-error)))
@@ -1,13 +1,17 @@
(ns status-im2.contexts.add-new-contact.events
(:require
[clojure.string :as string]
status-im2.contexts.add-new-contact.effects
[native-module.core :as native-module]
[re-frame.core :as re-frame]
[status-im.ethereum.ens :as ens]
[status-im2.constants :as constants]
[status-im2.contexts.contacts.events :as data-store.contacts]
[status-im2.navigation.events :as navigation]
[utils.ens.stateofus :as stateofus]
[utils.ethereum.chain :as chain]
[utils.re-frame :as rf]
[utils.string :as utils.string]
[utils.transforms :as transforms]
[utils.validators :as validators]))
(defn init-contact
@@ -104,14 +108,14 @@
:empty {:db (dissoc db :contacts/new-identity)}
(:valid :invalid) {:db (assoc db :contacts/new-identity contact)}
:decompress-key {:db (assoc db :contacts/new-identity contact)
:effects.contacts/decompress-public-key
:contacts/decompress-public-key
{:compressed-key id
:on-success
(dispatcher :contacts/set-new-identity-success input)
:on-error
(dispatcher :contacts/set-new-identity-error input)}}
:resolve-ens {:db (assoc db :contacts/new-identity contact)
:effects.contacts/resolve-public-key-from-ens
:contacts/resolve-public-key-from-ens
{:chain-id (chain/chain-id db)
:ens ens
:on-success
@@ -119,7 +123,22 @@
:on-error
(dispatcher :contacts/set-new-identity-error input)}})))
(re-frame/reg-fx
:contacts/decompress-public-key
(fn [{:keys [compressed-key on-success on-error]}]
(native-module/compressed-key->public-key
compressed-key
constants/deserialization-key
(fn [resp]
(let [{:keys [error]} (transforms/json->clj resp)]
(if error
(on-error error)
(on-success (str "0x" (subs resp 5)))))))))
(re-frame/reg-fx
:contacts/resolve-public-key-from-ens
(fn [{:keys [chain-id ens on-success on-error]}]
(ens/pubkey chain-id ens on-success on-error)))
(rf/defn build-contact
{:events [:contacts/build-contact]}
@@ -115,7 +115,7 @@
:ens ens-stateofus-eth
:public-key nil ; not yet...
:state :resolve-ens}))
:effects.contacts/resolve-public-key-from-ens
:contacts/resolve-public-key-from-ens
{:chain-id 1
:ens ens-stateofus-eth
:on-success [:contacts/set-new-identity-success ens]
@@ -131,7 +131,7 @@
:type :compressed-key
:public-key nil ; not yet...
:state :decompress-key}))
:effects.contacts/decompress-public-key
:contacts/decompress-public-key
{:compressed-key user-ckey
:on-success [:contacts/set-new-identity-success user-ckey]
:on-error [:contacts/set-new-identity-error user-ckey]}})))
@@ -1,20 +0,0 @@
(ns status-im2.contexts.add-new-contact.scan.scan-profile-qr-page
(:require [react-native.core :as rn]
[react-native.hooks :as hooks]
[status-im2.common.scan-qr-code.view :as scan-qr-code]
[utils.debounce :as debounce]
[utils.i18n :as i18n]))
(defn- f-internal-view
[]
(let [{:keys [keyboard-shown]} (hooks/use-keyboard)]
[:<>
(when keyboard-shown
(rn/dismiss-keyboard!))
[scan-qr-code/view
{:title (i18n/label :t/scan-qr)
:on-success-scan #(debounce/debounce-and-dispatch [:contacts/set-new-identity % %] 300)}]]))
(defn view
[]
[:f> f-internal-view])
@@ -4,6 +4,7 @@
[react-native.clipboard :as clipboard]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im.qr-scanner.core :as qr-scanner]
[status-im2.contexts.add-new-contact.style :as style]
[utils.address :as address]
[utils.debounce :as debounce]
@@ -95,7 +96,8 @@
{:type :outline
:icon-only? true
:size 40
:on-press #(rf/dispatch [:open-modal :scan-profile-qr-code])}
:on-press #(rf/dispatch [::qr-scanner/scan-code
{:handler :contacts/qr-code-scanned}])}
:i/scan]]])
(finally
(rf/dispatch [:contacts/clear-new-identity]))))
@@ -7,7 +7,7 @@
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]
[reagent.core :as reagent]
[status-im2.common.alert.effects :as alert.effects]
[status-im2.common.alert.events :as alert]
[status-im2.common.device-permissions :as device-permissions]
[status-im2.constants :as constants]
[status-im2.contexts.chat.composer.actions.style :as style]
@@ -146,7 +146,7 @@
:on-denied
#(js/setTimeout
(fn []
(alert.effects/show-popup
(alert/show-popup
(i18n/label :t/audio-recorder-error)
(i18n/label
:t/audio-recorder-permissions-error)
@@ -198,9 +198,9 @@
(reanimated/get-shared-value height)])
(rf/dispatch [:open-modal :photo-selector {:insets insets}]))
:on-denied (fn []
(alert.effects/show-popup (i18n/label :t/error)
(i18n/label
:t/external-storage-denied)))}))
(alert/show-popup (i18n/label :t/error)
(i18n/label
:t/external-storage-denied)))}))
(defn image-button
[props animations insets edit]
@@ -246,6 +246,6 @@
[:f> send-button props state animations window-height images edit send-btn-opacity
scroll-to-bottom-fn]
(when (and (not edit) (not images))
;; TODO(alwx): needs to be replaced with an `audio-button` later. See
;; https://github.com/status-im/status-mobile/issues/16084 for more details.
;; TODO(alwx): needs to be replaced with an `audio-button` later.
;; See https://github.com/status-im/status-mobile/issues/16084 for more details.
[:f> disabled-audio-button audio-btn-opacity])]))
-18
View File
@@ -1,18 +0,0 @@
(ns status-im2.contexts.chat.effects
(:require
[react-native.async-storage :as async-storage]
[status-im2.contexts.shell.jump-to.constants :as shell.constants]
[utils.re-frame :as rf]))
(rf/reg-fx :effects.chat/open-last-chat
(fn [key-uid]
(async-storage/get-item
:chat-id
(fn [chat-id]
(when chat-id
(async-storage/get-item
:key-uid
(fn [stored-key-uid]
(when (= stored-key-uid key-uid)
(rf/dispatch [:chat/navigate-to-chat chat-id
shell.constants/open-screen-without-animation])))))))))
+22 -7
View File
@@ -3,6 +3,7 @@
[clojure.set :as set]
[quo.foundations.colors :as colors]
[re-frame.core :as re-frame]
[react-native.async-storage :as async-storage]
[reagent.core :as reagent]
[status-im.chat.models.loading :as loading]
[status-im.data-store.chats :as chats-store]
@@ -10,11 +11,11 @@
[status-im2.config :as config]
[status-im2.constants :as constants]
[status-im2.contexts.chat.composer.link-preview.events :as link-preview]
status-im2.contexts.chat.effects
[status-im2.contexts.chat.messages.delete-message-for-me.events :as delete-for-me]
[status-im2.contexts.chat.messages.delete-message.events :as delete-message]
[status-im2.contexts.chat.messages.list.state :as chat.state]
[status-im2.contexts.contacts.events :as contacts-store]
[status-im2.contexts.shell.jump-to.constants :as shell.constants]
[status-im2.navigation.events :as navigation]
[taoensso.timbre :as log]
[utils.datetime :as datetime]
@@ -171,11 +172,11 @@
(chat.state/reset-visible-item)
(rf/merge cofx
(merge
{:db (-> db
(dissoc :current-chat-id)
(assoc-in [:chat/inputs chat-id :focused?] false))
:effects.async-storage/set {:chat-id nil
:key-uid nil}}
{:db (-> db
(dissoc :current-chat-id)
(assoc-in [:chat/inputs chat-id :focused?] false))
:async-storage-set {:chat-id nil
:key-uid nil}}
(let [community-id (get-in db [:chats chat-id :community-id])]
;; When navigating back from community chat to community, update switcher card
;; A close chat event is also called while opening any chat.
@@ -430,7 +431,21 @@
[{:keys [db]} value]
{:db (assoc db :lightbox/scale value)})
(re-frame/reg-fx
:chat/open-last-chat
(fn [key-uid]
(async-storage/get-item
:chat-id
(fn [chat-id]
(when chat-id
(async-storage/get-item
:key-uid
(fn [stored-key-uid]
(when (= stored-key-uid key-uid)
(re-frame/dispatch [:chat/navigate-to-chat chat-id
shell.constants/open-screen-without-animation])))))))))
(rf/defn check-last-chat
{:events [:chat/check-last-chat]}
[{:keys [db]}]
{:effects.chat/open-last-chat (get-in db [:profile/profile :key-uid])})
{:chat/open-last-chat (get-in db [:profile/profile :key-uid])})
@@ -1,12 +1,11 @@
(ns status-im2.contexts.chat.menus.pinned-messages.style
(:require
[quo.foundations.colors :as colors]
[react-native.platform :as platform]))
[quo.foundations.colors :as colors]))
(defn heading
[community?]
{:padding-horizontal 20
:margin-bottom (when-not community? 12)})
{:margin-horizontal 20
:margin-bottom (when-not community? 24)})
(defn heading-container
[]
@@ -32,28 +31,23 @@
:margin-right 8
:color (colors/theme-colors colors/neutral-60 colors/neutral-20)})
(def no-pinned-messages-container
(defn list-footer
[bottom-inset]
{:height bottom-inset})
(defn no-pinned-messages-container
[bottom-inset]
{:justify-content :center
:align-items :center
:margin 12
:margin-bottom (when platform/android? 12)})
:margin-top 20
:margin-bottom bottom-inset})
(def no-pinned-messages-icon
{:width 80
:height 80
{:width 120
:height 120
:justify-content :center
:align-items :center
:border-width 1})
(def no-pinned-messages-content
{:margin-top 12})
(def no-pinned-messages-title
{:text-align :center})
(def no-pinned-messages-text
{:text-align :center
:margin-top 2})
(def list-footer
{:height (when platform/android? 12)})
{:margin-top 20})
@@ -5,6 +5,7 @@
[react-native.core :as rn]
[react-native.fast-image :as fast-image]
[react-native.gesture :as gesture]
[react-native.safe-area :as safe-area]
[status-im2.contexts.chat.menus.pinned-messages.style :as style]
[status-im2.contexts.chat.messages.content.view :as message]
[utils.i18n :as i18n]
@@ -23,25 +24,6 @@
[message _ _ context]
[message/message message context (atom false)])
(defn empty-pinned-messages-state
[{:keys [community?]}]
[rn/view {:style style/no-pinned-messages-container}
[rn/view {:style style/no-pinned-messages-icon}
[quo/icon :i/placeholder]]
[rn/view {:style style/no-pinned-messages-content}
[quo/text
{:size :paragraph-1
:weight :semi-bold
:style style/no-pinned-messages-title}
(i18n/label :t/no-pinned-messages)]
[quo/text
{:size :paragraph-2
:style style/no-pinned-messages-text}
(i18n/label
(if community?
:t/no-pinned-messages-community-desc
:t/no-pinned-messages-desc))]]])
(defn pinned-messages
[chat-id]
(let [pinned (rf/sub [:chats/pinned-sorted-list chat-id])
@@ -49,10 +31,10 @@
current-chat (rf/sub [:chat-by-id chat-id])
{:keys [community-id]} current-chat
community (rf/sub [:communities/community community-id])
bottom-inset (safe-area/get-bottom)
community-images (rf/sub [:community/images community-id])]
[gesture/scroll-view
{:accessibility-label :pinned-messages-menu
:bounces false}
{:accessibility-label :pinned-messages-menu}
[:<>
[quo/text
{:size :heading-2
@@ -79,8 +61,18 @@
{:data pinned
:render-data render-data
:render-fn message-render-fn
:footer [rn/view {:style style/list-footer}]
:footer [rn/view {:style (style/list-footer bottom-inset)}]
:key-fn list-key-fn
:separator [quo/separator {:style {:margin-vertical 8}}]}]
[empty-pinned-messages-state
{:community? (boolean community)}])]))
[rn/view {:style (style/no-pinned-messages-container bottom-inset)}
[rn/view {:style style/no-pinned-messages-icon}
[quo/icon :i/placeholder]]
[quo/text
{:weight :semi-bold
:style style/no-pinned-messages-text}
(i18n/label :t/no-pinned-messages)]
[quo/text {:size :paragraph-2}
(i18n/label
(if community
:t/no-pinned-messages-community-desc
:t/no-pinned-messages-desc))]])]))
@@ -9,8 +9,11 @@
(defn- on-press
[{:keys [own message-id emoji-id emoji-reaction-id]}]
(if own
(rf/dispatch [:reactions/send-emoji-reaction-retraction emoji-reaction-id])
(rf/dispatch [:reactions/send-emoji-reaction
(rf/dispatch [:models.reactions/send-emoji-reaction-retraction
{:message-id message-id
:emoji-id emoji-id
:emoji-reaction-id emoji-reaction-id}])
(rf/dispatch [:models.reactions/send-emoji-reaction
{:message-id message-id
:emoji-id emoji-id}])))
@@ -192,8 +192,11 @@
:on-press
(fn []
(if emoji-reaction-id
(rf/dispatch [:reactions/send-emoji-reaction-retraction emoji-reaction-id])
(rf/dispatch [:reactions/send-emoji-reaction
(rf/dispatch [:models.reactions/send-emoji-reaction-retraction
{:message-id message-id
:emoji-id id
:emoji-reaction-id emoji-reaction-id}])
(rf/dispatch [:models.reactions/send-emoji-reaction
{:message-id message-id
:emoji-id id}]))
(rf/dispatch [:hide-bottom-sheet]))}])]))
@@ -1,94 +0,0 @@
(ns status-im2.contexts.chat.photo-selector.effects
(:require
[clojure.string :as string]
[react-native.cameraroll :as cameraroll]
[react-native.core :as rn]
[react-native.image-resizer :as image-resizer]
[react-native.permissions :as permissions]
[react-native.platform :as platform]
[taoensso.timbre :as log]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(def ^:private maximum-image-size-px 2000)
(rf/reg-fx :effects.camera-roll/request-permissions-and-get-photos
(fn [[num end-cursor album]]
(permissions/request-permissions
{:permissions [:read-external-storage]
:on-allowed
(fn []
(cameraroll/get-photos
(merge {:first num
:assetType "Photos"
:groupTypes (if (= album (i18n/label :t/recent)) "All" "Albums")
:groupName (if (not= album (i18n/label :t/recent)) album "")
:include ["imageSize"]}
(when end-cursor
{:after end-cursor}))
#(rf/dispatch [:on-camera-roll-get-photos (:edges %) (:page_info %) end-cursor])))})))
(defn- resize-photo
[uri callback]
(rn/image-get-size
uri
(fn [width height]
(let [resize? (> (max width height) maximum-image-size-px)]
(image-resizer/resize
uri
(if resize? maximum-image-size-px width)
(if resize? maximum-image-size-px height)
60
(fn [^js resized-image]
(let [path (.-path resized-image)
path (if (string/starts-with? path "file") path (str "file://" path))]
(callback {:resized-uri path
:width width
:height height})))
#(log/error "could not resize image" %))))))
(rf/reg-fx :effects.camera-roll/image-selected
(fn [[image chat-id]]
(resize-photo (:uri image) #(rf/dispatch [:photo-selector/image-selected chat-id image %]))))
(defn- get-albums
[callback]
(let [albums (atom {:smart-album []
:my-albums []})]
;; Get the "recent" album first
(cameraroll/get-photos
{:first 1 :groupTypes "All" :assetType "Photos"}
(fn [res-recent]
(swap! albums assoc
:smart-album
{:title (i18n/label :t/recent)
:uri (get-in (first (:edges res-recent)) [:node :image :uri])})
;; Get albums, then loop over albums and get each one's cover (first photo)
(cameraroll/get-albums
{:assetType "Photos"}
(fn [res-albums]
(let [response-count (count res-albums)]
(if (pos? response-count)
(doseq [album res-albums]
(cameraroll/get-photos
{:first 1 :groupTypes "Albums" :groupName (:title album) :assetType "Photos"}
(fn [res]
(let [uri (get-in (first (:edges res)) [:node :image :uri])]
(swap! albums update :my-albums conj (merge album {:uri uri}))
(when (= (count (:my-albums @albums)) response-count)
(swap! albums update :my-albums #(sort-by :title %))
(callback @albums))))))
(callback @albums)))))))))
(rf/reg-fx :effects.camera-roll/get-albums
(fn []
(get-albums #(rf/dispatch [:on-camera-roll-get-albums %]))))
(defn get-photos-count-ios-fx
[cb]
(cameraroll/get-photos-count-ios cb))
(rf/reg-fx :effects.camera-roll/get-photos-count-ios
(fn []
(when platform/ios?
(get-photos-count-ios-fx #(rf/dispatch [:on-camera-roll-get-images-count-ios %])))))
@@ -1,10 +1,104 @@
(ns status-im2.contexts.chat.photo-selector.events
(:require
[clojure.string :as string]
[re-frame.core :as re-frame]
[react-native.cameraroll :as cameraroll]
[react-native.core :as rn]
[react-native.image-resizer :as image-resizer]
[react-native.permissions :as permissions]
[react-native.platform :as platform]
[status-im2.constants :as constants]
status-im2.contexts.chat.photo-selector.effects
[taoensso.timbre :as log]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(def maximum-image-size-px 2000)
(defn- resize-photo
[uri callback]
(rn/image-get-size
uri
(fn [width height]
(let [resize? (> (max width height) maximum-image-size-px)]
(image-resizer/resize
uri
(if resize? maximum-image-size-px width)
(if resize? maximum-image-size-px height)
60
(fn [^js resized-image]
(let [path (.-path resized-image)
path (if (string/starts-with? path "file") path (str "file://" path))]
(callback {:resized-uri path
:width width
:height height})))
#(log/error "could not resize image" %))))))
(re-frame/reg-fx
:camera-roll-request-permissions-and-get-photos
(fn [[num end-cursor album]]
(permissions/request-permissions
{:permissions [:read-external-storage]
:on-allowed
(fn []
(cameraroll/get-photos
(merge {:first num
:assetType "Photos"
:groupTypes (if (= album (i18n/label :t/recent)) "All" "Albums")
:groupName (if (not= album (i18n/label :t/recent)) album "")
:include ["imageSize"]}
(when end-cursor
{:after end-cursor}))
#(re-frame/dispatch [:on-camera-roll-get-photos (:edges %) (:page_info %) end-cursor])))})))
(re-frame/reg-fx
:camera-roll-image-selected
(fn [[image chat-id]]
(resize-photo (:uri image) #(re-frame/dispatch [:photo-selector/image-selected chat-id image %]))))
(defn get-albums
[callback]
(let [albums (atom {:smart-album []
:my-albums []})]
;; Get the "recent" album first
(cameraroll/get-photos
{:first 1 :groupTypes "All" :assetType "Photos"}
(fn [res-recent]
(swap! albums assoc
:smart-album
{:title (i18n/label :t/recent)
:uri (get-in (first (:edges res-recent)) [:node :image :uri])})
;; Get albums, then loop over albums and get each one's cover (first photo)
(cameraroll/get-albums
{:assetType "Photos"}
(fn [res-albums]
(let [response-count (count res-albums)]
(if (pos? response-count)
(doseq [album res-albums]
(cameraroll/get-photos
{:first 1 :groupTypes "Albums" :groupName (:title album) :assetType "Photos"}
(fn [res]
(let [uri (get-in (first (:edges res)) [:node :image :uri])]
(swap! albums update :my-albums conj (merge album {:uri uri}))
(when (= (count (:my-albums @albums)) response-count)
(swap! albums update :my-albums #(sort-by :title %))
(callback @albums))))))
(callback @albums)))))))))
(defn get-photos-count-ios-fx
[cb]
(cameraroll/get-photos-count-ios cb))
(re-frame/reg-fx
:camera-roll-get-albums
(fn []
(get-albums #(re-frame/dispatch [:on-camera-roll-get-albums %]))))
(re-frame/reg-fx
:camera-roll-get-photos-count-ios
(fn []
(when platform/ios?
(get-photos-count-ios-fx #(re-frame/dispatch [:on-camera-roll-get-images-count-ios %])))))
(rf/defn on-camera-roll-get-albums
{:events [:on-camera-roll-get-albums]}
[{:keys [db]} albums]
@@ -19,12 +113,12 @@
(rf/defn camera-roll-get-albums
{:events [:photo-selector/camera-roll-get-albums]}
[_]
{:effects.camera-roll/get-albums nil})
{:camera-roll-get-albums nil})
(rf/defn camera-roll-get-ios-photo-count
{:events [:photo-selector/camera-roll-get-ios-photo-count]}
[_]
{:effects.camera-roll/get-photos-count-ios nil})
{:camera-roll-get-photos-count-ios nil})
(rf/defn camera-roll-select-album
{:events [:chat.ui/camera-roll-select-album]}
@@ -56,10 +150,9 @@
(rf/defn get-photos-for-selected-album
{:events [:photo-selector/get-photos-for-selected-album]}
[{:keys [db]} end-cursor]
{:effects.camera-roll/request-permissions-and-get-photos
[21 end-cursor
(or (:camera-roll/selected-album db)
(i18n/label :t/recent))]})
{:camera-roll-request-permissions-and-get-photos [21 end-cursor
(or (:camera-roll/selected-album db)
(i18n/label :t/recent))]})
(rf/defn camera-roll-loading-more
{:events [:photo-selector/camera-roll-loading-more]}
@@ -73,4 +166,4 @@
images (get-in db [:chat/inputs current-chat-id :metadata :sending-image])]
(when (and (< (count images) constants/max-album-photos)
(not (some #(= (:uri image) (:uri %)) images)))
{:effects.camera-roll/image-selected [image current-chat-id]})))
{:camera-roll-image-selected [image current-chat-id]})))
@@ -242,6 +242,7 @@
(defn- internal-discover-view
[params]
(rf/dispatch [:fetch-contract-communities])
[:f> f-view-internal params])
(def view (quo.theme/with-theme internal-discover-view))
@@ -366,11 +366,9 @@
(defn community-card-page-view
[id]
(let [{:keys [id joined]
(let [{:keys [id]
:as community} (rf/sub [:communities/community id])
pending? (rf/sub [:communities/my-pending-request-to-join id])]
(when joined
(rf/dispatch [:activity-center.notifications/dismiss-community-overview id]))
[community-scroll-page community pending?]))
(defn overview
@@ -128,7 +128,7 @@
same-password-length? #(and (seq @password)
(= (count @password) (count @repeat-password)))]
(fn []
(let [{user-color :color} (rf/sub [:onboarding/profile])
(let [{user-color :color} (rf/sub [:onboarding-2/profile])
{:keys [long-enough?]
:as validations} (password-validations @password)
password-strength (calc-password-strength validations)
@@ -177,7 +177,7 @@
{:disabled? (not meet-requirements?)
:customization-color user-color
:on-press #(rf/dispatch
[:onboarding/password-set
[:onboarding-2/password-set
(security/mask-data @password)])}
(i18n/label :t/password-creation-confirm)]]]]))))
@@ -218,7 +218,7 @@
:type :primary
:customization-color @custom-color
:on-press (fn []
(rf/dispatch [:onboarding/profile-data-set
(rf/dispatch [:onboarding-2/profile-data-set
{:image-path @profile-pic
:display-name @full-name
:color @custom-color}]))
@@ -232,7 +232,7 @@
(defn create-profile
[]
(let [{:keys [top]} (safe-area/get-insets)
onboarding-profile-data (rf/sub [:onboarding/profile])]
onboarding-profile-data (rf/sub [:onboarding-2/profile])]
[:<>
[:f> f-page
{:navigation-bar-top top
@@ -27,7 +27,7 @@
[insets]
(let [supported-biometric-type (rf/sub [:biometric/supported-type])
bio-type-label (biometric/get-label-by-type supported-biometric-type)
profile-color (or (:color (rf/sub [:onboarding/profile]))
profile-color (or (:color (rf/sub [:onboarding-2/profile]))
(rf/sub [:profile/customization-color]))
syncing-results? (= :syncing-results @state/root-id)]
[rn/view {:style (style/buttons insets)}
@@ -36,7 +36,7 @@
:accessibility-label :enable-biometrics-button
:icon-left :i/face-id
:customization-color profile-color
:on-press #(rf/dispatch [:onboarding/enable-biometrics])
:on-press #(rf/dispatch [:onboarding-2/enable-biometrics])
:button-label (i18n/label :t/biometric-enable-button {:bio-type-label bio-type-label})}]
[quo/button
{:accessibility-label :maybe-later-button
@@ -45,7 +45,7 @@
:on-press #(rf/dispatch (if syncing-results?
[:navigate-to-within-stack
[:enable-notifications :enable-biometrics]]
[:onboarding/create-account-and-login]))
[:onboarding-2/create-account-and-login]))
:container-style {:margin-top 12}}
(i18n/label :t/maybe-later)]]))
@@ -20,7 +20,7 @@
(defn enable-notification-buttons
[{:keys [insets]}]
(let [profile-color (rf/sub [:onboarding/customization-color])]
(let [profile-color (rf/sub [:onboarding-2/customization-color])]
[rn/view {:style (style/buttons insets)}
[quo/button
{:on-press (fn []
@@ -103,7 +103,7 @@
(reset! seed-phrase new-phrase))
on-submit (fn []
(swap! seed-phrase clean-seed-phrase)
(rf/dispatch [:onboarding/seed-phrase-entered
(rf/dispatch [:onboarding-2/seed-phrase-entered
(security/mask-data @seed-phrase)
set-invalid-seed-phrase]))]
(let [words-coll (mnemonic/passphrase->words @seed-phrase)
+39 -39
View File
@@ -24,57 +24,57 @@
(on-success mnemonic keyUID)))))))
(rf/defn profile-data-set
{:events [:onboarding/profile-data-set]}
{:events [:onboarding-2/profile-data-set]}
[{:keys [db]} onboarding-data]
{:db (update db :onboarding/profile merge onboarding-data)
{:db (update db :onboarding-2/profile merge onboarding-data)
:dispatch [:navigate-to-within-stack [:create-profile-password :new-to-status]]})
(rf/defn enable-biometrics
{:events [:onboarding/enable-biometrics]}
{:events [:onboarding-2/enable-biometrics]}
[_]
{:biometric/authenticate {:on-success #(rf/dispatch [:onboarding/biometrics-done])
:on-fail #(rf/dispatch [:onboarding/biometrics-fail %])}})
{:biometric/authenticate {:on-success #(rf/dispatch [:onboarding-2/biometrics-done])
:on-fail #(rf/dispatch [:onboarding-2/biometrics-fail %])}})
(rf/defn navigate-to-enable-notifications
{:events [:onboarding/navigate-to-enable-notifications]}
{:events [:onboarding-2/navigate-to-enable-notifications]}
[{:keys [db]}]
(let [key-uid (get-in db [:profile/profile :key-uid])]
{:db (dissoc db :onboarding/profile)
{:db (dissoc db :onboarding-2/profile)
:dispatch [:navigate-to-within-stack [:enable-notifications :enable-biometrics]]}))
(rf/defn biometrics-done
{:events [:onboarding/biometrics-done]}
{:events [:onboarding-2/biometrics-done]}
[{:keys [db]}]
(let [syncing? (get-in db [:onboarding/profile :syncing?])]
{:db (assoc-in db [:onboarding/profile :auth-method] constants/auth-method-biometric)
(let [syncing? (get-in db [:onboarding-2/profile :syncing?])]
{:db (assoc-in db [:onboarding-2/profile :auth-method] constants/auth-method-biometric)
:dispatch (if syncing?
[:onboarding/finalize-setup]
[:onboarding/create-account-and-login])}))
[:onboarding-2/finalize-setup]
[:onboarding-2/create-account-and-login])}))
(rf/defn biometrics-fail
{:events [:onboarding/biometrics-fail]}
{:events [:onboarding-2/biometrics-fail]}
[cofx code]
(biometric/show-message cofx code))
(rf/defn create-account-and-login
{:events [:onboarding/create-account-and-login]}
{:events [:onboarding-2/create-account-and-login]}
[{:keys [db] :as cofx}]
(let [{:keys [display-name seed-phrase password image-path color] :as profile}
(:onboarding/profile db)]
(:onboarding-2/profile db)]
(rf/merge cofx
{:dispatch [:navigate-to-within-stack [:generating-keys :new-to-status]]
:dispatch-later [{:ms constants/onboarding-generating-keys-animation-duration-ms
:dispatch [:onboarding/navigate-to-identifiers]}]
:dispatch [:onboarding-2/navigate-to-identifiers]}]
:db (-> db
(dissoc :profile/login)
(dissoc :auth-method)
(assoc :onboarding/new-account? true))}
(assoc :onboarding-2/new-account? true))}
(if seed-phrase
(profile.recover/recover-profile-and-login profile)
(profile.create/create-profile-and-login profile)))))
(rf/defn on-delete-profile-success
{:events [:onboarding/on-delete-profile-success]}
{:events [:onboarding-2/on-delete-profile-success]}
[{:keys [db]} key-uid]
(let [multiaccounts (dissoc (:profile/profiles-overview db) key-uid)]
(merge
@@ -83,18 +83,18 @@
{:set-root :intro}))))
(rf/defn password-set
{:events [:onboarding/password-set]}
{:events [:onboarding-2/password-set]}
[{:keys [db]} password]
(let [supported-type (:biometric/supported-type db)]
{:db (-> db
(assoc-in [:onboarding/profile :password] password)
(assoc-in [:onboarding/profile :auth-method] constants/auth-method-password))
(assoc-in [:onboarding-2/profile :password] password)
(assoc-in [:onboarding-2/profile :auth-method] constants/auth-method-password))
:dispatch (if supported-type
[:navigate-to-within-stack [:enable-biometrics :new-to-status]]
[:onboarding/create-account-and-login])}))
[:onboarding-2/create-account-and-login])}))
(rf/defn navigate-to-enable-biometrics
{:events [:onboarding/navigate-to-enable-biometrics]}
{:events [:onboarding-2/navigate-to-enable-biometrics]}
[{:keys [db]}]
(let [supported-type (:biometric/supported-type db)]
{:dispatch (if supported-type
@@ -102,19 +102,19 @@
[:open-modal :enable-notifications])}))
(rf/defn seed-phrase-entered
{:events [:onboarding/seed-phrase-entered]}
{:events [:onboarding-2/seed-phrase-entered]}
[_ seed-phrase on-error]
{:multiaccount/validate-mnemonic [seed-phrase
(fn [mnemonic key-uid]
(re-frame/dispatch [:onboarding/seed-phrase-validated
(re-frame/dispatch [:onboarding-2/seed-phrase-validated
mnemonic key-uid]))
on-error]})
(rf/defn seed-phrase-validated
{:events [:onboarding/seed-phrase-validated]}
{:events [:onboarding-2/seed-phrase-validated]}
[{:keys [db]} seed-phrase key-uid]
(if (contains? (:profile/profiles-overview db) key-uid)
{:effects.utils/show-confirmation
{:utils/show-confirmation
{:title (i18n/label :t/multiaccount-exists-title)
:content (i18n/label :t/multiaccount-exists-content)
:confirm-button-text (i18n/label :t/unlock)
@@ -123,25 +123,25 @@
(re-frame/dispatch
[:profile/profile-selected key-uid]))
:on-cancel #(re-frame/dispatch [:pop-to-root :multiaccounts])}}
{:db (assoc-in db [:onboarding/profile :seed-phrase] seed-phrase)
{:db (assoc-in db [:onboarding-2/profile :seed-phrase] seed-phrase)
:dispatch [:navigate-to-within-stack [:create-profile :new-to-status]]}))
(rf/defn navigate-to-create-profile
{:events [:onboarding/navigate-to-create-profile]}
{:events [:onboarding-2/navigate-to-create-profile]}
[{:keys [db]}]
;; Restart the flow
{:db (dissoc db :onboarding/profile)
{:db (dissoc db :onboarding-2/profile)
:dispatch [:navigate-to-within-stack [:create-profile :new-to-status]]})
(rf/defn onboarding-new-account-finalize-setup
{:events [:onboarding/finalize-setup]}
{:events [:onboarding-2/finalize-setup]}
[{:keys [db]}]
(let [masked-password (get-in db [:onboarding/profile :password])
(let [masked-password (get-in db [:onboarding-2/profile :password])
key-uid (get-in db [:profile/profile :key-uid])
syncing? (get-in db [:onboarding/profile :syncing?])
biometric-enabled? (= (get-in db [:onboarding/profile :auth-method])
syncing? (get-in db [:onboarding-2/profile :syncing?])
biometric-enabled? (= (get-in db [:onboarding-2/profile :auth-method])
constants/auth-method-biometric)]
(cond-> {:db (assoc db :onboarding/generated-keys? true)}
(cond-> {:db (assoc db :onboarding-2/generated-keys? true)}
biometric-enabled?
(assoc :keychain/save-password-and-auth-method
{:key-uid key-uid
@@ -150,16 +150,16 @@
(security/hash-masked-password masked-password))
:on-success (fn []
(if syncing?
(rf/dispatch [:onboarding/navigate-to-enable-notifications])
(rf/dispatch [:onboarding-2/navigate-to-enable-notifications])
(log/error "successfully saved biometrics")))
:on-error #(log/error "failed to save biometrics"
{:key-uid key-uid
:error %})}))))
(rf/defn navigate-to-identifiers
{:events [:onboarding/navigate-to-identifiers]}
{:events [:onboarding-2/navigate-to-identifiers]}
[{:keys [db]}]
(if (:onboarding/generated-keys? db)
(if (:onboarding-2/generated-keys? db)
{:dispatch [:navigate-to-within-stack [:identifiers :new-to-status]]}
{:dispatch-later [{:ms constants/onboarding-generating-keys-navigation-retry-ms
:dispatch [:onboarding/navigate-to-identifiers]}]}))
:dispatch [:onboarding-2/navigate-to-identifiers]}]}))
@@ -28,7 +28,7 @@
drag-amount (atom nil)
{:keys [emoji-hash display-name compressed-key
public-key]} (rf/sub [:profile/profile])
{:keys [color]} (rf/sub [:onboarding/profile])
{:keys [color]} (rf/sub [:onboarding-2/profile])
photo-path (rf/sub [:chats/photo-path public-key])
emoji-string (string/join emoji-hash)]
(carousel.animation/use-initialize-animation progress paused? true is-dragging? drag-amount)
@@ -30,7 +30,7 @@
(* 2 56) ;; two other list items
(* 2 16) ;; spacing between items
220) ;; extra spacing (top bar)
:on-press #(rf/dispatch [:onboarding/navigate-to-create-profile])}]
:on-press #(rf/dispatch [:onboarding-2/navigate-to-create-profile])}]
[rn/view {:style style/subtitle-container}
[quo/text
{:style style/subtitle
@@ -39,7 +39,7 @@
(defn view
[in-onboarding?]
(let [pairing-status (rf/sub [:pairing/pairing-status])
profile-color (:color (rf/sub [:onboarding/profile]))]
profile-color (:color (rf/sub [:onboarding-2/profile]))]
[rn/view {:style (style/page-container in-onboarding?)}
(when-not in-onboarding? [background/view true])
[quo/page-nav {:type :no-title :background :blur}]
@@ -54,7 +54,7 @@
{:on-press (fn []
(when on-press
(on-press))
(rf/dispatch [:onboarding/navigate-to-enable-biometrics]))
(rf/dispatch [:onboarding-2/navigate-to-enable-biometrics]))
:accessibility-label :continue-button
:customization-color profile-color
:container-style style/continue-button}
@@ -14,7 +14,7 @@
(defn page-title
[]
(let [new-account? (rf/sub [:onboarding/new-account?])]
(let [new-account? (rf/sub [:onboarding-2/new-account?])]
[quo/text-combinations
{:container-style {:margin-top 12 :margin-horizontal 20}
:title (i18n/label (if new-account?
@@ -31,7 +31,7 @@
(defn view
[]
(let [profile-color (rf/sub [:onboarding/customization-color])
(let [profile-color (rf/sub [:onboarding-2/customization-color])
{:keys [status-type]} (rf/sub [:multiaccount/current-user-visibility-status])
window (rf/sub [:dimensions/window])
insets (safe-area/get-insets)]
@@ -1,9 +0,0 @@
(ns status-im2.contexts.profile.create.effects
(:require
[native-module.core :as native-module]
[utils.re-frame :as rf]))
(rf/reg-fx :effects.profile/create-and-login
(fn [request]
;;"node.login" signal will be triggered as a callback
(native-module/create-account-and-login request)))
@@ -1,15 +1,21 @@
(ns status-im2.contexts.profile.create.events
(:require
[native-module.core :as native-module]
[re-frame.core :as re-frame]
[status-im2.contexts.profile.config :as profile.config]
status-im2.contexts.profile.create.effects
[utils.re-frame :as rf]
[utils.security.core :as security]))
(re-frame/reg-fx
::create-profile-and-login
(fn [request]
;;"node.login" signal will be triggered as a callback
(native-module/create-account-and-login request)))
(rf/defn create-profile-and-login
{:events [:profile.create/create-and-login]}
[_ {:keys [display-name password image-path color]}]
{:effects.profile/create-and-login
{::create-profile-and-login
(assoc (profile.config/create)
:displayName display-name
:password (native-module/sha3 (security/safe-unmask-data password))
+2 -2
View File
@@ -43,10 +43,10 @@
{:keys [key-uid]} (first (sort-by :timestamp > (vals profiles)))]
(rf/merge cofx
(navigation/init-root :profiles)
(when key-uid (init-profiles-overview profiles key-uid))
(init-profiles-overview profiles key-uid)
;;we check if biometric is available, and try to login with it,
;;if succeed "node.login" signal will be triggered
(when key-uid (profile.login/login-with-biometric-if-available key-uid))))
(profile.login/login-with-biometric-if-available key-uid)))
(navigation/init-root cofx :intro)))
(rf/defn update-setting-from-backup
@@ -1,11 +0,0 @@
(ns status-im2.contexts.profile.login.effects
(:require
[native-module.core :as native-module]
[status-im2.contexts.profile.config :as profile.config]
[utils.re-frame :as rf]))
(rf/reg-fx :effects.profile/login
(fn [[key-uid hashed-password]]
;;"node.login" signal will be triggered as a callback
(native-module/login-account
(assoc (profile.config/login) :keyUid key-uid :password hashed-password))))
@@ -9,18 +9,14 @@
[status-im.data-store.switcher-cards :as switcher-cards-store]
[status-im.data-store.visibility-status-updates :as visibility-status-updates-store]
[status-im.group-chats.core :as group-chats]
[status-im.mailserver.core :as mailserver]
[status-im.mobile-sync-settings.core :as mobile-network]
[status-im.pairing.core :as pairing]
[status-im.stickers.core :as stickers]
[status-im.transport.core :as transport]
[status-im2.common.keychain.events :as keychain]
[status-im2.common.log :as logging]
[status-im2.common.universal-links :as universal-links]
[status-im2.config :as config]
[status-im2.contexts.chat.messages.link-preview.events :as link-preview]
[status-im2.contexts.contacts.events :as contacts]
[status-im2.contexts.profile.config :as profile.config]
status-im2.contexts.profile.login.effects
[status-im2.contexts.profile.rpc :as profile.rpc]
[status-im2.contexts.profile.settings.events :as profile.settings.events]
[status-im2.contexts.push-notifications.events :as notifications]
@@ -31,29 +27,36 @@
[utils.re-frame :as rf]
[utils.security.core :as security]))
(re-frame/reg-fx
::login
(fn [[key-uid hashed-password]]
;;"node.login" signal will be triggered as a callback
(native-module/login-account
(assoc (profile.config/login) :keyUid key-uid :password hashed-password))))
(rf/defn login
{:events [:profile.login/login]}
[{:keys [db]}]
(let [{:keys [key-uid password]} (:profile/login db)]
{:db (assoc-in db [:profile/login :processing] true)
:effects.profile/login [key-uid (native-module/sha3 (security/safe-unmask-data password))]}))
{:db (assoc-in db [:profile/login :processing] true)
::login [key-uid (native-module/sha3 (security/safe-unmask-data password))]}))
(rf/defn biometrics-login
{:events [:profile.login/biometrics-login]}
[{:keys [db]}]
(let [{:keys [key-uid password]} (:profile/login db)]
{:db (assoc-in db [:profile/login :processing] true)
:effects.profile/login [key-uid (security/safe-unmask-data password)]}))
{:db (assoc-in db [:profile/login :processing] true)
::login [key-uid (security/safe-unmask-data password)]}))
(rf/defn login-local-paired-user
{:events [:profile.login/local-paired-user]}
[{:keys [db]}]
(let [{:keys [key-uid password]} (get-in db [:syncing :profile])
masked-password (security/mask-data password)]
{:db (-> db
(assoc-in [:onboarding/profile :password] masked-password)
(assoc-in [:onboarding/profile :syncing?] true))
:effects.profile/login [key-uid password]}))
{:db (-> db
(assoc-in [:onboarding-2/profile :password] masked-password)
(assoc-in [:onboarding-2/profile :syncing?] true))
::login [key-uid password]}))
(rf/defn redirect-to-root
[{:keys [db] :as cofx}]
@@ -63,8 +66,8 @@
{:db (dissoc db :syncing)
:dispatch [:init-root :syncing-results]}
(get db :onboarding/new-account?)
{:dispatch [:onboarding/finalize-setup]}
(get db :onboarding-2/new-account?)
{:dispatch [:onboarding-2/finalize-setup]}
:else
(rf/merge
@@ -113,13 +116,9 @@
network-id (str (get-in networks
[current-network :config :NetworkId]))]
(rf/merge cofx
(cond-> {:json-rpc/call [{:method "wakuext_startMessenger"
:on-success #(re-frame/dispatch [:messenger-started %])
:on-error #(log/error "failed to start messenger")}]
:wallet-legacy/initialize-transactions-management-enabled nil
(cond-> {:wallet-legacy/initialize-transactions-management-enabled nil
:wallet-legacy/initialize-wallet
[network-id
current-network-config
(fn [accounts tokens custom-tokens favourites]
(re-frame/dispatch [:wallet-legacy/initialize-wallet
accounts tokens custom-tokens favourites]))]
@@ -128,6 +127,7 @@
(assoc :chat/open-last-chat (get-in db [:profile/profile :key-uid]))
notifications-enabled?
(assoc :effects/push-notifications-enable nil))
(transport/start-messenger)
(contacts/initialize-contacts)
(browser/initialize-browser)
(mobile-network/on-network-status-change)
@@ -138,30 +138,8 @@
(visibility-status-updates-store/fetch-visibility-status-updates-rpc)
(switcher-cards-store/fetch-switcher-cards-rpc))))
(rf/defn messenger-started
{:events [:messenger-started]}
[{:keys [db] :as cofx} {:keys [mailservers] :as response}]
(log/info "Messenger started")
(let [new-account? (get db :onboarding-2/new-account?)]
(rf/merge cofx
{:db (-> db
(assoc :messenger/started? true)
(mailserver/add-mailservers mailservers))
:json-rpc/call [{:method "admin_nodeInfo"
:on-success #(re-frame/dispatch [:node-info-fetched %])
:on-error #(log/error "node-info: failed error" %)}]}
(pairing/init)
(stickers/load-packs)
(when-not new-account?
(universal-links/process-stored-event)))))
(rf/defn set-node-info
{:events [:node-info-fetched]}
[{:keys [db]} node-info]
{:db (assoc db :node-info node-info)})
(rf/defn login-node-signal
[{{:onboarding/keys [recovered-account? new-account?] :as db} :db :as cofx}
[{{:onboarding-2/keys [recovered-account? new-account?] :as db} :db :as cofx}
{:keys [settings account ensUsernames error]}]
(log/debug "[signals] node.login" "error" error)
(if error
@@ -77,7 +77,7 @@
key-uid
(fn [result]
(let [{:keys [error]} (transforms/json->clj result)]
(rf/dispatch [:onboarding/on-delete-profile-success key-uid])
(rf/dispatch [:onboarding-2/on-delete-profile-success key-uid])
(log/info "profile deleted: error" error)))))}])
(defn show-confirmation
@@ -1,9 +0,0 @@
(ns status-im2.contexts.profile.recover.effects
(:require
[native-module.core :as native-module]
[utils.re-frame :as rf]))
(rf/reg-fx :effects.profile/restore-and-login
(fn [request]
;;"node.login" signal will be triggered as a callback
(native-module/restore-account-and-login request)))

Some files were not shown because too many files have changed in this diff Show More