Compare commits

...
Author SHA1 Message Date
Mohamed Javid a42289f387 [Fix] Token name display in accounts home
Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2023-12-09 02:23:22 +05:30
Ulises Manuel 0ba057ae9d [#17965] Create token component (#18018)
* Create token component

* Replace token images by new token component

The new component is being used in the following components:
 - token-input
 - network-amount
 - token-tag
 - summary-tag
 - context-tag
 - token-value
 - token-network
 - preview-list

* Rename token image file: eth-token -> eth

* Remove resources/get-token function
2023-12-08 14:13:11 -06:00
Ulises Manuel 8b919f4058 [#17896] Raw balances using big number (#17920)
* Add `utils.money/add` version able to work with `nil`s

* Store token raw-balance as big-number

* Improve account balance calculations using `utils.money` existing functions

* Update `:wallet/tokens-filtered` sub

* Make `prettify-balance` able to work with bignumbers
2023-12-08 13:40:26 -06:00
flexsurfer f79860fb97 move blob to rn, remove unused code, move images events to status-im2 (#18117) 2023-12-08 17:27:21 +01:00
Parvesh Monu 7a6f05a440 fix sometimes add contact screen is closed by itself after scanning QR code (#18101) 2023-12-08 18:53:56 +05:30
Ulises Manuel de4e233884 [#17974] text combinations - username component (#17987)
* Move docstring to be available while using `colors/resolve-color`
* Add text combinations - username component and tests
* Add username related svg icons
2023-12-07 17:44:24 -06:00
100 changed files with 790 additions and 2102 deletions

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

-12
View File
@@ -368,17 +368,6 @@
:LineChart #js {}
:LineChartBicolor #js {}})
(def wallet-connect-client
#js
{:default #js {}
:CLIENT_EVENTS #js
{:session #js
{:request nil
:created nil
:deleted nil
:proposal nil
:updated nil}}})
(def worklet-factory
#js {:applyAnimationsToStyle (fn [])})
@@ -447,7 +436,6 @@
"../src/js/worklets/parallax.js" #js {}
"../src/js/worklets/identifiers_highlighting.js" #js {}
"./fleets.js" default-fleets
"@walletconnect/client" wallet-connect-client
"../translations/ar.json" (js/JSON.parse (slurp "./translations/ar.json"))
"../translations/de.json" (js/JSON.parse (slurp "./translations/de.json"))
"../translations/en.json" (js/JSON.parse (slurp "./translations/en.json"))
+25 -29
View File
@@ -10,40 +10,36 @@
(defn token-requirement-list-row
[tokens padding?]
[rn/view
{:style (style/token-row padding?)}
(doall
(map-indexed (fn [token-index token]
(let [{:keys [img-src amount sufficient? purchasable?]} token]
^{:key token-index}
[rn/view {:style style/token-tag-spacing}
[token-tag/view
{:token-symbol (:symbol token)
:token-value amount
:size :size-24
:options (cond
sufficient? :hold
purchasable? :add)
:token-img-src img-src}]]))
tokens))])
[rn/view {:style (style/token-row padding?)}
(map-indexed (fn [token-index token]
(let [{:keys [amount sufficient? purchasable?]} token]
^{:key token-index}
[rn/view {:style style/token-tag-spacing}
[token-tag/view
{:token-symbol (:symbol token)
:token-value amount
:size :size-24
:options (cond
sufficient? :hold
purchasable? :add)}]]))
tokens)])
(defn- internal-view
[{:keys [tokens padding? theme]}]
[:<>
(if (> (count tokens) 1)
(doall
(map-indexed
(fn [token-requirement-index tokens]
^{:key token-requirement-index}
[rn/view {:margin-bottom 12}
(when-not (= token-requirement-index 0)
[rn/view {:style (style/token-row-or-border theme)}])
(when-not (= token-requirement-index 0)
[text/text
{:style (style/token-row-or-text padding? theme)
:size :label} (string/lower-case (i18n/label :t/or))])
[token-requirement-list-row tokens padding?]])
tokens))
(map-indexed
(fn [token-requirement-index tokens]
^{:key token-requirement-index}
[rn/view {:margin-bottom 12}
(when-not (= token-requirement-index 0)
[rn/view {:style (style/token-row-or-border theme)}])
(when-not (= token-requirement-index 0)
[text/text
{:style (style/token-row-or-text padding? theme)
:size :label} (string/lower-case (i18n/label :t/or))])
[token-requirement-list-row tokens padding?]])
tokens)
[token-requirement-list-row (first tokens) padding?])])
(def token-requirement-list (quo.theme/with-theme internal-view))
+6 -5
View File
@@ -9,9 +9,10 @@
(defn- valid-color?
[color]
(or (keyword? color)
(and (string? color)
(not (string/blank? color)))))
(and color
(or (keyword? color)
(and (string? color)
(not (string/blank? color))))))
(defn- image-icon-style
[{:keys [color no-color size container-style theme]}]
@@ -37,8 +38,8 @@
(cond-> {:size size
:accessibility-label accessibility-label
:style container-style}
(and color (valid-color? color)) (assoc :color color)
(and color-2 (valid-color? color-2)) (assoc :color-2 color-2))]
(valid-color? color) (assoc :color color)
(valid-color? color-2) (assoc :color-2 color-2))]
[rn/image
{:style (image-icon-style (assoc props :size size))
:accessibility-label accessibility-label
+54 -6
View File
@@ -118,13 +118,61 @@
"M2.79504 9.01494C2.89473 8.85584 3.00297 8.70977 3.11963 8.5761C3.90594 7.67512 4.97212 7.45024 5.99992 7.45024C7.02772 7.45024 8.0939 7.67512 8.88021 8.5761C8.99688 8.70978 9.10512 8.85585 9.2048 9.01495C8.9501 9.28561 8.66149 9.52401 8.34577 9.72335C8.25403 9.55824 8.15512 9.41818 8.05145 9.29939C7.56503 8.74204 6.88121 8.55024 5.99992 8.55024C5.11862 8.55024 4.43481 8.74204 3.94839 9.29939C3.84472 9.41818 3.74582 9.55824 3.65408 9.72334C3.33835 9.524 3.04975 9.2856 2.79504 9.01494ZM5.99992 3.5502C5.47525 3.5502 5.04992 3.97552 5.04992 4.5002C5.04992 5.02487 5.47525 5.4502 5.99992 5.4502C6.52459 5.4502 6.94992 5.02487 6.94992 4.5002C6.94992 3.97552 6.52459 3.5502 5.99992 3.5502ZM3.94992 4.5002C3.94992 3.36801 4.86773 2.4502 5.99992 2.4502C7.1321 2.4502 8.04992 3.36801 8.04992 4.5002C8.04992 5.63238 7.1321 6.5502 5.99992 6.5502C4.86773 6.5502 3.94992 5.63238 3.94992 4.5002Z"
:fill color-2}]])
(defn- contact-20
[{:keys [color color-2]
:or {color colors/neutral-100
color-2 colors/white}
:as props}]
[container props
[svg/circle
{:cx 10
:cy 10
:r 7.5
:fill color}]
[svg/path
{:d
"M8.65002 7.99998C8.65002 7.25439 9.25443 6.64998 10 6.64998C10.7456 6.64998 11.35 7.25439 11.35 7.99998C11.35 8.74556 10.7456 9.34998 10 9.34998C9.25443 9.34998 8.65002 8.74556 8.65002 7.99998ZM10 5.34998C8.53646 5.34998 7.35002 6.53642 7.35002 7.99998C7.35002 9.46353 8.53646 10.65 10 10.65C11.4636 10.65 12.65 9.46353 12.65 7.99998C12.65 6.53642 11.4636 5.34998 10 5.34998ZM10 13.65C8.67557 13.65 7.53064 14.4186 6.98692 15.5341C6.60094 15.3235 6.23942 15.0737 5.90771 14.79C6.69408 13.3369 8.23179 12.35 10 12.35C11.7682 12.35 13.306 13.3369 14.0923 14.79C13.7606 15.0737 13.3991 15.3235 13.0131 15.5341C12.4694 14.4186 11.3245 13.65 10 13.65Z"
:fill color-2}]])
(defn- verified-20
[{:keys [color color-2]
:or {color colors/neutral-100
color-2 colors/white}
:as props}]
[container props
[svg/path
{:d
"M18 10C18 8.77003 17.1118 7.74751 15.9418 7.53891C16.6216 6.56407 16.5267 5.21294 15.6569 4.34321C14.7872 3.47344 13.436 3.37852 12.4611 4.05845C12.2526 2.88834 11.23 2 10 2C8.77 2 7.74747 2.88827 7.53889 4.05832C6.56406 3.37846 5.21292 3.47339 4.34318 4.34313C3.47343 5.21288 3.3785 6.56404 4.05839 7.53888C2.88831 7.74743 2 8.76998 2 10C2 11.23 2.88824 12.2525 4.05826 12.4611C3.3784 13.4359 3.47333 14.7871 4.34307 15.6568C5.21284 16.5266 6.56403 16.6215 7.53887 15.9416C7.74741 17.1117 8.76996 18 10 18C11.23 18 12.2525 17.1117 12.4611 15.9417C13.4359 16.6215 14.7871 16.5266 15.6568 15.6569C16.5265 14.7871 16.6215 13.436 15.9416 12.4611C17.1117 12.2526 18 11.23 18 10Z"
:fill color}]
[svg/path
{:d "M7.25 10.75L9.25 12.25L12.75 7.75"
:stroke color-2
:stroke-width "1.2"}]])
(defn- untrustworthy-20
[{:keys [color color-2]
:or {color colors/neutral-100
color-2 colors/white}
:as props}]
[container props
[svg/path
{:d "M10 2L15.6569 4.34315L18 10L15.6569 15.6569L10 18L4.34315 15.6569L2 10L4.34315 4.34315L10 2Z"
:fill color}]
[svg/path
{:d
"M10.75 5.5L10.55 11.5H9.45L9.25 5.5H10.75ZM10 13C10.4142 13 10.75 13.3358 10.75 13.75C10.75 14.1642 10.4142 14.5 10 14.5C9.58579 14.5 9.25 14.1642 9.25 13.75C9.25 13.3358 9.58579 13 10 13Z"
:fill color-2}]])
(def ^:private icons
{:i/clear-20 clear-20
:i/dropdown-20 dropdown-20
:i/pullup-20 pullup-20
:i/dropdown-12 dropdown-12
:i/pullup-12 pullup-12
:i/contact-12 contact-12})
{:i/clear-20 clear-20
:i/dropdown-20 dropdown-20
:i/pullup-20 pullup-20
:i/dropdown-12 dropdown-12
:i/pullup-12 pullup-12
:i/contact-12 contact-12
:i/contact-20 contact-20
:i/verified-20 verified-20
:i/untrustworthy-20 untrustworthy-20})
(defn- append-to-keyword
[k & xs]
@@ -4,6 +4,7 @@
[quo.components.avatars.user-avatar.view :as user-avatar]
[quo.components.list-items.preview-list.properties :as properties]
[quo.components.tags.number-tag.view :as number-tag]
[quo.components.utilities.token.view :as token]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[react-native.fast-image :as fast-image]
@@ -31,7 +32,12 @@
:height size
:border-radius border-radius}}]
(:tokens :network :dapps) [fast-image/fast-image
:tokens [token/view
{:token item
:size size
:style {:border-radius border-radius}}]
(:network :dapps) [fast-image/fast-image
{:source (or (:source item) item)
:style {:width size
:height size
@@ -5,7 +5,7 @@
[test-helpers.component :as h]))
(def props
{:token (resources/get-token :snt)
{:token :snt
:state :default
:label "Status"
:networks [(resources/get-network :ethereum)]
@@ -34,9 +34,7 @@
:flex 1})
(def token-image
{:width 32
:height 32
:border-width 1
{:border-width 1
:border-radius 16
:border-color colors/neutral-80-opa-5
:margin-right 8
@@ -4,6 +4,7 @@
[quo.components.list-items.preview-list.view :as preview-list]
[quo.components.list-items.token-network.style :as style]
[quo.components.markdown.text :as text]
[quo.components.utilities.token.view :as token]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[reagent.core :as reagent]))
@@ -11,9 +12,11 @@
(defn- info
[{:keys [token label networks]}]
[rn/view {:style style/info}
[rn/image
{:source (or (:source token) token)
:style style/token-image}]
(when token
[token/view
{:style style/token-image
:size :size-32
:token token}])
[rn/view {:style style/token-info}
[text/text
{:weight :semi-bold
@@ -1,12 +1,10 @@
(ns quo.components.list-items.token-value.view
(:require
[clojure.string :as string]
[quo.components.icon :as icon]
[quo.components.list-items.token-value.style :as style]
[quo.components.markdown.text :as text]
[quo.components.utilities.token.view :as token]
[quo.foundations.colors :as colors]
[quo.foundations.common :as common]
[quo.foundations.resources :as resources]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[reagent.core :as reagent]))
@@ -14,7 +12,8 @@
(defn- internal-view
[]
(let [state (reagent/atom :default)]
(fn [{:keys [theme customization-color status token metrics? values on-press on-long-press]}]
(fn [{:keys [theme customization-color status token metrics? values on-press
on-long-press]}]
(let [bg-opacity (case @state
:active 10
:pressed 5
@@ -34,16 +33,13 @@
{:style {:flex-direction :row
:align-items :center
:flex 1}}
[rn/image
{:source (resources/get-token token)
:style {:width 32
:height 32}}]
[token/view {:token (:symbol token) :size :size-32}]
[rn/view {:style {:margin-left 8}}
[text/text {:weight :semi-bold} (common/token-label token)]
[text/text {:weight :semi-bold} (:name token)]
[text/text
{:size :paragraph-2
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
(str crypto-value " " (if token (string/upper-case (clj->js token)) ""))]]]
(str crypto-value " " (:symbol token))]]]
[rn/view
{:style {:align-items :flex-end
:justify-content :space-between}}
@@ -59,6 +59,10 @@
[theme]
{:color (colors/theme-colors colors/neutral-100 colors/white theme)})
(defn token-logo
[size]
{:border-radius (if (= size 24) 10 14)})
(defn circle-logo
[size]
(if (= size 24)
@@ -7,6 +7,7 @@
[quo.components.list-items.preview-list.view :as preview-list]
[quo.components.markdown.text :as text]
[quo.components.tags.context-tag.style :as style]
[quo.components.utilities.token.view :as token]
[quo.foundations.colors :as colors]
[quo.theme :as quo.theme]
[react-native.core :as rn]))
@@ -73,7 +74,7 @@
(defn- view-internal
[{:keys [theme type size state blur? customization-color profile-picture full-name users
group-name token-logo amount token-name network-logo network-name networks
group-name amount token network-logo network-name networks
account-name emoji collectible collectible-name collectible-number duration container-style]
:or {customization-color :blue
type :default
@@ -123,8 +124,11 @@
[communities-tag (assoc props :channel? (= type :channel))]
:token
[tag-skeleton {:theme theme :size size :text (str amount " " token-name)}
[rn/image {:style (style/circle-logo size) :source token-logo}]]
[tag-skeleton {:theme theme :size size :text (str amount " " token)}
[token/view
{:style (style/token-logo size)
:token token
:size (if (= size 24) :size-20 :size-28)}]]
:network
[tag-skeleton {:theme theme :size size :text network-name}
@@ -182,9 +186,8 @@
- `:token`
- size
- token-logo (valid rn/image :source value)
- amount
- token-name
- token
- `:network`
- size
@@ -47,7 +47,7 @@
(h/test "Token view render"
(h/render [summary-tag/view
{:type :token
:label "1,000 SNT"
:image-source "path/to/token-image.png"}])
{:type :token
:label "1,000 SNT"
:token :eth}])
(h/is-truthy (h/get-by-text "1,000 SNT"))))
@@ -24,6 +24,4 @@
:border-radius 10})
(def token-image
{:width 24
:height 24
:border-radius 12})
{:border-radius 12})
@@ -5,12 +5,13 @@
[quo.components.avatars.wallet-user-avatar.view :as wallet-user-avatar]
[quo.components.markdown.text :as text]
[quo.components.tags.summary-tag.style :as style]
[quo.components.utilities.token.view :as token]
[quo.foundations.colors :as colors]
[quo.theme :as quo.theme]
[react-native.core :as rn]))
(defn- left-view
[{:keys [label type customization-color emoji image-source]}]
[{:keys [label type customization-color emoji image-source token]}]
(case type
:account
[account-avatar/view
@@ -38,9 +39,10 @@
:profile-picture image-source
:customization-color customization-color}]
:token
[rn/image
{:source image-source
:style style/token-image}]
[token/view
{:token token
:size :size-24
:style style/token-image}]
nil))
(defn- view-internal
@@ -50,7 +52,7 @@
should vary based on a custom color.
- :type - :token / :user / :collectible / :saved-address / :network / :account
- :emoji - string - emoji used for displaying account avatar
- :image-source - resource - image to display on :network, :collectible :user and :token
- :image-source - resource - image to display on :network, :collectible and :user
- :theme - :light / :dark"
[{:keys [label customization-color type theme]
:as props
@@ -62,6 +64,7 @@
[text/text
{:style (style/label type theme)
:weight :semi-bold
:size :heading-1} label]])
:size :heading-1}
label]])
(def view (quo.theme/with-theme view-internal))
+3 -7
View File
@@ -34,14 +34,10 @@
(defn token-img
[size]
(condp = size
:size-24 {:width 20
:height 20
:margin-right 6
(case size
:size-24 {:margin-right 6
:border-radius 10}
:size-32 {:width 28
:height 28
:margin-right 8
:size-32 {:margin-right 8
:border-radius 14}))
(defn label
+16 -12
View File
@@ -4,6 +4,7 @@
[quo.components.icon :as icons]
[quo.components.markdown.text :as text]
[quo.components.tags.token-tag.style :as style]
[quo.components.utilities.token.view :as token]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[react-native.hole-view :as hole-view]
@@ -14,13 +15,12 @@
- :options - false / :add / :hold (default false)
- :size - :size-24 / :size-32 (default :size-24)
- :blur? - boolean (default false)
- :theme - :light / :dark
- :token-img-src - token image source
- :theme - :light / :dark
- :token-value - string - token value
- :token-symbol - string"
[]
(let [container-width (reagent/atom 0)]
(fn [{:keys [options size blur? theme token-img-src token-value token-symbol]
(fn [{:keys [options size blur? theme token-value token-symbol]
:or {size :size-24}}]
[rn/view
{:on-layout #(reset! container-width
@@ -28,21 +28,25 @@
[hole-view/hole-view
{:holes (if options
[{:x (- @container-width
(condp = size
(case size
:size-24 10
:size-32 12))
:y (condp = size
:size-32 12
nil))
:y (case size
:size-24 -6
:size-32 -4)
:size-32 -4
nil)
:width 16
:height 16
:borderRadius 8}]
[])}
[rn/view
{:style (style/container size options blur? theme)}
[rn/image
{:style (style/token-img size)
:source token-img-src}]
[rn/view {:style (style/container size options blur? theme)}
[token/view
{:style (style/token-img size)
:token token-symbol
:size (case size
:size-24 :size-20
:size-32 :size-28)}]
[text/text
{:size :paragraph-2
:weight :medium
@@ -0,0 +1,68 @@
(ns quo.components.text-combinations.username.component-spec
(:require [quo.components.text-combinations.username.view :as username]
[test-helpers.component :as h]))
(defn test-all-status
[component-to-render component-props]
(h/test "Verified status"
(h/render [component-to-render (assoc component-props :status :verified)])
(h/is-truthy (h/get-by-label-text :username-status-icon)))
(h/test "Contact status"
(h/render [component-to-render (assoc component-props :status :contact)])
(h/is-truthy (h/get-by-label-text :username-status-icon)))
(h/test "Untrustworthy status"
(h/render [component-to-render (assoc component-props :status :untrustworthy)])
(h/is-truthy (h/get-by-label-text :username-status-icon)))
(h/test "Untrustworthy contact status"
(h/render [component-to-render (assoc component-props :status :untrustworthy-contact)])
(let [icons (h/get-all-by-label-text :username-status-icon)]
(h/is-truthy (aget icons 0))
(h/is-truthy (aget icons 1))))
(h/test "Blocked status"
(h/render [component-to-render (assoc component-props :status :blocked)])
(h/is-truthy (h/get-by-label-text :username-status-icon))))
(h/describe "Text combinations - Username"
(h/test "Renders default"
(h/render [username/view {:username "Test username"}])
(h/is-truthy (h/get-by-text "Test username")))
(h/describe "Render different :name-type values"
(h/describe "default"
(let [props {:name-type :default
:username "Test username"}]
(h/test "default render"
(h/render [username/view props])
(h/is-truthy (h/get-by-text "Test username")))
(h/describe "All status are rendered"
(test-all-status username/view props))))
(h/describe "ens"
(let [props {:name-type :ens
:username "test-username.eth"}]
(h/test "no status render"
(h/render [username/view props])
(h/is-truthy (h/get-by-text "test-username.eth")))
(h/describe "All status are rendered"
(test-all-status username/view props))))
(h/describe "nickname"
(let [props {:name-type :nickname
:username "Nickname"
:name "Real name"}]
(h/test "no status render"
(h/render [username/view props])
(h/is-truthy (h/get-by-text "Nickname"))
(h/is-truthy (h/get-by-text "Real name")))
(h/describe "All status are rendered"
(test-all-status username/view props))))))
@@ -0,0 +1,30 @@
(ns quo.components.text-combinations.username.style
(:require [quo.foundations.colors :as colors]))
(def container
{:flex-direction :row
:height 32})
(def username-text-container
{:flex-direction :row
:align-items :flex-end})
(defn real-name-text
[theme blur?]
{:color (if blur?
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
(colors/theme-colors colors/neutral-60 colors/neutral-40 theme))})
(defn real-name-dot
[theme blur?]
(assoc (real-name-text theme blur?) :margin-horizontal 6))
(defn status-icon-container
[name-type status]
(cond-> {:flex-direction :row
:margin-left 4}
(#{:default :ens} name-type) (assoc :margin-top 8
:margin-bottom 4)
(= :nickname name-type) (assoc :margin-top 10
:margin-bottom 2)
(= status :untrustworthy-contact) (assoc :margin-right 2)))
@@ -0,0 +1,57 @@
(ns quo.components.text-combinations.username.view
(:require [quo.components.icon :as icon]
[quo.components.markdown.text :as text]
[quo.components.text-combinations.username.style :as style]
[quo.foundations.colors :as colors]
[quo.theme]
[react-native.core :as rn]))
(defn- username-text
[{:keys [theme name-type username blur?]
real-name :name}]
[rn/view {:style style/username-text-container}
[text/text
{:size :heading-1
:weight :semi-bold}
username]
(when (= name-type :nickname)
[:<>
[text/text
{:style (style/real-name-dot theme blur?)
:size :paragraph-1
:weight :medium}
"∙"]
[text/text
{:style (style/real-name-text theme blur?)
:size :paragraph-1
:weight :medium}
real-name]])])
(defn- icon-20
[icon-name theme color]
[icon/icon icon-name
{:accessibility-label :username-status-icon
:size 20
:color (colors/resolve-color color theme)}])
(defn status-icon
[{:keys [theme name-type status]
:or {name-type :default}}]
[rn/view {:style (style/status-icon-container name-type status)}
(case status
:verified [icon-20 :i/verified theme :success]
:contact [icon-20 :i/contact theme :blue]
:untrustworthy [icon-20 :i/untrustworthy theme :danger]
:blocked [icon-20 :i/block theme :danger]
:untrustworthy-contact [:<>
[icon-20 :i/untrustworthy theme :danger]
[icon-20 :i/contact theme :blue]]
nil)])
(defn view-internal
[props]
[rn/view {:style style/container}
[username-text props]
[status-icon props]])
(def view (quo.theme/with-theme view-internal))
@@ -0,0 +1,34 @@
(ns quo.components.utilities.token.loader
(:require [clojure.java.io :as io]
[clojure.string :as string]))
(def ^:private token-path "./resources/images/tokens/mainnet/")
(defn- clean-filename
"Return a (string) filename without the .png extension and @<number>x suffix."
[file]
(first (string/split (str file) #"@|\.png")))
(defn- get-js-require
[filename]
(let [require-path (str "." filename ".png")]
`(js/require ~require-path)))
(defn- get-file-key
[filename]
(-> filename
(string/split #"\/")
(peek)
(string/lower-case)))
(defn get-tokens
[]
(let [files (file-seq (io/file token-path))
png-filenames (keep (fn [file]
(when (string/ends-with? file "png")
(clean-filename file)))
files)]
(zipmap (map get-file-key png-filenames)
(map get-js-require png-filenames))))
(defmacro resolve-tokens [] (get-tokens))
@@ -0,0 +1,14 @@
(ns quo.components.utilities.token.loader
(:require-macros [quo.components.utilities.token.loader :as loader])
(:require [clojure.string :as string]))
(def ^:private tokens (loader/resolve-tokens))
(defn- get-token-image*
[token]
(let [token-symbol (cond-> token
(keyword? token) name
:always string/lower-case)]
(get tokens token-symbol)))
(def get-token-image (memoize get-token-image*))
@@ -0,0 +1,58 @@
(ns quo.components.utilities.token.view
(:require [quo.components.utilities.token.loader :as token-loader]
[react-native.core :as rn]
[schema.core :as schema]
[utils.number]))
(def ?schema
[:=>
[:cat
[:map {:closed true}
[:size {:optional true :default 32} [:or keyword? pos-int?]]
[:token {:optional true} [:or keyword? string?]]
[:style {:optional true} map?]
;; Ignores `token` and uses this as parameter to `rn/image`'s source.
[:image-source {:optional true} [:or string? map?]]
;; If true, adds `data:image/png;base64,` as prefix to the string passed as `image-source`
[:add-b64-prefix? {:optional true} boolean?]]]
:any])
(defn- size->number
"Remove `size-` prefix in size keywords and returns a number useful for styling."
[size]
(-> size name (subs 5) utils.number/parse-int))
(defn- token-style
[style size]
(let [size-number (if (keyword? size)
(size->number size)
size)]
(assoc style
:width size-number
:height size-number)))
(def ^:private b64-png-image-prefix "data:image/png;base64,")
(defn view-internal
"Render a token image.
Props:
- style: extra styles to apply to the `rn/image` component.
- size: `:size-nn` or just `nn`, being `nn` any number. Defaults to 32.
- token: string or keyword, it can contain upper case letters or not.
E.g. all of these are valid and resolve to the same:
:token/snt | :snt | :SNT | \"SNT\" | \"snt\".
- image-source: Ignores `token` and uses this as parameter to `rn/image`'s source.
- add-b64-prefix?: If true, adds `data:image/png;base64,` as prefix to the string
passed as `image-source`.
"
[{:keys [token size style image-source add-b64-prefix?]
:or {size 32}}]
(let [b64-string (if (and image-source add-b64-prefix?)
(str b64-png-image-prefix image-source)
image-source)
source (or b64-string (token-loader/get-token-image token))]
[rn/image
{:style (token-style style size)
:source source}]))
(def view (schema/instrument #'view-internal ?schema))
@@ -93,7 +93,7 @@
:end {:x 1 :y 0}}])
(defn- user-account
[]
[_]
(let [pressed? (reagent/atom false)
on-press-in #(reset! pressed? true)
on-press-out #(reset! pressed? false)]
@@ -147,7 +147,7 @@
[gradient-overview theme customization-color])])))))
(defn- add-account-view
[]
[_]
(let [pressed? (reagent/atom false)]
(fn [{:keys [on-press customization-color theme metrics?]}]
[rn/pressable
@@ -2,17 +2,15 @@
(:require
[clojure.string :as string]
[quo.components.markdown.text :as text]
[quo.components.utilities.token.view :as token]
[quo.components.wallet.network-amount.style :as style]
[quo.foundations.resources :as resources]
[quo.theme :as quo.theme]
[react-native.core :as rn]))
(defn- view-internal
[{:keys [amount token theme]}]
[rn/view {:style style/container}
[rn/image
{:source (resources/get-token token)
:style {:width 12 :height 12}}]
[token/view {:token token :size :size-12}]
[text/text
{:weight :medium
:size :paragraph-2
@@ -16,10 +16,6 @@
:flex-direction :row
:justify-content :space-between})
(def token
{:width 32
:height 32})
(defn text-input
[theme]
(merge typography/heading-1
@@ -5,10 +5,10 @@
[quo.components.dividers.divider-line.view :as divider-line]
[quo.components.markdown.text :as text]
[quo.components.tags.network-tags.view :as network-tag]
[quo.components.utilities.token.view :as token]
[quo.components.wallet.token-input.style :as style]
[quo.foundations.colors :as colors]
[quo.foundations.common :as common]
[quo.foundations.resources :as resources]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[reagent.core :as reagent]))
@@ -41,9 +41,7 @@
:style {:flex-direction :row
:flex-grow 1
:align-items :flex-end}}
[rn/image
{:style style/token
:source (resources/get-token token)}]
[token/view {:token token :size :size-32}]
[rn/text-input
(cond-> {:auto-focus true
:ref #(reset! input-ref %)
@@ -19,10 +19,10 @@
(h/test "Context tag rendered"
(h/render [transaction-summary/view
{:transaction :send
:first-tag {:size 24
:type :token
:token-name "SNT"
:amount 1500}}])
:first-tag {:size 24
:type :token
:token "SNT"
:amount 1500}}])
(h/is-truthy (h/query-by-label-text :context-tag))))
+6
View File
@@ -141,7 +141,9 @@
quo.components.tags.token-tag.view
quo.components.text-combinations.channel-name.view
quo.components.text-combinations.standard-title.view
quo.components.text-combinations.username.view
quo.components.text-combinations.view
quo.components.utilities.token.view
quo.components.wallet.account-card.view
quo.components.wallet.account-origin.view
quo.components.wallet.account-overview.view
@@ -385,6 +387,10 @@
(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 username quo.components.text-combinations.username.view/view)
;;;; Utilities - Outside of design system
(def token quo.components.utilities.token.view/view)
;;;; Wallet
(def account-card quo.components.wallet.account-card.view/view)
+1
View File
@@ -77,6 +77,7 @@
[quo.components.tags.summary-tag.component-spec]
[quo.components.tags.tiny-tag.component-spec]
[quo.components.text-combinations.channel-name.component-spec]
[quo.components.text-combinations.username.component-spec]
[quo.components.wallet.account-card.component-spec]
[quo.components.wallet.account-origin.component-spec]
[quo.components.wallet.account-overview.component-spec]
+6 -5
View File
@@ -285,10 +285,6 @@
(get-in colors-map [color suffix]))))
(defn- resolve-color*
"(resolve-color color theme opacity)
color hex string or keyword (resolves from custom, network and semantic colors)
theme :light/:dark
opacity 0-100 (optional) - if set theme is ignored and goes to 50 suffix internally"
([color theme]
(resolve-color* color theme nil))
([color theme opacity]
@@ -300,7 +296,12 @@
suffix (get-from-colors-map suffix)
opacity (alpha (/ opacity 100))))))
(def resolve-color (memoize resolve-color*))
(def resolve-color
"(resolve-color color theme opacity)
color hex string or keyword (resolves from custom, network and semantic colors)
theme :light/:dark
opacity 0-100 (optional) - if set theme is ignored and goes to 50 suffix internally"
(memoize resolve-color*))
(def ^{:deprecated true :superseded-by "resolve-color"}
custom-color
-5
View File
@@ -3,8 +3,3 @@
(def currency-label
{:eur "€"
:usd "$"})
(def token-label
{:eth "Ethereum"
:snt "Status"
:dai "Dai"})
-191
View File
@@ -32,197 +32,6 @@
[k]
(get dapps k))
(def tokens
{:0-native (js/require "../resources/images/tokens/mainnet/0-native.png")
:0xbtc (js/require "../resources/images/tokens/mainnet/0XBTC.png")
:1st (js/require "../resources/images/tokens/mainnet/1ST.png")
:abt (js/require "../resources/images/tokens/mainnet/ABT.png")
:abyss (js/require "../resources/images/tokens/mainnet/ABYSS.png")
:ae (js/require "../resources/images/tokens/mainnet/AE.png")
:agld (js/require "../resources/images/tokens/mainnet/AGLD.png")
:akro (js/require "../resources/images/tokens/mainnet/AKRO.png")
:amb (js/require "../resources/images/tokens/mainnet/AMB.png")
:ampl (js/require "../resources/images/tokens/mainnet/AMPL.png")
:ant (js/require "../resources/images/tokens/mainnet/ANT.png")
:appc (js/require "../resources/images/tokens/mainnet/APPC.png")
:ast (js/require "../resources/images/tokens/mainnet/AST.png")
:atmchain (js/require "../resources/images/tokens/mainnet/ATMChain.png")
:ausdc (js/require "../resources/images/tokens/mainnet/aUSDC.png")
:bal (js/require "../resources/images/tokens/mainnet/BAL.png")
:bam (js/require "../resources/images/tokens/mainnet/BAM.png")
:band (js/require "../resources/images/tokens/mainnet/BAND.png")
:bat (js/require "../resources/images/tokens/mainnet/BAT.png")
:blt (js/require "../resources/images/tokens/mainnet/BLT.png")
:blz (js/require "../resources/images/tokens/mainnet/BLZ.png")
:bnb (js/require "../resources/images/tokens/mainnet/BNB.png")
:bnt (js/require "../resources/images/tokens/mainnet/BNT.png")
:brln (js/require "../resources/images/tokens/mainnet/BRLN.png")
:btm (js/require "../resources/images/tokens/mainnet/BTM.png")
:btu (js/require "../resources/images/tokens/mainnet/BTU.png")
:cdai (js/require "../resources/images/tokens/mainnet/cDAI.png")
:cdt (js/require "../resources/images/tokens/mainnet/CDT.png")
:centra (js/require "../resources/images/tokens/mainnet/Centra.png")
:cfi (js/require "../resources/images/tokens/mainnet/CFI.png")
:ck (js/require "../resources/images/tokens/mainnet/CK.png")
:cnd (js/require "../resources/images/tokens/mainnet/CND.png")
:cob (js/require "../resources/images/tokens/mainnet/COB.png")
:comp (js/require "../resources/images/tokens/mainnet/COMP.png")
:crv (js/require "../resources/images/tokens/mainnet/CRV.png")
:cvc (js/require "../resources/images/tokens/mainnet/CVC.png")
:dai (js/require "../resources/images/tokens/mainnet/DAI.png")
:dat (js/require "../resources/images/tokens/mainnet/DAT.png")
:data (js/require "../resources/images/tokens/mainnet/DATA.png")
:dcn (js/require "../resources/images/tokens/mainnet/DCN.png")
:dgd (js/require "../resources/images/tokens/mainnet/DGD.png")
:dgx (js/require "../resources/images/tokens/mainnet/DGX.png")
:dlt (js/require "../resources/images/tokens/mainnet/DLT.png")
:dnt (js/require "../resources/images/tokens/mainnet/DNT.png")
:dpy (js/require "../resources/images/tokens/mainnet/DPY.png")
:drt (js/require "../resources/images/tokens/mainnet/DRT.png")
:dta (js/require "../resources/images/tokens/mainnet/DTA.png")
:edg (js/require "../resources/images/tokens/mainnet/EDG.png")
:edo (js/require "../resources/images/tokens/mainnet/EDO.png")
:ekg (js/require "../resources/images/tokens/mainnet/EKG.png")
:eko (js/require "../resources/images/tokens/mainnet/EKO.png")
:elf (js/require "../resources/images/tokens/mainnet/ELF.png")
:emona (js/require "../resources/images/tokens/mainnet/EMONA.png")
:eng (js/require "../resources/images/tokens/mainnet/ENG.png")
:enj (js/require "../resources/images/tokens/mainnet/ENJ.png")
:ens (js/require "../resources/images/tokens/mainnet/ENS.png")
:eos (js/require "../resources/images/tokens/mainnet/EOS.png")
:equad (js/require "../resources/images/tokens/mainnet/EQUAD.png")
:eth (js/require "../resources/images/tokens/mainnet/ETH-token.png")
:eth2x-fli (js/require "../resources/images/tokens/mainnet/ETH2x-FLI.png")
:ethos (js/require "../resources/images/tokens/mainnet/ETHOS.png")
:evx (js/require "../resources/images/tokens/mainnet/EVX.png")
:fuel (js/require "../resources/images/tokens/mainnet/FUEL.png")
:fun (js/require "../resources/images/tokens/mainnet/FUN.png")
:fxc (js/require "../resources/images/tokens/mainnet/FXC.png")
:gdc (js/require "../resources/images/tokens/mainnet/GDC.png")
:gen (js/require "../resources/images/tokens/mainnet/GEN.png")
:glm (js/require "../resources/images/tokens/mainnet/GLM.png")
:gno (js/require "../resources/images/tokens/mainnet/GNO.png")
:gnt (js/require "../resources/images/tokens/mainnet/GNT.png")
:grid (js/require "../resources/images/tokens/mainnet/GRID.png")
:grt (js/require "../resources/images/tokens/mainnet/GRT.png")
:hez (js/require "../resources/images/tokens/mainnet/HEZ.png")
:hst (js/require "../resources/images/tokens/mainnet/HST.png")
:ht (js/require "../resources/images/tokens/mainnet/HT.png")
:icn (js/require "../resources/images/tokens/mainnet/ICN.png")
:icos (js/require "../resources/images/tokens/mainnet/ICOS.png")
:iost (js/require "../resources/images/tokens/mainnet/IOST.png")
:kdo (js/require "../resources/images/tokens/mainnet/KDO.png")
:kin (js/require "../resources/images/tokens/mainnet/KIN.png")
:knc (js/require "../resources/images/tokens/mainnet/KNC.png")
:kudos (js/require "../resources/images/tokens/mainnet/Kudos.png")
:lend (js/require "../resources/images/tokens/mainnet/LEND.png")
:link (js/require "../resources/images/tokens/mainnet/LINK.png")
:lisk (js/require "../resources/images/tokens/mainnet/LISK.png")
:loom (js/require "../resources/images/tokens/mainnet/LOOM.png")
:lpt (js/require "../resources/images/tokens/mainnet/LPT.png")
:lrc (js/require "../resources/images/tokens/mainnet/LRC.png")
:mana (js/require "../resources/images/tokens/mainnet/MANA.png")
:mco (js/require "../resources/images/tokens/mainnet/MCO.png")
:mda (js/require "../resources/images/tokens/mainnet/MDA.png")
:met (js/require "../resources/images/tokens/mainnet/MET.png")
:mfg (js/require "../resources/images/tokens/mainnet/MFG.png")
:mgo (js/require "../resources/images/tokens/mainnet/MGO.png")
:mkr (js/require "../resources/images/tokens/mainnet/MKR.png")
:mln (js/require "../resources/images/tokens/mainnet/MLN.png")
:moc (js/require "../resources/images/tokens/mainnet/MOC.png")
:mod (js/require "../resources/images/tokens/mainnet/MOD.png")
:mth (js/require "../resources/images/tokens/mainnet/MTH.png")
:mtl (js/require "../resources/images/tokens/mainnet/MTL.png")
:myb (js/require "../resources/images/tokens/mainnet/MYB.png")
:nexo (js/require "../resources/images/tokens/mainnet/NEXO.png")
:nexxo (js/require "../resources/images/tokens/mainnet/NEXXO.png")
:nmr (js/require "../resources/images/tokens/mainnet/NMR.png")
:npxs (js/require "../resources/images/tokens/mainnet/NPXS.png")
:ogn (js/require "../resources/images/tokens/mainnet/OGN.png")
:omg (js/require "../resources/images/tokens/mainnet/OMG.png")
:otn (js/require "../resources/images/tokens/mainnet/OTN.png")
:oxt (js/require "../resources/images/tokens/mainnet/OXT.png")
:pax (js/require "../resources/images/tokens/mainnet/PAX.png")
:paxg (js/require "../resources/images/tokens/mainnet/PAXG.png")
:pay (js/require "../resources/images/tokens/mainnet/PAY.png")
:pbtc (js/require "../resources/images/tokens/mainnet/PBTC.png")
:plr (js/require "../resources/images/tokens/mainnet/PLR.png")
:poe (js/require "../resources/images/tokens/mainnet/POE.png")
:poly (js/require "../resources/images/tokens/mainnet/POLY.png")
:powr (js/require "../resources/images/tokens/mainnet/POWR.png")
:ppp (js/require "../resources/images/tokens/mainnet/PPP.png")
:ppt (js/require "../resources/images/tokens/mainnet/PPT.png")
:pt (js/require "../resources/images/tokens/mainnet/PT.png")
:qkc (js/require "../resources/images/tokens/mainnet/QKC.png")
:qrl (js/require "../resources/images/tokens/mainnet/QRL.png")
:qsp (js/require "../resources/images/tokens/mainnet/QSP.png")
:r (js/require "../resources/images/tokens/mainnet/R.png")
:rae (js/require "../resources/images/tokens/mainnet/RAE.png")
:rare (js/require "../resources/images/tokens/mainnet/RARE.png")
:rcn (js/require "../resources/images/tokens/mainnet/RCN.png")
:rdn (js/require "../resources/images/tokens/mainnet/RDN.png")
:ren (js/require "../resources/images/tokens/mainnet/REN.png")
:rep (js/require "../resources/images/tokens/mainnet/REP.png")
:req (js/require "../resources/images/tokens/mainnet/REQ.png")
:rhoc (js/require "../resources/images/tokens/mainnet/RHOC.png")
:rlc (js/require "../resources/images/tokens/mainnet/RLC.png")
:rol (js/require "../resources/images/tokens/mainnet/ROL.png")
:sai (js/require "../resources/images/tokens/mainnet/SAI.png")
:salt (js/require "../resources/images/tokens/mainnet/SALT.png")
:san (js/require "../resources/images/tokens/mainnet/SAN.png")
:sngls (js/require "../resources/images/tokens/mainnet/SNGLS.png")
:snm (js/require "../resources/images/tokens/mainnet/SNM.png")
:snt (js/require "../resources/images/tokens/mainnet/SNT.png")
:snx (js/require "../resources/images/tokens/mainnet/SNX.png")
:socks (js/require "../resources/images/tokens/mainnet/SOCKS.png")
:spank (js/require "../resources/images/tokens/mainnet/SPANK.png")
:spike (js/require "../resources/images/tokens/mainnet/SPIKE.png")
:spn (js/require "../resources/images/tokens/mainnet/SPN.png")
:st (js/require "../resources/images/tokens/mainnet/ST.png")
:storj (js/require "../resources/images/tokens/mainnet/STORJ.png")
:storm (js/require "../resources/images/tokens/mainnet/STORM.png")
:strk (js/require "../resources/images/tokens/mainnet/STRK.png")
:stx (js/require "../resources/images/tokens/mainnet/STX.png")
:sub (js/require "../resources/images/tokens/mainnet/SUB.png")
:supr (js/require "../resources/images/tokens/mainnet/SUPR.png")
:susd (js/require "../resources/images/tokens/mainnet/sUSD.png")
:taas (js/require "../resources/images/tokens/mainnet/TAAS.png")
:taud (js/require "../resources/images/tokens/mainnet/TAUD.png")
:tcad (js/require "../resources/images/tokens/mainnet/TCAD.png")
:tgbp (js/require "../resources/images/tokens/mainnet/TGBP.png")
:tkn (js/require "../resources/images/tokens/mainnet/TKN.png")
:tkx (js/require "../resources/images/tokens/mainnet/TKX.png")
:tnt (js/require "../resources/images/tokens/mainnet/TNT.png")
:trst (js/require "../resources/images/tokens/mainnet/TRST.png")
:trx (js/require "../resources/images/tokens/mainnet/TRX.png")
:tusd (js/require "../resources/images/tokens/mainnet/TUSD.png")
:ubi (js/require "../resources/images/tokens/mainnet/UBI.png")
:ubt (js/require "../resources/images/tokens/mainnet/UBT.png")
:ukg (js/require "../resources/images/tokens/mainnet/UKG.png")
:uni (js/require "../resources/images/tokens/mainnet/UNI.png")
:upp (js/require "../resources/images/tokens/mainnet/UPP.png")
:usdc (js/require "../resources/images/tokens/mainnet/USDC.png")
:usds (js/require "../resources/images/tokens/mainnet/USDS.png")
:usdt (js/require "../resources/images/tokens/mainnet/USDT.png")
:veri (js/require "../resources/images/tokens/mainnet/VERI.png")
:vgx (js/require "../resources/images/tokens/mainnet/VGX.png")
:vib (js/require "../resources/images/tokens/mainnet/VIB.png")
:wabi (js/require "../resources/images/tokens/mainnet/WaBi.png")
:wbtc (js/require "../resources/images/tokens/mainnet/WBTC.png")
:weth (js/require "../resources/images/tokens/mainnet/WETH.png")
:wings (js/require "../resources/images/tokens/mainnet/WINGS.png")
:wtc (js/require "../resources/images/tokens/mainnet/WTC.png")
:xaur (js/require "../resources/images/tokens/mainnet/XAUR.png")
:xpa (js/require "../resources/images/tokens/mainnet/XPA.png")
:xrl (js/require "../resources/images/tokens/mainnet/XRL.png")
:xuc (js/require "../resources/images/tokens/mainnet/XUC.png")
:zrx (js/require "../resources/images/tokens/mainnet/ZRX.png")
:zsc (js/require "../resources/images/tokens/mainnet/ZSC.png")})
(defn get-token
[k]
(get tokens k))
(def ^:private networks
{:arbitrum (js/require "../resources/images/networks/Arbitrum.png")
:ethereum (js/require "../resources/images/networks/Ethereum.png")
+10
View File
@@ -0,0 +1,10 @@
(ns react-native.blob
(:require ["react-native-blob-util" :default ReactNativeBlobUtil]
[taoensso.timbre :as log]))
(defn fetch
[base64-uri config on-success]
(-> (.config ReactNativeBlobUtil (clj->js config))
(.fetch "GET" base64-uri)
(.then #(on-success (.path %)))
(.catch #(log/error "could not download uri" {:error %}))))
-64
View File
@@ -1,64 +0,0 @@
(ns status-im.chat.models.gaps
(:require
[status-im.mailserver.core :as mailserver]
[status-im2.contexts.chat.messages.list.events :as message-list]
[taoensso.timbre :as log]
[utils.re-frame :as rf]))
(rf/defn gaps-filled
{:events [:gaps/filled]}
[{:keys [db] :as cofx} chat-id message-ids]
(rf/merge
cofx
{:db (-> db
(update-in [:messages chat-id] (fn [messages] (apply dissoc messages message-ids)))
(dissoc :mailserver/fetching-gaps-in-progress))}
(message-list/rebuild-message-list chat-id)))
(rf/defn gaps-failed
{:events [:gaps/failed]}
[{:keys [db]} chat-id gap-ids error]
(log/error "failed to fetch gaps" chat-id gap-ids error)
{:db (dissoc db :mailserver/fetching-gaps-in-progress)})
(rf/defn sync-chat-from-sync-from-failed
{:events [::sync-chat-from-sync-from-failed]}
[{:keys [db]} chat-id error]
(log/error "failed to sync chat" chat-id error)
{:db (dissoc db :mailserver/fetching-gaps-in-progress)})
(rf/defn sync-chat-from-sync-from-success
{:events [::sync-chat-from-sync-from-success]}
[{:keys [db] :as cofx} chat-id synced-from]
(log/debug "synced success" chat-id synced-from)
{:db
(-> db
(assoc-in [:chats chat-id :synced-from] synced-from)
(dissoc :mailserver/fetching-gaps-in-progress))})
(rf/defn fill-gaps
[_ chat-id gap-ids]
{:json-rpc/call [{:method "wakuext_fillGaps"
:params [chat-id gap-ids]
:on-success #(rf/dispatch [:gaps/filled chat-id gap-ids %])
:on-error #(rf/dispatch [:gaps/failed chat-id gap-ids %])}]})
(rf/defn sync-chat-from-sync-from
[_ chat-id]
(log/debug "syncing chat from sync from")
{:json-rpc/call [{:method "wakuext_syncChatFromSyncedFrom"
:params [chat-id]
:on-success #(rf/dispatch [::sync-chat-from-sync-from-success chat-id %])
:on-error #(rf/dispatch [::sync-chat-from-sync-from-failed chat-id %])}]})
(rf/defn chat-ui-fill-gaps
{:events [:chat.ui/fill-gaps]}
[{:keys [db] :as cofx} chat-id gap-ids]
(let [use-status-nodes? (mailserver/fetch-use-mailservers? {:db db})]
(log/info "filling gaps if use-status-nodes = true" chat-id gap-ids)
(when use-status-nodes?
(rf/merge cofx
{:db (assoc db :mailserver/fetching-gaps-in-progress gap-ids)}
(if (= gap-ids #{:first-gap})
(sync-chat-from-sync-from chat-id)
(fill-gaps chat-id gap-ids))))))
-73
View File
@@ -1,73 +0,0 @@
(ns status-im.chat.models.images
(:require
["react-native-blob-util" :default ReactNativeBlobUtil]
[re-frame.core :as re-frame]
[react-native.cameraroll :as cameraroll]
[react-native.fs :as fs]
[react-native.platform :as platform]
[react-native.share :as share]
[status-im.ui.components.react :as react]
[status-im2.constants :as constants]
[taoensso.timbre :as log]
[utils.re-frame :as rf]))
(def temp-image-url (str (fs/cache-dir) "/StatusIm_Image.jpeg"))
(defn download-image-http
[base64-uri on-success]
(-> (.config ReactNativeBlobUtil
(clj->js {:trusty platform/ios?
:path temp-image-url}))
(.fetch "GET" base64-uri)
(.then #(on-success (.path %)))
(.catch #(log/error "could not download image" {:error %}))))
(defn share-image
[uri]
(download-image-http uri
(fn [downloaded-url]
(share/open {:url (str (when platform/android? "file://") downloaded-url)
:isNewTask true}
#(fs/unlink downloaded-url)
#(fs/unlink downloaded-url)))))
(defn save-image-to-gallery
[base64-uri on-success]
(-> (download-image-http base64-uri cameraroll/save-image)
(.then on-success)
(.catch #(log/error (str "could not save image to gallery" %)))))
(re-frame/reg-fx
::chat-open-image-picker-camera
(fn [current-chat-id]
(react/show-image-picker-camera
#(re-frame/dispatch [:chat.ui/image-captured current-chat-id (.-path %)])
{})))
(rf/defn image-captured
{:events [:chat.ui/image-captured]}
[{:keys [db]} chat-id uri]
(let [current-chat-id (or chat-id (:current-chat-id db))
images (get-in db [:chat/inputs current-chat-id :metadata :sending-image])]
(when (and (< (count images) constants/max-album-photos)
(not (get images uri)))
{::image-selected [uri current-chat-id]})))
(rf/defn clear-sending-images
{:events [:chat.ui/clear-sending-images]}
[{:keys [db]}]
{:db (update-in db [:chat/inputs (:current-chat-id db) :metadata] assoc :sending-image {})})
(rf/defn image-unselected
{:events [:chat.ui/image-unselected]}
[{:keys [db]} original]
(let [current-chat-id (:current-chat-id db)]
{:db (update-in db [:chat/inputs current-chat-id :metadata :sending-image] dissoc (:uri original))}))
(rf/defn chat-show-image-picker-camera
{:events [:chat.ui/show-image-picker-camera]}
[{:keys [db]} chat-id]
(let [current-chat-id (or chat-id (:current-chat-id db))
images (get-in db [:chat/inputs current-chat-id :metadata :sending-image])]
(when (< (count images) constants/max-album-photos)
{::chat-open-image-picker-camera current-chat-id})))
+10 -4
View File
@@ -5,7 +5,6 @@
[goog.object :as object]
[re-frame.core :as re-frame]
[status-im.chat.models.mentions :as mentions]
[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]
@@ -139,14 +138,21 @@
(let [current-chat-id (:current-chat-id db)]
{:db (assoc-in db [:chat/inputs current-chat-id :metadata :responding-to-message] nil)}))
(defn emoji-only-content?
"Determines if text is just an emoji"
[{:keys [text response-to]}]
(and (not response-to)
(string? text)
(re-matches constants/regx-emoji text)))
(defn build-text-message
[{:keys [db]} input-text current-chat-id]
(when-not (string/blank? input-text)
(let [{:keys [message-id]}
(get-in db [:chat/inputs current-chat-id :metadata :responding-to-message])
preferred-name (get-in db [:profile/profile :preferred-name])
emoji? (message-content/emoji-only-content? {:text input-text
:response-to message-id})]
emoji? (emoji-only-content? {:text input-text
:response-to message-id})]
{:chat-id current-chat-id
:content-type (if emoji?
constants/content-type-emoji
@@ -243,7 +249,7 @@
{:json-rpc/call [{:method "wakuext_editMessage"
:params [{:id message-id
:text text
:content-type (if (message-content/emoji-only-content?
:content-type (if (emoji-only-content?
{:text text
:response-to quoted-message})
constants/content-type-emoji
+3 -31
View File
@@ -9,7 +9,6 @@
[status-im2.contexts.chat.messages.delete-message.events :as delete-message]
[status-im2.contexts.chat.messages.list.events :as message-list]
[status-im2.contexts.chat.messages.list.state :as view.state]
[taoensso.timbre :as log]
[utils.re-frame :as rf]))
(defn- message-loaded?
@@ -116,30 +115,12 @@
(when (and (:current-chat-id db) (= "active" (:app-state db)))
[{:ms 100 :dispatch [:chat/mark-all-as-read (:current-chat-id db)]}]))}))
(rf/defn update-db-message-status
[{:keys [db] :as cofx} chat-id message-id status]
(when (get-in db [:messages chat-id message-id])
(rf/merge cofx
{:db (assoc-in db
[:messages chat-id message-id :outgoing-status]
status)})))
(rf/defn update-message-status
[{:keys [db] :as cofx} chat-id message-id status]
(rf/merge cofx
(update-db-message-status chat-id message-id status)))
(rf/defn resend-message
[{:keys [db] :as cofx} chat-id message-id]
(rf/merge cofx
{:json-rpc/call [{:method "wakuext_reSendChatMessage"
:params [message-id]
:on-success #(log/debug "re-sent message successfully")
:on-error #(log/error "failed to re-send message" %)}]}
(update-message-status chat-id message-id :sending)))
[{:keys [db]} chat-id message-id status]
(when (get-in db [:messages chat-id message-id])
{:db (assoc-in db [:messages chat-id message-id :outgoing-status] status)}))
(rf/defn handle-removed-messages
{:events [::handle-removed-messages]}
[{:keys [db] :as cofx} removed-messages]
(let [mark-as-deleted-fx (->> removed-messages
(map #(assoc %
@@ -166,14 +147,6 @@
(concat mark-as-seen-fx)
(conj remove-messages-fx)))))
(comment
(handle-removed-messages
{:db {:messages {:c1 {:m1 {:chat-id :c1 :message-id :m1}
:m2 {:chat-id :c1 :message-id :m2}}
:c2 {:m3 {:chat-id :c2 :message-id :m3}
:m4 {:chat-id :c2 :message-id :m4}}}}}
[:m1 :m3]))
(defn remove-cleared-message
[messages cleared-at]
(into {}
@@ -182,7 +155,6 @@
messages)))
(rf/defn handle-cleared-histories-messages
{:events [::handle-cleared-hisotories-messages]}
[{:keys [db]} cleared-histories]
{:db (reduce (fn [acc current]
(update-in acc
@@ -1,10 +0,0 @@
(ns status-im.chat.models.message-content
(:require
[status-im2.constants :as constants]))
(defn emoji-only-content?
"Determines if text is just an emoji"
[{:keys [text response-to]}]
(and (not response-to)
(string? text)
(re-matches constants/regx-emoji text)))
-2
View File
@@ -10,8 +10,6 @@
status-im.bootnodes.core
status-im.browser.core
status-im.browser.permissions
status-im.chat.models.gaps
status-im.chat.models.images
status-im.chat.models.input
status-im.chat.models.loading
status-im.contact.block
-2
View File
@@ -96,8 +96,6 @@
:contact (handle-view-profile cofx data)
:browser (handle-browse cofx data)
:eip681 (handle-eip681 cofx data)
;; Re-enable with https://github.com/status-im/status-mobile/issues/13429
;;:wallet-connect (handle-wallet-connect cofx data)
:localpairing (handle-local-pairing cofx data)
(do
(log/info "Unable to find matcher for scanned value"
-8
View File
@@ -121,14 +121,6 @@
(reg-root-key-sub :signing/tx :signing/tx)
(reg-root-key-sub :signing/edit-fee :signing/edit-fee)
;; wallet connect
(reg-root-key-sub :wallet-connect/proposal-metadata :wallet-connect/proposal-metadata)
(reg-root-key-sub :wallet-connect/enabled? :wallet-connect/enabled?)
(reg-root-key-sub :wallet-connect/session-connected :wallet-connect/session-connected)
(reg-root-key-sub :wallet-connect/showing-app-management-sheet?
:wallet-connect/showing-app-management-sheet?)
(reg-root-key-sub :wallet-connect/sessions :wallet-connect/sessions)
(reg-root-key-sub :wallet-connect/session-managed :wallet-connect/session-managed)
(reg-root-key-sub :contact-requests/pending :contact-requests/pending)
(reg-root-key-sub :bug-report/description-error :bug-report/description-error)
@@ -98,17 +98,6 @@
{:public-key chat-id
:photo-container (:default-chat-icon styles)}])])
(defn chat-icon-view-toolbar
[chat-id group-chat name color emoji size]
[emoji-chat-icon-view chat-id group-chat name emoji
{:container (styles/container-chat-toolbar size)
:size size
:chat-icon (styles/chat-icon-chat-toolbar size)
:default-chat-icon (styles/default-chat-icon-chat-toolbar color size)
:default-chat-icon-text (if (string/blank? emoji)
(styles/default-chat-icon-text size)
(styles/emoji-chat-icon-text size))}])
(defn chat-icon-view-chat-list
[chat-id group-chat name color]
[chat-icon-view chat-id group-chat name
@@ -118,19 +107,6 @@
:default-chat-icon (styles/default-chat-icon-chat-list color)
:default-chat-icon-text (styles/default-chat-icon-text 40)}])
(defn chat-icon-view-chat-list-redesign
[chat-id group-chat name color size]
[chat-icon-view chat-id group-chat name
{:container (if (= size 20)
(styles/token-icon-container-chat-list size)
(styles/community-icon-container-chat-list size))
:size size
:chat-icon (if (= size 20)
(styles/community-icon-chat-list-redesign size)
(styles/community-icon-chat-list size))
:default-chat-icon (styles/default-list-chat-icon-redesign color size)
:default-chat-icon-text (styles/default-chat-icon-text size)}])
(defn chat-icon-view-chat-sheet
[chat-id group-chat name color]
[chat-icon-view chat-id group-chat name
@@ -140,17 +116,6 @@
:default-chat-icon (styles/default-chat-icon-chat-list color)
:default-chat-icon-text (styles/default-chat-icon-text 40)}])
(defn emoji-chat-icon-view-chat-sheet
[chat-id group-chat name color emoji]
[emoji-chat-icon-view chat-id group-chat name emoji
{:container styles/container-chat-list
:size 40
:chat-icon styles/chat-icon-chat-list
:default-chat-icon (styles/default-chat-icon-chat-list color)
:default-chat-icon-text (if (string/blank? emoji)
(styles/default-chat-icon-text 40)
(styles/emoji-chat-icon-text 40))}])
(defn custom-icon-view-list
[name color & [size]]
[rn/view (styles/container-list-size (or size 40))
@@ -181,24 +146,6 @@
:default-chat-icon (styles/default-chat-icon-profile colors/default-chat-color size)
:default-chat-icon-text (styles/default-chat-icon-text size)}])
(defn chat-intro-icon-view
[icon-text chat-id group-chat styles]
(if group-chat
[default-chat-icon icon-text styles]
(let [photo-path @(re-frame.core/subscribe [:chats/photo-path chat-id])]
(when-not (string/blank? photo-path)
[photos/photo photo-path styles]))))
(defn emoji-chat-intro-icon-view
[icon-text chat-id group-chat emoji styles]
(if group-chat
(if (string/blank? emoji)
[default-chat-icon icon-text styles]
[emoji-chat-icon emoji styles])
(let [photo-path @(re-frame.core/subscribe [:chats/photo-path chat-id])]
(when-not (string/blank? photo-path)
[photos/photo photo-path styles]))))
(defn profile-icon-view
[photo-path name color emoji edit? size override-styles public-key community?]
(let [styles (merge {:container {:width size :height size}
-10
View File
@@ -6,19 +6,9 @@
[status-im.ui.components.core :as quo]
[status-im.ui.components.react :as react]
[status-im2.constants :as constants]
[utils.debounce :as debounce]
[utils.i18n :as i18n])
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
(defn decline-chat
[chat-id]
[quo/button
{:type :secondary
:accessibility-label :decline-chat-button
:on-press #(debounce/dispatch-and-chill [:group-chats.ui/leave-chat-confirmed chat-id]
2000)}
(i18n/label :t/group-chat-decline-invitation)])
(def message-max-length 100)
(defn request-membership
@@ -1,42 +0,0 @@
(ns status-im.ui.screens.chat.message.gap
(:require-macros [status-im.utils.views :as views])
(:require
[quo.core :as quo]
[re-frame.core :as re-frame]
[status-im.ui.components.react :as react]
[status-im.ui.screens.chat.styles.input.gap :as style]
[utils.datetime :as datetime]
[utils.i18n :as i18n]))
(views/defview gap
[{:keys [gap-ids chat-id gap-parameters public? community?]}]
(views/letsubs [in-progress? [:chats/fetching-gap-in-progress?
gap-ids
chat-id]
connected? [:mailserver/connected?]
use-status-nodes? [:mailserver/use-status-nodes?]
first-gap? (= gap-ids #{:first-gap})
window-height [:dimensions/window-height]]
(when (or (not first-gap?) public? community?)
[react/view {:style (when-not in-progress? style/gap-container)}
[react/touchable-highlight
{:on-press (when (and (not in-progress?) use-status-nodes? connected?)
(re-frame/dispatch [:chat.ui/fill-gaps chat-id gap-ids]))
:style {:height (if in-progress? window-height 48)}}
[react/view {:style style/label-container}
(if in-progress?
[quo/skeleton-list
{:parent-height window-height
:animated true
:content :messages}]
[react/nested-text
{:style (style/gap-text (and connected? use-status-nodes?))}
(i18n/label (if first-gap? :t/load-more-messages :t/fetch-messages))
(when first-gap?
[{:style style/date}
(let [date (datetime/timestamp->long-date
(* 1000 (:from gap-parameters)))]
(str
"\n"
(i18n/label :t/load-messages-before
{:date date})))])])]]])))
@@ -1,4 +1,4 @@
(ns status-im.ui.screens.chat.styles.message.message
(ns status-im.ui.screens.chat.message.legacy-style
(:require
[quo.foundations.colors :as quo.colors]
[quo.foundations.typography :as typography]
@@ -10,50 +10,6 @@
[]
{:color colors/text})
(defn system-message-body
[_]
{:margin-top 4
:margin-left 8
:margin-right 8
:align-self :center
:align-items :center})
(defn message-body
[]
(let [align :flex-start
direction :row]
{:flex-direction direction
:margin-top 4
:align-self align
:align-items align}))
(def message-timestamp
{:font-size 10})
(defn message-status-placeholder
[]
(merge message-timestamp {:opacity 0 :color "rgba(0,0,0,0)"}))
(defn message-timestamp-text
[]
(merge message-timestamp
{:color colors/gray
:text-align :center}))
(defn message-status-text
[]
{:font-size 10
:line-height 10
:border-color :red
:border-width 1
:color :red})
(defn audio-message-timestamp-text
[]
(merge message-timestamp
{:line-height 10
:color colors/gray}))
(defn message-wrapper
[{:keys [in-popover?]}]
(if (not in-popover?)
@@ -61,67 +17,6 @@
:padding-right 5}
{:margin-right 10}))
(defn message-author-wrapper
[]
{:flex-direction :column
:flex-shrink 1
:align-items :flex-start
:margin-left 4})
(defn pin-indicator
[]
(merge {:flex-direction :row}))
(defn pin-indicator-container
[]
{:margin-top 4
:margin-left 54
:top 4
:justify-content :center
:align-self :flex-start
:align-items :flex-start})
(defn pinned-by-text-icon-container
[]
{:flex-direction :row
:align-items :flex-start
:top 5
:left 8
:position :absolute})
(defn pin-icon-container
[]
{:flex-direction :row
:margin-top 1})
(defn pinned-by-text
[]
{:margin-left 5})
(def message-author-touchable
{:margin-left 0
:flex-direction :row})
(def delivery-text
{:color colors/gray
:margin-top 2
:font-size 12})
(def not-sent-view
{:flex-direction :row
:margin-bottom 2
:padding-top 2})
(def not-sent-text
(assoc delivery-text
:color colors/red
:text-align :right
:padding-top 4))
(def not-sent-icon
{:padding-top 3
:padding-left 3})
(defn emoji-message
[{:keys [incoming-group]}]
{:font-size 28
@@ -129,10 +24,6 @@
:margin-right 0 ;; Margin to display outgoing message status
:margin-top (if incoming-group 4 0)})
(def message-view-wrapper
{:align-self :flex-end
:flex-direction :row-reverse})
(defn message-view
[{:keys [content-type]}]
(merge
@@ -154,40 +45,6 @@
:font-size 14
:color colors/gray})
(defn message-author-name
[chosen?]
{:font-size (if chosen? 13 12)
:font-weight (if chosen? "500" "400")
:padding-top 6
:padding-left 12
:text-align-vertical :center})
(defn quoted-message-container
[]
{:margin-bottom 6
:margin-top 5
:padding-horizontal 15})
(def quoted-message-author-container
{:flex-direction :row
:align-items :center
:justify-content :flex-start})
(defn quoted-message-author
[chosen?]
(assoc (message-author-name chosen?)
:padding-bottom 6
:padding-top 0
:padding-left 0
:line-height 18
:font-weight "500"
:color colors/gray))
(defn quoted-message-text
[]
{:font-size 14
:color colors/gray})
(defn message-default-style
[]
{:font-family "Inter-Regular"
@@ -197,19 +54,11 @@
:letter-spacing -0.135})
;; Markdown styles
(defn default-text-style
[]
{:max-font-size-multiplier react/max-font-size-multiplier
:style (message-default-style)})
(defn outgoing-text-style
[]
(update (default-text-style)
:style
assoc
:color colors/white-persist))
(defn system-text-style
[]
(update (default-text-style)
@@ -284,21 +133,11 @@
:line-height 18.2
:letter-spacing (typography/tracking 13))))
(def code-block-background "#2E386B")
(defn inline-code-style
[]
{:color colors/white-persist
:background-color code-block-background})
(def codeblock-style
{:padding 10
:background-color code-block-background
:background-color "#2E386B"
:border-radius 4})
(def codeblock-text-style
{:color colors/white-persist})
(defn default-blockquote-style
[]
{:style {:border-left-width 2
@@ -330,24 +169,6 @@
(outgoing-blockquote-text-style)
(default-blockquote-text-style))
(defn image-message
[{:keys [width height]}]
{:overflow :hidden
:border-radius 8
:width width
:height height})
(defn image-message-border
[opts]
(merge (image-message opts)
{:opacity (:opacity opts)
:border-width 1
:top 0
:left 0
:position :absolute
:background-color :transparent
:border-color colors/black-transparent}))
(defn community-verified
[]
{:border-right-width 1
@@ -7,9 +7,7 @@
[status-im.react-native.resources :as resources]
[status-im.ui.components.colors :as quo.colors]
[status-im.ui.components.fast-image :as fast-image]
[status-im.ui.screens.chat.message.gap :as message.gap]
[status-im.ui.screens.chat.styles.message.message :as style]
[status-im.ui.screens.chat.utils :as chat.utils]
[status-im.ui.screens.chat.message.legacy-style :as style]
[status-im2.constants :as constants]
[status-im2.contexts.chat.messages.delete-message-for-me.events]
[status-im2.contexts.chat.messages.delete-message.events]
@@ -131,16 +129,11 @@
[:<>]
(:parsed-text content))))
(defview message-author-name
[from opts max-length]
(letsubs [contact-with-names [:contacts/contact-by-identity from]]
(chat.utils/format-author contact-with-names opts max-length)))
(defmulti ->message :content-type)
(defmethod ->message constants/content-type-gap
[message]
[message.gap/gap message])
[_]
[rn/view])
;; STATUS ? whats that ?
(defmethod ->message constants/content-type-status
+28 -5
View File
@@ -2,18 +2,41 @@
(:require
[status-im.ui.components.colors :as colors]
[status-im.ui.components.fast-image :as fast-image]
[status-im.ui.components.react :as react]
[status-im.ui.screens.chat.styles.photos :as style]))
[status-im.ui.components.react :as react]))
(defn radius [size] (/ size 2))
(defn photo-container
[size]
{:position :relative
:border-radius (radius size)})
(defn photo-border
([size] (photo-border size :absolute))
([size position]
{:position position
:width size
:height size
:border-color colors/black-transparent
:border-width 1
:border-radius (radius size)}))
(defn photo-style
[size]
{:border-radius (radius size)
:width size
:height size
:background-color colors/white})
(def memo-photo-rend
(memoize
(fn [photo-path size accessibility-label _]
[react/view {:style (style/photo-container size)}
[react/view {:style (photo-container size)}
[fast-image/fast-image
{:source photo-path
:style (style/photo size)
:style (photo-style size)
:accessibility-label (or accessibility-label :chat-icon)}]
[react/view {:style (style/photo-border size)}]])))
[react/view {:style (photo-border size)}]])))
;; "(colors/dark?)" is passed to memoized function to avoid previous themes cache
;; TODO: it's only used for old code, `quo/user-avatar` should be used instead for all the new one
-125
View File
@@ -1,125 +0,0 @@
(ns status-im.ui.screens.chat.sheets
(:require
[re-frame.core :as re-frame]
[status-im.ui.components.chat-icon.screen :as chat-icon]
[status-im.ui.components.list.item :as list.item]
[status-im.ui.components.react :as react]
[status-im2.constants :as constants]
[utils.i18n :as i18n]))
(defn hide-sheet-and-dispatch
[event]
(re-frame/dispatch [:bottom-sheet/hide-old])
(re-frame/dispatch event))
(defn one-to-one-chat-accents
[chat-id]
(let [{:keys [primary-name] :as contact} @(re-frame/subscribe [:contacts/contact-by-identity chat-id])]
[react/view
[list.item/list-item
{:theme :accent
:icon [chat-icon/contact-icon-contacts-tab contact]
:title primary-name
:subtitle (i18n/label :t/view-profile)
:accessibility-label :view-chat-details-button
:chevron true
:on-press #(do
(hide-sheet-and-dispatch [:chat.ui/show-profile chat-id])
(re-frame/dispatch [:pin-message/load-pin-messages chat-id]))}]
[list.item/list-item
{:theme :accent
:title (i18n/label :t/mark-all-read)
:accessibility-label :mark-all-read-button
:icon :main-icons/check
:on-press #(hide-sheet-and-dispatch [:chat.ui/mark-all-read-pressed chat-id])}]
[list.item/list-item
{:theme :negative
:title (i18n/label :t/delete-chat)
:accessibility-label :delete-chat-button
:icon :main-icons/delete
:on-press #(re-frame/dispatch [:chat.ui/show-remove-confirmation chat-id])}]]))
(defn community-chat-accents
[]
(fn [{:keys [chat-id group-chat chat-name color emoji]}]
[react/view
[list.item/list-item
{:theme :accent
:title chat-name
:icon [chat-icon/emoji-chat-icon-view-chat-sheet
chat-id group-chat chat-name color emoji]
:subtitle (i18n/label :t/view-details)
:chevron true
:accessibility-label :view-community-channel-details
:on-press #(do
(hide-sheet-and-dispatch [:navigate-to :community-channel-details
{:chat-id chat-id}])
(re-frame/dispatch [:pin-message/load-pin-messages chat-id]))}]
[list.item/list-item
{:theme :accent
:title (i18n/label :t/mark-all-read)
:accessibility-label :mark-all-read-button
:icon :main-icons/check
:on-press #(hide-sheet-and-dispatch [:chat.ui/mark-all-read-pressed chat-id])}]]))
(defn group-chat-accents
[]
(fn [{:keys [chat-id group-chat chat-name color invitation-admin]}]
(let [{:keys [member?]} @(re-frame/subscribe [:group-chat/inviter-info chat-id])
removed? @(re-frame/subscribe [:group-chat/removed-from-current-chat?])]
(if invitation-admin
[list.item/list-item
{:theme :accent
:title (i18n/label :t/remove)
:accessibility-label :remove-group-chat
:icon :main-icons/delete
:on-press #(hide-sheet-and-dispatch [:group-chats.ui/remove-chat-confirmed
chat-id])}]
[react/view
[list.item/list-item
{:theme :accent
:title chat-name
:subtitle (i18n/label :t/group-info)
:icon [chat-icon/chat-icon-view-chat-sheet
chat-id group-chat chat-name color]
:chevron true
:on-press #(do
(hide-sheet-and-dispatch [:show-group-chat-profile chat-id])
(re-frame/dispatch [:pin-message/load-pin-messages chat-id]))}]
[list.item/list-item
{:theme :accent
:title (i18n/label :t/mark-all-read)
:accessibility-label :mark-all-read-button
:icon :main-icons/check
:on-press #(hide-sheet-and-dispatch [:chat.ui/mark-all-read-pressed chat-id])}]
(when member?
[list.item/list-item
{:theme :negative
:title (i18n/label :t/leave-chat)
:accessibility-label :leave-chat-button
:icon :main-icons/arrow-left
:on-press #(re-frame/dispatch [:group-chats.ui/leave-chat-pressed chat-id])}])
(when removed?
[list.item/list-item
{:theme :accent
:title (i18n/label :t/remove)
:accessibility-label :remove-group-chat
:icon :main-icons/delete
:on-press #(hide-sheet-and-dispatch [:group-chats.ui/remove-chat-confirmed
chat-id])}])]))))
(defn actions
[{:keys [chat-type chat-id]
:as current-chat}]
(cond
(= chat-type constants/community-chat-type)
[community-chat-accents current-chat]
(= chat-type constants/private-group-chat-type)
[group-chat-accents current-chat]
:else [one-to-one-chat-accents chat-id]))
@@ -1,15 +0,0 @@
(ns status-im.ui.screens.chat.stickers.styles)
(def stickers-panel
{:flex 1 :margin 5 :flex-direction :row :justify-content :space-between :flex-wrap :wrap})
(defn pack-icon
[background-color icon-size icon-horizontal-margin]
{:background-color background-color
:margin-vertical 5
:margin-horizontal icon-horizontal-margin
:height icon-size
:width icon-size
:border-radius (/ icon-size 2)
:align-items :center
:justify-content :center})
@@ -1,169 +0,0 @@
(ns status-im.ui.screens.chat.stickers.views
(:require-macros [status-im.utils.views :refer [defview letsubs]])
(:require
[re-frame.core :as re-frame]
[reagent.core :as reagent]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.core :as quo]
[status-im.ui.components.fast-image :as fast-image]
[status-im.ui.components.icons.icons :as icons]
[status-im.ui.components.react :as react]
[status-im.ui.screens.chat.stickers.styles :as styles]
[utils.debounce :as debounce]
[utils.i18n :as i18n]))
(def icon-size 28)
(def icon-horizontal-margin 8)
(def indicator-width 16)
(def dx (- (+ icon-horizontal-margin (/ icon-size 2)) (/ indicator-width 2)))
(def icon-container (+ (* icon-horizontal-margin 2) icon-size))
(def scroll-x (reagent/atom 0))
(defn- no-stickers-yet-panel
[]
[react/view {:style {:flex 1 :align-items :center :justify-content :center}}
[icons/icon :stickers-icons/stickers-big
{:color colors/gray
:width 64
:height 64}]
[react/text {:style {:margin-vertical 8 :font-size 17}} (i18n/label :t/you-dont-have-stickers)]
[quo/button
{:type :secondary
:on-press #(re-frame/dispatch [:navigate-to :stickers])}
(i18n/label :t/get-stickers)]])
(defn- stickers-panel
[stickers window-width]
[react/view {:width window-width :flex 1}
[react/scroll-view
[react/view {:style styles/stickers-panel}
(for [{:keys [url] :as sticker} stickers]
^{:key (str url)}
[react/touchable-highlight
{:style {:height 75 :width 75 :margin 5}
:on-press #(debounce/dispatch-and-chill [:chat/send-sticker sticker] 1000)}
[fast-image/fast-image
{:style {:width "100%" :height "100%"}
:accessibility-label :sticker-icon
:source {:uri (str url "&download=true")}}]])]]])
(defview recent-stickers-panel
[window-width]
(letsubs [stickers [:stickers/recent-stickers]]
(if (seq stickers)
[stickers-panel stickers window-width]
[react/view
{:style {:flex 1
:align-items :center
:justify-content :center
:width window-width}}
[icons/icon :stickers-icons/sticker-history
{:width 64
:height 64
:color colors/gray}]
[react/text
{:style {:margin-top 12
:font-size 17}}
(i18n/label :t/recently-used-stickers)]])))
(defn update-scroll-position
[^js ref installed-packs selected-pack window-width animated?]
(when ref
;; bug on Android https://github.com/facebook/react-native/issues/24531
(js/setTimeout
(fn []
(let [x (if (= selected-pack :recent)
0
(* (inc (some #(when (= selected-pack (:id (second %))) (first %))
(map-indexed vector installed-packs)))
window-width))]
(.scrollTo ref #js {:x x :animated animated?})))
1)))
(defn on-scroll
[^js e installed-packs window-width]
(let [num (/ (.-nativeEvent.contentOffset.x e) window-width)
pack-id (if (zero? num)
:recent
(get-in (vec installed-packs) [(dec num) :id]))]
(when pack-id
(re-frame/dispatch [:stickers/select-pack pack-id]))))
(defview stickers-paging-panel
[installed-packs selected-pack]
(letsubs [ref (atom nil)
width [:dimensions/window-width]]
{:UNSAFE_componentWillUpdate
(fn [_ [_ installed-packs selected-pack]]
(update-scroll-position @ref installed-packs selected-pack width true))
:component-did-mount #(update-scroll-position @ref installed-packs selected-pack width false)}
[react/scroll-view
{:style {:flex 1}
:horizontal true
:paging-enabled true
:ref #(reset! ref %)
:shows-horizontal-scroll-indicator false
:on-momentum-scroll-end #(on-scroll % installed-packs width)
:scroll-event-throttle 8
:scroll-to-overflow-enabled true
:on-scroll #(reset! scroll-x (.-nativeEvent.contentOffset.x ^js %))}
^{:key "recent"}
[recent-stickers-panel width]
(for [{:keys [stickers id]} installed-packs]
^{:key (str "sticker" id)}
[stickers-panel (map #(assoc % :pack id) stickers) width])]))
(defn pack-icon
[{:keys [id on-press background-color]
:or {on-press #(re-frame/dispatch [:stickers/select-pack id])}}
icon]
[react/touchable-highlight {:on-press on-press}
[react/view {:style {:align-items :center}}
[react/view {:style (styles/pack-icon background-color icon-size icon-horizontal-margin)}
icon]]])
(defview scroll-indicator
[]
(letsubs [window-width [:dimensions/window-width]]
[react/view
{:style {:height 2
:width indicator-width
:border-radius 1
:margin-left (+ dx (* icon-container (/ @scroll-x window-width)))
:background-color colors/blue}}]))
(defview stickers-view
[]
(letsubs [selected-pack [:stickers/selected-pack]
installed-packs [:stickers/installed-packs]]
[react/view
{:style {:background-color colors/white
:flex 1}}
(cond
(= selected-pack :recent) [stickers-paging-panel installed-packs selected-pack]
(not (seq installed-packs)) [no-stickers-yet-panel]
:else [stickers-paging-panel installed-packs selected-pack])
[react/view {:style {:flex-direction :row :padding-horizontal 4}}
[pack-icon
{:on-press #(re-frame/dispatch [:navigate-to :stickers])
:selected? false
:background-color colors/blue}
[icons/icon :main-icons/add {:width 20 :height 20 :color colors/white-persist}]]
[react/view {:width 2}]
[react/scroll-view {:horizontal true :style {:padding-left 2}}
[react/view
[react/view {:style {:flex-direction :row}}
[pack-icon {:id :recent :background-color colors/white}
[icons/icon :stickers-icons/recent
{:color colors/gray
:width 44
:height 44}]]
(for [{:keys [id thumbnail]} installed-packs]
^{:key (str "pack-icon" id)}
[pack-icon
{:id id
:background-color colors/white}
[fast-image/fast-image
{:style {:width icon-size :height icon-size :border-radius (/ icon-size 2)}
:source {:uri (str thumbnail "&download=true")}}]])]
[scroll-indicator]]]]]))
@@ -1,35 +0,0 @@
(ns status-im.ui.screens.chat.styles.input.gap
(:require
[status-im.ui.components.colors :as colors]))
(defn gap-container
[]
{:align-self :stretch
:margin-top 24
:margin-bottom 24
:height 48
:align-items :center
:justify-content :center
:border-color colors/gray-lighter
:border-top-width 1
:border-bottom-width 1})
(def label-container
{:flex 1
:align-items :center
:justify-content :center
:text-align :center})
(defn gap-text
[connected?]
{:text-align :center
:color (if connected?
colors/blue
colors/gray)})
(def touchable
{:height 48})
(def date
{:typography :caption
:color colors/gray})
@@ -1,59 +0,0 @@
(ns status-im.ui.screens.chat.styles.main
(:require
[status-im.ui.components.colors :as colors]))
(def toolbar-container
{:flex 1
:align-items :center
:flex-direction :row})
(def chat-name-view
{:flex 1
:justify-content :center})
(def chat-name-text
{:typography :main-medium
:font-size 15
:line-height 22})
(def toolbar-subtitle
{:typography :caption
:line-height 16
:color colors/text-gray})
;; this map looks a bit strange
;; but this way of setting elevation seems to be the only way to set z-index (in RN 0.30)
(defn add-contact
[]
{:flex-direction :row
:align-items :center
:justify-content :center
:padding-vertical 6
:border-bottom-width 1
:border-color colors/gray-lighter})
(def add-contact-text
{:margin-left 4
:color colors/blue})
(def empty-chat-container
{:flex 1
:justify-content :center
:align-items :center
:padding-vertical 50
:margin-right 6})
(def loading-text
{:color colors/gray
:font-size 15
:line-height 22
:letter-spacing -0.2
:margin-right 4
:text-align :center})
(def contact-request
{:width "100%"
:justify-content :center
:align-items :center
:border-top-width 1
:border-color colors/gray-transparent-10})
@@ -1,9 +0,0 @@
(ns status-im.ui.screens.chat.styles.message.sheets
(:require
[status-im.ui.components.colors :as colors]))
(def sheet-text
{:color colors/gray
:padding 24
:line-height 22
:font-size 15})
@@ -1,29 +0,0 @@
(ns status-im.ui.screens.chat.styles.photos
(:require
[status-im.ui.components.colors :as colors]))
(def default-size 36)
(defn radius [size] (/ size 2))
(defn photo-container
[size]
{:position :relative
:border-radius (radius size)})
(defn photo-border
([size] (photo-border size :absolute))
([size position]
{:position position
:width size
:height size
:border-color colors/black-transparent
:border-width 1
:border-radius (radius size)}))
(defn photo
[size]
{:border-radius (radius size)
:width size
:height size
:background-color colors/white})
-29
View File
@@ -28,32 +28,3 @@
:line-height (if profile? 22 18)
:font-weight "400"}}
primary-name])))
(defn format-author
([contact] (format-author contact nil nil))
([contact {:keys [modal profile? you?]} max-length]
(let [{:keys [primary-name secondary-name]} contact]
(if secondary-name
[react/nested-text
{:number-of-lines 2
:style {:color (if modal colors/white-persist colors/black)
:font-size (if profile? 15 13)
:line-height (if profile? 22 18)
:letter-spacing -0.2
:font-weight "600"}}
(subs primary-name 0 81)
(when you?
[{:style {:color colors/black-light :font-weight "500" :font-size 13}}
(str " " (i18n/label :t/You))])
[{:style {:color colors/black-light :font-weight "500"}}
(str " " (subs secondary-name 0 81))]]
[react/text
{:style {:color (if modal colors/white-persist colors/black)
:font-size (if profile? 15 13)
:line-height (if profile? 22 18)
:font-weight "600"
:letter-spacing -0.2}
:number-of-lines 1}
(if (and max-length (> (count primary-name) max-length))
(str (subs primary-name 0 max-length) "...")
primary-name)]))))
@@ -11,7 +11,6 @@
[status-im.ui.components.react :as react]
[status-im.ui.components.topbar :as topbar]
[status-im.ui.screens.chat.photos :as photos]
[status-im.ui.screens.chat.sheets :as chat.sheets]
[status-im.ui.screens.chat.utils :as chat.utils]
[status-im.ui.screens.profile.components.styles :as profile.components.styles]
[status-im2.constants :as constants]
@@ -20,6 +19,11 @@
[utils.i18n :as i18n])
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
(defn hide-sheet-and-dispatch
[event]
(re-frame/dispatch [:bottom-sheet/hide-old])
(re-frame/dispatch event))
(defn member-sheet
[chat-id member us-admin?]
[react/view
@@ -30,7 +34,7 @@
:subtitle (i18n/label :t/view-profile)
:accessibility-label :view-chat-details-button
:chevron true
:on-press #(chat.sheets/hide-sheet-and-dispatch
:on-press #(hide-sheet-and-dispatch
[:chat.ui/show-profile
(:public-key member)])}]
(when (and us-admin? (not (:admin? member)))
@@ -39,15 +43,15 @@
:title (i18n/label :t/make-admin)
:accessibility-label :make-admin
:icon :main-icons/make-admin
:on-press #(chat.sheets/hide-sheet-and-dispatch [:group-chats.ui/make-admin-pressed
chat-id (:public-key member)])}])
:on-press #(hide-sheet-and-dispatch [:group-chats.ui/make-admin-pressed
chat-id (:public-key member)])}])
(when-not (:admin? member)
[list.item/list-item
{:theme :accent
:title (i18n/label :t/remove-from-chat)
:accessibility-label :remove-from-chat
:icon :main-icons/remove-contact
:on-press #(chat.sheets/hide-sheet-and-dispatch
:on-press #(hide-sheet-and-dispatch
[:group-chats.ui/remove-member-pressed chat-id
(:public-key member)])}])])
@@ -102,7 +106,7 @@
:on-press #(re-frame/dispatch [:open-modal :add-participants-toggle-list])}])
[chat-group-members-view chat-id admin? current-pk]])
(defn hide-sheet-and-dispatch
(defn hide-sheet-and-dispatch-old
[event]
(re-frame/dispatch [:bottom-sheet/hide-old])
(debounce/dispatch-and-chill event 2000))
@@ -125,14 +129,15 @@
:subtitle (when-not allow-adding-members? (i18n/label :t/members-limit-reached))
:accessibility-label :accept-invitation-button
:icon :main-icons/checkmark-circle
:on-press #(hide-sheet-and-dispatch
:on-press #(hide-sheet-and-dispatch-old
[:group-chats.ui/add-members-from-invitation id (:public-key contact)])}]
[list.item/list-item
{:theme :negative
:title (i18n/label :t/decline)
:accessibility-label :decline-invitation-button
:icon :main-icons/cancel
:on-press #(hide-sheet-and-dispatch [:send-group-chat-membership-rejection id])}]]))
:on-press #(hide-sheet-and-dispatch-old [:send-group-chat-membership-rejection
id])}]]))
(defn contacts-list-item
[{:keys [from] :as invitation}]
-7
View File
@@ -67,7 +67,6 @@
[status-im.ui.screens.wallet.buy-crypto.views :as wallet.buy-crypto]
[status-im.ui.screens.wallet.collectibles.views :as wallet.collectibles]
[status-im.ui.screens.wallet.custom-tokens.views :as custom-tokens]
[status-im.ui.screens.wallet.manage-connections.views :as manage-all-connections]
[status-im.ui.screens.wallet.recipient.views :as recipient]
[status-im.ui.screens.wallet.send.views :as wallet.send]
[status-im.ui.screens.wallet.settings.views :as wallet-settings]
@@ -647,12 +646,6 @@
:insets {:bottom? true}
:component keycard.pairing/change-pairing-code}
{:name :show-all-connections
:options {:topBar {:title {:text (i18n/label :t/all-connections)}}
:insets {:bottom? true
:top? true}}
:component manage-all-connections/views}
;; BUG REPORT
{:name :bug-report
:options {:insets {:top? true}}
@@ -28,13 +28,6 @@
:accessibility-label :wallet-manage-assets
:on-press #(hide-sheet-and-dispatch
[:navigate-to :wallet-settings-assets])}]
[list.item/list-item
{:theme :accent
:title (i18n/label :t/wallet-manage-app-connections)
:icon :main-icons/manage-connections
:accessibility-label :wallet-manage-app-connections
:on-press #(hide-sheet-and-dispatch
[:navigate-to :show-all-connections])}]
[list.item/list-item
{:theme :accent
:title (i18n/label :t/scan-tokens)
@@ -1,46 +0,0 @@
(ns status-im.ui.screens.wallet.manage-connections.styles
(:require
[status-im.ui.components.colors :as colors]))
(def dapp-icon
{:width 30
:height 30
:resize-mode :cover
:margin 10
:border-radius 15
:border-width 2
:padding 10})
(def app-row
{:flex-direction :row
:margin-vertical 8
:align-items :center})
(def app-column
{:flex-direction :column
:max-width 160
:justify-content :center})
(def dapp-name
{:font-size 15})
(def dapp-url
{:font-size 15
:opacity 0.5})
(def selected-account
{:font-size 13
:color colors/white})
(defn selected-account-container
[account-background-color]
{:background-color account-background-color
:padding-horizontal 10
:justify-content :center
:flex-direction :row
:align-items :center
:border-radius 40
:height 26})
(def delete-icon-container
{:margin-horizontal 10})
@@ -1,20 +0,0 @@
(ns status-im.ui.screens.wallet.manage-connections.views
(:require
[re-frame.core :as re-frame]
[react-native.core :as rn]
[status-im.ui.screens.wallet.manage-connections.styles :as styles]
[status-im2.common.not-implemented :as not-implemented]))
(defn print-session-info
[{:keys [peer]}]
^{:key peer}
[rn/view
[:<>
[not-implemented/not-implemented
[rn/view {:style styles/app-row}]]]])
(defn views
[]
(let [sessions @(re-frame/subscribe [:wallet-connect/sessions])]
[rn/view {:margin-top 10}
(doall (map print-session-info sessions))]))
@@ -1,155 +0,0 @@
(ns status-im.ui.screens.wallet-connect.session-proposal.styles
(:require
[status-im.ui.components.colors :as colors]))
(defn toolbar-container
[background-color]
{:height 36
:border-radius 18
:background-color background-color
:align-items :center
:flex-direction :row
:padding-left 13
:padding-right 6})
(def toolbar-text
{:flex-grow 1
:margin-right 3})
(defn dapp-logo
[]
{:width 120
:height 120
:resize-mode :cover
:margin-top 31
:border-radius 16
:border-width 2
:border-color (:interactive-02 @colors/theme)
:padding 5})
(def sheet-body-container
{:flex 1
:align-items :center})
(defn acc-sheet
[]
{:background-color (:ui-background @colors/theme)
:border-top-right-radius 16
:border-top-left-radius 16
:padding-bottom 1})
(defn proposal-sheet-container
[]
{:background-color (:ui-background @colors/theme)
:width "100%"
:align-items :center
:padding-top 0
:padding-bottom 50
:border-top-right-radius 16
:border-top-left-radius 16})
(defn proposal-sheet-header
[]
{:flex-direction :row
:align-items :center
:justify-content :center
:height 56
:width "100%"
:border-color colors/gray-lighter
:border-bottom-width 1})
(def proposal-title-container
{:align-items :center
:margin-top 21})
(def message-title
{:margin-top 10
:margin-bottom 14
:margin-horizontal 72.5
:text-align :center})
(defn proposal-buttons-container
[]
{:width "100%"
:height 76
:border-color colors/gray-lighter
:border-top-width 1
:flex 1
:flex-direction :row
:justify-content :space-between
:align-items :center
:padding-horizontal 16})
(defn success-button-container
[]
{:width "100%"
:height 76
:border-color colors/gray-lighter
:border-top-width 1
:flex-direction :row
:justify-content :flex-end
:align-items :center
:padding-horizontal 16})
(defn account-container
[color account-selected?]
{:height 34
:background-color color
:border-radius 17
:padding-horizontal 10
:justify-content :center
:margin-right 4
:opacity (if account-selected? 1 0.5)})
(def account-selector-container
{:height 80
:width "100%"
:justify-content :center
:padding-horizontal 16})
(def account-selector-wrapper
{:margin-top 40
:width "100%"})
(def account-selector-list
{:height 40
:width "100%"
:margin-top 10})
(def single-account-container
{:width "100%"
:align-items :center
:padding-top 8})
(defn blur-view
[]
{:position :absolute
:top 60
:left 0
:right 0
:bottom 0
:background-color (:blurred-bg @colors/theme)})
(def shadow
{:width "100%"
:height 50
:opacity 0.3})
(defn management-sheet-header
[]
{:width "100%"
:flex-direction :row
:padding 16
:align-items :center
:border-bottom-width 1
:border-bottom-color colors/gray-lighter})
(def management-icon
{:width 40
:height 40
:border-radius 20
:margin-right 16})
(def app-info-container
{:flex-direction :column
:flex 1})
@@ -1,246 +0,0 @@
(ns status-im.ui.screens.wallet-connect.session-proposal.views
(:require-macros [status-im.utils.views :refer [defview letsubs]])
(:require
[clojure.string :as string]
[re-frame.core :as re-frame]
[react-native.platform :as platform]
[reagent.core :as reagent]
[status-im.ui.components.bottom-panel.views :as bottom-panel]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.core :as quo]
[status-im.ui.components.icons.icons :as icons]
[status-im.ui.components.list.views :as list]
[status-im.ui.components.react :as react]
[status-im.ui.screens.wallet-connect.session-proposal.styles :as styles]
[status-im.utils.utils :as status.utils]
[utils.i18n :as i18n]
[utils.security.core]))
(def chevron-icon-container-width 24)
(def chevron-icon-container-height 24)
(defn toolbar-selection
[{:keys [text background-color on-press]}]
[react/touchable-opacity {:on-press on-press}
[react/view (styles/toolbar-container background-color)
[quo/text
{:color :inverse
:weight :medium
:style styles/toolbar-text}
text]
[icons/icon
:main-icons/chevron-down
{:color (:text-05 @colors/theme)
:width chevron-icon-container-width
:height chevron-icon-container-height}]]])
(def show-account-selector? (reagent/atom false))
(defn render-account
[{:keys [address name color] :as account} _ _ {:keys [selected-account on-select]}]
(let [account-selected? (= (:address @selected-account) address)]
[react/touchable-without-feedback
{:on-press #(do
(reset! selected-account (merge {} account))
(when on-select (on-select)))}
[react/view (styles/account-container color account-selected?)
[quo/text
{:color :inverse
:weight (if account-selected? :medium :regular)}
name]]]))
(defn account-selector
[accounts selected-account-atom on-select]
[react/view styles/account-selector-container
[quo/text {:size :small} (i18n/label :t/select-account)]
[list/flat-list
{:data accounts
:key-fn :address
:render-fn render-account
:render-data {:selected-account selected-account-atom
:on-select on-select}
:horizontal true
:shows-horizontal-scroll-indicator false
:extra-data @selected-account-atom
:style styles/account-selector-list}]])
(defn account-picker
[accounts selected-account-atom {:keys [on-press on-select]}]
(if (> (count accounts) 1)
[react/view {:style styles/account-selector-wrapper}
[account-selector accounts selected-account-atom on-select]]
[react/touchable-opacity {:style styles/single-account-container}
[toolbar-selection
{:text (:name @selected-account-atom)
:background-color (:color @selected-account-atom)
:on-press on-press}]]))
(defview success-sheet-view
[{:keys [topic]}]
(letsubs [visible-accounts [:visible-accounts-without-watch-only]
dapps-account [:dapps-account]
sessions [:wallet-connect/sessions]
managed-session [:wallet-connect/session-managed]]
(let [{:keys [peer state] :as session} (first (filter #(= (:topic %) topic) sessions))
{:keys [metadata]} peer
{:keys [accounts]} state
{:keys [name icons]} metadata
filtered-icons (status.utils/exclude-svg-resources icons)
icon-uri (when (and filtered-icons (pos? (count filtered-icons)))
(first filtered-icons))
address (last (string/split (first accounts) #":"))
account (first (filter #(= (:address %) address) visible-accounts))
selected-account-atom (reagent/atom account)]
[react/view (styles/proposal-sheet-container)
[react/view (styles/proposal-sheet-header)
[quo/text
{:weight :bold
:size :large}
(i18n/label :t/successful-connection)]]
[react/image
{:style (styles/dapp-logo)
:source {:uri icon-uri}}]
[react/view styles/sheet-body-container
[react/view styles/proposal-title-container
[quo/text
{:weight :bold
:size :large}
name]
[quo/text
{:weight :regular
:size :large}
(i18n/label :t/connected)]]]
[account-picker
(vector dapps-account)
selected-account-atom
{:on-press (fn []
(re-frame/dispatch [:wallet-connect/manage-app session])
(reset! show-account-selector? true))}]
[quo/text
{:weight :regular
:color :secondary
:style styles/message-title}
(i18n/label :t/manage-connections)]
[react/view (styles/success-button-container)
[quo/button
{:theme :accent
:on-press #(do
(reset! show-account-selector? false)
(re-frame/dispatch [:hide-wallet-connect-success-sheet]))}
(i18n/label :t/close)]]
(when managed-session
(if platform/ios?
[react/blur-view
{:style (styles/blur-view)
:blurAmount 2
:blurType (if (colors/dark?) :dark :light)}]
[react/view (styles/blur-view)]))])))
(defview app-management-sheet-view
[{:keys [topic]}]
(letsubs [sessions [:wallet-connect/sessions]
visible-accounts [:visible-accounts-without-watch-only]]
(let [{:keys [peer state]} (first (filter #(= (:topic %) topic) sessions))
{:keys [metadata]} peer
{:keys [accounts]} state
{:keys [name icons url]} metadata
filtered-icons (status-im.utils.utils/exclude-svg-resources icons)
icon-uri (when (and filtered-icons (pos? (count filtered-icons)))
(first filtered-icons))
address (last (string/split (first accounts) #":"))
account (first (filter #(= (:address %) address) visible-accounts))
selected-account-atom (reagent/atom account)]
[react/view {:style (merge (styles/acc-sheet) {:background-color "rgba(0,0,0,0)"})}
[react/linear-gradient
{:colors ["rgba(0,0,0,0)" "rgba(0,0,0,0.3)"]
:start {:x 0 :y 0}
:end {:x 0 :y 1}
:style styles/shadow}]
[react/view (styles/proposal-sheet-container)
[react/view (styles/management-sheet-header)
[react/image
{:style styles/management-icon
:source {:uri icon-uri}}]
[react/view styles/app-info-container
[quo/text {:weight :medium} name]
[quo/text
{:color :secondary
:number-of-lines 1
:elipsize-mode :tail} url]]
[quo/button
{:type :secondary
:theme :secondary
:on-press #(re-frame/dispatch [:wallet-connect/disconnect topic])}
(i18n/label :t/disconnect)]]
[account-selector
visible-accounts
selected-account-atom
#(re-frame/dispatch
[:wallet-connect/change-session-account topic @selected-account-atom])]]])))
(defview session-proposal-sheet
[{:keys [name icons]}]
(letsubs [visible-accounts [:visible-accounts-without-watch-only]
dapps-account [:dapps-account]]
(let [filtered-icons (status-im.utils.utils/exclude-svg-resources icons)
icon-uri (when (and filtered-icons (> (count filtered-icons) 0))
(first filtered-icons))
selected-account-atom (reagent/atom dapps-account)]
[react/view (styles/proposal-sheet-container)
[react/view (styles/proposal-sheet-header)
[quo/text
{:weight :bold
:size :large}
(i18n/label :t/connection-request)]]
[react/image
{:style (styles/dapp-logo)
:source {:uri icon-uri}}]
[react/view styles/sheet-body-container
[react/view styles/proposal-title-container
[quo/text
{:weight :bold
:size :large}
(str name " ")]
[quo/text
{:weight :regular
:size :large}
(i18n/label :t/wallet-connect-proposal-title)]]]
[account-picker visible-accounts selected-account-atom]
[react/view
(merge (styles/proposal-buttons-container)
(when (= (count visible-accounts) 1) {:margin-top 12}))
[quo/button
{:type :secondary
:on-press #(re-frame/dispatch [:wallet-connect/reject-proposal])}
(i18n/label :t/reject)]
[quo/button
{:theme :accent
:on-press #(re-frame/dispatch [:wallet-connect/approve-proposal @selected-account-atom])}
(i18n/label :t/connect)]]])))
(defview wallet-connect-proposal-sheet
[]
(letsubs [proposal-metadata [:wallet-connect/proposal-metadata]]
[bottom-panel/animated-bottom-panel
proposal-metadata
session-proposal-sheet
#(re-frame/dispatch [:hide-wallet-connect-sheet])]))
(defview wallet-connect-success-sheet-view
[]
(letsubs [session [:wallet-connect/session-connected]]
[bottom-panel/animated-bottom-panel
session
success-sheet-view
#(re-frame/dispatch [:hide-wallet-connect-success-sheet])]))
(defview wallet-connect-app-management-sheet-view
[]
(letsubs [session [:wallet-connect/session-managed]]
[bottom-panel/animated-bottom-panel
session
app-management-sheet-view
#(re-frame/dispatch [:hide-wallet-connect-app-management-sheet])
#(re-frame/dispatch [:hide-wallet-connect-app-management-sheet])
false]))
+7 -3
View File
@@ -129,9 +129,12 @@
[camera-permission-view]))
(defn- check-qr-code-and-navigate
[{:keys [event error-message validate-fn on-success-scan on-failed-scan]}]
[{:keys [event error-message validate-fn on-success-scan on-failed-scan scan-code?]}]
(let [scanned-value (string/trim (oops/oget event "nativeEvent.codeStringValue"))
validated? (if validate-fn (validate-fn scanned-value) true)]
;; Note - camera-kit keeps scanning until the screen is dismissed,
;; so disable scanning to make sure the on-read-code doesn't get executed multiple times
(reset! scan-code? false)
(if validated?
(on-success-scan scanned-value)
(do
@@ -155,8 +158,9 @@
:zoom-mode :off
:torch-mode torch-mode
:scan-barcode true
:on-read-code #(when scan-code?
:on-read-code #(when @scan-code?
(check-qr-code-and-navigate {:event %
:scan-code? scan-code?
:validate-fn validate-fn
:error-message error-message
:on-success-scan set-qr-code-succeeded
@@ -209,7 +213,7 @@
[render-camera
{:torch-mode torch-mode
:qr-view-finder @qr-view-finder
:scan-code? @scan-code?
:scan-code? scan-code?
:error-message error-message
:validate-fn validate-fn
:set-qr-code-succeeded (fn [value]
+4 -4
View File
@@ -57,10 +57,10 @@
"message.delivered" (let [{:keys [chatID messageID]} (js->clj event-js
:keywordize-keys
true)]
(models.message/update-db-message-status cofx
chatID
messageID
:delivered))
(models.message/update-message-status cofx
chatID
messageID
:delivered))
"mailserver.changed" (mailserver/handle-mailserver-changed cofx (.-id event-js))
"mailserver.available" (mailserver/handle-mailserver-available cofx (.-id event-js))
"mailserver.not.working" (mailserver/handle-mailserver-not-working cofx)
-12
View File
@@ -139,24 +139,12 @@
[id network])
default-networks)))
(def default-wallet-connect-metadata
{:name "Status Wallet"
:description
"Status is a secure messaging app, crypto wallet, and Web3 browser built with state of the art technology."
:url "#"
:icons ["https://statusnetwork.com/img/press-kit-status-logo.svg"]})
(def default-network-id
(get-in default-networks-by-id [default-network :config :NetworkId]))
(def default-network-rpc-url
(get-in default-networks-by-id [default-network :config :UpstreamConfig :URL]))
(def wallet-connect-project-id "87815d72a81d739d2a7ce15c2cfdefb3")
(def delete-message-undo-time-limit-ms 4000)
(def delete-message-for-me-undo-time-limit-ms 4000)
(def waku-nodes-config
{:status.prod
["enrtree://AL65EKLJAUXKKPG43HVTML5EFFWEZ7L4LOKTLZCLJASG4DSESQZEC@prod.status.nodes.status.im"]
+1
View File
@@ -11,6 +11,7 @@
[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.lightbox.events
[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]
@@ -0,0 +1,29 @@
(ns status-im2.contexts.chat.lightbox.effects
(:require [react-native.blob :as blob]
[react-native.cameraroll :as cameraroll]
[react-native.fs :as fs]
[react-native.platform :as platform]
[react-native.share :as share]
[utils.re-frame :as rf]))
(def config
{:trusty platform/ios?
:path (str (fs/cache-dir) "/StatusIm_Image.jpeg")})
(rf/reg-fx :effects.chat/share-image
(fn [uri]
(blob/fetch uri
config
(fn [downloaded-url]
(share/open {:url (str (when platform/android? "file://") downloaded-url)
:isNewTask true}
#(fs/unlink downloaded-url)
#(fs/unlink downloaded-url))))))
(rf/reg-fx :effects.chat/save-image-to-gallery
(fn [[uri on-success]]
(blob/fetch uri
config
(fn [downloaded-url]
(cameraroll/save-image downloaded-url)
(on-success)))))
@@ -0,0 +1,23 @@
(ns status-im2.contexts.chat.lightbox.events
(:require status-im2.contexts.chat.lightbox.effects
[utils.re-frame :as rf]))
(rf/reg-event-fx :chat.ui/clear-sending-images
(fn [{:keys [db]}]
{:db (update-in db [:chat/inputs (:current-chat-id db) :metadata] assoc :sending-image {})}))
(rf/reg-event-fx :chat.ui/image-unselected
(fn [{:keys [db]} [original]]
(let [current-chat-id (:current-chat-id db)]
{:db (update-in db
[:chat/inputs current-chat-id :metadata :sending-image]
dissoc
(:uri original))})))
(rf/reg-event-fx :chat.ui/share-image
(fn [_ [uri]]
{:effects.chat/share-image uri}))
(rf/reg-event-fx :chat.ui/save-image-to-gallery
(fn [_ [uri on-success]]
{:effects.chat/save-image-to-gallery [uri on-success]}))
@@ -6,7 +6,6 @@
[react-native.orientation :as orientation]
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]
[status-im.chat.models.images :as images]
[status-im2.contexts.chat.lightbox.animations :as anim]
[status-im2.contexts.chat.lightbox.constants :as c]
[status-im2.contexts.chat.lightbox.style :as style]
@@ -52,20 +51,21 @@
:label (i18n/label :t/save-image-library)
:on-press (fn []
(rf/dispatch [:hide-bottom-sheet])
(images/save-image-to-gallery
uri
#(rf/dispatch [:toasts/upsert
{:id :random-id
:icon :i/correct
:icon-color colors/success-50
:container-style {:bottom (when platform/android? 20)}
:text (i18n/label :t/photo-saved)}])))}]]]))
(rf/dispatch
[:chat.ui/save-image-to-gallery
uri
#(rf/dispatch [:toasts/upsert
{:id :random-id
:icon :i/correct
:icon-color colors/success-50
:container-style {:bottom (when platform/android? 20)}
:text (i18n/label :t/photo-saved)}])]))}]]]))
(defn share-image
[messages index]
(let [{:keys [content]} (nth messages index)
uri (url/replace-port (:image content) (rf/sub [:mediaserver/port]))]
(images/share-image uri)))
(rf/dispatch [:chat.ui/share-image uri])))
(defn top-view
[messages insets index animations derived landscape? screen-width]
@@ -200,6 +200,9 @@
constants/content-type-album
[album/album-message message-data context on-long-press message-container-data]
constants/content-type-gap
[rn/view]
[not-implemented/not-implemented
[content.unknown/unknown-content message-data]])
@@ -11,7 +11,6 @@
[react-native.react-native-intersection-observer :as rnio]
[react-native.reanimated :as reanimated]
[status-im.ui.screens.chat.group :as chat.group]
[status-im.ui.screens.chat.message.gap :as message.gap]
[status-im2.constants :as constants]
[status-im2.contexts.chat.composer.constants :as composer.constants]
[status-im2.contexts.chat.messages.content.view :as message]
@@ -274,9 +273,6 @@
(= type :datemark)
[quo/divider-date value]
(= content-type constants/content-type-gap)
[message.gap/gap message-data]
:else
[message/message message-data context keyboard-shown?])]))
@@ -1,7 +1,6 @@
(ns status-im2.contexts.quo-preview.community.token-gating
(:require
[quo.core :as quo]
[quo.foundations.resources :as resources]
[reagent.core :as reagent]
[status-im2.contexts.quo-preview.preview :as preview]))
@@ -22,29 +21,24 @@
[sufficient? many-tokens? loading?]
(into
[{:symbol "KNC"
:img-src (resources/get-token :knc)
:amount 200
:sufficient? true
:loading? loading?}
{:symbol "MANA"
:img-src (resources/get-token :mana)
:amount 10
:sufficient? sufficient?
:purchasable? true
:loading? loading?}
{:symbol "RARE"
:img-src (resources/get-token :rare)
:amount 10
:sufficient? sufficient?
:loading? loading?}]
(when many-tokens?
[{:symbol "FXC"
:img-src (resources/get-token :fxc)
:amount 20
:sufficient? true
:loading? loading?}
{:symbol "SNT"
:img-src (resources/get-token :snt)
:amount 10000
:sufficient? sufficient?
:loading? loading?}])))
@@ -58,11 +52,9 @@
many-tokens?
loading?)
[{:symbol "FXC"
:img-src (resources/get-token :fxc)
:amount 20
:sufficient? true}
{:symbol "USDT"
:img-src (resources/get-token :usdt)
:amount 20
:sufficient? false}]]
[(join-gate-options-base sufficient?
@@ -2,7 +2,6 @@
(:require
[quo.core :as quo]
[quo.foundations.colors :as colors]
[quo.foundations.resources :as quo.resources]
[react-native.core :as rn]
[status-im2.common.resources :as resources]))
@@ -42,10 +41,9 @@
[:<>
[quo/text {:style {:margin-right 4}} "Hold"]
[quo/token-tag
{:size :size-24
:token-img-src (quo.resources/get-token :eth)
:token-value 5
:token-symbol "ETH"}]
{:size :size-24
:token-value 5
:token-symbol "ETH"}]
[quo/text {:style {:margin-left 4}} "To post"]])
(defn example-3
@@ -66,12 +66,7 @@
:emoji "🍓"
:type :default}])
(def tokens-list
[{:source (quo.resources/get-token :snt)}
{:source (quo.resources/get-token :eth)}
{:source (quo.resources/get-token :knc)}
{:source (quo.resources/get-token :mana)}
{:source (quo.resources/get-token :rare)}])
(def tokens-list [:snt :eth :knc :mana :rare])
(def communities-list
[{:source (resources/get-mock-image :coinbase)}
@@ -20,12 +20,9 @@
{:key :selected}]}
{:key :token
:type :select
:options [{:value :eth
:key (quo.resources/get-token :eth)}
{:value :snt
:key (quo.resources/get-token :snt)}
{:value :dai
:key (quo.resources/get-token :dai)}]}
:options [{:key :eth}
{:key :snt}
{:key :dai}]}
{:key :label
:type :text}
{:key :token-value
@@ -38,7 +35,7 @@
(defn view
[]
(let [state (reagent/atom {:token (quo.resources/get-token :snt)
(let [state (reagent/atom {:token :snt
:label "Status"
:token-value "0.00 SNT"
:fiat-value "€0.00"
@@ -5,11 +5,7 @@
[status-im2.contexts.quo-preview.preview :as preview]))
(def descriptor
[{:key :token
:type :select
:options [{:key :eth}
{:key :snt}]}
{:key :status
[{:key :status
:type :select
:options [{:key :empty}
{:key :positive}
@@ -19,7 +15,8 @@
(defn view
[]
(let [state (reagent/atom {:token :snt
(let [state (reagent/atom {:token {:symbol "SNT"
:name "Status Network Token"}
:state :default
:status :empty
:customization-color :blue
@@ -166,6 +166,7 @@
[status-im2.contexts.quo-preview.text-combinations.preview :as
text-combinations]
[status-im2.contexts.quo-preview.text-combinations.standard-title :as standard-title]
[status-im2.contexts.quo-preview.text-combinations.username :as username]
[status-im2.contexts.quo-preview.wallet.account-card :as account-card]
[status-im2.contexts.quo-preview.wallet.account-origin :as account-origin]
[status-im2.contexts.quo-preview.wallet.account-overview :as
@@ -461,7 +462,9 @@
{:name :channel-name
:component channel-name/view}
{:name :standard-title
:component standard-title/view}]
:component standard-title/view}
{:name :username
:component username/view}]
:wallet [{:name :account-card :component account-card/view}
{:name :account-origin :component account-origin/view}
{:name :account-overview
@@ -21,7 +21,10 @@
[{:key :blur? :type :boolean}
{:key :list-type
:type :select
:options [{:key :settings :value :settings} {:key :reorder :value :reorder}]}])
:options [{:key :settings
:value :settings}
{:key :reorder
:value :reorder}]}])
(defn view
[]
@@ -2,7 +2,6 @@
(:require
[quo.components.settings.reorder-item.types :as types]
[quo.core :as quo]
[quo.foundations.resources :as quo.resources]
[status-im2.common.resources :as resources]
[status-im2.contexts.quo-preview.preview :as preview]))
@@ -22,10 +21,10 @@
:title "Status"}}
{:id 3
:type types/item
:data {:image (quo.resources/get-token :eth)
:data {:image (resources/get-mock-image :status-logo)
:image-size 21
:right-icon :i/world
:title "Ethereum"}}
:title "Status"}}
{:id 4
:type types/item
:data {:image (resources/get-mock-image :monkey)
@@ -97,8 +97,11 @@
[size-descriptor
{:key :amount
:type :text}
{:key :token-name
:type :text}])
{:key :token
:type :select
:options [{:key "ETH"}
{:key "SNT"}
{:key "DAI"}]}])
(def network-descriptor
[size-descriptor
@@ -202,8 +205,7 @@
:community-logo (resources/mock-images :coinbase)
:community-name "Community"
:channel-name "my channel"
:token-logo (resources/mock-images :diamond)
:token-name "ETH"
:token "ETH"
:amount "10"
:network-logo (resources/mock-images :monkey)
:network-name "Network"
@@ -13,7 +13,7 @@
:token
{:customization-color "#9999991A"
:label "150 ETH"
:image-source (quo.resources/get-token :eth)}
:token :eth}
:address
{:label "0x39c...Bd2"}
:user
@@ -1,7 +1,6 @@
(ns status-im2.contexts.quo-preview.tags.token-tag
(:require
[quo.core :as quo]
[quo.foundations.resources :as resources]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im2.contexts.quo-preview.preview :as preview]))
@@ -42,9 +41,6 @@
{:key "SNT"
:value "SNT"}]}])
(def eth-token (resources/get-token :eth))
(def snt-token (resources/get-token :snt))
(defn view
[]
(let [state (reagent/atom {:size :size-24
@@ -59,7 +55,4 @@
:show-blur-background? true
:descriptor descriptor}
[rn/view {:style {:align-items :center}}
[quo/token-tag
(assoc @state
:token-img-src
(if (= (get-in @state [:token-symbol]) "ETH") eth-token snt-token))]]])))
[quo/token-tag @state]]])))
@@ -0,0 +1,52 @@
(ns status-im2.contexts.quo-preview.text-combinations.username
(:require [quo.core :as quo]
[reagent.core :as reagent]
[status-im2.contexts.quo-preview.preview :as preview]))
(def descriptor
[{:key :name-type
:type :select
:options [{:key :default}
{:key :ens
:value "ENS"}
{:key :nickname}]}
{:key :username
:type :text}
{:key :name
:type :text}
{:key :status
:type :select
:options [{:key nil
:value "(Nothing)"}
{:key :verified}
{:key :contact}
{:key :untrustworthy}
{:key :untrustworthy-contact}
{:key :blocked}]}
{:key :blur?
:type :boolean}])
(defn- set-username-based-on-name-type
[_ ratom {previous-type :name-type} {new-type :name-type}]
(when (not= previous-type new-type)
(swap! ratom assoc
:username
(if (= new-type :ens)
"juan.eth"
"Juanito Mdz"))))
(defn view
[]
(let [state (reagent/atom {:name-type :default
:username "Juanito Mdz"
:name "Juan Méndez"
:status nil
:blur? true})
_ (add-watch state :on-state-change set-username-based-on-name-type)]
(fn []
[preview/preview-container
{:state state
:descriptor descriptor
:show-blur-background? true
:blur? (:blur? @state)}
[quo/username @state]])))
@@ -7,25 +7,22 @@
[status-im2.contexts.quo-preview.preview :as preview]))
(def asset-snt
{:size 24
:type :token
:token-name "SNT"
:amount 1500
:token-logo (quo.resources/get-token :snt)})
{:size 24
:type :token
:token "SNT"
:amount 1500})
(def asset-eth
{:size 24
:type :token
:token-name "ETH"
:amount 75
:token-logo (quo.resources/get-token :eth)})
{:size 24
:type :token
:token "ETH"
:amount 75})
(def asset-dai
{:size 24
:type :token
:token-name "DAI"
:amount 2400
:token-logo (quo.resources/get-token :dai)})
{:size 24
:type :token
:token "DAI"
:amount 2400})
(def asset-collectible
{:size 24
@@ -157,7 +154,6 @@
:value "At"}])
(def descriptor
(concat
[{:key :transaction
:type :select
@@ -8,18 +8,16 @@
[status-im2.contexts.quo-preview.preview :as preview]))
(def asset-snt
{:size 24
:type :token
:token-name "SNT"
:amount 1500
:token-logo (quo.resources/get-token :snt)})
{:size 24
:type :token
:token "SNT"
:amount 1500})
(def asset-dai
{:size 24
:type :token
:token-name "DAI"
:amount 2400
:token-logo (quo.resources/get-token :dai)})
{:size 24
:type :token
:token "DAI"
:amount 2400})
(def asset-collectible
{:size 24
@@ -16,6 +16,7 @@
(case selected-tab
:assets [rn/flat-list
{:render-fn token-value/view
:style {:flex 1}
:data tokens
:content-container-style {:padding-horizontal 8}}]
:collectibles [collectibles/view]
@@ -1,6 +1,5 @@
(ns status-im2.contexts.wallet.common.temp
(:require
[quo.foundations.resources :as quo.resources]
[react-native.core :as rn]
[status-im2.common.resources :as status.resources]
[utils.i18n :as i18n]))
@@ -86,21 +85,21 @@
(defn bridge-token-list
[networks-list]
[{:token (quo.resources/get-token :snt)
[{:token :snt
:label "Status"
:token-value "0.00 SNT"
:fiat-value "€0.00"
:networks networks-list
:state :default
:customization-color :blue}
{:token (quo.resources/get-token :eth)
{:token :eth
:label "Ethereum"
:token-value "0.00 ETH"
:fiat-value "€0.00"
:networks networks-list
:state :default
:customization-color :blue}
{:token (quo.resources/get-token :dai)
{:token :dai
:label "Dai"
:token-value "0.00 DAI"
:fiat-value "€0.00"
@@ -10,11 +10,17 @@
(defn prettify-balance
[balance]
(str "$" (.toFixed (if (number? balance) balance 0) 2)))
(let [valid-balance? (and balance
(or (number? balance) (.-toFixed balance)))]
(as-> balance $
(if valid-balance? $ 0)
(.toFixed $ 2)
(str "$" $))))
(defn get-derivation-path
[number-of-accounts]
(str constants/path-wallet-root "/" number-of-accounts))
(defn format-derivation-path
[path]
(string/replace path "/" " / "))
@@ -24,32 +30,42 @@
(let [path (get-derivation-path number-of-accounts)]
(format-derivation-path path)))
(defn- total-raw-balance-in-all-chains
[balances-per-chain]
(->> balances-per-chain
(map (comp :raw-balance val))
(reduce money/add)))
(defn total-token-units-in-all-chains
[{:keys [balances-per-chain decimals] :as _token}]
(-> balances-per-chain
(total-raw-balance-in-all-chains)
(money/token->unit decimals)))
(defn calculate-raw-balance
[raw-balance decimals]
(if-let [n (utils.number/parse-int raw-balance nil)]
(/ n (Math/pow 10 (utils.number/parse-int decimals)))
0))
(defn total-token-value-in-all-chains
[{:keys [balances-per-chain decimals]}]
(->> balances-per-chain
(vals)
(map #(calculate-raw-balance (:raw-balance %) decimals))
(reduce +)))
(defn token-value-in-chain
[{:keys [balances-per-chain decimals]} chain-id]
(let [balance-in-chain (get balances-per-chain chain-id)]
(when balance-in-chain
(calculate-raw-balance (:raw-balance balance-in-chain) decimals))))
(defn calculate-balance
[tokens-in-account]
(->> tokens-in-account
(map (fn [token]
(* (total-token-value-in-all-chains token)
(-> token :market-values-per-currency :usd :price))))
(reduce +)))
(defn total-token-fiat-value
"Returns the total token fiat value taking into account all token's chains."
[{:keys [market-values-per-currency] :as token}]
(let [usd-price (-> market-values-per-currency :usd :price)
total-units-in-all-chains (total-token-units-in-all-chains token)]
(money/crypto->fiat total-units-in-all-chains usd-price)))
(defn calculate-balance-for-account
[{:keys [tokens] :as _account}]
(->> tokens
(map total-token-fiat-value)
(reduce money/add)))
(defn network-list
[{:keys [balances-per-chain]} networks]
+6 -3
View File
@@ -12,6 +12,7 @@
[utils.ethereum.chain :as chain]
[utils.ethereum.eip.eip55 :as eip55]
[utils.i18n :as i18n]
[utils.money :as money]
[utils.number]
[utils.re-frame :as rf]
[utils.transforms :as types]))
@@ -108,9 +109,11 @@
:event :wallet/get-wallet-token
:params addresses})}]]]})))
(defn- fix-chain-id-keys
(defn- fix-balances-per-chain
[token]
(update token :balances-per-chain update-keys (comp utils.number/parse-int name)))
(-> token
(update :balances-per-chain update-vals #(update % :raw-balance money/bignumber))
(update :balances-per-chain update-keys (comp utils.number/parse-int name))))
(rf/reg-event-fx
:wallet/store-wallet-token
@@ -118,7 +121,7 @@
(let [tokens (-> raw-tokens-data
(update-keys name)
(update-vals #(cske/transform-keys csk/->kebab-case %))
(update-vals #(mapv fix-chain-id-keys %)))
(update-vals #(mapv fix-balances-per-chain %)))
add-tokens (fn [stored-accounts tokens-per-account]
(reduce-kv (fn [accounts address tokens-data]
(if (accounts address)
@@ -1,8 +1,6 @@
(ns status-im2.contexts.wallet.send.select-asset.view
(:require
[clojure.string :as string]
[quo.core :as quo]
[quo.foundations.resources :as quo.resources]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
@@ -24,7 +22,7 @@
balance-fiat-formatted (.toFixed (:total-balance-fiat token) 2)
currency-symbol "$"]
[quo/token-network
{:token (quo.resources/get-token (keyword (string/lower-case (:symbol token))))
{:token (:symbol token)
:label (:name token)
:token-value (str total-balance-formatted " " (:symbol token))
:fiat-value (str currency-symbol balance-fiat-formatted)
@@ -1,7 +1,6 @@
(ns status-im2.contexts.wallet.send.transaction-confirmation.view
(:require
[quo.core :as quo]
[quo.foundations.resources :as quo.resources]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
@@ -24,7 +23,7 @@
[quo/summary-tag
{:label "150 ETH"
:type :token
:image-source (quo.resources/get-token :eth)}]]
:image-source :eth}]]
[rn/view
{:style {:flex-direction :row
:margin-top 4}}
-15
View File
@@ -111,21 +111,6 @@
(fn [] (gesture/gesture-handler-root-hoc views/sheet-comp-old))
(fn [] views/sheet-comp-old))
(navigation/register-component
"wallet-connect-sheet"
(fn [] (gesture/gesture-handler-root-hoc views/wallet-connect-comp))
(fn [] views/wallet-connect-comp))
(navigation/register-component
"wallet-connect-success-sheet"
(fn [] (gesture/gesture-handler-root-hoc views/wallet-connect-success-comp))
(fn [] views/wallet-connect-success-comp))
(navigation/register-component
"wallet-connect-app-management-sheet"
(fn [] (gesture/gesture-handler-root-hoc views/wallet-connect-app-management-comp))
(fn [] views/wallet-connect-app-management-comp))
(navigation/register-component
"signing-sheet"
(fn [] (gesture/gesture-handler-root-hoc views/signing-comp))
+1 -30
View File
@@ -134,31 +134,6 @@
[_]
{:hide-signing-sheet nil})
(rf/defn hide-select-acc-sheet
{:events [:hide-select-acc-sheet]}
[_]
{:hide-select-acc-sheet nil})
(rf/defn hide-wallet-connect-sheet
{:events [:hide-wallet-connect-sheet]}
[_]
{:hide-wallet-connect-sheet nil})
(rf/defn hide-wallet-connect-success-sheet
{:events [:hide-wallet-connect-success-sheet]}
[_]
{:hide-wallet-connect-success-sheet nil})
(rf/defn hide-wallet-connect-app-management-sheet
{:events [:hide-wallet-connect-app-management-sheet]}
[{:keys [db]}]
{:db (-> db
(assoc db
:wallet-connect/showing-app-management-sheet?
false)
(dissoc :wallet-connect/session-managed))
:hide-wallet-connect-app-management-sheet nil})
(rf/defn set-multiaccount-root
{:events [:set-multiaccount-root]}
[{:keys [db]}]
@@ -171,16 +146,12 @@
(rf/defn dismiss-all-overlays
{:events [:dismiss-all-overlays]}
[{:keys [db]}]
[_]
{:dispatch-n [[:hide-popover]
[:hide-visibility-status-popover]
[:hide-bottom-sheet]
[:bottom-sheet-hidden]
[:hide-wallet-connect-sheet]
[:hide-wallet-connect-success-sheet]
[:hide-wallet-connect-app-management-sheet]
[:hide-signing-sheet]
[:hide-select-acc-sheet]
[:bottom-sheet/hide-old-navigation-overlay]
[:toasts/close-all-toasts]]})
-31
View File
@@ -10,7 +10,6 @@
[status-im.ui.screens.popover.views :as popover]
[status-im.ui.screens.profile.visibility-status.views :as visibility-status-views]
[status-im.ui.screens.signing.views :as signing]
[status-im.ui.screens.wallet-connect.session-proposal.views :as wallet-connect]
[status-im2.common.bottom-sheet-screen.view :as bottom-sheet-screen]
[status-im2.common.bottom-sheet.view :as bottom-sheet]
[status-im2.common.toasts.view :as toasts]
@@ -133,33 +132,3 @@
[signing/signing]
(when js/goog.DEBUG
[reloader/reload-view])])))
(def wallet-connect-comp
(reagent/reactify-component
(fn []
^{:key (str "wallet-connect-sheet" @reloader/cnt)}
[:<>
[inactive]
[wallet-connect/wallet-connect-proposal-sheet]
(when js/goog.DEBUG
[reloader/reload-view])])))
(def wallet-connect-success-comp
(reagent/reactify-component
(fn []
^{:key (str "wallet-connect-success-sheet" @reloader/cnt)}
[:<>
[inactive]
[wallet-connect/wallet-connect-success-sheet-view]
(when js/goog.DEBUG
[reloader/reload-view])])))
(def wallet-connect-app-management-comp
(reagent/reactify-component
(fn []
^{:key (str "wallet-connect-app-management-sheet" @reloader/cnt)}
[:<>
[inactive]
[wallet-connect/wallet-connect-app-management-sheet-view]
(when js/goog.DEBUG
[reloader/reload-view])])))
+1 -56
View File
@@ -5,7 +5,6 @@
[status-im2.constants :as constants]
[status-im2.contexts.chat.messages.list.events :as models.message-list]
[status-im2.contexts.chat.messages.resolver.message-resolver :as resolver]
[utils.datetime :as datetime]
[utils.i18n :as i18n]))
(defn intersperse-datemark
@@ -50,54 +49,6 @@
{:value (:datemark (peek messages-with-datemarks))
:type :datemark}))))
(defn last-gap
"last-gap is a special gap that is put last in the message stream"
[chat-id synced-from]
{:message-id "0x123"
:message-type constants/message-type-gap
:chat-id chat-id
:content-type constants/content-type-gap
:gap-ids #{:first-gap}
:gap-parameters {:from synced-from}})
(defn collapse-gaps
"collapse-gaps will take an array of messages and collapse any gap next to
each other in a single gap.
It will also append one last gap if the last message is a non-gap"
[messages chat-id synced-from now chat-type joined loading-messages?]
(let [messages-with-gaps (reduce
(fn [acc {:keys [gap-parameters message-id] :as message}]
(let [last-element (peek acc)]
(cond
;; If it's a message, just add
(empty? gap-parameters)
(conj acc message)
;; Both are gaps, merge them
(and
(seq (:gap-parameters last-element))
(seq gap-parameters))
(conj (pop acc) (update last-element :gap-ids conj message-id))
;; it's a gap
:else
(conj acc (assoc message :gap-ids #{message-id})))))
[]
messages)]
(if (or loading-messages? ; it's loading messages from the database
(nil? synced-from) ; it's still syncing
(= constants/timeline-chat-type chat-type) ; it's a timeline chat
(= constants/profile-chat-type chat-type) ; it's a profile chat
(and (not (nil? synced-from)) ; it's not more than a month
(<= synced-from (- (quot now 1000) constants/one-month)))
(and (= constants/private-group-chat-type chat-type) ; it's a private group chat
(or (not (pos? joined)) ; we haven't joined
(>= (quot joined 1000) synced-from))) ; the history goes before we joined
(:gap-ids (peek messages-with-gaps))) ; there's already a gap on top of the
; chat history
messages-with-gaps ; don't add an extra gap
(conj messages-with-gaps (last-gap chat-id synced-from)))))
(defn hydrate-messages
"Pull data from messages and add it to the sorted list"
([message-list messages] (hydrate-messages message-list messages {}))
@@ -258,7 +209,7 @@
(re-frame/subscribe [:chats/synced-from chat-id])
(re-frame/subscribe [:chats/chat-type chat-id])
(re-frame/subscribe [:chats/joined chat-id])])
(fn [[message-list messages pin-messages loading-messages? synced-from chat-type joined] [_ chat-id]]
(fn [[message-list messages pin-messages loading-messages?] _]
;;TODO (perf)
(let [message-list-seq (models.message-list/->seq message-list)]
; Don't show gaps if that's the case as we are still loading messages
@@ -267,12 +218,6 @@
(-> message-list-seq
(add-datemarks)
(hydrate-messages messages pin-messages)
(collapse-gaps chat-id
synced-from
(datetime/timestamp)
chat-type
joined
loading-messages?)
(albumize-messages))))))
(re-frame/reg-sub
+15 -17
View File
@@ -40,7 +40,7 @@
:<- [:wallet/accounts]
(fn [accounts]
(zipmap (map :address accounts)
(map #(-> % :tokens utils/calculate-balance) accounts))))
(map utils/calculate-balance-for-account accounts))))
(rf/reg-sub
:wallet/account-cards-data
@@ -71,21 +71,18 @@
:<- [:wallet/current-viewing-account]
:<- [:wallet/network-details]
(fn [[account networks] [_ query]]
(let [tokens (map (fn [token]
(assoc token
:networks (utils/network-list token networks)
:total-balance (utils/total-token-value-in-all-chains token)
:total-balance-fiat (utils/calculate-balance token)))
(:tokens account))
sorted-tokens
(sort-by :name compare tokens)
filtered-tokens
(filter #(or (string/starts-with? (string/lower-case (:name %))
(string/lower-case query))
(string/starts-with? (string/lower-case (:symbol %))
(string/lower-case query)))
sorted-tokens)]
(let [tokens (map (fn [token]
(assoc token
:networks (utils/network-list token networks)
:total-balance (utils/total-token-units-in-all-chains token)
:total-balance-fiat 0))
(:tokens account))
sorted-tokens (sort-by :name compare tokens)
filtered-tokens (filter #(or (string/starts-with? (string/lower-case (:name %))
(string/lower-case query))
(string/starts-with? (string/lower-case (:symbol %))
(string/lower-case query)))
sorted-tokens)]
filtered-tokens)))
(rf/reg-sub
@@ -107,7 +104,8 @@
{:keys [price change-pct-24hour]} market-values
fiat-change (utils/calculate-fiat-change crypto-value change-pct-24hour)]
(when crypto-value
{:token (keyword (string/lower-case (:symbol item)))
{:token {:symbol (:symbol item)
:name (:name item)}
:state :default
:status (cond
(pos? change-pct-24hour) :positive
+43 -36
View File
@@ -1,8 +1,9 @@
(ns status-im2.subs.wallet.wallet-test
(:require [cljs.test :refer [is testing use-fixtures]]
[re-frame.db :as rf-db]
status-im2.subs.root
[status-im2.subs.root]
[test-helpers.unit :as h]
[utils.money :as money]
[utils.re-frame :as rf]))
(use-fixtures :each
@@ -12,30 +13,31 @@
[{:decimals 1
:symbol "ETH"
:name "Ether"
:balances-per-chain {1 {:raw-balance "20" :has-error false}
2 {:raw-balance "10" :has-error false}}
:balances-per-chain {1 {:raw-balance (money/bignumber "20") :has-error false}
2 {:raw-balance (money/bignumber "10") :has-error false}}
:market-values-per-currency {:usd {:price 1000}}}
{:decimals 2
:symbol "DAI"
:name "Dai Stablecoin"
:balances-per-chain {1 {:raw-balance "100" :has-error false}
2 {:raw-balance "150" :has-error false}}
:balances-per-chain {1 {:raw-balance (money/bignumber "100") :has-error false}
2 {:raw-balance (money/bignumber "150") :has-error false}
3 {:raw-balance nil :has-error false}}
:market-values-per-currency {:usd {:price 100}}}])
(def tokens-0x2
[{:decimals 3
:symbol "ETH"
:name "Ether"
:balances-per-chain {1 {:raw-balance "2500" :has-error false}
2 {:raw-balance "3000" :has-error false}
3 {:raw-balance "<nil>" :has-error false}}
:balances-per-chain {1 {:raw-balance (money/bignumber "2500") :has-error false}
2 {:raw-balance (money/bignumber "3000") :has-error false}
3 {:raw-balance (money/bignumber "<nil>") :has-error false}}
:market-values-per-currency {:usd {:price 200}}}
{:decimals 10
:symbol "DAI"
:name "Dai Stablecoin"
:balances-per-chain {1 {:raw-balance "10000000000" :has-error false}
2 {:raw-balance "0" :has-error false}
3 {:raw-balance "<nil>" :has-error false}}
:balances-per-chain {1 {:raw-balance (money/bignumber "10000000000") :has-error false}
2 {:raw-balance (money/bignumber "0") :has-error false}
3 {:raw-balance (money/bignumber "<nil>") :has-error false}}
:market-values-per-currency {:usd {:price 1000}}}])
(def accounts
@@ -84,9 +86,12 @@
[sub-name]
(testing "a map: address->balance"
(swap! rf-db/app-db #(assoc-in % [:wallet :accounts] accounts))
(let [result (rf/sub [sub-name])
balance-0x1 (money/bignumber 3250)
balance-0x2 (money/bignumber 2100)]
(is (= {"0x1" 3250 "0x2" 2100}
(rf/sub [sub-name])))))
(is (money/equal-to balance-0x1 (get result "0x1")))
(is (money/equal-to balance-0x2 (get result "0x2"))))))
(h/deftest-sub :wallet/accounts
[sub-name]
@@ -143,30 +148,32 @@
#(-> %
(assoc-in [:wallet :accounts] accounts)
(assoc-in [:wallet :current-viewing-account-address] "0x1")))
(let [result (rf/sub [sub-name])]
(is
(= {:path "m/44'/60'/0'/0/0"
:emoji "😃"
:key-uid "0x2f5ea39"
:address "0x1"
:wallet false
:name "Account One"
:type :generated
:chat false
:test-preferred-chain-ids #{5 420 421613}
:color :blue
:hidden false
:prod-preferred-chain-ids #{1 10 42161}
:position 0
:clock 1698945829328
:created-at 1698928839000
:operable "fully"
:mixedcase-address "0x7bcDfc75c431"
:public-key "0x04371e2d9d66b82f056bc128064"
:removed false
:balance 3250
:tokens tokens-0x1}
(rf/sub [sub-name])))))
(is
(= {:path "m/44'/60'/0'/0/0"
:emoji "😃"
:key-uid "0x2f5ea39"
:address "0x1"
:wallet false
:name "Account One"
:type :generated
:chat false
:test-preferred-chain-ids #{5 420 421613}
:color :blue
:hidden false
:prod-preferred-chain-ids #{1 10 42161}
:position 0
:clock 1698945829328
:created-at 1698928839000
:operable "fully"
:mixedcase-address "0x7bcDfc75c431"
:public-key "0x04371e2d9d66b82f056bc128064"
:removed false
:tokens tokens-0x1}
(dissoc result :balance)))
(is (money/equal-to (:balance result) (money/bignumber 3250))))))
(h/deftest-sub :wallet/addresses
+6 -2
View File
@@ -152,7 +152,7 @@
;; E.g. for Ether, it's smallest part is wei or 10^(-18) of 1 ether
;; for arbitrary ERC20 token the smallest part is 10^(-decimals) of 1 token
;;
;; Different tokens can have different number of allowed decimals, so it's neccessary to include the
;; Different tokens can have different number of allowed decimals, so it's necessary to include the
;; decimals parameter
;; to get the amount scale right.
@@ -205,10 +205,14 @@
(with-precision 2)
str))
(defn add
(defn- add*
[bn1 n2]
(.add ^js bn1 n2))
(def add
"Add with defaults, this version is able to receive `nil` and takes them as 0."
(fnil add* (bignumber 0) (bignumber 0)))
(defn mul
[bn1 bn2]
(.mul ^js bn1 bn2))