Compare commits

..
Author SHA1 Message Date
Igor Sirotin 657736c499 chore: update status-go for StoreNodeRequestManager 2023-12-13 14:06:49 +00:00
65 changed files with 633 additions and 1236 deletions
@@ -14,8 +14,6 @@
[react-native.core :as rn]
[utils.i18n :as i18n]))
(def ^:private left-image-supported-types #{:account :keypair :default-keypair})
(defn- left-image
[{:keys [type customization-color account-avatar-emoji icon-avatar profile-picture]}]
(case type
@@ -167,14 +165,13 @@
button-disabled? account-avatar-emoji customization-color icon-avatar
profile-picture keycard? networks label]}]
[rn/view {:style style/container}
(when (left-image-supported-types type)
[rn/view {:style style/left-container}
[left-image
{:type type
:customization-color customization-color
:account-avatar-emoji account-avatar-emoji
:icon-avatar icon-avatar
:profile-picture profile-picture}]])
[rn/view {:style style/left-container}
[left-image
{:type type
:customization-color customization-color
:account-avatar-emoji account-avatar-emoji
:icon-avatar icon-avatar
:profile-picture profile-picture}]]
[rn/view {:style style/body-container}
[left-title
{:type type
@@ -71,7 +71,6 @@
(def system-message-contact-request-account-wrapper
{:flex-direction :row
:align-items :center
:margin-left 4
:flex-shrink 1})
(def system-message-contact-request-account-name
+1 -1
View File
@@ -15,7 +15,7 @@
[: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 :schema.common/image-source :string]]
[: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])
@@ -1,30 +0,0 @@
(ns quo.components.wallet.required-tokens.component-spec
(:require
[quo.components.wallet.required-tokens.view :as required-tokens]
[test-helpers.component :as h]))
(defn render
[component]
(h/render-with-theme-provider component :light))
(h/describe "Wallet: Required Tokens"
(h/test "basic render"
(render [required-tokens/view
{:token "SNT"
:type :token
:amount 100}])
(h/is-truthy (h/get-by-label-text :wallet-required-tokens)))
(h/test "render collectible"
(render [required-tokens/view
{:type :collectible
:collectible-img-src (js/require "../resources/images/mock2/collectible.png")
:collectible-name "Diamond"}])
(h/is-truthy (h/get-by-text "Diamond")))
(h/test "render token with correct amount & symbol"
(render [required-tokens/view
{:type :token
:token "ETH"
:amount 100}])
(h/is-truthy (h/get-by-text "100 ETH"))))
@@ -1,21 +0,0 @@
(ns quo.components.wallet.required-tokens.style
(:require [quo.foundations.colors :as colors]))
(def container
{:align-items :center
:flex-direction :row})
(def collectible-img
{:width 14
:height 14
:border-radius 4})
(defn divider
[theme]
{:width 2
:height 2
:border-radius 1
:margin-left 8
:background-color (colors/theme-colors colors/neutral-40
colors/neutral-50
theme)})
@@ -1,56 +0,0 @@
(ns quo.components.wallet.required-tokens.view
(:require [quo.components.markdown.text :as text]
[quo.components.utilities.token.view :as token]
[quo.components.wallet.required-tokens.style :as style]
quo.theme
[react-native.core :as rn]
[schema.core :as schema]))
(def ?schema
[:=>
[:catn
[:props
[:map {:closed true}
[:type [:enum :token :collectible]]
[:amount {:optional true} [:maybe [:or :string :int]]]
[:token {:optional true} [:maybe :string]]
[:token-img-src {:optional true} [:maybe :schema.common/image-source]]
[:collectible-img-src {:optional true} :schema.common/image-source]
[:collectible-name {:optional true} [:maybe :string]]
[:divider? {:optional true} [:maybe :boolean]]
[:theme :schema.common/theme]
[:container-style {:optional true} [:maybe :map]]]]]
:any])
(defn- view-internal
[{:keys [type amount token token-img-src collectible-img-src collectible-name divider? theme
container-style]}]
[rn/view
{:style (merge style/container container-style)
:accessibility-label :wallet-required-tokens}
(case type
:token [token/view
(assoc (if token-img-src
{:image-source token-img-src}
{:token token})
:size
14)]
:collectible [rn/image
{:style style/collectible-img
:source collectible-img-src}]
nil)
[text/text
{:size :paragraph-2
:weight :medium
:style {:margin-left 4}}
(case type
:token (str amount " " token)
:collectible collectible-name
nil)]
(when divider?
[rn/view
{:style (style/divider theme)}])])
(def view
(quo.theme/with-theme
(schema/instrument #'view-internal ?schema)))
-2
View File
@@ -155,7 +155,6 @@
quo.components.wallet.network-link.view
quo.components.wallet.network-routing.view
quo.components.wallet.progress-bar.view
quo.components.wallet.required-tokens.view
quo.components.wallet.summary-info.view
quo.components.wallet.token-input.view
quo.components.wallet.transaction-progress.view
@@ -404,7 +403,6 @@
(def network-bridge quo.components.wallet.network-bridge.view/view)
(def network-routing quo.components.wallet.network-routing.view/view)
(def progress-bar quo.components.wallet.progress-bar.view/view)
(def required-tokens quo.components.wallet.required-tokens.view/view)
(def summary-info quo.components.wallet.summary-info.view/view)
(def network-link quo.components.wallet.network-link.view/view)
(def token-input quo.components.wallet.token-input.view/view)
-1
View File
@@ -87,7 +87,6 @@
[quo.components.wallet.network-bridge.component-spec]
[quo.components.wallet.network-routing.component-spec]
[quo.components.wallet.progress-bar.component-spec]
[quo.components.wallet.required-tokens.component-spec]
[quo.components.wallet.summary-info.component-spec]
[quo.components.wallet.token-input.component-spec]
[quo.components.wallet.transaction-progress.component-spec]
+5 -7
View File
@@ -3,10 +3,8 @@
["react-native-share" :default react-native-share]))
(defn open
([options]
(open options #() #()))
([options on-success on-error]
(-> ^js react-native-share
(.open (clj->js options))
(.then on-success)
(.catch on-error))))
[options on-success on-error]
(-> ^js react-native-share
(.open (clj->js options))
(.then on-success)
(.catch on-error)))
-7
View File
@@ -11,12 +11,6 @@
(def ^:private ?public-key
[:re #"^0x04[0-9a-f]{128}$"])
(def ^:private ?image-source
[:or
[:int]
[:map
[:uri [:maybe [:string]]]]])
(def ^:private ?rpc-call
[:sequential
{:min 1}
@@ -33,5 +27,4 @@
(registry/register ::theme ?theme)
(registry/register ::customization-color ?customization-color)
(registry/register ::public-key ?public-key)
(registry/register ::image-source ?image-source)
(registry/register ::rpc-call ?rpc-call))
@@ -1,25 +1,41 @@
(ns status-im2.contexts.chat.composer.events
(:require [clojure.string :as string]
[status-im.chat.models.mentions :as mentions]
[status-im.data-store.messages :as data-store-messages]
[status-im2.constants :as constants]
[status-im2.contexts.chat.composer.link-preview.events :as link-preview]
[status-im2.contexts.chat.messages.transport.events :as messages.transport]
[taoensso.timbre :as log]
[utils.emojilib :as emoji]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
utils.string))
(ns status-im.chat.models.input
(:require
["emojilib" :as emojis]
[clojure.string :as string]
[goog.object :as object]
[re-frame.core :as re-frame]
[status-im.chat.models.mentions :as mentions]
[status-im.data-store.messages :as data-store-messages]
[status-im2.constants :as constants]
[status-im2.contexts.chat.composer.link-preview.events :as link-preview]
[status-im2.contexts.chat.messages.transport.events :as messages.transport]
[taoensso.timbre :as log]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[utils.string :as utils.string]))
(defn text->emoji
"Replaces emojis in a specified `text`"
[text]
(utils.string/safe-replace text
#":([a-z_\-+0-9]*):"
(fn [[original emoji-id]]
(if-let [emoji-map (object/get (.-lib emojis) emoji-id)]
(.-char ^js emoji-map)
original))))
;; effects
(rf/defn set-chat-input-text
"Set input text for current-chat. Takes db and input text and cofx
as arguments and returns new fx. Always clear all validation messages."
{:events [:chat.ui/set-chat-input-text]}
[{:keys [db] :as cofx} new-input chat-id]
(let [current-chat-id (or chat-id (:current-chat-id db))]
(rf/merge
cofx
{:db (assoc-in db [:chat/inputs current-chat-id :input-text] (emoji/text->emoji new-input))}
(when (empty? new-input)
(mentions/clear-mentions)))))
(rf/merge cofx
{:db (assoc-in db [:chat/inputs current-chat-id :input-text] (text->emoji new-input))}
(when (empty? new-input)
(mentions/clear-mentions)))))
(rf/defn set-input-content-height
{:events [:chat.ui/set-input-content-height]}
@@ -50,6 +66,27 @@
[{db :db} recording?]
{:db (assoc db :chats/recording? recording?)})
(rf/defn select-mention
{:events [:chat.ui/select-mention]}
[{:keys [db] :as cofx} text-input-ref {:keys [primary-name searched-text match public-key] :as user}]
(let [chat-id (:current-chat-id db)
text (get-in db [:chat/inputs chat-id :input-text])
method "wakuext_chatMentionSelectMention"
params [chat-id text primary-name public-key]]
{:json-rpc/call [{:method method
:params params
:on-success #(rf/dispatch [:mention/on-select-mention-success %
primary-name match searched-text public-key])
:on-error #(rf/dispatch [:mention/on-error
{:method method
:params params} %])}]}))
(rf/defn disable-chat-cooldown
"Turns off chat cooldown (protection against message spamming)"
{:events [:chat/disable-cooldown]}
[{:keys [db]}]
{:db (assoc db :chat/cooldown-enabled? false)})
(rf/defn reply-to-message
"Sets reference to previous chat message and focuses on input"
{:events [:chat.ui/reply-to-message]}
@@ -66,7 +103,7 @@
(rf/defn edit-message
"Sets reference to previous chat message and focuses on input"
{:events [:chat.ui/edit-message]}
[{:keys [db]} message]
[{:keys [db] :as cofx} message]
(let [current-chat-id (:current-chat-id db)
text (get-in message [:content :text])]
{:db (-> db
@@ -79,6 +116,21 @@
:dispatch-n [[:chat.ui/set-chat-input-text nil current-chat-id]
[:mention/to-input-field text current-chat-id]]}))
(rf/defn show-contact-request-input
"Sets reference to previous chat message and focuses on input"
{:events [:chat.ui/send-contact-request]}
[{:keys [db]}]
(let [current-chat-id (:current-chat-id db)]
{:db (-> db
(assoc-in [:chat/inputs current-chat-id :metadata :sending-contact-request]
current-chat-id)
(assoc-in [:chat/inputs current-chat-id :metadata :responding-to-message]
nil)
(assoc-in [:chat/inputs current-chat-id :metadata :editing-message] nil)
(update-in [:chat/inputs current-chat-id :metadata]
dissoc
:sending-image))}))
(rf/defn cancel-message-reply
"Cancels stage message reply"
{:events [:chat.ui/cancel-message-reply]}
@@ -86,6 +138,49 @@
(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? (emoji-only-content? {:text input-text
:response-to message-id})]
{:chat-id current-chat-id
:content-type (if emoji?
constants/content-type-emoji
constants/content-type-text)
:text input-text
:response-to message-id
:ens-name preferred-name
:link-previews (map #(select-keys % [:url :title :description :thumbnail])
(get-in db [:chat/link-previews :unfurled]))})))
(defn build-image-messages
[{db :db} chat-id input-text]
(let [images (get-in db [:chat/inputs chat-id :metadata :sending-image])
{:keys [message-id]} (get-in db [:chat/inputs chat-id :metadata :responding-to-message])
album-id (str (random-uuid))]
(mapv (fn [[_ {:keys [resized-uri width height]}]]
{:chat-id chat-id
:album-id album-id
:content-type constants/content-type-image
:image-path (utils.string/safe-replace resized-uri #"file://" "")
:image-width width
:image-height height
:text input-text
:link-previews (map #(select-keys % [:url :title :description :thumbnail])
(get-in db [:chat/link-previews :unfurled]))
:response-to message-id})
images)))
(rf/defn clean-input
[{:keys [db] :as cofx} current-chat-id]
(rf/merge cofx
@@ -106,50 +201,6 @@
(link-preview/reset-unfurled)
(mentions/clear-mentions))))
(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-image-messages
[{db :db} chat-id input-text]
(let [images (get-in db [:chat/inputs chat-id :metadata :sending-image])
{:keys [message-id]} (get-in db [:chat/inputs chat-id :metadata :responding-to-message])
album-id (str (random-uuid))]
(mapv (fn [[_ {:keys [resized-uri width height]}]]
{:chat-id chat-id
:album-id album-id
:content-type constants/content-type-image
:image-path (utils.string/safe-replace resized-uri #"file://" "")
:image-width width
:image-height height
:text input-text
:link-previews (map #(select-keys % [:url :title :description :thumbnail])
(get-in db [:chat/link-previews :unfurled]))
:response-to message-id})
images)))
(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? (emoji-only-content? {:text input-text
:response-to message-id})]
{:chat-id current-chat-id
:content-type (if emoji?
constants/content-type-emoji
constants/content-type-text)
:text input-text
:response-to message-id
:ens-name preferred-name
:link-previews (map #(select-keys % [:url :title :description :thumbnail])
(get-in db [:chat/link-previews :unfurled]))})))
(rf/defn send-messages
[{:keys [db] :as cofx} input-text current-chat-id]
(let [image-messages (build-image-messages cofx current-chat-id input-text)
@@ -163,10 +214,8 @@
(messages.transport/send-chat-messages messages)))))
(rf/defn send-audio-message
{:events [:chat/send-audio]}
[{:keys [db] :as cofx} audio-path duration]
(let [{:keys [current-chat-id]} db
{:keys [message-id]}
[{:keys [db] :as cofx} audio-path duration current-chat-id]
(let [{:keys [message-id]}
(get-in db [:chat/inputs current-chat-id :metadata :responding-to-message])]
(when-not (string/blank? audio-path)
(rf/merge
@@ -181,6 +230,17 @@
(when message-id
{:response-to message-id}))])))))
(rf/defn send-sticker-message
[cofx {:keys [hash packID pack]} current-chat-id]
(when-not (or (string/blank? hash) (and (string/blank? packID) (string/blank? pack)))
(messages.transport/send-chat-messages
cofx
[{:chat-id current-chat-id
:content-type constants/content-type-sticker
:sticker {:hash hash
:pack (int (if (string/blank? packID) pack packID))}
:text (i18n/label :t/update-to-see-sticker {"locale" "en"})}])))
(rf/defn send-edited-message
[{:keys [db]
:as cofx} text {:keys [message-id quoted-message chat-id]}]
@@ -202,29 +262,79 @@
:js-response true
:on-error #(log/error "failed to edit message " %)
:on-success (fn [result]
(rf/dispatch [:sanitize-messages-and-process-response
result]))}]}
(re-frame/dispatch [:sanitize-messages-and-process-response
result]))}]}
(link-preview/reset-unfurled)
(cancel-message-edit)))
(rf/defn replace-mentions-and-send-current-message
(rf/defn send-current-message
"Sends message from current chat input"
{:events [:chat.ui/replace-mentions-and-send-current-message]}
[{{:keys [current-chat-id] :as db} :db}]
(let [{:keys [input-text metadata]} (get-in db [:chat/inputs current-chat-id])]
{:json-rpc/call [{:method "wakuext_chatMentionReplaceWithPublicKey"
:params [current-chat-id input-text]
:on-error #(log/error "[wakuext_chatMentionReplaceWithPublicKey] on-error" %)
:on-success #(rf/dispatch [:chat.ui/send-current-message-with-mentions
{:events [:chat.ui/send-current-message]}
[{{:keys [current-chat-id] :as db} :db :as cofx}]
(let [{:keys [input-text metadata]} (get-in db [:chat/inputs current-chat-id])
editing-message (:editing-message metadata)
method "wakuext_chatMentionReplaceWithPublicKey"
params [current-chat-id input-text]]
{:json-rpc/call [{:method method
:params params
:on-error #(rf/dispatch [:mention/on-error {:method method :params params} %])
:on-success #(rf/dispatch [:mention/on-replace-with-public-key-success
current-chat-id
(:editing-message metadata)
editing-message
input-text
%])}]}))
(rf/defn send-current-message-with-mentions
{:events [:chat.ui/send-current-message-with-mentions]}
(rf/defn on-replace-with-public-key-success
{:events [:mention/on-replace-with-public-key-success]}
[{:keys [db] :as cofx} current-chat-id editing-message input-text new-text]
(log/debug "[mentions] on-replace-with-public-key-success"
{:chat-id current-chat-id
:editing-message editing-message
:input-text input-text
:new-text new-text})
(rf/merge cofx
(if editing-message
(send-edited-message new-text editing-message)
(send-messages new-text current-chat-id))))
(rf/defn send-contact-request
{:events [:contacts/send-contact-request]}
[{:keys [db] :as cofx} public-key message]
(rf/merge cofx
{:chat.ui/clear-inputs nil
:json-rpc/call [{:method "wakuext_sendContactRequest"
:js-response true
:params [{:id public-key :message message}]
:on-error #(log/warn "failed to send a contact request" %)
:on-success #(re-frame/dispatch [:transport/message-sent %])}]}
(mentions/clear-mentions)
(clean-input (:current-chat-id db))))
(rf/defn cancel-contact-request
"Cancels contact request"
{:events [:chat.ui/cancel-contact-request]}
[{:keys [db] :as cofx}]
(let [current-chat-id (:current-chat-id db)]
(rf/merge cofx
{:db (assoc-in db [:chat/inputs current-chat-id :metadata :sending-contact-request] nil)}
(mentions/clear-mentions)
(clean-input (:current-chat-id db)))))
(rf/defn chat-send-sticker
{:events [:chat/send-sticker]}
[{{:keys [current-chat-id] :as db} :db :as cofx} {:keys [hash packID pack] :as sticker}]
(rf/merge
cofx
{:db (update db
:stickers/recent-stickers
(fn [recent]
(conj (remove #(= hash (:hash %)) recent) sticker)))
:json-rpc/call [{:method "stickers_addRecent"
:params [(int (if (string/blank? packID) pack packID)) hash]
:on-success #()}]}
(send-sticker-message sticker current-chat-id)))
(rf/defn chat-send-audio
{:events [:chat/send-audio]}
[{{:keys [current-chat-id] :as db} :db :as cofx} audio-path duration]
(send-audio-message cofx audio-path duration current-chat-id))
+10
View File
@@ -0,0 +1,10 @@
(ns status-im.chat.models.input-test
(:require
[cljs.test :refer-macros [deftest is]]
[status-im.chat.models.input :as input]))
(deftest text->emoji
(is (nil? (input/text->emoji nil)))
(is (= "" (input/text->emoji "")))
(is (= "test" (input/text->emoji "test")))
(is (= "word1 \uD83D\uDC4D word2" (input/text->emoji "word1 :+1: word2"))))
-15
View File
@@ -161,18 +161,3 @@
:on-error #(log/error "Error while calling wakuext_chatMentionClearMentions"
{:error %})}]}
(clear-suggestions))))
(rf/defn select-mention
{:events [:chat.ui/select-mention]}
[{:keys [db]} {:keys [primary-name searched-text match public-key] :as user}]
(let [chat-id (:current-chat-id db)
text (get-in db [:chat/inputs chat-id :input-text])
method "wakuext_chatMentionSelectMention"
params [chat-id text primary-name public-key]]
{:json-rpc/call [{:method method
:params params
:on-success #(rf/dispatch [:mention/on-select-mention-success %
primary-name match searched-text public-key])
:on-error #(rf/dispatch [:mention/on-error
{:method method
:params params} %])}]}))
+1 -2
View File
@@ -15,6 +15,5 @@
(multiaccounts.update/multiaccount-update
:currency
currency
;; on changing currency, we should fetch tokens prices again
{:on-success #(rf/dispatch [:wallet/get-wallet-token])})
{})
(prices/update-prices)))
+5 -5
View File
@@ -69,10 +69,10 @@
(rf/defn new-wallet-event
[cofx {:keys [type blockNumber accounts] :as event}]
(log/debug "[wallet-subs] new-wallet-event"
"event-type" type
"blockNumber" blockNumber
"accounts" accounts)
(log/info "[wallet-subs] new-wallet-event"
"event-type" type
"blockNumber" blockNumber
"accounts" accounts)
(case type
"new-transfers" (new-transfers cofx blockNumber accounts)
"recent-history-fetching" (recent-history-fetching-started cofx accounts)
@@ -85,4 +85,4 @@
"wallet-get-collectibles-details-done" {:fx [[:dispatch
[:wallet/get-collectible-details-done
event]]]}
(log/debug ::unknown-wallet-event :type type :event event)))
(log/warn ::unknown-wallet-event :type type :event event)))
+1
View File
@@ -10,6 +10,7 @@
status-im.bootnodes.core
status-im.browser.core
status-im.browser.permissions
status-im.chat.models.input
status-im.chat.models.loading
status-im.contact.block
status-im.currency.core
+14 -6
View File
@@ -1153,18 +1153,26 @@
#(async-storage/set-item! :invalid-ens-name-seen true)))))
nil)
(re-frame/reg-fx
::enable-local-notifications
(fn []
(native-module/start-local-notifications)))
(rf/defn initialize-wallet
{:events [:wallet-legacy/initialize-wallet]}
[{:keys [db] :as cofx} accounts tokens custom-tokens
favourites scan-all-tokens? new-account?]
(rf/merge
cofx
{:db (assoc db
:profile/wallet-accounts
(rpc->accounts accounts))
:dispatch-n [(when (or (not (utils.mobile-sync/syncing-allowed? cofx))
(chain/binance-chain? db))
[:transaction/get-fetched-transfers])]}
{:db (assoc db
:profile/wallet-accounts
(rpc->accounts accounts))
;; NOTE: Local notifications should be enabled only after wallet was started
::enable-local-notifications nil
:dispatch-n [(when (or (not (utils.mobile-sync/syncing-allowed? cofx))
(chain/binance-chain? db))
[:transaction/get-fetched-transfers])]
:dispatch [:wallet/get-accounts-success accounts]}
(check-invalid-ens)
(initialize-tokens tokens custom-tokens)
(initialize-favourites favourites)
+2 -8
View File
@@ -15,10 +15,6 @@
[ids]
(string/join constants/chain-id-separator ids))
(defn add-keys-to-account
[account]
(assoc account :watch-only? (= (:type account) :watch)))
(defn rpc->account
[account]
(-> account
@@ -29,8 +25,7 @@
(update :prod-preferred-chain-ids chain-ids-string->set)
(update :test-preferred-chain-ids chain-ids-string->set)
(update :type keyword)
(update :color #(if (seq %) (keyword %) constants/account-default-customization-color))
add-keys-to-account))
(update :color #(if (seq %) (keyword %) constants/account-default-customization-color))))
(defn rpc->accounts
[accounts]
@@ -45,8 +40,7 @@
:test-preferred-chain-ids :testPreferredChainIds
:color :colorId})
(update :prodPreferredChainIds chain-ids-set->string)
(update :testPreferredChainIds chain-ids-set->string)
(dissoc :watch-only?)))
(update :testPreferredChainIds chain-ids-set->string)))
(defn <-rpc
[network]
+5 -6
View File
@@ -2,8 +2,7 @@
(:require
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]
[react-native.safe-area :as safe-area]
[status-im2.constants :as constants]))
[react-native.safe-area :as safe-area]))
(def ^:private card-height (+ 56 16))
(def ^:private max-scroll (+ card-height 8))
@@ -24,7 +23,7 @@
(reanimated/interpolate scroll-shared-value [0 max-scroll] [0 (+ max-scroll)] :clamp))
(defn banner-card-blur-layer
[scroll-shared-value testnet-enabled?]
[scroll-shared-value]
(reanimated/apply-animations-to-style
{:transform [{:translate-y (animated-card-translation-y scroll-shared-value)}]}
{:overflow (if platform/ios? :visible :hidden)
@@ -33,7 +32,7 @@
:top 0
:right 0
:left 0
:height (+ (safe-area/get-top) 244 (when testnet-enabled? constants/testnet-banner-height))}))
:height (+ (safe-area/get-top) 244)}))
(defn banner-card-hiding-layer
[scroll-shared-value]
@@ -54,12 +53,12 @@
{}))
(defn banner-card-tabs-layer
[scroll-shared-value testnet-enabled?]
[scroll-shared-value]
(reanimated/apply-animations-to-style
{:transform [{:translate-y (animated-card-translation-y scroll-shared-value)}]}
{:z-index 3
:position :absolute
:top (+ (safe-area/get-top) 192 (when testnet-enabled? constants/testnet-banner-height))
:top (+ (safe-area/get-top) 192)
:right 0
:left 0}))
+16 -18
View File
@@ -31,9 +31,8 @@
(defn- banner-card-blur-layer
[scroll-shared-value child]
(let [testnet-enabled? (rf/sub [:profile/testnet-enabled?])
open-sheet? (-> (rf/sub [:bottom-sheet]) :sheets seq)]
[reanimated/view {:style (style/banner-card-blur-layer scroll-shared-value testnet-enabled?)}
(let [open-sheet? (-> (rf/sub [:bottom-sheet]) :sheets seq)]
[reanimated/view {:style (style/banner-card-blur-layer scroll-shared-value)}
[blur/view
{:style style/fill-space
:blur-amount (if platform/ios? 20 10)
@@ -55,21 +54,20 @@
(defn- banner-card-tabs-layer
[{:keys [selected-tab tabs on-tab-change scroll-ref scroll-shared-value customization-color]}]
(let [testnet-enabled? (rf/sub [:profile/testnet-enabled?])]
[reanimated/view {:style (style/banner-card-tabs-layer scroll-shared-value testnet-enabled?)}
^{:key (str "tabs-" selected-tab)}
[quo/tabs
{:style style/banner-card-tabs
:customization-color customization-color
:size 32
:default-active selected-tab
:data tabs
:on-change (fn [tab]
(reset-banner-animation scroll-shared-value)
(some-> scroll-ref
deref
reset-scroll)
(on-tab-change tab))}]]))
[reanimated/view {:style (style/banner-card-tabs-layer scroll-shared-value)}
^{:key (str "tabs-" selected-tab)}
[quo/tabs
{:style style/banner-card-tabs
:customization-color customization-color
:size 32
:default-active selected-tab
:data tabs
:on-change (fn [tab]
(reset-banner-animation scroll-shared-value)
(some-> scroll-ref
deref
reset-scroll)
(on-tab-change tab))}]])
(defn animated-banner
[{:keys [scroll-ref tabs selected-tab on-tab-change scroll-shared-value content customization-color]}]
@@ -1,11 +1,8 @@
(ns status-im2.common.home.header-spacing.style
(:require
[react-native.safe-area :as safe-area]
[status-im2.common.home.constants :as constants]
status-im2.constants))
[status-im2.common.home.constants :as constants]))
(defn header-spacing
[testnet-enabled?]
{:height (+ constants/header-height
(safe-area/get-top)
(when testnet-enabled? status-im2.constants/testnet-banner-height))})
[]
{:height (+ constants/header-height (safe-area/get-top))})
@@ -1,10 +1,8 @@
(ns status-im2.common.home.header-spacing.view
(:require
[react-native.core :as rn]
[status-im2.common.home.header-spacing.style :as style]
[utils.re-frame :as rf]))
[status-im2.common.home.header-spacing.style :as style]))
(defn view
[]
(let [testnet-enabled? (rf/sub [:profile/testnet-enabled?])]
[rn/view {:style (style/header-spacing testnet-enabled?)}]))
[rn/view {:style (style/header-spacing)}])
+2 -6
View File
@@ -14,8 +14,7 @@
:jump-to? true/false
:container-style passed to outer view of component}"
[{:keys [container-style blur? jump-to?]}]
(let [testnet-enabled? (rf/sub [:profile/testnet-enabled?])
{:keys [public-key] :as profile} (rf/sub [:profile/profile-with-image])
(let [{:keys [public-key] :as profile} (rf/sub [:profile/profile-with-image])
online? (rf/sub [:visibility-status-updates/online?
public-key])
customization-color (rf/sub [:profile/customization-color])
@@ -38,10 +37,7 @@
:scan-on-press #(js/alert "to be implemented")
:activity-center-on-press #(rf/dispatch [:activity-center/open])
:qr-code-on-press #(dispatch-and-chill [:open-modal :share-shell] 1000)
:container-style (merge style/top-nav-container
(when testnet-enabled?
{:margin-top constants/testnet-banner-height})
container-style)
:container-style (merge style/top-nav-container container-style)
:blur? blur?
:jump-to? jump-to?
:customization-color customization-color
-3
View File
@@ -105,7 +105,6 @@
(def ^:const profile-default-color :blue)
(def ^:const profile-name-max-length 24)
(def ^:const profile-default-currency :usd)
(def ^:const profile-pictures-show-to-contacts-only 1)
(def ^:const profile-pictures-show-to-everyone 2)
@@ -394,5 +393,3 @@
(def ^:const status-address-domain ".stateofus.eth")
(def ^:const eth-address-domain ".eth")
(def ^:const testnet-banner-height 40)
@@ -32,7 +32,7 @@
(js/setTimeout #(reanimated/set-shared-value background-y
(- window-height))
300)
(rf/dispatch [:chat.ui/replace-mentions-and-send-current-message])
(rf/dispatch [:chat.ui/send-current-message])
(rf/dispatch [:chat.ui/set-input-maximized false])
(rf/dispatch [:chat.ui/set-input-content-height comp-constants/input-height])
(rf/dispatch [:chat.ui/set-chat-input-text nil])
@@ -25,7 +25,7 @@
[user _ _ render-data]
[contact-list-item/contact-list-item
{:on-press (fn []
(rf/dispatch [:chat.ui/select-mention user])
(rf/dispatch [:chat.ui/select-mention nil user])
(update-cursor user render-data))}
user])
@@ -133,7 +133,7 @@
:max-font-size-multiplier 1
:multiline true
:placeholder (i18n/label :t/type-something)
:placeholder-text-color (colors/theme-colors colors/neutral-40 colors/neutral-50)
:placeholder-text-color (colors/theme-colors colors/neutral-30 colors/neutral-50)
:style (style/input-text props
state
{:max-height max-height
@@ -16,10 +16,12 @@
(assoc :margin-top 4))))
(defn user-message-content
[{:keys [outgoing outgoing-status]}]
[{:keys [first-in-group? outgoing outgoing-status]}]
{:border-radius 16
:padding-horizontal 8
:padding-vertical 4
:padding-vertical (if first-in-group?
8
4)
:opacity (if (and outgoing (= outgoing-status :sending))
0.5
1)})
@@ -32,11 +32,10 @@
(defn avatar-container
[{:keys [content last-in-group? pinned-by quoted-message from]} show-reactions?
in-reaction-and-action-menu? show-user-info? in-pinned-view?]
in-reaction-and-action-menu? in-pinned-view?]
(if (or (and (seq (:response-to content))
quoted-message)
last-in-group?
show-user-info?
pinned-by
(not show-reactions?)
in-reaction-and-action-menu?)
@@ -55,12 +54,10 @@
from
timestamp]}
show-reactions?
in-reaction-and-action-menu?
show-user-info?]
in-reaction-and-action-menu?]
(when (or (and (seq response-to) quoted-message)
last-in-group?
pinned-by
show-user-info?
(not show-reactions?)
in-reaction-and-action-menu?)
(let [[primary-name secondary-name] (rf/sub [:contacts/contact-two-names-by-identity from])
@@ -119,7 +116,7 @@
[]
(let [show-delivery-state? (reagent/atom false)]
(fn [{:keys [message-data context keyboard-shown? show-reactions? in-reaction-and-action-menu?
show-user-info? theme]}]
theme]}]
(let [{:keys [content-type quoted-message content
outgoing outgoing-status pinned-by]} message-data
first-image (first (:album message-data))
@@ -173,7 +170,7 @@
[rn/view
{:style {:padding-horizontal 4
:flex-direction :row}}
[avatar-container message-data show-reactions? in-reaction-and-action-menu? show-user-info?
[avatar-container message-data show-reactions? in-reaction-and-action-menu?
(:in-pinned-view? context)]
(into
(if show-reactions?
@@ -183,7 +180,7 @@
:flex 1
:max-height (when-not show-reactions?
(* 0.4 height))}}
[author message-data show-reactions? in-reaction-and-action-menu? show-user-info?]
[author message-data show-reactions? in-reaction-and-action-menu?]
(condp = content-type
constants/content-type-text
[content.text/text-content message-data context]
@@ -45,11 +45,12 @@
:margin-bottom header-avatar-top-offset})
(defn header-image
[scale-animation side-animation bottom-animation]
[scale-animation top-margin-animation side-margin-animation]
(reanimated/apply-animations-to-style
{:transform [{:scale scale-animation}
{:translate-x side-animation}
{:translate-y bottom-animation}]}
{:transform [{:scale scale-animation}]
:margin-top top-margin-animation
:margin-left side-margin-animation
:margin-bottom side-margin-animation}
{:align-items :flex-start}))
(def bio
@@ -6,11 +6,11 @@
[quo.theme :as quo.theme]
[react-native.background-timer :as background-timer]
[react-native.core :as rn]
[react-native.hooks :as hooks]
[react-native.platform :as platform]
[react-native.react-native-intersection-observer :as rnio]
[react-native.reanimated :as reanimated]
[status-im.ui.screens.chat.group :as chat.group]
[status-im2.common.home.actions.view :as home.actions]
[status-im2.constants :as constants]
[status-im2.contexts.chat.composer.constants :as composer.constants]
[status-im2.contexts.chat.messages.content.view :as message]
@@ -21,13 +21,12 @@
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defonce ^:const card-border-radius 16)
(defonce ^:const threshold-percentage-to-show-floating-scroll-down-button 75)
(defonce ^:const loading-indicator-extra-spacing 250)
(defonce ^:const loading-indicator-page-loading-height 100)
(defonce ^:const scroll-animation-input-range [0 50])
(defonce ^:const min-message-height 32)
(defonce ^:const topbar-visible-scroll-y-value 50)
(defonce ^:const topbar-visible-scroll-y-value 85)
(defonce ^:const topbar-invisible-scroll-y-value 135)
(defonce ^:const minimum-scroll-y-topbar-overlaying-avatar 400)
(def root-margin-for-big-name-visibility-detector {:bottom -35})
@@ -132,38 +131,36 @@
;; https://github.com/status-im/status-mobile/issues/17426
[quo/skeleton-list (skeleton-list-props :messages parent-height platform/ios?)]])))
(defn calc-list-header-height
[insets able-to-send-message? images]
(if able-to-send-message?
(+ composer.constants/composer-default-height
jump-to.constants/floating-shell-button-height
(if (seq images) composer.constants/images-container-height 0)
(:bottom insets))
(- 70 (:bottom insets))))
(defn list-header
[insets able-to-send-message? images theme]
(let [height (calc-list-header-height insets able-to-send-message? images)]
[insets able-to-send-message? theme]
(let [images (rf/sub [:chats/sending-image])]
[rn/view
{:background-color (colors/theme-colors colors/white colors/neutral-95 theme)
:height height}]))
:height (if able-to-send-message?
(+ composer.constants/composer-default-height
jump-to.constants/floating-shell-button-height
(if (seq images) composer.constants/images-container-height 0)
(:bottom insets))
(- 70 (:bottom insets)))}]))
(defn f-list-footer-avatar
[{:keys [scroll-y display-name online? profile-picture]}]
(let [image-scale-animation (reanimated/interpolate scroll-y
scroll-animation-input-range
[1 0.5]
header-extrapolation-option)
image-bottom-animation (reanimated/interpolate scroll-y
scroll-animation-input-range
[0 56]
header-extrapolation-option)
image-side-animation (reanimated/interpolate scroll-y
scroll-animation-input-range
[0 -40]
header-extrapolation-option)]
(let [image-scale-animation (reanimated/interpolate scroll-y
scroll-animation-input-range
[1 0.5]
header-extrapolation-option)
image-top-margin-animation (reanimated/interpolate scroll-y
scroll-animation-input-range
[0 40]
header-extrapolation-option)
image-side-margin-animation (reanimated/interpolate scroll-y
scroll-animation-input-range
[0 -20]
header-extrapolation-option)]
[reanimated/view
{:style (style/header-image image-scale-animation image-side-animation image-bottom-animation)}
{:style (style/header-image image-scale-animation
image-top-margin-animation
image-side-margin-animation)}
[quo/user-avatar
{:full-name display-name
:online? online?
@@ -177,13 +174,8 @@
(defn actions
[chat-id cover-bg-color]
(let [latest-pin-text (rf/sub [:chats/last-pinned-message-text chat-id])
pins-count (rf/sub [:chats/pin-messages-count chat-id])
{:keys [muted muted-till chat-type]} (rf/sub [:chat-by-id chat-id])
community-channel? (= constants/community-chat-type chat-type)
muted? (and muted (some? muted-till))
mute-chat-label (if community-channel? :t/mute-channel :t/mute-chat)
unmute-chat-label (if community-channel? :t/unmute-channel :t/unmute-chat)]
(let [latest-pin-text (rf/sub [:chats/last-pinned-message-text chat-id])
pins-count (rf/sub [:chats/pin-messages-count chat-id])]
[quo/channel-actions
{:style {:margin-top 16}
:actions [{:accessibility-label :action-button-pinned
@@ -195,19 +187,7 @@
:on-press (fn []
(rf/dispatch [:dismiss-keyboard])
(rf/dispatch [:pin-message/show-pins-bottom-sheet
chat-id]))}
{:accessibility-label :action-button-mute
:label (i18n/label (if muted
unmute-chat-label
mute-chat-label))
:color cover-bg-color
:icon (if muted? :i/muted :i/activity-center)
:on-press (fn []
(if muted?
(home.actions/unmute-chat-action chat-id)
(home.actions/mute-chat-action chat-id
chat-type
muted?)))}]}]))
chat-id]))}]}]))
(defn f-list-footer
[{:keys [chat scroll-y cover-bg-color on-layout theme messages-view-height
@@ -227,8 +207,8 @@
(rf/sub [:contacts/contact-by-address chat-id]))
photo-path (rf/sub [:chats/photo-path chat-id])
border-animation (reanimated/interpolate scroll-y
[30 50]
[card-border-radius 0]
[30 125]
[14 0]
header-extrapolation-option)]
[rn/view {:flex 1}
[rn/view
@@ -289,23 +269,21 @@
:else
[message/message message-data context keyboard-shown?])]))
(defn use-scroll-handler
[{:keys [scroll-y-animated-value
content-size-animated-value
animate-topbar-opacity?
on-end-reached?
animate-topbar-name?]}]
(fn [new-scroll-y new-content-size]
(when (and @on-end-reached? (pos? new-scroll-y))
(defn scroll-handler
[event scroll-y animate-topbar-opacity? on-end-reached? animate-topbar-name?]
(let [content-size-y (- (oops/oget event "nativeEvent.contentSize.height")
(oops/oget event "nativeEvent.layoutMeasurement.height"))
current-y (oops/oget event "nativeEvent.contentOffset.y")
scroll-distance (- content-size-y current-y)]
(when (and @on-end-reached? (pos? scroll-distance))
(reset! on-end-reached? false))
(if (< topbar-visible-scroll-y-value new-scroll-y)
(if (< topbar-visible-scroll-y-value scroll-distance)
(reset! animate-topbar-opacity? true)
(reset! animate-topbar-opacity? false))
(if (< topbar-invisible-scroll-y-value new-scroll-y)
(if (< topbar-invisible-scroll-y-value scroll-distance)
(reset! animate-topbar-name? true)
(reset! animate-topbar-name? false))
(reanimated/set-shared-value content-size-animated-value new-content-size)
(reanimated/set-shared-value scroll-y-animated-value (max new-scroll-y 0))))
(reanimated/set-shared-value scroll-y scroll-distance)))
(defn f-messages-list-content
[{:keys [chat insets scroll-y content-height cover-bg-color keyboard-shown? inner-state-atoms
@@ -319,21 +297,14 @@
[composer-active? @on-end-reached? @animate-topbar-opacity?])
(let [theme (quo.theme/use-theme-value)
{window-height :height} (rn/get-window)
{:keys [keyboard-height]} (hooks/use-keyboard)
context (rf/sub [:chats/current-chat-message-list-view-context])
messages (rf/sub [:chats/raw-chat-messages-stream (:chat-id chat)])
images (rf/sub [:chats/sending-image])
recording? (rf/sub [:chats/recording?])
all-loaded? (rf/sub [:chats/all-loaded? (:chat-id chat)])
{:keys [show-floating-scroll-down-button?
messages-scroll-y-value-initialized?
messages-view-height
messages-view-header-height]} inner-state-atoms
scroll-handler (use-scroll-handler
{:animate-topbar-name? animate-topbar-name?
:animate-topbar-opacity? animate-topbar-opacity?
:on-end-reached? on-end-reached?
:scroll-y-animated-value scroll-y
:content-size-animated-value
content-height})]
messages-view-header-height]} inner-state-atoms]
[rn/view {:style {:flex 1}}
[rnio/flat-list
{:root-margin root-margin-for-big-name-visibility-detector
@@ -341,7 +312,7 @@
:ref list-ref
:bounces false
:header [:<>
[list-header insets (:able-to-send-message? context) images theme]
[list-header insets (:able-to-send-message? context) theme]
(when (= (:chat-type chat) constants/private-group-chat-type)
[list-group-chat-header chat])]
:footer [list-footer
@@ -362,61 +333,37 @@
:insets insets}
:render-fn render-fn
:on-viewable-items-changed on-viewable-items-changed
:on-content-size-change
(fn [_ y]
(if (or
(< minimum-scroll-y-topbar-overlaying-avatar
(reanimated/get-shared-value scroll-y))
(< topbar-visible-scroll-y-value
(reanimated/get-shared-value scroll-y)))
(reset! animate-topbar-opacity? true)
(reset! animate-topbar-opacity? false))
(when-not (or
(not @big-name-visible?)
(= :initial-render @big-name-visible?)
(pos? (reanimated/get-shared-value
scroll-y)))
(reset! on-end-reached? false))
;; NOTE(alwx): here we set the initial value of `scroll-y` which is needed because by
;; default the chat is scrolled to the bottom and no initial `on-scroll` event is getting
;; triggered. Also makes sure changes in the content size are reflected in `scroll-y` e.g.
;; incoming messages scrolling the content up, which should affect the header
;; animations/interpolations.
(let [content-size-shared (reanimated/get-shared-value
content-height)
scroll-y-shared (if
@messages-scroll-y-value-initialized?
(reanimated/get-shared-value
scroll-y)
y)
;; NOTE: when the keyboard is shown and the message list
;; doesn't fill the screen, we use a different value for
;; scroll-y, which would make sure the avatar is minimized
;; appropriately and the header is shown.
keyboard-shown-with-unfilled-list? (< y window-height)
keyboard-space (- window-height y)
keyboard-scroll-value (- y keyboard-space keyboard-space)
;; NOTE: doing the calculations as we would in `on-scroll`, so the animations
;; and interpolations are triggered properly.
content-size (- y
window-height
;; NOTE: for some reason android insets are
;; included in the content size `y`, while iOS
;; are not.
(when platform/android? (:top insets)))
current-y (max (- content-size-shared
scroll-y-shared)
0)
new-scroll-value (if keyboard-shown-with-unfilled-list?
keyboard-scroll-value
(- content-size
current-y))]
(when (and (>= new-scroll-value 0)
(or (= scroll-y-shared 0)
(> (Math/abs (- content-size-shared y))
min-message-height)))
(reset! messages-scroll-y-value-initialized? true)
(scroll-handler new-scroll-value content-size))))
:on-content-size-change (fn [_ y]
(if (or
(< minimum-scroll-y-topbar-overlaying-avatar
(reanimated/get-shared-value scroll-y))
(< topbar-visible-scroll-y-value
(reanimated/get-shared-value scroll-y)))
(reset! animate-topbar-opacity? true)
(reset! animate-topbar-opacity? false))
(when-not (or
(not @big-name-visible?)
(= :initial-render @big-name-visible?)
(pos? (reanimated/get-shared-value
scroll-y)))
(reset! on-end-reached? false))
;; NOTE(alwx): here we set the initial value of
;; `scroll-y` which is needed because by default the
;; chat is scrolled to the bottom and no initial
;; `on-scroll` event is getting triggered
(let [scroll-y-shared (reanimated/get-shared-value
scroll-y)
content-height-shared (reanimated/get-shared-value
content-height)]
(when (or (= scroll-y-shared 0)
(> (Math/abs (- content-height-shared y))
min-message-height))
(reanimated/set-shared-value scroll-y
(- y
window-height
(- (when keyboard-shown?
keyboard-height))))
(reanimated/set-shared-value content-height y))))
:on-end-reached #(list-on-end-reached scroll-y on-end-reached?)
:on-scroll-to-index-failed identity
:scroll-indicator-insets {:top (if (:able-to-send-message? context)
@@ -431,21 +378,26 @@
:on-momentum-scroll-end state/stop-scrolling
:scroll-event-throttle 16
:on-scroll (fn [event]
(let [content-size-y
(- (oops/oget event "nativeEvent.contentSize.height")
(oops/oget event
"nativeEvent.layoutMeasurement.height"))
current-y (oops/oget event
"nativeEvent.contentOffset.y")
scroll-distance (- content-size-y current-y)]
(scroll-handler scroll-distance content-size-y))
(scroll-handler event
scroll-y
animate-topbar-opacity?
on-end-reached?
animate-topbar-name?)
(on-scroll event show-floating-scroll-down-button?))
:content-container-style {:justify-content :flex-end
:min-height @messages-view-height}
:style {:background-color (colors/theme-colors
colors/white
colors/neutral-95
theme)}
:style
{:background-color (if all-loaded?
(colors/theme-colors
(colors/custom-color cover-bg-color
50
20)
(colors/custom-color cover-bg-color
50
40)
theme)
(colors/theme-colors
colors/white
colors/neutral-95
theme))}
:inverted true
:on-layout (fn [e]
;; FIXME: the 1s timeout is to assure all effects with
@@ -99,6 +99,7 @@
[rn/view {:style (style/navigation-view chat-screen-loaded?)}
[reanimated/view
{:style (style/animated-background-view all-loaded? opacity-animation nil)}]
[reanimated/view {:style (style/animated-blur-view all-loaded? opacity-animation)}
[blur/view
{:blur-amount 20
@@ -13,10 +13,6 @@
[status-im2.contexts.chat.messages.navigation.view :as messages.navigation]
[utils.re-frame :as rf]))
;; NOTE(parvesh) - I am working on refactoring/optimization of the chat screen for performance
;; improvement. Please avoid refactoring these files. Also if you are not already working on bug
;; fixes related to the chat navigation bar, please skip them.
;; And ping me, so I can address them while refactoring
(defn f-chat
[{:keys [show-floating-scroll-down-button? animate-topbar-name?
big-name-visible? animate-topbar-opacity? on-end-reached? messages-list-on-layout-finished?]
@@ -98,14 +94,13 @@
(defn chat
[]
(let [inner-state-atoms
{:extra-keyboard-height (reagent/atom 0)
:show-floating-scroll-down-button? (reagent/atom false)
:messages-scroll-y-value-initialized? (reagent/atom false)
:messages-view-height (reagent/atom 0)
:messages-view-header-height (reagent/atom 0)
:animate-topbar-name? (reagent/atom false)
:big-name-visible? (reagent/atom :initial-render)
:animate-topbar-opacity? (reagent/atom false)
:on-end-reached? (reagent/atom false)
:messages-list-on-layout-finished? (reagent/atom false)}]
{:extra-keyboard-height (reagent/atom 0)
:show-floating-scroll-down-button? (reagent/atom false)
:messages-view-height (reagent/atom 0)
:messages-view-header-height (reagent/atom 0)
:animate-topbar-name? (reagent/atom false)
:big-name-visible? (reagent/atom :initial-render)
:animate-topbar-opacity? (reagent/atom false)
:on-end-reached? (reagent/atom false)
:messages-list-on-layout-finished? (reagent/atom false)}]
[:f> f-chat inner-state-atoms]))
@@ -9,7 +9,3 @@
;;"node.login" signal will be triggered as a callback
(native-module/login-account
(assoc (profile.config/login) :keyUid key-uid :password hashed-password))))
(rf/reg-fx :effects.profile/enable-local-notifications
(fn []
(native-module/start-local-notifications)))
@@ -112,29 +112,31 @@
current-network-config (get networks current-network)
network-id (str (get-in networks
[current-network :config :NetworkId]))]
(rf/merge
cofx
(cond-> {:json-rpc/call [{:method "wakuext_startMessenger"
:on-success #(re-frame/dispatch
[:messenger-started %])
:on-error #(log/error
"failed to start messenger")}]
:check-eip1559-activation {:network-id network-id}
:effects.profile/enable-local-notifications nil
:dispatch-n [[:wallet/get-accounts]]}
(not (:universal-links/handling db))
(assoc :effects.chat/open-last-chat (get-in db [:profile/profile :key-uid]))
notifications-enabled?
(assoc :effects/push-notifications-enable nil))
(contacts/initialize-contacts)
(browser/initialize-browser)
(mobile-network/on-network-status-change)
(group-chats/get-group-chat-invitations)
(profile.settings.events/get-profile-picture)
(profile.settings.events/change-preview-privacy)
(link-preview/request-link-preview-whitelist)
(visibility-status-updates-store/fetch-visibility-status-updates-rpc)
(switcher-cards-store/fetch-switcher-cards-rpc))))
(rf/merge cofx
(cond-> {:json-rpc/call [{:method "wakuext_startMessenger"
:on-success #(re-frame/dispatch [:messenger-started %])
:on-error #(log/error "failed to start messenger")}]
:wallet-legacy/initialize-transactions-management-enabled nil
:wallet-legacy/initialize-wallet
[network-id
current-network-config
(fn [accounts tokens custom-tokens favourites]
(re-frame/dispatch [:wallet-legacy/initialize-wallet
accounts tokens custom-tokens favourites]))]
:check-eip1559-activation {:network-id network-id}}
(not (:universal-links/handling db))
(assoc :effects.chat/open-last-chat (get-in db [:profile/profile :key-uid]))
notifications-enabled?
(assoc :effects/push-notifications-enable nil))
(contacts/initialize-contacts)
(browser/initialize-browser)
(mobile-network/on-network-status-change)
(group-chats/get-group-chat-invitations)
(profile.settings.events/get-profile-picture)
(profile.settings.events/change-preview-privacy)
(link-preview/request-link-preview-whitelist)
(visibility-status-updates-store/fetch-visibility-status-updates-rpc)
(switcher-cards-store/fetch-switcher-cards-rpc))))
(rf/defn messenger-started
{:events [:messenger-started]}
@@ -178,7 +178,6 @@
[status-im2.contexts.quo-preview.wallet.network-link :as network-link]
[status-im2.contexts.quo-preview.wallet.network-routing :as network-routing]
[status-im2.contexts.quo-preview.wallet.progress-bar :as progress-bar]
[status-im2.contexts.quo-preview.wallet.required-tokens :as required-tokens]
[status-im2.contexts.quo-preview.wallet.summary-info :as summary-info]
[status-im2.contexts.quo-preview.wallet.token-input :as token-input]
[status-im2.contexts.quo-preview.wallet.transaction-progress :as transaction-progress]
@@ -478,8 +477,6 @@
{:name :network-link :component network-link/view}
{:name :network-routing :component network-routing/view}
{:name :progress-bar :component progress-bar/view}
{:name :required-tokens
:component required-tokens/view}
{:name :summary-info :component summary-info/view}
{:name :token-input :component token-input/view}
{:name :wallet-activity :component wallet-activity/view}
@@ -5,7 +5,6 @@
[quo.core :as quo]
[quo.foundations.colors :as colors]
[quo.theme :as quo.theme]
[re-frame.core :as rf]
[react-native.blur :as blur]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
@@ -321,10 +320,9 @@
[{:keys [title state descriptor blur? blur-dark-only?
component-container-style
blur-container-style blur-view-props blur-height show-blur-background?]
:or {blur-height 200}}
:or {blur-height 200 title "quo component"}}
& children]
(let [theme (quo.theme/use-theme-value)
title (or title @(rf/subscribe [:view-id]))]
(let [theme (quo.theme/use-theme-value)]
(rn/use-effect (fn []
(when blur-dark-only?
(if blur?
@@ -8,7 +8,8 @@
(def mock-data
[{:id 1
:type types/item
:data {:image (resources/get-mock-image :diamond)
:data {:on-press (println "pressed")
:image (resources/get-mock-image :diamond)
:image-size 21
:right-icon :i/world
:title "Trip to Bahamas"}}
@@ -1,47 +0,0 @@
(ns status-im2.contexts.quo-preview.wallet.required-tokens
(:require
[quo.core :as quo]
[reagent.core :as reagent]
[status-im2.common.resources :as resources]
[status-im2.contexts.quo-preview.preview :as preview]))
(def descriptor
[{:key :type
:type :select
:options [{:key :token}
{:key :collectible}]}
{:key :divider?
:type :boolean}])
(def token-descriptor
[{:key :amount
:type :text}
{:key :token
:type :select
:options [{:key "SNT"}
{:key "ETH"}]}])
(def collectible-descriptor
[{:key :collectible-name
:type :text}])
(defn view
[]
(let
[state
(reagent/atom
{:type :token
:collectible-img-src (resources/mock-images :collectible)
:collectible-name "Collectible name"
:token "SNT"
:amount "100"
:divider? false})]
(fn []
[preview/preview-container
{:state state
:descriptor (concat descriptor
(case (:type @state)
:token token-descriptor
:collectible collectible-descriptor
nil))}
[quo/required-tokens @state]])))
@@ -33,6 +33,10 @@
(assoc :test-ID stack-id
:icon icon
:icon-color-anim icon-color
;NOTE temporary use of on long press while we support old wallet
:on-long-press #(when (= stack-id :wallet-stack)
(swap! state/load-new-wallet? not)
(animation/bottom-tab-on-press stack-id true))
:on-press #(animation/bottom-tab-on-press stack-id true)
:accessibility-label (str (name stack-id) "-tab")
:customization-color customization-color))]))
@@ -3,6 +3,7 @@
[quo.theme :as quo.theme]
[react-native.reanimated :as reanimated]
[status-im.ui.screens.browser.stack :as browser.stack]
[status-im.ui.screens.wallet.accounts.views :as wallet.accounts]
[status-im2.contexts.chat.home.view :as chat]
[status-im2.contexts.communities.home.view :as communities]
[status-im2.contexts.shell.jump-to.components.home-stack.style :as style]
@@ -31,7 +32,10 @@
(case stack-id
:communities-stack [:f> communities/view]
:chats-stack [:f> chat/view]
:wallet-stack [wallet-new/view]
;NOTE temporary while we support old wallet
:wallet-stack (if @state/load-new-wallet?
[wallet-new/view]
[wallet.accounts/accounts-overview-old])
:browser-stack [browser.stack/browser-stack]
[:<>])])
@@ -8,7 +8,6 @@
[react-native.linear-gradient :as linear-gradient]
[react-native.safe-area :as safe-area]
[status-im2.common.home.top-nav.view :as common.top-nav]
[status-im2.constants :as constants]
[status-im2.contexts.shell.jump-to.components.bottom-tabs.view :as bottom-tabs]
[status-im2.contexts.shell.jump-to.components.jump-to-screen.style :as style]
[status-im2.contexts.shell.jump-to.components.switcher-cards.view :as switcher-cards]
@@ -42,13 +41,11 @@
(defn jump-to-text
[]
(let [testnet-enabled? (rf/sub [:profile/testnet-enabled?])]
[quo/text
{:size :heading-1
:weight :semi-bold
:style (style/jump-to-text (+ (safe-area/get-top)
(when testnet-enabled? constants/testnet-banner-height)))}
(i18n/label :t/jump-to)]))
[quo/text
{:size :heading-1
:weight :semi-bold
:style (style/jump-to-text (safe-area/get-top))}
(i18n/label :t/jump-to)])
(defn render-card
[{:keys [type screen-id] :as card}]
@@ -99,11 +96,10 @@
(defn view
[]
(let [testnet-enabled? (rf/sub [:profile/testnet-enabled?])
switcher-cards (rf/sub [:shell/sorted-switcher-cards])
width (rf/sub [:dimensions/window-width])
top (+ (safe-area/get-top) (when testnet-enabled? constants/testnet-banner-height))
shell-margin (/ (- width (* 2 shell.constants/switcher-card-size)) 3)]
(let [switcher-cards (rf/sub [:shell/sorted-switcher-cards])
width (rf/sub [:dimensions/window-width])
top (safe-area/get-top)
shell-margin (/ (- width (* 2 shell.constants/switcher-card-size)) 3)]
[theme/provider {:theme :dark}
[rn/view
{:style {:top 0
@@ -17,3 +17,5 @@
(def load-chats-stack? (reagent/atom false))
(def load-wallet-stack? (reagent/atom false))
(def load-browser-stack? (reagent/atom false))
;NOTE temporary while we support old wallet
(def load-new-wallet? (reagent/atom true))
@@ -2,8 +2,6 @@
(:require
[quo.core :as quo]
[react-native.core :as rn]
[react-native.platform :as platform]
[react-native.share :as share]
[status-im2.contexts.profile.utils :as profile.utils]
[status-im2.contexts.wallet.account.tabs.about.style :as style]
[utils.i18n :as i18n]
@@ -11,51 +9,35 @@
(defn about-options
[]
(let [{:keys [address] :as account} (rf/sub [:wallet/current-viewing-account])
share-title (str (:name account) " " (i18n/label :t/address))]
[quo/action-drawer
[[{:icon :i/link
:accessibility-label :view-on-eth
:label (i18n/label :t/view-on-eth)
:right-icon :i/external}
{:icon :i/link
:accessibility-label :view-on-opt
:label (i18n/label :t/view-on-opt)
:right-icon :i/external}
{:icon :i/link
:accessibility-label :view-on-arb
:label (i18n/label :t/view-on-arb)
:right-icon :i/external}
{:icon :i/copy
:accessibility-label :copy-address
:label (i18n/label :t/copy-address)}
{:icon :i/qr-code
:accessibility-label :show-address-qr
:label (i18n/label :t/show-address-qr)}
{:icon :i/share
:accessibility-label :share-address
:label (i18n/label :t/share-address)
:on-press (fn []
(rf/dispatch [:hide-bottom-sheet])
(js/setTimeout
#(share/open
(if platform/ios?
{:activityItemSources [{:placeholderItem {:type "text"
:content address}
:item {:default {:type "text"
:content
address}}
:linkMetadata {:title share-title}}]}
{:title share-title
:subject share-title
:message address}))
600))}]]]))
[quo/action-drawer
[[{:icon :i/link
:accessibility-label :view-on-eth
:label (i18n/label :t/view-on-eth)
:right-icon :i/external}
{:icon :i/link
:accessibility-label :view-on-opt
:label (i18n/label :t/view-on-opt)
:right-icon :i/external}
{:icon :i/link
:accessibility-label :view-on-arb
:label (i18n/label :t/view-on-arb)
:right-icon :i/external}
{:icon :i/copy
:accessibility-label :copy-address
:label (i18n/label :t/copy-address)}
{:icon :i/qr-code
:accessibility-label :show-address-qr
:label (i18n/label :t/show-address-qr)}
{:icon :i/share
:accessibility-label :share-address
:label (i18n/label :t/share-address)}]]])
(defn view
[]
(let [{:keys [customization-color] :as profile} (rf/sub [:profile/profile-with-image])
{:keys [address path watch-only?]} (rf/sub [:wallet/current-viewing-account])
networks (rf/sub [:wallet/network-details])]
{:keys [type address path]} (rf/sub [:wallet/current-viewing-account])
networks (rf/sub [:wallet/network-details])
watch-only? (= type :watch)]
[rn/view {:style style/about-tab}
[quo/data-item
{:description :default
@@ -16,7 +16,6 @@
(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]
@@ -35,12 +35,12 @@
[]
(let [selected-tab (reagent/atom first-tab-id)]
(fn []
(let [{:keys [name color balance watch-only?]} (rf/sub [:wallet/current-viewing-account])
currency-symbol (rf/sub [:profile/currency-symbol])]
(let [{:keys [name color balance type]} (rf/sub [:wallet/current-viewing-account])
watch-only? (= type :watch)]
[rn/view {:style {:flex 1}}
[account-switcher/view {:on-press #(rf/dispatch [:wallet/close-account-page])}]
[quo/account-overview
{:current-value (utils/prettify-balance currency-symbol balance)
{:current-value (utils/prettify-balance balance)
:account-name name
:account (if watch-only? :watched-address :default)
:customization-color color}]
@@ -1,26 +1,14 @@
(ns status-im2.contexts.wallet.common.account-switcher.view
(:require [quo.core :as quo]
[status-im2.contexts.wallet.common.sheets.account-options.view :as account-options]
[status-im2.contexts.wallet.common.sheets.select-account.view :as select-account]
[utils.re-frame :as rf]))
(defn get-bottom-sheet-args
[switcher-type]
(case switcher-type
:account-options {:content account-options/view
:hide-handle? true}
:select-account {:content select-account/view}
nil))
(defn view
[{:keys [on-press accessibility-label icon-name switcher-type]
:or {icon-name :i/close
accessibility-label :top-bar
switcher-type :account-options}}]
[{:keys [on-press accessibility-label] :or {accessibility-label :top-bar}}]
(let [{:keys [color emoji]} (rf/sub [:wallet/current-viewing-account])
networks (rf/sub [:wallet/network-details])]
[quo/page-nav
{:icon-name icon-name
{:icon-name :i/close
:background :blur
:on-press on-press
:accessibility-label accessibility-label
@@ -29,5 +17,6 @@
:right-side :account-switcher
:account-switcher {:customization-color color
:on-press #(rf/dispatch [:show-bottom-sheet
(get-bottom-sheet-args switcher-type)])
{:content account-options/view
:hide-handle? true}])
:emoji emoji}}]))
@@ -1,4 +0,0 @@
(ns status-im2.contexts.wallet.common.sheets.select-account.style)
(def list-container
{:margin-horizontal 8})
@@ -1,33 +0,0 @@
(ns status-im2.contexts.wallet.common.sheets.select-account.view
(:require [quo.core :as quo]
quo.theme
[react-native.gesture :as gesture]
[status-im2.contexts.wallet.common.sheets.select-account.style :as style]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn- render-account-item
[{:keys [color address] :as account} _ _ {:keys [selected-account-address]}]
[quo/account-item
{:type :default
:account-props (assoc account :customization-color color)
:customization-color color
:state (if (= address selected-account-address) :selected :default)
:on-press (fn []
(rf/dispatch [:wallet/switch-current-viewing-account address])
(rf/dispatch [:hide-bottom-sheet]))}])
(defn- view-internal
[]
(let [selected-account-address (rf/sub [:wallet/current-viewing-account-address])
accounts (rf/sub [:wallet/accounts-without-watched-accounts])]
[:<>
[quo/drawer-top {:title (i18n/label :t/select-account)}]
[gesture/flat-list
{:data accounts
:render-fn render-account-item
:render-data {:selected-account-address selected-account-address}
:content-container-style style/list-container
:shows-vertical-scroll-indicator false}]]))
(def view (quo.theme/with-theme view-internal))
@@ -9,13 +9,13 @@
(first (string/split full-name #" ")))
(defn prettify-balance
[currency-symbol balance]
[balance]
(let [valid-balance? (and balance
(or (number? balance) (.-toFixed balance)))]
(as-> balance $
(if valid-balance? $ 0)
(.toFixed $ 2)
(str currency-symbol $))))
(str "$" $))))
(defn get-derivation-path
[number-of-accounts]
@@ -60,18 +60,15 @@
(defn total-token-fiat-value
"Returns the total token fiat value taking into account all token's chains."
[currency {:keys [market-values-per-currency] :as token}]
(let [price (get-in market-values-per-currency
[currency :price]
(get-in market-values-per-currency
[constants/profile-default-currency :price]))
[{: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 price)))
(money/crypto->fiat total-units-in-all-chains usd-price)))
(defn calculate-balance-for-account
[currency {:keys [tokens] :as _account}]
[{:keys [tokens] :as _account}]
(->> tokens
(map #(total-token-fiat-value currency %))
(map total-token-fiat-value)
(reduce money/add)))
(defn network-list
+5 -17
View File
@@ -17,11 +17,6 @@
[utils.re-frame :as rf]
[utils.transforms :as types]))
(rf/reg-event-fx
:wallet/hide-token-loading
(fn [{:keys [db]}]
{:db (assoc-in db [:wallet :ui :tokens-loading?] false)}))
(rf/reg-event-fx :wallet/show-account-created-toast
(fn [{:keys [db]} [address]]
(let [account (get-in db [:wallet :accounts address])]
@@ -105,21 +100,14 @@
(let [addresses (->> (get-in db [:wallet :accounts])
vals
(map :address))]
{:db (assoc-in db [:wallet :ui :tokens-loading?] true)
:fx [[:json-rpc/call
{:fx [[:json-rpc/call
[{:method "wallet_getWalletToken"
:params [addresses]
:on-success [:wallet/store-wallet-token]
:on-error [:wallet/get-wallet-token-failed addresses]}]]]})))
(rf/reg-event-fx
:wallet/get-wallet-token-failed
(fn [{:keys [db]} [params error]]
(log/info "failed to get wallet token "
{:error error
:event :wallet/get-wallet-token
:params params})
{:db (assoc-in db [:wallet :ui :tokens-loading?] false)}))
:on-error #(log/info "failed to get wallet token "
{:error %
:event :wallet/get-wallet-token
:params addresses})}]]]})))
(defn- fix-balances-per-chain
[token]
@@ -12,33 +12,12 @@
(fn [_] (val keyval)))))
(def sub-mocks
{:profile/profile {:currency :usd}
:wallet/network-details [{:source 525
:short-name "eth"
:network-name :ethereum
:chain-id 1
:related-chain-id 5}]
:wallet/current-viewing-account {:path "m/44'/60'/0'/0/1"
:emoji "💎"
:key-uid "0x2f5ea39"
:address "0x1"
:wallet false
:name "Account One"
:type :generated
:watch-only? false
:chat false
:test-preferred-chain-ids #{5 420 421613}
:color :purple
:hidden false
:prod-preferred-chain-ids #{1 10 42161}
:network-preferences-names #{:ethereum :arbitrum :optimism}
:position 1
:clock 1698945829328
:created-at 1698928839000
:operable "fully"
:mixedcase-address "0x7bcDfc75c431"
:public-key "0x04371e2d9d66b82f056bc128064"
:removed false}})
{:profile/profile {:currency :usd}
:wallet/network-details [{:source 525
:short-name "eth"
:network-name :ethereum
:chain-id 1
:related-chain-id 5}]})
(h/describe "Send > input amount screen"
(h/test "Default render"
@@ -6,7 +6,6 @@
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
[reagent.core :as reagent]
[status-im2.contexts.wallet.common.account-switcher.view :as account-switcher]
[status-im2.contexts.wallet.send.input-amount.style :as style]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@@ -102,10 +101,14 @@
#(.remove app-keyboard-listener))))
[rn/view
{:style style/screen}
[account-switcher/view
{:icon-name :i/arrow-left
:on-press #(rf/dispatch [:navigate-back])
:switcher-type :select-account}]
[quo/page-nav
{:background :blur
:icon-name :i/arrow-left
:on-press #(rf/dispatch [:navigate-back])
:right-side :account-switcher
:account-switcher {:customization-color :yellow
:emoji "🎮"
:on-press #(js/alert "Switch account")}}]
[quo/token-input
{:container-style style/input-container
:token token
@@ -128,9 +128,7 @@
{:content-container-style style/container
:keyboard-should-persist-taps :handled
:scroll-enabled false}
[account-switcher/view
{:on-press on-close
:switcher-type :select-account}]
[account-switcher/view {:on-press on-close}]
[quo/text-combinations
{:title (i18n/label :t/send-to)
:container-style style/title-container
@@ -20,7 +20,7 @@
(let [on-press #(js/alert "Not implemented yet")
total-balance-formatted (.toFixed (:total-balance token) 2)
balance-fiat-formatted (.toFixed (:total-balance-fiat token) 2)
currency-symbol (rf/sub [:profile/currency-symbol])]
currency-symbol "$"]
[quo/token-network
{:token (:symbol token)
:label (:name token)
@@ -75,10 +75,7 @@
{:content-container-style {:flex 1}
:keyboard-should-persist-taps :handled
:scroll-enabled false}
[account-switcher/view
{:icon-name :i/arrow-left
:on-press on-close
:switcher-type :select-account}]
[account-switcher/view {:on-press on-close}]
[quo/text-combinations
{:title (i18n/label :t/select-asset)
:container-style style/title-container
-1
View File
@@ -11,7 +11,6 @@
status-im2.common.theme.events
[status-im2.common.toasts.events]
[status-im2.contexts.add-new-contact.events]
status-im2.contexts.chat.composer.events
status-im2.contexts.chat.events
status-im2.contexts.chat.photo-selector.events
status-im2.contexts.communities.overview.events
+21 -25
View File
@@ -81,8 +81,7 @@
(def transparent-screen-options
(merge
{:show-blur? true
:modalPresentationStyle :overCurrentContext
{:modalPresentationStyle :overCurrentContext
:theme :dark
:layout {:componentBackgroundColor :transparent
:orientation ["portrait"]
@@ -113,29 +112,26 @@
:backgroundColor colors/neutral-95}}))
(def lightbox
{:hide-testnet-banner? true
:topBar {:visible false}
:statusBar {:backgroundColor :transparent
:style :light
:animate true
:drawBehind true
:translucent true}
:navigationBar {:backgroundColor colors/neutral-100}
:layout {:componentBackgroundColor :transparent
:backgroundColor :transparent
;; issue: https://github.com/wix/react-native-navigation/issues/7726
:orientation (if platform/ios?
["portrait" "landscape"]
["portrait"])}
:animations {:push {:sharedElementTransitions [{:fromId :shared-element
:toId :shared-element
:interpolation {:type :decelerate
:factor 1.5}}]}
:pop {:sharedElementTransitions [{:fromId :shared-element
:toId :shared-element
:interpolation {:type
:decelerate
:factor 1.5}}]}}})
{:topBar {:visible false}
:statusBar {:backgroundColor :transparent
:style :light
:animate true
:drawBehind true
:translucent true}
:navigationBar {:backgroundColor colors/neutral-100}
:layout {:componentBackgroundColor :transparent
:backgroundColor :transparent
;; issue: https://github.com/wix/react-native-navigation/issues/7726
:orientation (if platform/ios? ["portrait" "landscape"] ["portrait"])}
:animations {:push {:sharedElementTransitions [{:fromId :shared-element
:toId :shared-element
:interpolation {:type :decelerate
:factor 1.5}}]}
:pop {:sharedElementTransitions [{:fromId :shared-element
:toId :shared-element
:interpolation {:type
:decelerate
:factor 1.5}}]}}})
(def camera-screen
{:navigationBar {:backgroundColor colors/black}})
+9 -64
View File
@@ -1,9 +1,7 @@
(ns status-im2.navigation.view
(:require
[quo.core :as quo]
[quo.foundations.colors :as colors]
[quo.theme :as theme]
[react-native.blur :as blur]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
[reagent.core :as reagent]
@@ -15,10 +13,8 @@
[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]
[status-im2.constants :as constants]
[status-im2.navigation.screens :as screens]
[status-im2.setup.hot-reload :as reloader]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn get-screens
@@ -54,76 +50,25 @@
(when top?
{:padding-top (safe-area/get-top)})))
(defn banner-view-internal
[{:keys [theme show-blur?]}]
[:<>
;; Adding blur for top safe area for screens such as activity center, and scan QR code.
(when show-blur?
[blur/view
{:style {:position :absolute
:top 0
:left 0
:right 0
:height (safe-area/get-top)}
:overlayColor colors/neutral-80-opa-80
:blur-amount 20}])
[rn/view
{:style {:position :absolute
:top 0
:left 0
:right 0
:z-index 1
:padding-top (safe-area/get-top)
:background-color (colors/resolve-color :warning theme 20)}}
[quo/text
{:style {:padding-vertical 11
:height constants/testnet-banner-height
:color (colors/resolve-color :warning theme)
:text-align :center}
:weight :medium
:size :paragraph-2}
(i18n/label :t/testnet-mode-enabled)]]])
(def banner-view (quo.theme/with-theme banner-view-internal))
(defn wrapper-view
[{:keys [component show-blur? hide-testnet-banner?]
:or {hide-testnet-banner? false}}]
(let [testnet-enabled? (rf/sub [:profile/testnet-enabled?])]
[:<>
[rn/view
{:style (cond-> {:flex 1}
testnet-enabled?
(assoc :padding-top constants/testnet-banner-height))}
[component]]
(when (and testnet-enabled? (not hide-testnet-banner?))
[banner-view {:show-blur? show-blur?}])]))
(defn screen
[screen-key]
(reagent.core/reactify-component
(fn []
(let [{:keys [component options]} (get (if js/goog.DEBUG
(get-screens)
screens)
(keyword screen-key))
{:keys [insets sheet? theme show-blur?
hide-testnet-banner?]} options
user-theme (theme/get-theme)
background-color (or (get-in options [:layout :backgroundColor])
(when sheet? :transparent))]
(let [{:keys [component options]} (get (if js/goog.DEBUG
(get-screens)
screens)
(keyword screen-key))
{:keys [insets sheet? theme]} options
user-theme (theme/get-theme)
background-color (or (get-in options [:layout :backgroundColor])
(when sheet? :transparent))]
^{:key (str "root" screen-key @reloader/cnt)}
[theme/provider {:theme (or theme user-theme)}
[rn/view {:style (wrapped-screen-style insets background-color)}
[inactive]
(if sheet?
[bottom-sheet-screen/view {:content component}]
[wrapper-view
{:component component
:show-blur? show-blur?
:hide-testnet-banner? hide-testnet-banner?}])]
[component])]
(when js/goog.DEBUG
[:<>
[reloader/reload-view]
-21
View File
@@ -6,39 +6,18 @@
[re-frame.core :as re-frame]
[status-im.fleet.core :as fleet]
[status-im.multiaccounts.db :as multiaccounts.db]
[status-im.utils.currency :as currency]
[status-im.wallet.utils :as wallet.utils]
[status-im2.constants :as constants]
[utils.address :as address]
[utils.image-server :as image-server]
[utils.security.core :as security]))
(re-frame/reg-sub
:profile/testnet-enabled?
:<- [:multiaccount/logged-in?]
:<- [:profile/profile]
(fn [[logged-in? {:keys [test-networks-enabled?]}]]
(if logged-in? (boolean? test-networks-enabled?) false)))
(re-frame/reg-sub
:profile/customization-color
:<- [:profile/profile]
(fn [{:keys [customization-color]}]
(or customization-color constants/profile-default-color)))
(re-frame/reg-sub
:profile/currency
:<- [:profile/profile]
(fn [{:keys [currency]}]
(or currency constants/profile-default-currency)))
(re-frame/reg-sub
:profile/currency-symbol
:<- [:profile/currency]
(fn [currency-id]
(-> (get currency/currencies currency-id)
:symbol)))
(re-frame/reg-sub
:profile/onboarding-placeholder-avatar
:<- [:mediaserver/port]
-114
View File
@@ -1,114 +0,0 @@
(ns status-im2.subs.profile-test
(:require [cljs.test :refer [is testing use-fixtures]]
[re-frame.db :as rf-db]
status-im2.subs.root
[test-helpers.unit :as h]
[utils.re-frame :as rf]))
(use-fixtures :each
{:before #(reset! rf-db/app-db {})})
(def sample-profile
{:keycard-pairing nil
:send-push-notifications? true
:send-status-updates? true
:key-uid "0x2285f5c1ffd94ade0aa3568bff85f6c06f2860391ba65ccf56276cbc6829a22a"
:backup-enabled? true
:address "0x70F8913fbE0Ca5687F1Fb73068944d6e99B27804"
:mnemonic "lucky veteran business source debris large priority color endless answer strong pave"
:preview-privacy? true
:identicon ""
:use-mailservers? true
:signing-phrase "polo rush vest"
:url-unfurling-mode 1
:custom-bootnodes-enabled? {}
:log-level "INFO"
:profile-pictures-visibility 2
:messages-from-contacts-only false
:pinned-mailservers {}
:eip1581-address "0x15636c0aa4036b9f984e8998db085328795b26d8"
:images [{:keyUid "0x2285f5c1ffd94ade0aa3568bff85f6c06f2860391ba65ccf56276cbc6829a22a"
:type "large"
:uri "data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwcJC="
:width 240
:height 240
:fileSize 15973
:resizeTarget 240
:clock 0}
{:keyUid "0x2285f5c1ffd94ade0aa3568bff85f6c06f2860391ba65ccf56276cbc6829a22a"
:type "thumbnail"
:uri "data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwcJC="
:width 80
:height 240
:fileSize 2558
:resizeTarget 80
:clock 0}]
:name "Plush Shiny Songbird"
:latest-derived-path 0
:compressed-key "zQ3shS6tp3NsQT4RSUFtnTqnBQzC5kt2SZzxZmnPEiNkHetwj"
:wallet-legacy/visible-tokens {:mainnet #{:SNT}}
:kdfIterations 3200
:ens-name? false
:emoji-hash ["👮" "🧑🏿‍🏭" "📬" "👰‍♀️" "🦚" "💳" "👨🏿‍🍳" "☝️" "🤰🏾" "🍊" "☁️" "☔" "👷🏽" "🤹🏾"]
:wallet-root-address "0x704c9a261b918cb8e522f7fc2bc477c12d0c74ac"
:last-backup 1701832050
:link-previews-enabled-sites #{}
:networks/networks {}
:wakuv2-config {:Port 0
:DataDir ""
:LightClient true
:AutoUpdate true
:MaxMessageSize 0
:KeepAliveInterval 0
:Nameserver ""
:UseShardAsDefaultTopic false
:PeerExchange true
:StoreCapacity 0
:UDPPort 0
:EnableStore false
:EnableFilterFullNode false
:Enabled true
:EnableConfirmations false
:Host "0.0.0.0"
:CustomNodes {}
:FullNode false
:EnableDiscV5 true
:DiscoveryLimit 20
:StoreSeconds 0}
:current-user-visibility-status {:clock 1701798568
:text ""
:status-type 1}
:gifs/api-key ""
:currency :usd
:gifs/favorite-gifs nil
:customization-color :magenta
:default-sync-period 777600
:photo-path ""
:dapps-address "0x52fB56556A039244CED121AFB9ec829788Db78c8"
:custom-bootnodes {}
:display-name "Alisher Y"
:gifs/recent-gifs nil
:appearance 0
:link-preview-request-enabled true
:profile-pictures-show-to 2
:timestamp 1701798892
:device-name ""
:colorId 2
:networks/current-network "mainnet_rpc"
:mutual-contact-enabled? false
:public-key
"0x0445b4d3a20f9fcf95b9e669857f83a073e7fdb7b79d0ac03ffb601d6889c413fa86282a2b2bed46ecf7d499807c1567549367a4eaa2b7b925067d44562d93cfa6"
:colorHash [[3 25] [4 3] [5 4] [2 0] [1 10] [5 2] [2 4] [1 17] [3 23] [2 19] [4 1]]
:installation-id "cee7e269-1ca7-4468-a1dd-e60e5cfb0894"})
(h/deftest-sub :profile/currency
[sub-name]
(testing "returns the selected currency of user"
(swap! rf-db/app-db #(assoc % :profile/profile sample-profile))
(is (match? :usd (rf/sub [sub-name])))))
(h/deftest-sub :profile/currency-symbol
[sub-name]
(testing "returns the symbol of the user's selected currency"
(swap! rf-db/app-db #(assoc % :profile/profile sample-profile))
(is (match? "$" (rf/sub [sub-name])))))
+27 -37
View File
@@ -1,7 +1,6 @@
(ns status-im2.subs.wallet.wallet
(:require [clojure.string :as string]
[re-frame.core :as rf]
[status-im2.constants :as constants]
[status-im2.contexts.wallet.common.utils :as utils]
[utils.number]))
@@ -70,25 +69,23 @@
(rf/reg-sub
:wallet/balances
:<- [:wallet/accounts]
:<- [:profile/currency]
(fn [[accounts currency]]
(fn [accounts]
(zipmap (map :address accounts)
(map #(utils/calculate-balance-for-account currency %) accounts))))
(map utils/calculate-balance-for-account accounts))))
(rf/reg-sub
:wallet/account-cards-data
:<- [:wallet/accounts]
:<- [:wallet/balances]
:<- [:wallet/tokens-loading?]
:<- [:profile/currency-symbol]
(fn [[accounts balances tokens-loading? currency-symbol]]
(mapv (fn [{:keys [color address watch-only?] :as account}]
(fn [[accounts balances tokens-loading?]]
(mapv (fn [{:keys [color address type] :as account}]
(assoc account
:customization-color color
:type (if watch-only? :watch-only :empty)
:type (if (= type :watch) :watch-only :empty)
:on-press #(rf/dispatch [:wallet/navigate-to-account address])
:loading? tokens-loading?
:balance (utils/prettify-balance currency-symbol (get balances address))))
:balance (utils/prettify-balance (get balances address))))
accounts)))
(rf/reg-sub
@@ -127,39 +124,32 @@
(fn [[accounts current-viewing-account-address]]
(remove #(= (:address %) current-viewing-account-address) accounts)))
(rf/reg-sub
:wallet/accounts-without-watched-accounts
:<- [:wallet/accounts]
(fn [accounts]
(remove #(:watch-only? %) accounts)))
(defn- calc-token-value
[{:keys [market-values-per-currency] :as token} color currency currency-symbol]
(let [token-units (utils/total-token-units-in-all-chains token)
fiat-value (utils/total-token-fiat-value currency token)
market-values (get market-values-per-currency
currency
(get market-values-per-currency
constants/profile-default-currency))
{:keys [change-pct-24hour]} market-values]
{:token (:symbol token)
:token-name (:name token)
:state :default
:status (cond
(pos? change-pct-24hour) :positive
(neg? change-pct-24hour) :negative
:else :empty)
:customization-color color
:values {:crypto-value token-units
:fiat-value (utils/prettify-balance currency-symbol fiat-value)}}))
[{:keys [market-values-per-currency] :as item} chain-id]
(let [crypto-value (utils/token-value-in-chain item chain-id)
market-values (:usd market-values-per-currency)
{:keys [price change-pct-24hour]} market-values
fiat-change (utils/calculate-fiat-change crypto-value change-pct-24hour)]
(when (and crypto-value (seq (:name item)))
{:token (keyword (string/lower-case (:symbol item)))
:token-name (:name item)
:state :default
:status (cond
(pos? change-pct-24hour) :positive
(neg? change-pct-24hour) :negative
:else :empty)
:customization-color :blue
:values {:crypto-value crypto-value
:fiat-value (utils/prettify-balance (* crypto-value price))
:percentage-change (.toFixed change-pct-24hour 2)
:fiat-change (utils/prettify-balance fiat-change)}})))
(rf/reg-sub
:wallet/account-token-values
:<- [:wallet/current-viewing-account]
:<- [:profile/currency]
:<- [:profile/currency-symbol]
(fn [[{:keys [tokens color]} currency currency-symbol]]
(mapv #(calc-token-value % color currency currency-symbol) tokens)))
:<- [:chain-id]
(fn [[current-account chain-id]]
(mapv #(calc-token-value % chain-id) (:tokens current-account))))
(rf/reg-sub
:wallet/network-preference-details
+78 -221
View File
@@ -40,22 +40,6 @@
3 {:raw-balance (money/bignumber "<nil>") :has-error false}}
:market-values-per-currency {:usd {:price 1000}}}])
(def tokens-0x3
[{:decimals 3
:symbol "ETH"
:name "Ether"
:balances-per-chain {1 {:raw-balance (money/bignumber "5000") :has-error false}
2 {:raw-balance (money/bignumber "2000") :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 (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
{"0x1" {:path "m/44'/60'/0'/0/0"
:emoji "😃"
@@ -64,7 +48,6 @@
:wallet false
:name "Account One"
:type :generated
:watch-only? false
:chat false
:test-preferred-chain-ids #{5 420 421613}
:color :blue
@@ -85,7 +68,6 @@
:wallet false
:name "Account Two"
:type :generated
:watch-only? false
:chat false
:test-preferred-chain-ids #{5 420 421613}
:color :purple
@@ -98,28 +80,7 @@
:mixedcase-address "0x7bcDfc75c431"
:public-key "0x04371e2d9d66b82f056bc128064"
:removed false
:tokens tokens-0x2}
"0x3" {:path ""
:emoji "🎉"
:key-uid "0x2f5ea39"
:address "0x3"
:wallet false
:name "Watched Account 1"
:type :watch
:watch-only? true
:chat false
:test-preferred-chain-ids #{0}
:color :magenta
:hidden false
:prod-preferred-chain-ids #{0}
:position 2
:clock 1698945829328
:created-at 1698928839000
:operable "fully"
:mixedcase-address "0x7bcDfc75c431"
:public-key "0x"
:removed false
:tokens tokens-0x3}})
:tokens tokens-0x2}})
(def network-data
{:test [{:test? true
@@ -154,12 +115,10 @@
(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)
balance-0x3 (money/bignumber 2400)]
balance-0x2 (money/bignumber 2100)]
(is (money/equal-to balance-0x1 (get result "0x1")))
(is (money/equal-to balance-0x2 (get result "0x2")))
(is (money/equal-to balance-0x3 (get result "0x3"))))))
(is (money/equal-to balance-0x2 (get result "0x2"))))))
(h/deftest-sub :wallet/accounts
[sub-name]
@@ -169,81 +128,55 @@
(assoc-in [:wallet :accounts] accounts)
(assoc :wallet/networks network-data)))
(is
(=
(list {:path "m/44'/60'/0'/0/0"
:emoji "😃"
:key-uid "0x2f5ea39"
:address "0x1"
:wallet false
:name "Account One"
:type :generated
:watch-only? false
:chat false
:test-preferred-chain-ids #{5 420 421613}
:color :blue
:hidden false
:prod-preferred-chain-ids #{1 10 42161}
:network-preferences-names #{:ethereum :arbitrum :optimism}
:position 0
:clock 1698945829328
:created-at 1698928839000
:operable "fully"
:mixedcase-address "0x7bcDfc75c431"
:public-key "0x04371e2d9d66b82f056bc128064"
:removed false
:tokens tokens-0x1}
{:path "m/44'/60'/0'/0/1"
:emoji "💎"
:key-uid "0x2f5ea39"
:address "0x2"
:wallet false
:name "Account Two"
:type :generated
:watch-only? false
:chat false
:test-preferred-chain-ids #{5 420 421613}
:color :purple
:hidden false
:prod-preferred-chain-ids #{1 10 42161}
:network-preferences-names #{:ethereum :arbitrum :optimism}
:position 1
:clock 1698945829328
:created-at 1698928839000
:operable "fully"
:mixedcase-address "0x7bcDfc75c431"
:public-key "0x04371e2d9d66b82f056bc128064"
:removed false
:tokens tokens-0x2}
{:path ""
:emoji "🎉"
:key-uid "0x2f5ea39"
:address "0x3"
:wallet false
:name "Watched Account 1"
:type :watch
:watch-only? true
:chat false
:test-preferred-chain-ids #{0}
:color :magenta
:hidden false
:prod-preferred-chain-ids #{0}
:network-preferences-names #{}
:position 2
:clock 1698945829328
:created-at 1698928839000
:operable "fully"
:mixedcase-address "0x7bcDfc75c431"
:public-key "0x"
:removed false
:tokens tokens-0x3})
(rf/sub [sub-name])))))
(= (list {: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}
:network-preferences-names #{:ethereum :arbitrum :optimism}
:position 0
:clock 1698945829328
:created-at 1698928839000
:operable "fully"
:mixedcase-address "0x7bcDfc75c431"
:public-key "0x04371e2d9d66b82f056bc128064"
:removed false
:tokens tokens-0x1}
{:path "m/44'/60'/0'/0/1"
:emoji "💎"
:key-uid "0x2f5ea39"
:address "0x2"
:wallet false
:name "Account Two"
:type :generated
:chat false
:test-preferred-chain-ids #{5 420 421613}
:color :purple
:hidden false
:prod-preferred-chain-ids #{1 10 42161}
:network-preferences-names #{:ethereum :arbitrum :optimism}
:position 1
:clock 1698945829328
:created-at 1698928839000
:operable "fully"
:mixedcase-address "0x7bcDfc75c431"
:public-key "0x04371e2d9d66b82f056bc128064"
:removed false
:tokens tokens-0x2})
(rf/sub [sub-name])))))
(h/deftest-sub :wallet/current-viewing-account-address
[sub-name]
(testing "returns the address of the current viewing account"
(let [viewing-address "0x1"]
(swap! rf-db/app-db #(assoc-in % [:wallet :current-viewing-account-address] viewing-address))
(is (match? viewing-address (rf/sub [sub-name]))))))
(testing "returns current viewing account address"
(swap! rf-db/app-db #(assoc-in % [:wallet :current-viewing-account-address] "0x1"))
(is (= "0x1" (rf/sub [sub-name])))))
(h/deftest-sub :wallet/current-viewing-account
[sub-name]
@@ -253,7 +186,6 @@
(assoc-in [:wallet :accounts] accounts)
(assoc-in [:wallet :current-viewing-account-address] "0x1")
(assoc :wallet/networks network-data)))
(let [result (rf/sub [sub-name])]
(is
(= {:path "m/44'/60'/0'/0/0"
@@ -263,7 +195,6 @@
:wallet false
:name "Account One"
:type :generated
:watch-only? false
:chat false
:test-preferred-chain-ids #{5 420 421613}
:color :blue
@@ -285,22 +216,26 @@
(h/deftest-sub :wallet/addresses
[sub-name]
(testing "returns all addresses"
(swap! rf-db/app-db #(assoc-in % [:wallet :accounts] accounts))
(is (match? #{"0x1" "0x2" "0x3"}
(rf/sub [sub-name])))))
(swap! rf-db/app-db
#(-> %
(assoc-in [:wallet :accounts] accounts)
(assoc-in [:wallet :current-viewing-account-address] "0x1")))
(is
(= (set ["0x1" "0x2"])
(rf/sub [sub-name])))))
(h/deftest-sub :wallet/watch-address-activity-state
[sub-name]
(testing "watch address activity state with nil value"
(is (nil? (rf/sub [sub-name]))))
(is (= nil (rf/sub [sub-name]))))
(testing "watch address activity state with no-activity value"
(swap! rf-db/app-db #(assoc-in % [:wallet :ui :watch-address-activity-state] :no-activity))
(is (match? :no-activity (rf/sub [sub-name]))))
(is (= :no-activity (rf/sub [sub-name]))))
(testing "watch address activity state with has-activity value"
(swap! rf-db/app-db #(assoc-in % [:wallet :ui :watch-address-activity-state] :has-activity))
(is (match? :has-activity (rf/sub [sub-name])))))
(is (= :has-activity (rf/sub [sub-name])))))
(h/deftest-sub :wallet/accounts-without-current-viewing-account
[sub-name]
@@ -319,7 +254,6 @@
:wallet false
:name "Account One"
:type :generated
:watch-only? false
:chat false
:test-preferred-chain-ids #{5 420 421613}
:color :blue
@@ -333,84 +267,7 @@
:mixedcase-address "0x7bcDfc75c431"
:public-key "0x04371e2d9d66b82f056bc128064"
:removed false
:tokens tokens-0x1}
{:path ""
:emoji "🎉"
:key-uid "0x2f5ea39"
:address "0x3"
:wallet false
:name "Watched Account 1"
:type :watch
:watch-only? true
:chat false
:test-preferred-chain-ids #{0}
:color :magenta
:hidden false
:prod-preferred-chain-ids #{0}
:network-preferences-names #{}
:position 2
:clock 1698945829328
:created-at 1698928839000
:operable "fully"
:mixedcase-address "0x7bcDfc75c431"
:public-key "0x"
:removed false
:tokens tokens-0x3})
(rf/sub [sub-name])))))
(h/deftest-sub :wallet/accounts-without-watched-accounts
[sub-name]
(testing "returns the accounts list without the watched accounts in it"
(swap! rf-db/app-db
#(-> %
(assoc-in [:wallet :accounts] accounts)
(assoc :wallet/networks network-data)))
(is
(= (list
{:path "m/44'/60'/0'/0/0"
:emoji "😃"
:key-uid "0x2f5ea39"
:address "0x1"
:wallet false
:name "Account One"
:type :generated
:watch-only? false
:chat false
:test-preferred-chain-ids #{5 420 421613}
:color :blue
:hidden false
:prod-preferred-chain-ids #{1 10 42161}
:network-preferences-names #{:ethereum :arbitrum :optimism}
:position 0
:clock 1698945829328
:created-at 1698928839000
:operable "fully"
:mixedcase-address "0x7bcDfc75c431"
:public-key "0x04371e2d9d66b82f056bc128064"
:removed false
:tokens tokens-0x1}
{:path "m/44'/60'/0'/0/1"
:emoji "💎"
:key-uid "0x2f5ea39"
:address "0x2"
:wallet false
:name "Account Two"
:type :generated
:watch-only? false
:chat false
:test-preferred-chain-ids #{5 420 421613}
:color :purple
:hidden false
:prod-preferred-chain-ids #{1 10 42161}
:network-preferences-names #{:ethereum :arbitrum :optimism}
:position 1
:clock 1698945829328
:created-at 1698928839000
:operable "fully"
:mixedcase-address "0x7bcDfc75c431"
:public-key "0x04371e2d9d66b82f056bc128064"
:removed false
:tokens tokens-0x2})
:tokens tokens-0x1})
(rf/sub [sub-name])))))
(h/deftest-sub :wallet/network-preference-details
@@ -422,21 +279,21 @@
(assoc-in [:wallet :current-viewing-account-address] "0x1")
(assoc :wallet/networks network-data)))
(is
(match? [{:short-name "eth"
:network-name :ethereum
:chain-id 1
:related-chain-id nil
:layer 1}
{:short-name "arb1"
:network-name :arbitrum
:chain-id 42161
:related-chain-id nil
:layer 2}
{:short-name "opt"
:network-name :optimism
:chain-id 10
:related-chain-id nil
:layer 2}]
(->> (rf/sub [sub-name])
;; Removed `#js source` property for correct compare
(map #(dissoc % :source)))))))
(= [{:short-name "eth"
:network-name :ethereum
:chain-id 1
:related-chain-id nil
:layer 1}
{:short-name "arb1"
:network-name :arbitrum
:chain-id 42161
:related-chain-id nil
:layer 2}
{:short-name "opt"
:network-name :optimism
:chain-id 10
:related-chain-id nil
:layer 2}]
(->> (rf/sub [sub-name])
;; Removed `#js source` property for correct compare
(map #(dissoc % :source)))))))
-19
View File
@@ -1,19 +0,0 @@
(ns utils.emojilib
(:require ["emojilib" :as emojis]
[goog.object :as object]
utils.string))
(def lib (.-lib emojis))
(defn get-char
[emoji-id]
(when-let [emoji-map (object/get lib emoji-id)]
(.-char ^js emoji-map)))
(defn text->emoji
"Replaces emojis in a specified `text`"
[text]
(utils.string/safe-replace text
#":([a-z_\-+0-9]*):"
(fn [[original emoji-id]]
(or (get-char emoji-id) original))))
+3 -3
View File
@@ -3,7 +3,7 @@
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
"owner": "status-im",
"repo": "status-go",
"version": "v0.171.31",
"commit-sha1": "271778a1e07e585a12790b4e2226f13e36ea89f4",
"src-sha256": "1c998kyhya98a0zp795i3xrx2r08yjdaifb32ylr4snjjln6k34c"
"version": "chore/storenode-requests-manager",
"commit-sha1": "43d7c93cb6c1aeb414adc3f3f6e6f6e173d98c7a",
"src-sha256": "03va3x6q50kzb2g0kvqyqh3zpix0nlz1v5089sz24hq4k7bidz36"
}
+1 -2
View File
@@ -2429,6 +2429,5 @@
"backup-step-4": "I know I can only see it once",
"reveal-phrase": "Reveal phrase",
"i-have-written": "I have written it down on paper",
"next-you-will": "Next, you will be asked to confirm the position of certain words in your recovery phrase",
"testnet-mode-enabled": "Testnet mode enabled"
"next-you-will": "Next, you will be asked to confirm the position of certain words in your recovery phrase"
}