Compare commits

...
Author SHA1 Message Date
yqrashawn 2800719bfc fix: min pwd length for ::multiaccounts.db/password
https://github.com/status-im/status-go/compare/debfe1ca...debfe1ca

it's used in status-im.common.standard-authentication.enter-password
to decide if confirm button should be disabled

fix #18393

Signed-off-by: yqrashawn <namy.19@gmail.com>
2024-01-11 15:54:48 +08:00
Ulises Manuel 0f43daa836 [#18362] Add support for Reanimated inline styles in Reagent (#18381)
* Modify reanimated/view to support vectors contained in styles
* Add code examples of animated inline styles

Additionally,
*  Fix warning about reactive deref not supported in lazy-seqs
2024-01-10 20:09:32 -06:00
Siddarth Kumar fdfc06d6dd fix: random local make-run ios failures (#18446)
In this commit we build iOS `status-go` for both targets `amd64` and for `arm64` otherwise we get random failures when running `make run-ios`.
Maybe this was an impact of Xcode Upgrade Or RN Upgrade or MacOS Upgrade, it is not clear at the moment.
This will increase the time it took for iOS to be built locally, but it is better to be slow rather than have random build failures.
2024-01-10 22:25:08 +05:30
Brian Sztamfater 162c6dbf89 fix: route not found when attempting to transfer assets to additional eth account (#18325)
Signed-off-by: Brian Sztamfater <brian@status.im>
2024-01-10 12:49:45 -03:00
mmilad75andJamie Caprani da03989c88 Implement about tab on collectible page (#18269)
* add basics

* finalize component

* fix lint issues

* move color to props

* move variants to props

* change file structure

* working

* finalize loader

* fix lint issues

* fix style issues

* add tabs structure

* add basics

* draft codes

* draft

* make codes work after rebase

* fix lint issues

* remove Permissions tab

* revert codes

* finalize code

* fix lint issues

* revert podfile.lock

* create new reg-sub for traits and chain-id

* add real title and description for about tab

* resolve comments

* fix overview tab

* add tests

* resolve comments

---------

Co-authored-by: Jamie Caprani <jamiecaprani@gmail.com>
2024-01-10 18:47:07 +03:30
Yevheniia Berdnyk 433be1daef e2e: fixes 10.01 2024-01-10 16:10:31 +02:00
Mohamed Javid 5a707c0dca Wallet - Initialize event, refactor networks data and bug fix (#18374)
This commit:

- Introduces new event ":wallet/initialize" to group events that need to be called on login
- Refactors wallet networks to use the nested structure in re-frame
- Fixes a bug when updating the testnet network preferences of an account the production network preferences update

---------

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2024-01-10 18:47:24 +05:30
jakub eb53bbe4ec ci: fix handling of Android builds on Apple ARM64
Now that this PR has been merged:

* https://github.com/status-im/status-mobile/pull/16237

We need to handle ARM using an override.

Signed-off-by: Jakub Sokołowski <jakub@status.im>
2024-01-10 13:05:40 +01:00
jakub 257b0684ef nix: fix regex in clean.sh script
Repo used to be called `status-react`.

Signed-off-by: Jakub Sokołowski <jakub@status.im>
2024-01-10 13:05:39 +01:00
40 changed files with 513 additions and 259 deletions
+4 -2
View File
@@ -279,8 +279,9 @@ run-android: ##@run Build Android APK and start it on the device
npx react-native run-android --appIdSuffix debug
SIMULATOR=iPhone 13
# TODO: fix IOS_STATUS_GO_TARGETS to be either amd64 or arm64 when RN is upgraded
run-ios: export TARGET := ios
run-ios: export IOS_STATUS_GO_TARGETS := iossimulator/amd64
run-ios: export IOS_STATUS_GO_TARGETS := ios/arm64,iossimulator/amd64
run-ios: ##@run Build iOS app and start it in a simulator/device
ifneq ("$(SIMULATOR)", "")
npx react-native run-ios --simulator="$(SIMULATOR)" | xcbeautify
@@ -291,8 +292,9 @@ endif
show-ios-devices: ##@other shows connected ios device and its name
xcrun xctrace list devices
# TODO: fix IOS_STATUS_GO_TARGETS to be either amd64 or arm64 when RN is upgraded
run-ios-device: export TARGET := ios
run-ios-device: export IOS_STATUS_GO_TARGETS := ios/arm64
run-ios-device: export IOS_STATUS_GO_TARGETS := ios/arm64,iossimulator/amd64
run-ios-device: ##@run iOS app and start it on a connected device by its name
ifndef DEVICE_NAME
$(error Usage: make run-ios-device DEVICE_NAME=your-device-name)
+26 -9
View File
@@ -21,8 +21,10 @@ pipeline {
/* See nix/README.md */
NIX_IGNORE_SYMLINK_STORE = 1
/* we source .bash_profile to be able to use nix-store */
NIX_SSHOPTS = "-o StrictHostKeyChecking=no source .profile;"
NIX_SSHOPTS = "-oStrictHostKeyChecking=no"
NIX_CONF_DIR = "${env.WORKSPACE}/nix"
NIX_STORE_CMD = '/nix/var/nix/profiles/default/bin/nix-store'
NIX_SSH_REMOTE = "ssh://${params.NIX_CACHE_USER}@${params.NIX_CACHE_HOST}?remote-program=${env.NIX_STORE_CMD}"
}
options {
@@ -42,19 +44,21 @@ pipeline {
steps { script {
nix.shell('nix-env -i openssh', sandbox: false, pure: false)
/* some build targets don't build on MacOS */
os = sh(script: 'uname', returnStdout: true)
arch = sh(script: 'arch', returnStdout: true)
os = sh(script: 'uname', returnStdout: true).trim()
arch = sh(script: 'arch', returnStdout: true).trim()
} }
}
stage('Build status-go') {
steps { script {
def platforms = ['mobile.android', 'mobile.ios', 'library']
if (os != 'Darwin') { platforms.removeAll { it == 'mobile.ios' } }
/* FIXME: Remove this when #16237 is merged. */
/* FIXME: "'x86_64-darwin' with features {} is required to build" */
if (arch == 'arm64') { platforms.removeAll { it == 'mobile.android' } }
platforms.each { os ->
platforms.each { platform ->
/* Allow for Android builds on Apple ARM. */
env.NIXPKGS_SYSTEM_OVERRIDE = nixSysOverride(os, arch, platform)
nix.build(
attr: "targets.status-go.${os}",
attr: "targets.status-go.${platform}",
sandbox: false,
link: false
)
@@ -74,6 +78,8 @@ pipeline {
}
stage('Build android deps') {
steps { script {
/* Allow for Android builds on Apple ARM. */
env.NIXPKGS_SYSTEM_OVERRIDE = nixSysOverride(os, arch, 'android')
/* Build/fetch deps required to build android release. */
nix.build(
attr: 'targets.mobile.android.release.buildInputs',
@@ -86,9 +92,13 @@ pipeline {
stage('Build nix shell deps') {
steps { script {
def shells = ['android', 'ios', 'fastlane', 'keytool', 'clojure', 'gradle']
if (os != "Darwin") { shells.removeAll { it == 'ios' } }
if (os != 'Darwin') { shells.removeAll { it == 'ios' } }
/* FIXME: "'x86_64-darwin' with features {} is required to build" */
if (arch == 'arm64') { shells.removeAll { it == 'android' } }
/* Build/fetch deps required to start default Nix shell. */
shells.each { shell ->
/* Allow for Android builds on Apple ARM. */
env.NIXPKGS_SYSTEM_OVERRIDE = nixSysOverride(os, arch, shell)
nix.build(
attr: "shells.${shell}.buildInputs",
sandbox: false,
@@ -103,8 +113,7 @@ pipeline {
nix.shell("""
find /nix/store/ -mindepth 1 -maxdepth 1 -type d \
-not -name '*.links' -and -not -name '*-status-mobile-*' \
| xargs nix copy \
--to ssh-ng://${params.NIX_CACHE_USER}@${params.NIX_CACHE_HOST}
| xargs nix copy --to ${NIX_SSH_REMOTE}
""",
pure: false
)
@@ -119,3 +128,11 @@ pipeline {
} }
}
}
def nixSysOverride(os, arch, target='android') {
return (
os == 'Darwin' &&
arch == 'arm64' &&
target =~ /.*android$/
) ? 'x86_64-darwin' : ''
}
+1 -1
View File
@@ -89,7 +89,7 @@ if [[ -n "${nixResultPath}" ]]; then
toDelete=$(findByResult "${nixResultPath}")
else
# use regular expression that should match all status-mobile build artifacts
toDelete=$(findByRegex '.*-status-(react|go)-(shell|source|build|patched-npm-gradle-modules).*')
toDelete=$(findByRegex '.*-status-(mobile|go)-(shell|source|build|patched-npm-gradle-modules).*')
fi
# remove duplicates and return
@@ -1,8 +1,7 @@
(ns quo.components.buttons.slide-button.style
(:require
[quo.components.buttons.slide-button.constants :as constants]
[quo.components.buttons.slide-button.utils :as utils]
[react-native.reanimated :as reanimated]))
[quo.components.buttons.slide-button.utils :as utils]))
(def absolute-fill
{:position :absolute
@@ -13,28 +12,25 @@
(defn thumb-container
[{:keys [interpolate-track thumb-size customization-color theme]}]
(reanimated/apply-animations-to-style
{:transform [{:translate-x (interpolate-track :track-clamp)}]}
[{:transform [{:translate-x (interpolate-track :track-clamp)}]}
{:background-color (utils/main-color customization-color theme)
:border-radius 12
:height thumb-size
:width thumb-size
:align-items :center
:overflow :hidden
:justify-content :center}))
:justify-content :center}])
(defn arrow-icon-container
[interpolate-track]
(reanimated/apply-animations-to-style
{:transform [{:translate-x (interpolate-track :arrow-icon-position)}]}
{:flex 1
:align-items :center
:justify-content :center}))
{:transform [{:translate-x (interpolate-track :arrow-icon-position)}]
:flex 1
:align-items :center
:justify-content :center})
(defn action-icon
[interpolate-track size]
(reanimated/apply-animations-to-style
{:transform [{:translate-x (interpolate-track :action-icon-position)}]}
[{:transform [{:translate-x (interpolate-track :action-icon-position)}]}
{:height size
:width size
:position :absolute
@@ -42,7 +38,7 @@
:left 0
:top 0
:flex-direction :row
:justify-content :space-around}))
:justify-content :space-around}])
(defn track
[{:keys [disabled? customization-color height blur?]}]
@@ -57,9 +53,8 @@
(defn track-cover
[interpolate-track]
(reanimated/apply-animations-to-style
{:left (interpolate-track :track-cover)}
(assoc absolute-fill :overflow :hidden)))
[{:left (interpolate-track :track-cover)}
(assoc absolute-fill :overflow :hidden)])
(defn track-cover-text-container
[track-width]
@@ -8,7 +8,7 @@
[react-native.linear-gradient :as linear-gradient]))
(defn- view-internal
[{:keys [address theme on-press icon title customization-color]}]
[{:keys [address theme on-press icon title customization-color container-style]}]
[rn/pressable
{:accessibility-label :link-card
:on-press on-press}
@@ -17,7 +17,7 @@
(properties/gradient-end-color theme customization-color)]
:start {:x 0 :y 1}
:end {:x 1 :y 1}
:style (style/container theme)}
:style (merge (style/container theme) container-style)}
[rn/view {:style style/icon-container}
[social/view
{:accessibility-label :social-icon
+16 -1
View File
@@ -22,8 +22,10 @@
useAnimatedScrollHandler
runOnJS)]
["react-native-redash" :refer (withPause)]
[oops.core :as oops]
[react-native.flat-list :as rn-flat-list]
[reagent.core :as reagent]
[utils.transforms :as transforms]
[utils.worklets.core :as worklets.core]))
(def enable-layout-animations enableLayoutAnimations)
@@ -38,7 +40,20 @@
;; Animated Components
(def create-animated-component (comp reagent/adapt-react-class (.-createAnimatedComponent reanimated)))
(def view (reagent/adapt-react-class (.-View reanimated)))
(def ^:private view* (reagent/adapt-react-class (.-View reanimated)))
(defn view
[]
(let [current-component (reagent/current-component)
reagent-props (reagent/props current-component)
children (reagent/children current-component)
updated-props (update reagent-props :style transforms/styles-with-vectors)
;; Some components add JS props to their children (such as TouchableWithoutFeedback), to make
;; this component fully compatible we are passing those props to the inner component (`view*`).
external-props (oops/gobj-get current-component "props")
all-props (transforms/copy-js-obj-to-map external-props updated-props #(not= % "argv"))]
(into [view* all-props] children)))
(def text (reagent/adapt-react-class (.-Text reanimated)))
(def scroll-view (reagent/adapt-react-class (.-ScrollView reanimated)))
(def image (reagent/adapt-react-class (.-Image reanimated)))
+1 -1
View File
@@ -117,7 +117,7 @@
(def ^:const profile-pictures-visibility-everyone 2)
(def ^:const profile-pictures-visibility-none 3)
(def ^:const min-password-length 6)
(def ^:const min-password-length 10)
(def ^:const max-group-chat-participants 20)
(def ^:const default-number-of-messages 20)
(def ^:const default-number-of-pin-messages 3)
@@ -36,9 +36,9 @@
(if (seq images) constants/images-container-height 0)))
[images])
[reanimated/view
{:style (reanimated/apply-animations-to-style {:height height}
{:margin-horizontal -20
:z-index 1})}
{:style {:height height
:margin-horizontal -20
:z-index 1}}
[gesture/flat-list
{:key-fn first
:render-fn (fn [item]
@@ -22,6 +22,7 @@
(defn album-message
[{:keys [albumize?] :as message} context on-long-press message-container-data]
(let [shared-element-id (rf/sub [:shared-element-id])
media-server-port (rf/sub [:mediaserver/port])
first-image (first (:album message))
album-style (if (> (:image-width first-image) (:image-height first-image))
:landscape
@@ -57,8 +58,7 @@
:index index}])}
[fast-image/fast-image
{:style (style/image dimensions index portrait? images-count)
:source {:uri (url/replace-port (:image (:content item))
(rf/sub [:mediaserver/port]))}
:source {:uri (url/replace-port (:image (:content item)) media-server-port)}
:native-ID (when (and (= shared-element-id (:message-id item))
(< index constants/max-album-photos))
:shared-element)}]
@@ -90,11 +90,10 @@
(assoc :chats/loading? true
:networks/current-network current-network
:networks/networks (merge networks config/default-networks-by-id)
:profile/profile (merge profile-overview settings))
(assoc-in [:wallet :ui :tokens-loading?] true))
:fx [[:dispatch [:wallet/get-ethereum-chains]]
[:dispatch [:universal-links/generate-profile-url]]
[:dispatch [:community/fetch]]]}
:profile/profile (merge profile-overview settings)))
:fx [[:dispatch [:universal-links/generate-profile-url]]
[:dispatch [:community/fetch]]
[:dispatch [:wallet/initialize]]]}
(notifications/load-preferences)
(data-store.chats/fetch-chats-preview
{:on-success
@@ -125,8 +124,7 @@
: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]]}
:effects.profile/enable-local-notifications nil}
(not (:universal-links/handling db))
(assoc :effects.chat/open-last-chat (get-in db [:profile/profile :key-uid]))
notifications-enabled?
@@ -1,6 +1,5 @@
(ns status-im.contexts.profile.settings.header.style
(:require [quo.foundations.colors :as colors]
[react-native.reanimated :as reanimated]))
(:require [quo.foundations.colors :as colors]))
(defn header-view
[customization-color theme]
@@ -30,19 +29,17 @@
(defn radius-container
[opacity-animation]
(reanimated/apply-animations-to-style
{:opacity opacity-animation}
{:flex-direction :row
:justify-content :space-between}))
{:opacity opacity-animation
:flex-direction :row
:justify-content :space-between})
(defn avatar-container
[theme scale-animation top-margin-animation side-margin-animation]
(reanimated/apply-animations-to-style
{:transform [{:scale scale-animation}]
[{:transform [{:scale scale-animation}]
:margin-top top-margin-animation
:margin-left side-margin-animation
:margin-bottom side-margin-animation}
{:align-items :flex-start
:border-width 4
:border-color (colors/theme-colors colors/border-avatar-light colors/neutral-80-opa-80 theme)
:border-radius 100}))
:border-radius 100}])
@@ -2,13 +2,11 @@
(:require
[quo.foundations.colors :as colors]
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]
[status-im.contexts.shell.jump-to.utils :as utils]))
(defn bottom-tabs-container
[pass-through? height]
(reanimated/apply-animations-to-style
{:height height}
[{:height height}
{:background-color (if pass-through? :transparent colors/neutral-100)
:flex 1
:align-items :center
@@ -18,7 +16,7 @@
:right 0
:left 0
:overflow :hidden
:accessibility-label :bottom-tabs-container}))
:accessibility-label :bottom-tabs-container}])
(defn bottom-tabs
[]
@@ -30,11 +28,10 @@
(defn bottom-tabs-blur-overlay
[height]
(reanimated/apply-animations-to-style
{:height height}
[{:height height}
{:position :absolute
:left 0
:right 0
:bottom 0
:height (utils/bottom-tabs-container-height)
:background-color colors/neutral-100-opa-70-blur}))
:background-color colors/neutral-100-opa-70-blur}])
@@ -43,29 +43,3 @@
(def opensea-button
{:flex 1
:margin-left 6})
(def info-container
{:flex-direction :row
:margin-horizontal 20
:margin-top 8
:margin-bottom 12})
(def account
{:margin-right 6
:flex 1})
(def network
{:margin-left 6
:flex 1})
(def traits-title-container
{:margin-left 20
:margin-top 8})
(def traits-item
{:margin 6
:flex 1})
(def traits-container
{:margin-horizontal 14
:margin-vertical 12})
@@ -0,0 +1,27 @@
(ns status-im.contexts.wallet.collectible.tabs.about.style)
(def title
{:padding-horizontal 20
:padding-top 8
:padding-bottom 4})
(def description
{:padding-horizontal 20
:padding-top 4
:padding-bottom 12})
(def section-label
{:margin-horizontal 20
:margin-top 12})
(def link-cards-container
{:margin-horizontal 20
:margin-top 12
:flex-direction :row
:justify-content :space-between
:flex-wrap :wrap})
(defn link-card
[item-width]
{:margin-bottom 16
:width item-width})
@@ -0,0 +1,36 @@
(ns status-im.contexts.wallet.collectible.tabs.about.view
(:require [quo.core :as quo]
[quo.theme]
[react-native.core :as rn]
[status-im.contexts.wallet.collectible.tabs.about.style :as style]
[status-im.contexts.wallet.temp :as temp]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(def ^:private link-card-space 28)
(defn- view-internal
[]
(let [window-width (rf/sub [:dimensions/window-width])
item-width (- (/ window-width 2) link-card-space)
{:keys [collectible-data]} (rf/sub [:wallet/last-collectible-details])
link-card-container-style (style/link-card item-width)]
[:<>
[rn/view {:style style/title}
[quo/text
{:size :heading-2
:weight :semi-bold}
(:name collectible-data)]]
[rn/view {:style style/description}
[quo/text
{:size :paragraph-2}
(:description collectible-data)]]
[quo/section-label
{:container-style style/section-label
:section (i18n/label :t/on-the-web)}]
[rn/view {:style style/link-cards-container}
(for [item (:cards temp/collectible-about)]
^{:key (:title item)}
[quo/link-card (assoc item :container-style link-card-container-style)])]]))
(def view (quo.theme/with-theme view-internal))
@@ -0,0 +1,17 @@
(ns status-im.contexts.wallet.collectible.tabs.activity.view
(:require [quo.core :as quo]
[react-native.core :as rn]
[status-im.contexts.wallet.temp :as temp]))
(defn activity-item
[item]
[:<>
[quo/divider-date (:timestamp item)]
[quo/wallet-activity item]])
(defn view
[]
[rn/flat-list
{:data temp/collectible-activities
:style {:flex 1}
:render-fn activity-item}])
@@ -0,0 +1,27 @@
(ns status-im.contexts.wallet.collectible.tabs.overview.style)
(def info-container
{:flex-direction :row
:margin-horizontal 20
:margin-top 8
:margin-bottom 12})
(def account
{:margin-right 6
:flex 1})
(def network
{:margin-left 6
:flex 1})
(def traits-title-container
{:margin-left 20
:margin-top 8})
(def traits-item
{:margin 6
:flex 1})
(def traits-container
{:margin-horizontal 14
:margin-vertical 12})
@@ -0,0 +1,72 @@
(ns status-im.contexts.wallet.collectible.tabs.overview.view
(:require
[clojure.string :as string]
[quo.core :as quo]
[quo.foundations.resources :as quo.resources]
[quo.theme]
[react-native.core :as rn]
[status-im.contexts.wallet.collectible.tabs.overview.style :as style]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn- trait-item
[{:keys [trait-type value]}]
[quo/data-item
{:subtitle-type :default
:card? true
:status :default
:size :default
:title trait-type
:subtitle value
:container-style style/traits-item}])
(defn- traits-section
[]
(let [traits (rf/sub [:wallet/last-collectible-details-traits])]
(when (pos? (count traits))
[rn/view
[quo/section-label
{:section (i18n/label :t/traits)
:container-style style/traits-title-container}]
[rn/flat-list
{:render-fn trait-item
:data traits
:key :collectibles-list
:key-fn :id
:num-columns 2
:content-container-style style/traits-container}]])))
(defn- info
[]
(let [chain-id (rf/sub [:wallet/last-collectible-details-chain-id])
{:keys [network-name]} (rf/sub [:wallet/network-details-by-chain-id chain-id])
subtitle (string/capitalize (name (or network-name "")))
{:keys [name emoji color]} (rf/sub [:wallet/last-collectible-details-owner])]
[rn/view {:style style/info-container}
[rn/view {:style style/account}
[quo/data-item
{:card? true
:status :default
:size :default
:title (i18n/label :t/account-title)
:subtitle name
:emoji emoji
:subtitle-type :account
:customization-color color}]]
[rn/view {:style style/network}
[quo/data-item
{:subtitle-type :network
:card? true
:status :default
:size :default
:title (i18n/label :t/network)
:network-image (quo.resources/get-network network-name)
:subtitle subtitle}]]]))
(defn- view-internal
[]
[:<>
[info]
[traits-section]])
(def view (quo.theme/with-theme view-internal))
@@ -0,0 +1,15 @@
(ns status-im.contexts.wallet.collectible.tabs.view
(:require [quo.theme]
[status-im.contexts.wallet.collectible.tabs.about.view :as about]
[status-im.contexts.wallet.collectible.tabs.activity.view :as activity]
[status-im.contexts.wallet.collectible.tabs.overview.view :as overview]))
(defn- view-internal
[{:keys [selected-tab]}]
(case selected-tab
:overview [overview/view]
:about [about/view]
:activity [activity/view]
nil))
(def view (quo.theme/with-theme view-internal))
@@ -1,14 +1,12 @@
(ns status-im.contexts.wallet.collectible.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]
[reagent.core :as reagent]
[status-im.common.scroll-page.view :as scroll-page]
[status-im.contexts.wallet.collectible.style :as style]
[status-im.contexts.wallet.temp :as temp]
[status-im.contexts.wallet.collectible.tabs.view :as tabs]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@@ -42,105 +40,17 @@
:icon-left :i/opensea}
(i18n/label :t/opensea)]])
(def activity-tabs-data
(def tabs-data
[{:id :overview
:label (i18n/label :t/overview)
:accessibility-label :overview-tab}
{:id :activity
:label (i18n/label :t/activity)
:accessibility-label :activity-tab}
{:id :permissions
:label (i18n/label :t/permissions)
:accessibility-label :permissions-tab}
{:id :about
:label (i18n/label :t/about)
:accessibility-label :about-tab}])
(defn traits-section
[traits]
(when (pos? (count traits))
[rn/view
[quo/section-label
{:section (i18n/label :t/traits)
:container-style style/traits-title-container}]
[rn/flat-list
{:render-fn (fn [{:keys [trait-type value]}]
[quo/data-item
{:card? true
:status :default
:size :default
:title trait-type
:subtitle value
:subtitle-type :default
:container-style style/traits-item}])
:data traits
:key :collectibles-list
:key-fn :id
:num-columns 2
:content-container-style style/traits-container}]]))
(defn activity-item
[item]
[:<>
[quo/divider-date (:timestamp item)]
[quo/wallet-activity item]])
(defn activity-section
[]
[rn/flat-list
{:data temp/collectible-activities
:style {:flex 1}
:render-fn activity-item}])
(defn info
[chain-id]
(let [network (rf/sub [:wallet/network-details-by-chain-id
chain-id])
network-keyword (get network :network-name)
network-name (when network-keyword
(string/capitalize (name network-keyword)))]
[rn/view
{:style style/info-container}
[rn/view {:style style/account}
[quo/data-item
{:card? true
:status :default
:size :default
:title (i18n/label :t/account-title)
:subtitle "Collectibles vault"
:subtitle-type :account
:emoji "🎮"
:customization-color :yellow}]]
[rn/view {:style style/network}
[quo/data-item
{:card? true
:status :default
:size :default
:title (i18n/label :t/network)
:network-image (quo.resources/get-network network-keyword)
:subtitle network-name
:subtitle-type :network}]]]))
(defn tabs
[_]
(let [selected-tab (reagent/atom (:id (first activity-tabs-data)))]
(fn [{:keys [traits chain-id] :as _props}]
[:<>
[quo/tabs
{:size 32
:style style/tabs
:scrollable? true
:default-active @selected-tab
:data activity-tabs-data
:on-change #(reset! selected-tab %)}]
(condp = @selected-tab
:overview [:<>
[info chain-id]
[traits-section traits]]
:activity [activity-section]
nil)])))
(defn collectible-actions-sheet
[]
[quo/action-drawer
@@ -162,35 +72,41 @@
(defn view-internal
[{:keys [theme] :as _props}]
(let [collectible (rf/sub [:wallet/last-collectible-details])
{:keys [collectible-data preview-url
collection-data]} collectible
{traits :traits
collectible-name :name} collectible-data
{collection-image :image-url
collection-name :name} collection-data
chain-id (rf/sub [:wallet/last-collectible-chain-id])]
[scroll-page/scroll-page
{:navigate-back? true
:height 148
:page-nav-props {:type :title-description
:title collectible-name
:description collection-name
:right-side [{:icon-name :i/options
:on-press #(rf/dispatch
[:show-bottom-sheet
{:content collectible-actions-sheet
:theme theme}])}]
:picture preview-url}}
[rn/view {:style style/container}
[rn/view {:style style/preview-container}
[rn/image
{:source preview-url
:style style/preview}]]
[header collectible-name collection-name collection-image]
[cta-buttons]
[tabs
{:traits traits
:chain-id chain-id}]]]))
(let [selected-tab (reagent/atom :overview)
on-tab-change #(reset! selected-tab %)]
(fn []
(let [collectible (rf/sub [:wallet/last-collectible-details])
{:keys [collectible-data preview-url
collection-data]} collectible
{collection-image :image-url
collection-name :name} collection-data
{collectible-name :name} collectible-data]
[scroll-page/scroll-page
{:navigate-back? true
:height 148
:page-nav-props {:type :title-description
:title collectible-name
:description collection-name
:right-side [{:icon-name :i/options
:on-press #(rf/dispatch
[:show-bottom-sheet
{:content collectible-actions-sheet
:theme theme}])}]
:picture preview-url}}
[rn/view {:style style/container}
[rn/view {:style style/preview-container}
[rn/image
{:source preview-url
:style style/preview}]]
[header collectible-name collection-name collection-image]
[cta-buttons]
[quo/tabs
{:size 32
:style style/tabs
:scrollable? true
:default-active @selected-tab
:on-change on-tab-change
:data tabs-data}]
[tabs/view {:selected-tab @selected-tab}]]]))))
(def view (quo.theme/with-theme view-internal))
@@ -64,7 +64,7 @@
(update-vals #(cske/transform-keys csk/->kebab-case %))
(update-vals #(mapv rpc->balances-per-chain %))))
(defn <-rpc
(defn rpc->network
[network]
(-> network
(set/rename-keys
@@ -13,10 +13,11 @@
(defn- show-save-account-toast
[updated-key]
(let [message (case updated-key
:name :t/edit-wallet-account-name-updated-message
:color :t/edit-wallet-account-colour-updated-message
:emoji :t/edit-wallet-account-emoji-updated-message
:prod-preferred-chain-ids :t/edit-wallet-network-preferences-updated-message
:name :t/edit-wallet-account-name-updated-message
:color :t/edit-wallet-account-colour-updated-message
:emoji :t/edit-wallet-account-emoji-updated-message
(:prod-preferred-chain-ids
:test-preferred-chain-ids) :t/edit-wallet-network-preferences-updated-message
nil)]
(rf/dispatch [:toasts/upsert
{:id :edit-account
@@ -50,11 +51,15 @@
:new-value @edited-account-name}))]
(fn []
(let [{:keys [name emoji address color watch-only?]
:as account} (rf/sub [:wallet/current-viewing-account])
network-details (rf/sub [:wallet/network-preference-details])
account-name (or @edited-account-name name)
button-disabled? (or (nil? @edited-account-name)
(= name @edited-account-name))]
:as account} (rf/sub [:wallet/current-viewing-account])
network-details (rf/sub [:wallet/network-preference-details])
test-networks-enabled? (rf/sub [:profile/test-networks-enabled?])
network-preferences-key (if test-networks-enabled?
:test-preferred-chain-ids
:prod-preferred-chain-ids)
account-name (or @edited-account-name name)
button-disabled? (or (nil? @edited-account-name)
(= name @edited-account-name))]
[create-or-edit-account/view
{:page-nav-right-side [{:icon-name :i/delete
:on-press #(js/alert "Delete account: to be implemented")}]
@@ -95,7 +100,7 @@
(rf/dispatch [:hide-bottom-sheet])
(save-account
{:account account
:updated-key :prod-preferred-chain-ids
:updated-key network-preferences-key
:new-value chain-ids}))
:watch-only? watch-only?}])}]))
:container-style style/data-item}]]))))
+11 -3
View File
@@ -195,13 +195,13 @@
(let [network-data
{:test (map #(->> %
:Test
data-store/<-rpc)
data-store/rpc->network)
data)
:prod (map #(->> %
:Prod
data-store/<-rpc)
data-store/rpc->network)
data)}]
{:db (assoc db :wallet/networks network-data)})))
{:db (assoc-in db [:wallet :networks] network-data)})))
(rf/reg-event-fx :wallet/find-ens
(fn [{:keys [db]} [input contacts chain-id cb]]
@@ -301,6 +301,10 @@
(background-timer/clear-timeout current-timeout)
{:db (assoc db :wallet/local-suggestions [] :wallet/valid-ens-or-address? false)})))
(rf/reg-event-fx :wallet/clean-account-selection
(fn [{:keys [db]}]
{:db (update-in db [:wallet :ui :send] dissoc :send-account-address)}))
(rf/reg-event-fx :wallet/get-address-details-success
(fn [{:keys [db]} [{:keys [hasActivity]}]]
{:db (assoc-in db
@@ -327,3 +331,7 @@
(fn [_ [explorer-link address]]
{:fx [[:dispatch [:hide-bottom-sheet]]
[:dispatch [:browser.ui/open-url (str explorer-link "/" address)]]]}))
(rf/reg-event-fx :wallet/initialize
(fn []
{:fx [[:dispatch-n [[:wallet/get-ethereum-chains] [:wallet/get-accounts]]]]}))
+12 -6
View File
@@ -14,10 +14,6 @@
{:db (assoc-in db [:wallet :ui :send :select-address-tab] tab)}))
(rf/reg-event-fx :wallet/select-send-account-address
(fn [{:keys [db]} [address]]
{:db (assoc db [:wallet :ui :send :send-account-address] address)}))
(rf/reg-event-fx :wallet/suggested-routes-success
(fn [{:keys [db]} [suggested-routes timestamp]]
(when (= (get-in db [:wallet :ui :send :suggested-routes-call-timestamp]) timestamp)
@@ -44,9 +40,18 @@
(update-in [:wallet :ui :send] dissoc :route)
(update-in [:wallet :ui :send] dissoc :loading-suggested-routes?))}))
(rf/reg-event-fx :wallet/select-send-account-address
(fn [{:keys [db]} [{:keys [address stack-id]}]]
{:db (-> db
(assoc-in [:wallet :ui :send :send-account-address] address)
(update-in [:wallet :ui :send] dissoc :to-address))
:fx [[:navigate-to-within-stack [:wallet-select-asset stack-id]]]}))
(rf/reg-event-fx :wallet/select-send-address
(fn [{:keys [db]} [{:keys [address stack-id]}]]
{:db (assoc-in db [:wallet :ui :send :to-address] address)
{:db (-> db
(assoc-in [:wallet :ui :send :to-address] address)
(update-in [:wallet :ui :send] dissoc :send-account-address))
:fx [[:navigate-to-within-stack [:wallet-select-asset stack-id]]]}))
(rf/reg-event-fx :wallet/send-select-token
@@ -63,7 +68,8 @@
(fn [{:keys [db now]} [amount]]
(let [wallet-address (get-in db [:wallet :current-viewing-account-address])
token (get-in db [:wallet :ui :send :token])
to-address (get-in db [:wallet :ui :send :to-address])
account-address (get-in db [:wallet :ui :send :send-account-address])
to-address (or account-address (get-in db [:wallet :ui :send :to-address]))
token-decimal (:decimals token)
token-id (:symbol token)
network-preferences []
@@ -12,10 +12,9 @@
[{:keys [color address] :as account}]
[quo/account-item
{:account-props (assoc account :customization-color color)
:on-press (fn []
(rf/dispatch [:wallet/select-send-account-address address])
(rf/dispatch [:navigate-to-within-stack
[:wallet-select-asset :wallet-select-address]]))}])
:on-press #(rf/dispatch [:wallet/select-send-account-address
{:address address
:stack-id :wallet-select-address}])}])
(defn my-accounts
[theme]
@@ -117,6 +117,7 @@
(let [on-close (fn []
(rf/dispatch [:wallet/clean-scanned-address])
(rf/dispatch [:wallet/clean-local-suggestions])
(rf/dispatch [:wallet/clean-account-selection])
(rf/dispatch [:wallet/select-address-tab nil])
(rf/dispatch [:navigate-back]))
on-change-tab #(rf/dispatch [:wallet/select-address-tab %])
@@ -128,7 +129,8 @@
(rn/use-effect (fn []
(fn []
(rf/dispatch [:wallet/clean-scanned-address])
(rf/dispatch [:wallet/clean-local-suggestions]))))
(rf/dispatch [:wallet/clean-local-suggestions])
(rf/dispatch [:wallet/clean-account-selection]))))
[floating-button-page/view
{:header [account-switcher/view
{:on-press on-close
+17
View File
@@ -105,3 +105,20 @@
:type :network
:network-logo (quo.resources/get-network :ethereum)
:network-name "Mainnet"}}])
(def collectible-about
{:cards [{:title "BAYC"
:icon :social/link
:address "boredapeyachtclub"
:customization-color :social/link
:on-press #(js/alert "pressed")}
{:title "Twitter"
:icon :social/twitter
:address "@BoredApeYC"
:customization-color :social/twitter
:on-press #(js/alert "pressed")}
{:title "Opensea"
:icon :social/opensea
:address "Bored Ape Yacht Club"
:customization-color :social/opensea
:on-press #(js/alert "pressed")}]})
-1
View File
@@ -106,7 +106,6 @@
(fn [profile]
(:test-networks-enabled? profile)))
(re-frame/reg-sub
:multiaccount/contact
:<- [:profile/profile]
-1
View File
@@ -154,7 +154,6 @@
(reg-root-key-sub :wallet :wallet)
(reg-root-key-sub :wallet/scanned-address :wallet/scanned-address)
(reg-root-key-sub :wallet/create-account :wallet/create-account)
(reg-root-key-sub :wallet/networks :wallet/networks)
(reg-root-key-sub :wallet/local-suggestions :wallet/local-suggestions)
(reg-root-key-sub :wallet/valid-ens-or-address? :wallet/valid-ens-or-address?)
+16 -1
View File
@@ -38,7 +38,22 @@
(assoc last-collectible :preview-url (preview-url (:collectible-data last-collectible))))))
(re-frame/reg-sub
:wallet/last-collectible-chain-id
:wallet/last-collectible-details-chain-id
:<- [:wallet/last-collectible-details]
(fn [collectible]
(get-in collectible [:id :contract-id :chain-id])))
(re-frame/reg-sub
:wallet/last-collectible-details-traits
:<- [:wallet/last-collectible-details]
(fn [collectible]
(get-in collectible [:collectible-data :traits])))
(re-frame/reg-sub
:wallet/last-collectible-details-owner
:<- [:wallet/last-collectible-details]
:<- [:wallet]
(fn [[collectible wallet]]
(let [address (:address (first (:ownership collectible)))
account (get-in wallet [:accounts address])]
account)))
@@ -0,0 +1,50 @@
(ns status-im.subs.wallet.collectibles-test
(:require
[cljs.test :refer [is testing]]
[re-frame.db :as rf-db]
status-im.subs.root
status-im.subs.wallet.collectibles
[test-helpers.unit :as h]
[utils.re-frame :as rf]))
(def ^:private traits
[{:trait-type "Background"
:value "Gradient 5"
:display-type ""
:max-value ""}
{:trait-type "Skin"
:value "Pale"
:display-type ""
:max-value ""}
{:trait-type "Clothes"
:value "Naked"
:display-type ""
:max-value ""}])
(def ^:private collectible-owner-wallet
{:last-collectible-details {:ownership [{:address "0x1"}]}
:accounts {"0x1" {:name "account 1"
:color "army"}}})
(h/deftest-sub :wallet/last-collectible-details-chain-id
[sub-name]
(testing "correct chain-id of the last collectible should be returned"
(swap! rf-db/app-db assoc-in [:wallet :last-collectible-details :id :contract-id :chain-id] "1")
(let [result (rf/sub [sub-name])]
(is (= "1" result)))))
(h/deftest-sub :wallet/last-collectible-details-traits
[sub-name]
(testing "correct traits of the last collectible should be returned"
(swap! rf-db/app-db assoc-in [:wallet :last-collectible-details :collectible-data :traits] traits)
(let [result (rf/sub [sub-name])]
(is (= traits result)))))
(h/deftest-sub :wallet/last-collectible-details-owner
[sub-name]
(testing "correct owner of the last collectible should be returned"
(swap! rf-db/app-db assoc-in [:wallet] collectible-owner-wallet)
(let [result (rf/sub [sub-name])]
(is (= {:name "account 1"
:color "army"}
result)))))
+10 -4
View File
@@ -4,10 +4,16 @@
[status-im.constants :as constants]))
(re-frame/reg-sub
:wallet/filtered-networks-by-mode
:wallet/networks
:<- [:wallet]
:-> :networks)
(re-frame/reg-sub
:wallet/networks-by-mode
:<- [:wallet/networks]
(fn [networks [_ test?]]
(get networks (if test? :test :prod))))
:<- [:profile/test-networks-enabled?]
(fn [[networks test-networks-enabled?]]
(get networks (if test-networks-enabled? :test :prod))))
(def mainnet-network-details
{:source (resources/get-network constants/mainnet-network-name)
@@ -32,7 +38,7 @@
(re-frame/reg-sub
:wallet/network-details
:<- [:wallet/filtered-networks-by-mode false]
:<- [:wallet/networks-by-mode]
(fn [networks]
(->> networks
(keep
+1 -1
View File
@@ -37,7 +37,7 @@
(h/deftest-sub :wallet/network-details
[sub-name]
(testing "returns data with prod"
(swap! rf-db/app-db assoc :wallet/networks network-data)
(swap! rf-db/app-db assoc-in [:wallet :networks] network-data)
(is (= [{:network-name :ethereum
:short-name "eth"
:chain-id 1
+7 -9
View File
@@ -77,15 +77,13 @@
:wallet/accounts
:<- [:wallet]
:<- [:wallet/network-details]
(fn [[wallet network-details]]
;; TODO(@rende11): `testnet?` value would be relevant after this implementation,
;; https://github.com/status-im/status-mobile/issues/17826
(let [testnet? false]
(->> wallet
:accounts
vals
(map #(assoc-network-preferences-names network-details % testnet?))
(sort-by :position)))))
:<- [:profile/test-networks-enabled?]
(fn [[wallet network-details test-networks-enabled?]]
(->> wallet
:accounts
vals
(map #(assoc-network-preferences-names network-details % test-networks-enabled?))
(sort-by :position))))
(rf/reg-sub
:wallet/addresses
+5 -5
View File
@@ -167,7 +167,7 @@
(swap! rf-db/app-db
#(-> %
(assoc-in [:wallet :accounts] accounts)
(assoc :wallet/networks network-data)))
(assoc-in [:wallet :networks] network-data)))
(is
(=
(list {:path "m/44'/60'/0'/0/0"
@@ -252,7 +252,7 @@
#(-> %
(assoc-in [:wallet :accounts] accounts)
(assoc-in [:wallet :current-viewing-account-address] "0x1")
(assoc :wallet/networks network-data)))
(assoc-in [:wallet :networks] network-data)))
(let [result (rf/sub [sub-name])]
(is
@@ -310,7 +310,7 @@
#(-> %
(assoc-in [:wallet :accounts] accounts)
(assoc-in [:wallet :current-viewing-account-address] "0x2")
(assoc :wallet/networks network-data)))
(assoc-in [:wallet :networks] network-data)))
(is
(= (list
{:path "m/44'/60'/0'/0/0"
@@ -365,7 +365,7 @@
(swap! rf-db/app-db
#(-> %
(assoc-in [:wallet :accounts] accounts)
(assoc :wallet/networks network-data)))
(assoc-in [:wallet :networks] network-data)))
(is
(= (list
{:path "m/44'/60'/0'/0/0"
@@ -421,7 +421,7 @@
#(-> %
(assoc-in [:wallet :accounts] accounts)
(assoc-in [:wallet :current-viewing-account-address] "0x1")
(assoc :wallet/networks network-data)))
(assoc-in [:wallet :networks] network-data)))
(is
(match? [{:short-name "eth"
:network-name :ethereum
+40 -1
View File
@@ -1,7 +1,10 @@
(ns utils.transforms
(:refer-clojure :exclude [js->clj])
(:require
[cljs-bean.core :as clj-bean]))
[cljs-bean.core :as clj-bean]
[oops.core :as oops]
[reagent.impl.template :as reagent.template]
[reagent.impl.util :as reagent.util]))
(defn js->clj [data] (cljs.core/js->clj data :keywordize-keys true))
@@ -21,3 +24,39 @@
[json]
(when-not (= json "undefined")
(try (.parse js/JSON json) (catch js/Error _ (when (string? json) json)))))
(declare styles-with-vectors)
(defn ^:private convert-keys-and-values
"Takes a JS Object a key and a value.
Transforms the key from a Clojure style prop to a JS style prop, using the reagent cache.
Performs a mutual recursion transformation on the value using `styles-with-vectors`.
Based on `reagent.impl.template/kv-conv`."
[obj k v]
(doto obj
(oops/gobj-set (reagent.template/cached-prop-name k) (styles-with-vectors v))))
(defn styles-with-vectors
"Takes a Clojure style map or a Clojure vector of style maps and returns a JS Object
valid to use as React Native styles.
The transformation is done by performing mutual recursive calls with `convert-keys-and-values`.
Based on `reagent.impl.template/convert-prop-value`."
[x]
(cond (reagent.util/js-val? x) x
(reagent.util/named? x) (name x)
(map? x) (reduce-kv convert-keys-and-values #js {} x)
(vector? x) (to-array (mapv styles-with-vectors x))
:else (clj->js x)))
(defn copy-js-obj-to-map
"Copy `obj` keys and values into `m` if `(pred obj-key)` is satisfied."
[obj m pred]
(persistent!
(reduce (fn [acc js-prop]
(if (pred js-prop)
(assoc! acc js-prop (oops/gobj-get obj js-prop))
acc))
(transient m)
(js-keys obj))))
+1 -1
View File
@@ -196,7 +196,7 @@ def _upload_and_check_response_with_retries(apk_file_path, retries=3):
try:
_upload_and_check_response(apk_file_path)
break
except (ConnectionError, RemoteDisconnected):
except (ConnectionError, RemoteDisconnected, c_er):
time.sleep(10)
@@ -655,6 +655,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUiTwo(MultipleSharedDeviceTestCase
self.home_2.navigate_back_to_home_view()
self.home_2.chats_tab.click()
self.home_2.get_chat(self.username_1).click()
self.chat_2.chat_message_input.wait_for_visibility_of_element()
self.home_2.just_fyi("Getting chat history")
chat_history = list()
for element in self.chat_2.chat_element_by_text(text='').message_text_content.find_elements():
@@ -5,7 +5,7 @@ import emoji
import pytest
from _pytest.outcomes import Failed
from appium.webdriver.connectiontype import ConnectionType
from selenium.common.exceptions import NoSuchElementException, TimeoutException
from selenium.common.exceptions import NoSuchElementException, TimeoutException, StaleElementReferenceException
from tests import marks, run_in_parallel, pytest_config_global, transl
from tests.base_test_case import create_shared_drivers, MultipleSharedDeviceTestCase
@@ -108,7 +108,10 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
message_to_delete = "message to delete and undo"
self.channel.send_message(message_to_delete)
self.channel.delete_message_in_chat(message_to_delete)
self.channel.element_by_text("Undo").click()
try:
self.channel.element_by_text("Undo").click()
except StaleElementReferenceException:
pytest.fail("Can't press Undo button, not enough time")
try:
self.channel.chat_element_by_text(message_to_delete).wait_for_visibility_of_element()
except TimeoutException:
+2
View File
@@ -2449,6 +2449,8 @@
"copy-all-details": "Copy all details",
"share-details": "Share details",
"what-are-you-waiting-for": "What are you waiting for?",
"no-relevant-tokens": "No relevant tokens",
"on-the-web": "On the web",
"sending-with-elipsis": "Sending...",
"transaction-confirmed": "Transaction confirmed!",
"transacation-finalised": "Transaction finalised!",