diff --git a/.eslintrc.js b/.eslintrc.js index 6df1e6e1e52..f8cb2150123 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -39,5 +39,6 @@ module.exports = { ], 'jest/expect-expect': 'off', 'jest/no-disabled-tests': 'off', + 'no-nested-ternary': 'off', }, }; diff --git a/ios/Images.xcassets/badges/gnosis.imageset/Contents.json b/ios/Images.xcassets/badges/gnosis.imageset/Contents.json new file mode 100644 index 00000000000..834dad265bf --- /dev/null +++ b/ios/Images.xcassets/badges/gnosis.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "gnosis.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "gnosis@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "gnosis@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/gnosis.imageset/gnosis.png b/ios/Images.xcassets/badges/gnosis.imageset/gnosis.png new file mode 100644 index 00000000000..afb08cb40e6 Binary files /dev/null and b/ios/Images.xcassets/badges/gnosis.imageset/gnosis.png differ diff --git a/ios/Images.xcassets/badges/gnosis.imageset/gnosis@2x.png b/ios/Images.xcassets/badges/gnosis.imageset/gnosis@2x.png new file mode 100644 index 00000000000..3a021929690 Binary files /dev/null and b/ios/Images.xcassets/badges/gnosis.imageset/gnosis@2x.png differ diff --git a/ios/Images.xcassets/badges/gnosis.imageset/gnosis@3x.png b/ios/Images.xcassets/badges/gnosis.imageset/gnosis@3x.png new file mode 100644 index 00000000000..09946eb88a5 Binary files /dev/null and b/ios/Images.xcassets/badges/gnosis.imageset/gnosis@3x.png differ diff --git a/ios/Images.xcassets/badges/gnosisBadge.imageset/Contents.json b/ios/Images.xcassets/badges/gnosisBadge.imageset/Contents.json new file mode 100644 index 00000000000..a8ae4f3b2ee --- /dev/null +++ b/ios/Images.xcassets/badges/gnosisBadge.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "gnosisBadge.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "gnosisBadge@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "gnosisBadge@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/gnosisBadge.imageset/gnosisBadge.png b/ios/Images.xcassets/badges/gnosisBadge.imageset/gnosisBadge.png new file mode 100644 index 00000000000..961610867dd Binary files /dev/null and b/ios/Images.xcassets/badges/gnosisBadge.imageset/gnosisBadge.png differ diff --git a/ios/Images.xcassets/badges/gnosisBadge.imageset/gnosisBadge@2x.png b/ios/Images.xcassets/badges/gnosisBadge.imageset/gnosisBadge@2x.png new file mode 100644 index 00000000000..1355360aca0 Binary files /dev/null and b/ios/Images.xcassets/badges/gnosisBadge.imageset/gnosisBadge@2x.png differ diff --git a/ios/Images.xcassets/badges/gnosisBadge.imageset/gnosisBadge@3x.png b/ios/Images.xcassets/badges/gnosisBadge.imageset/gnosisBadge@3x.png new file mode 100644 index 00000000000..19592fc8d64 Binary files /dev/null and b/ios/Images.xcassets/badges/gnosisBadge.imageset/gnosisBadge@3x.png differ diff --git a/ios/Images.xcassets/badges/gnosisBadgeDark.imageset/Contents.json b/ios/Images.xcassets/badges/gnosisBadgeDark.imageset/Contents.json new file mode 100644 index 00000000000..3e640c6e39e --- /dev/null +++ b/ios/Images.xcassets/badges/gnosisBadgeDark.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "gnosisBadgeDark.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "gnosisBadgeDark@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "gnosisBadgeDark@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/gnosisBadgeDark.imageset/gnosisBadgeDark.png b/ios/Images.xcassets/badges/gnosisBadgeDark.imageset/gnosisBadgeDark.png new file mode 100644 index 00000000000..cd7d26152c2 Binary files /dev/null and b/ios/Images.xcassets/badges/gnosisBadgeDark.imageset/gnosisBadgeDark.png differ diff --git a/ios/Images.xcassets/badges/gnosisBadgeDark.imageset/gnosisBadgeDark@2x.png b/ios/Images.xcassets/badges/gnosisBadgeDark.imageset/gnosisBadgeDark@2x.png new file mode 100644 index 00000000000..029c07d9ddb Binary files /dev/null and b/ios/Images.xcassets/badges/gnosisBadgeDark.imageset/gnosisBadgeDark@2x.png differ diff --git a/ios/Images.xcassets/badges/gnosisBadgeDark.imageset/gnosisBadgeDark@3x.png b/ios/Images.xcassets/badges/gnosisBadgeDark.imageset/gnosisBadgeDark@3x.png new file mode 100644 index 00000000000..5c8ed229375 Binary files /dev/null and b/ios/Images.xcassets/badges/gnosisBadgeDark.imageset/gnosisBadgeDark@3x.png differ diff --git a/ios/Images.xcassets/badges/gnosisBadgeLarge.imageset/Contents.json b/ios/Images.xcassets/badges/gnosisBadgeLarge.imageset/Contents.json new file mode 100644 index 00000000000..5f89716e5e9 --- /dev/null +++ b/ios/Images.xcassets/badges/gnosisBadgeLarge.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "gnosisBadgeLarge.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "gnosisBadgeLarge@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "gnosisBadgeLarge@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/gnosisBadgeLarge.imageset/gnosisBadgeLarge.png b/ios/Images.xcassets/badges/gnosisBadgeLarge.imageset/gnosisBadgeLarge.png new file mode 100644 index 00000000000..9cf5511d8f1 Binary files /dev/null and b/ios/Images.xcassets/badges/gnosisBadgeLarge.imageset/gnosisBadgeLarge.png differ diff --git a/ios/Images.xcassets/badges/gnosisBadgeLarge.imageset/gnosisBadgeLarge@2x.png b/ios/Images.xcassets/badges/gnosisBadgeLarge.imageset/gnosisBadgeLarge@2x.png new file mode 100644 index 00000000000..301ddfb2914 Binary files /dev/null and b/ios/Images.xcassets/badges/gnosisBadgeLarge.imageset/gnosisBadgeLarge@2x.png differ diff --git a/ios/Images.xcassets/badges/gnosisBadgeLarge.imageset/gnosisBadgeLarge@3x.png b/ios/Images.xcassets/badges/gnosisBadgeLarge.imageset/gnosisBadgeLarge@3x.png new file mode 100644 index 00000000000..e787754b713 Binary files /dev/null and b/ios/Images.xcassets/badges/gnosisBadgeLarge.imageset/gnosisBadgeLarge@3x.png differ diff --git a/ios/Images.xcassets/badges/gnosisBadgeLargeDark.imageset/Contents.json b/ios/Images.xcassets/badges/gnosisBadgeLargeDark.imageset/Contents.json new file mode 100644 index 00000000000..ee423b90122 --- /dev/null +++ b/ios/Images.xcassets/badges/gnosisBadgeLargeDark.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "gnosisBadgeLargeDark.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "gnosisBadgeLargeDark@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "gnosisBadgeLargeDark@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/gnosisBadgeLargeDark.imageset/gnosisBadgeLargeDark.png b/ios/Images.xcassets/badges/gnosisBadgeLargeDark.imageset/gnosisBadgeLargeDark.png new file mode 100644 index 00000000000..4f3b0c859cb Binary files /dev/null and b/ios/Images.xcassets/badges/gnosisBadgeLargeDark.imageset/gnosisBadgeLargeDark.png differ diff --git a/ios/Images.xcassets/badges/gnosisBadgeLargeDark.imageset/gnosisBadgeLargeDark@2x.png b/ios/Images.xcassets/badges/gnosisBadgeLargeDark.imageset/gnosisBadgeLargeDark@2x.png new file mode 100644 index 00000000000..79768e5d97e Binary files /dev/null and b/ios/Images.xcassets/badges/gnosisBadgeLargeDark.imageset/gnosisBadgeLargeDark@2x.png differ diff --git a/ios/Images.xcassets/badges/gnosisBadgeLargeDark.imageset/gnosisBadgeLargeDark@3x.png b/ios/Images.xcassets/badges/gnosisBadgeLargeDark.imageset/gnosisBadgeLargeDark@3x.png new file mode 100644 index 00000000000..4975e795ef0 Binary files /dev/null and b/ios/Images.xcassets/badges/gnosisBadgeLargeDark.imageset/gnosisBadgeLargeDark@3x.png differ diff --git a/ios/Images.xcassets/badges/gnosisBadgeNoShadow.imageset/Contents.json b/ios/Images.xcassets/badges/gnosisBadgeNoShadow.imageset/Contents.json new file mode 100644 index 00000000000..f322a845147 --- /dev/null +++ b/ios/Images.xcassets/badges/gnosisBadgeNoShadow.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "gnosisBadgeNoShadow.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "gnosisBadgeNoShadow@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "gnosisBadgeNoShadow@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/gnosisBadgeNoShadow.imageset/gnosisBadgeNoShadow.png b/ios/Images.xcassets/badges/gnosisBadgeNoShadow.imageset/gnosisBadgeNoShadow.png new file mode 100644 index 00000000000..baa5ee94397 Binary files /dev/null and b/ios/Images.xcassets/badges/gnosisBadgeNoShadow.imageset/gnosisBadgeNoShadow.png differ diff --git a/ios/Images.xcassets/badges/gnosisBadgeNoShadow.imageset/gnosisBadgeNoShadow@2x.png b/ios/Images.xcassets/badges/gnosisBadgeNoShadow.imageset/gnosisBadgeNoShadow@2x.png new file mode 100644 index 00000000000..57e1e098b6a Binary files /dev/null and b/ios/Images.xcassets/badges/gnosisBadgeNoShadow.imageset/gnosisBadgeNoShadow@2x.png differ diff --git a/ios/Images.xcassets/badges/gnosisBadgeNoShadow.imageset/gnosisBadgeNoShadow@3x.png b/ios/Images.xcassets/badges/gnosisBadgeNoShadow.imageset/gnosisBadgeNoShadow@3x.png new file mode 100644 index 00000000000..42a52730e27 Binary files /dev/null and b/ios/Images.xcassets/badges/gnosisBadgeNoShadow.imageset/gnosisBadgeNoShadow@3x.png differ diff --git a/ios/Images.xcassets/badges/gravity.imageset/Contents.json b/ios/Images.xcassets/badges/gravity.imageset/Contents.json new file mode 100644 index 00000000000..5e1cbb0a037 --- /dev/null +++ b/ios/Images.xcassets/badges/gravity.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "gravity.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "gravity@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "gravity@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/gravity.imageset/gravity.png b/ios/Images.xcassets/badges/gravity.imageset/gravity.png new file mode 100644 index 00000000000..a515d5551c5 Binary files /dev/null and b/ios/Images.xcassets/badges/gravity.imageset/gravity.png differ diff --git a/ios/Images.xcassets/badges/gravity.imageset/gravity@2x.png b/ios/Images.xcassets/badges/gravity.imageset/gravity@2x.png new file mode 100644 index 00000000000..29e60cbad1c Binary files /dev/null and b/ios/Images.xcassets/badges/gravity.imageset/gravity@2x.png differ diff --git a/ios/Images.xcassets/badges/gravity.imageset/gravity@3x.png b/ios/Images.xcassets/badges/gravity.imageset/gravity@3x.png new file mode 100644 index 00000000000..55108967dea Binary files /dev/null and b/ios/Images.xcassets/badges/gravity.imageset/gravity@3x.png differ diff --git a/ios/Images.xcassets/badges/gravityBadge.imageset/Contents.json b/ios/Images.xcassets/badges/gravityBadge.imageset/Contents.json new file mode 100644 index 00000000000..83f2a19de8d --- /dev/null +++ b/ios/Images.xcassets/badges/gravityBadge.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "gravityBadge.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "gravityBadge@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "gravityBadge@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/gravityBadge.imageset/gravityBadge.png b/ios/Images.xcassets/badges/gravityBadge.imageset/gravityBadge.png new file mode 100644 index 00000000000..ad033ad3691 Binary files /dev/null and b/ios/Images.xcassets/badges/gravityBadge.imageset/gravityBadge.png differ diff --git a/ios/Images.xcassets/badges/gravityBadge.imageset/gravityBadge@2x.png b/ios/Images.xcassets/badges/gravityBadge.imageset/gravityBadge@2x.png new file mode 100644 index 00000000000..2264da68ec9 Binary files /dev/null and b/ios/Images.xcassets/badges/gravityBadge.imageset/gravityBadge@2x.png differ diff --git a/ios/Images.xcassets/badges/gravityBadge.imageset/gravityBadge@3x.png b/ios/Images.xcassets/badges/gravityBadge.imageset/gravityBadge@3x.png new file mode 100644 index 00000000000..8d6bdddc381 Binary files /dev/null and b/ios/Images.xcassets/badges/gravityBadge.imageset/gravityBadge@3x.png differ diff --git a/ios/Images.xcassets/badges/gravityBadgeDark.imageset/Contents.json b/ios/Images.xcassets/badges/gravityBadgeDark.imageset/Contents.json new file mode 100644 index 00000000000..652b4b30a25 --- /dev/null +++ b/ios/Images.xcassets/badges/gravityBadgeDark.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "gravityBadgeDark.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "gravityBadgeDark@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "gravityBadgeDark@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/gravityBadgeDark.imageset/gravityBadgeDark.png b/ios/Images.xcassets/badges/gravityBadgeDark.imageset/gravityBadgeDark.png new file mode 100644 index 00000000000..02fb9e0677f Binary files /dev/null and b/ios/Images.xcassets/badges/gravityBadgeDark.imageset/gravityBadgeDark.png differ diff --git a/ios/Images.xcassets/badges/gravityBadgeDark.imageset/gravityBadgeDark@2x.png b/ios/Images.xcassets/badges/gravityBadgeDark.imageset/gravityBadgeDark@2x.png new file mode 100644 index 00000000000..9aadd9549ae Binary files /dev/null and b/ios/Images.xcassets/badges/gravityBadgeDark.imageset/gravityBadgeDark@2x.png differ diff --git a/ios/Images.xcassets/badges/gravityBadgeDark.imageset/gravityBadgeDark@3x.png b/ios/Images.xcassets/badges/gravityBadgeDark.imageset/gravityBadgeDark@3x.png new file mode 100644 index 00000000000..5218bf5b88e Binary files /dev/null and b/ios/Images.xcassets/badges/gravityBadgeDark.imageset/gravityBadgeDark@3x.png differ diff --git a/ios/Images.xcassets/badges/gravityBadgeLarge.imageset/Contents.json b/ios/Images.xcassets/badges/gravityBadgeLarge.imageset/Contents.json new file mode 100644 index 00000000000..1a4bb0120b1 --- /dev/null +++ b/ios/Images.xcassets/badges/gravityBadgeLarge.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "gravityBadgeLarge.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "gravityBadgeLarge@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "gravityBadgeLarge@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/gravityBadgeLarge.imageset/gravityBadgeLarge.png b/ios/Images.xcassets/badges/gravityBadgeLarge.imageset/gravityBadgeLarge.png new file mode 100644 index 00000000000..ccfed23d64b Binary files /dev/null and b/ios/Images.xcassets/badges/gravityBadgeLarge.imageset/gravityBadgeLarge.png differ diff --git a/ios/Images.xcassets/badges/gravityBadgeLarge.imageset/gravityBadgeLarge@2x.png b/ios/Images.xcassets/badges/gravityBadgeLarge.imageset/gravityBadgeLarge@2x.png new file mode 100644 index 00000000000..51e00178021 Binary files /dev/null and b/ios/Images.xcassets/badges/gravityBadgeLarge.imageset/gravityBadgeLarge@2x.png differ diff --git a/ios/Images.xcassets/badges/gravityBadgeLarge.imageset/gravityBadgeLarge@3x.png b/ios/Images.xcassets/badges/gravityBadgeLarge.imageset/gravityBadgeLarge@3x.png new file mode 100644 index 00000000000..805d9fcd7b9 Binary files /dev/null and b/ios/Images.xcassets/badges/gravityBadgeLarge.imageset/gravityBadgeLarge@3x.png differ diff --git a/ios/Images.xcassets/badges/gravityBadgeLargeDark.imageset/Contents.json b/ios/Images.xcassets/badges/gravityBadgeLargeDark.imageset/Contents.json new file mode 100644 index 00000000000..0d735b28d3a --- /dev/null +++ b/ios/Images.xcassets/badges/gravityBadgeLargeDark.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "gravityBadgeLargeDark.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "gravityBadgeLargeDark@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "gravityBadgeLargeDark@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/gravityBadgeLargeDark.imageset/gravityBadgeLargeDark.png b/ios/Images.xcassets/badges/gravityBadgeLargeDark.imageset/gravityBadgeLargeDark.png new file mode 100644 index 00000000000..ab9ee2fcbae Binary files /dev/null and b/ios/Images.xcassets/badges/gravityBadgeLargeDark.imageset/gravityBadgeLargeDark.png differ diff --git a/ios/Images.xcassets/badges/gravityBadgeLargeDark.imageset/gravityBadgeLargeDark@2x.png b/ios/Images.xcassets/badges/gravityBadgeLargeDark.imageset/gravityBadgeLargeDark@2x.png new file mode 100644 index 00000000000..067b373a7e4 Binary files /dev/null and b/ios/Images.xcassets/badges/gravityBadgeLargeDark.imageset/gravityBadgeLargeDark@2x.png differ diff --git a/ios/Images.xcassets/badges/gravityBadgeLargeDark.imageset/gravityBadgeLargeDark@3x.png b/ios/Images.xcassets/badges/gravityBadgeLargeDark.imageset/gravityBadgeLargeDark@3x.png new file mode 100644 index 00000000000..362d6f3d772 Binary files /dev/null and b/ios/Images.xcassets/badges/gravityBadgeLargeDark.imageset/gravityBadgeLargeDark@3x.png differ diff --git a/ios/Images.xcassets/badges/gravityBadgeNoShadow.imageset/Contents.json b/ios/Images.xcassets/badges/gravityBadgeNoShadow.imageset/Contents.json new file mode 100644 index 00000000000..33f754ed1be --- /dev/null +++ b/ios/Images.xcassets/badges/gravityBadgeNoShadow.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "gravityBadgeNoShadow.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "gravityBadgeNoShadow@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "gravityBadgeNoShadow@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/gravityBadgeNoShadow.imageset/gravityBadgeNoShadow.png b/ios/Images.xcassets/badges/gravityBadgeNoShadow.imageset/gravityBadgeNoShadow.png new file mode 100644 index 00000000000..9492a525822 Binary files /dev/null and b/ios/Images.xcassets/badges/gravityBadgeNoShadow.imageset/gravityBadgeNoShadow.png differ diff --git a/ios/Images.xcassets/badges/gravityBadgeNoShadow.imageset/gravityBadgeNoShadow@2x.png b/ios/Images.xcassets/badges/gravityBadgeNoShadow.imageset/gravityBadgeNoShadow@2x.png new file mode 100644 index 00000000000..5052d829f1e Binary files /dev/null and b/ios/Images.xcassets/badges/gravityBadgeNoShadow.imageset/gravityBadgeNoShadow@2x.png differ diff --git a/ios/Images.xcassets/badges/gravityBadgeNoShadow.imageset/gravityBadgeNoShadow@3x.png b/ios/Images.xcassets/badges/gravityBadgeNoShadow.imageset/gravityBadgeNoShadow@3x.png new file mode 100644 index 00000000000..474f948bf99 Binary files /dev/null and b/ios/Images.xcassets/badges/gravityBadgeNoShadow.imageset/gravityBadgeNoShadow@3x.png differ diff --git a/ios/Images.xcassets/badges/linea.imageset/Contents.json b/ios/Images.xcassets/badges/linea.imageset/Contents.json new file mode 100644 index 00000000000..673ca809472 --- /dev/null +++ b/ios/Images.xcassets/badges/linea.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "linea.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "linea@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "linea@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/linea.imageset/linea.png b/ios/Images.xcassets/badges/linea.imageset/linea.png new file mode 100644 index 00000000000..14e4a7fface Binary files /dev/null and b/ios/Images.xcassets/badges/linea.imageset/linea.png differ diff --git a/ios/Images.xcassets/badges/linea.imageset/linea@2x.png b/ios/Images.xcassets/badges/linea.imageset/linea@2x.png new file mode 100644 index 00000000000..42f41b35f9d Binary files /dev/null and b/ios/Images.xcassets/badges/linea.imageset/linea@2x.png differ diff --git a/ios/Images.xcassets/badges/linea.imageset/linea@3x.png b/ios/Images.xcassets/badges/linea.imageset/linea@3x.png new file mode 100644 index 00000000000..4cc7abd0cdc Binary files /dev/null and b/ios/Images.xcassets/badges/linea.imageset/linea@3x.png differ diff --git a/ios/Images.xcassets/badges/lineaBadge.imageset/Contents.json b/ios/Images.xcassets/badges/lineaBadge.imageset/Contents.json new file mode 100644 index 00000000000..01ecb7425f8 --- /dev/null +++ b/ios/Images.xcassets/badges/lineaBadge.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "lineaBadge.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "lineaBadge@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "lineaBadge@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/lineaBadge.imageset/lineaBadge.png b/ios/Images.xcassets/badges/lineaBadge.imageset/lineaBadge.png new file mode 100644 index 00000000000..267723587ca Binary files /dev/null and b/ios/Images.xcassets/badges/lineaBadge.imageset/lineaBadge.png differ diff --git a/ios/Images.xcassets/badges/lineaBadge.imageset/lineaBadge@2x.png b/ios/Images.xcassets/badges/lineaBadge.imageset/lineaBadge@2x.png new file mode 100644 index 00000000000..70bb69fae24 Binary files /dev/null and b/ios/Images.xcassets/badges/lineaBadge.imageset/lineaBadge@2x.png differ diff --git a/ios/Images.xcassets/badges/lineaBadge.imageset/lineaBadge@3x.png b/ios/Images.xcassets/badges/lineaBadge.imageset/lineaBadge@3x.png new file mode 100644 index 00000000000..814892f7fdb Binary files /dev/null and b/ios/Images.xcassets/badges/lineaBadge.imageset/lineaBadge@3x.png differ diff --git a/ios/Images.xcassets/badges/lineaBadgeDark.imageset/Contents.json b/ios/Images.xcassets/badges/lineaBadgeDark.imageset/Contents.json new file mode 100644 index 00000000000..18b85aa99d7 --- /dev/null +++ b/ios/Images.xcassets/badges/lineaBadgeDark.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "lineaBadgeDark.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "lineaBadgeDark@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "lineaBadgeDark@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/lineaBadgeDark.imageset/lineaBadgeDark.png b/ios/Images.xcassets/badges/lineaBadgeDark.imageset/lineaBadgeDark.png new file mode 100644 index 00000000000..1fa46075d00 Binary files /dev/null and b/ios/Images.xcassets/badges/lineaBadgeDark.imageset/lineaBadgeDark.png differ diff --git a/ios/Images.xcassets/badges/lineaBadgeDark.imageset/lineaBadgeDark@2x.png b/ios/Images.xcassets/badges/lineaBadgeDark.imageset/lineaBadgeDark@2x.png new file mode 100644 index 00000000000..152eb8d6177 Binary files /dev/null and b/ios/Images.xcassets/badges/lineaBadgeDark.imageset/lineaBadgeDark@2x.png differ diff --git a/ios/Images.xcassets/badges/lineaBadgeDark.imageset/lineaBadgeDark@3x.png b/ios/Images.xcassets/badges/lineaBadgeDark.imageset/lineaBadgeDark@3x.png new file mode 100644 index 00000000000..a58ff5b93ac Binary files /dev/null and b/ios/Images.xcassets/badges/lineaBadgeDark.imageset/lineaBadgeDark@3x.png differ diff --git a/ios/Images.xcassets/badges/lineaBadgeLarge.imageset/Contents.json b/ios/Images.xcassets/badges/lineaBadgeLarge.imageset/Contents.json new file mode 100644 index 00000000000..ed3cb5016ee --- /dev/null +++ b/ios/Images.xcassets/badges/lineaBadgeLarge.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "lineaBadgeLarge.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "lineaBadgeLarge@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "lineaBadgeLarge@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/lineaBadgeLarge.imageset/lineaBadgeLarge.png b/ios/Images.xcassets/badges/lineaBadgeLarge.imageset/lineaBadgeLarge.png new file mode 100644 index 00000000000..93a23a92347 Binary files /dev/null and b/ios/Images.xcassets/badges/lineaBadgeLarge.imageset/lineaBadgeLarge.png differ diff --git a/ios/Images.xcassets/badges/lineaBadgeLarge.imageset/lineaBadgeLarge@2x.png b/ios/Images.xcassets/badges/lineaBadgeLarge.imageset/lineaBadgeLarge@2x.png new file mode 100644 index 00000000000..0fe5d25acdf Binary files /dev/null and b/ios/Images.xcassets/badges/lineaBadgeLarge.imageset/lineaBadgeLarge@2x.png differ diff --git a/ios/Images.xcassets/badges/lineaBadgeLarge.imageset/lineaBadgeLarge@3x.png b/ios/Images.xcassets/badges/lineaBadgeLarge.imageset/lineaBadgeLarge@3x.png new file mode 100644 index 00000000000..4f3a3c0ce1c Binary files /dev/null and b/ios/Images.xcassets/badges/lineaBadgeLarge.imageset/lineaBadgeLarge@3x.png differ diff --git a/ios/Images.xcassets/badges/lineaBadgeLargeDark.imageset/Contents.json b/ios/Images.xcassets/badges/lineaBadgeLargeDark.imageset/Contents.json new file mode 100644 index 00000000000..0a56a80d868 --- /dev/null +++ b/ios/Images.xcassets/badges/lineaBadgeLargeDark.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "lineaBadgeLargeDark.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "lineaBadgeLargeDark@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "lineaBadgeLargeDark@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/lineaBadgeLargeDark.imageset/lineaBadgeLargeDark.png b/ios/Images.xcassets/badges/lineaBadgeLargeDark.imageset/lineaBadgeLargeDark.png new file mode 100644 index 00000000000..f463c5abcc7 Binary files /dev/null and b/ios/Images.xcassets/badges/lineaBadgeLargeDark.imageset/lineaBadgeLargeDark.png differ diff --git a/ios/Images.xcassets/badges/lineaBadgeLargeDark.imageset/lineaBadgeLargeDark@2x.png b/ios/Images.xcassets/badges/lineaBadgeLargeDark.imageset/lineaBadgeLargeDark@2x.png new file mode 100644 index 00000000000..f417f8f1f16 Binary files /dev/null and b/ios/Images.xcassets/badges/lineaBadgeLargeDark.imageset/lineaBadgeLargeDark@2x.png differ diff --git a/ios/Images.xcassets/badges/lineaBadgeLargeDark.imageset/lineaBadgeLargeDark@3x.png b/ios/Images.xcassets/badges/lineaBadgeLargeDark.imageset/lineaBadgeLargeDark@3x.png new file mode 100644 index 00000000000..86c51a9e20b Binary files /dev/null and b/ios/Images.xcassets/badges/lineaBadgeLargeDark.imageset/lineaBadgeLargeDark@3x.png differ diff --git a/ios/Images.xcassets/badges/lineaBadgeNoShadow.imageset/Contents.json b/ios/Images.xcassets/badges/lineaBadgeNoShadow.imageset/Contents.json new file mode 100644 index 00000000000..1e5565d1c2c --- /dev/null +++ b/ios/Images.xcassets/badges/lineaBadgeNoShadow.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "lineaBadgeNoShadow.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "lineaBadgeNoShadow@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "lineaBadgeNoShadow@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/lineaBadgeNoShadow.imageset/lineaBadgeNoShadow.png b/ios/Images.xcassets/badges/lineaBadgeNoShadow.imageset/lineaBadgeNoShadow.png new file mode 100644 index 00000000000..1af3c5fd42d Binary files /dev/null and b/ios/Images.xcassets/badges/lineaBadgeNoShadow.imageset/lineaBadgeNoShadow.png differ diff --git a/ios/Images.xcassets/badges/lineaBadgeNoShadow.imageset/lineaBadgeNoShadow@2x.png b/ios/Images.xcassets/badges/lineaBadgeNoShadow.imageset/lineaBadgeNoShadow@2x.png new file mode 100644 index 00000000000..cddfa99c67f Binary files /dev/null and b/ios/Images.xcassets/badges/lineaBadgeNoShadow.imageset/lineaBadgeNoShadow@2x.png differ diff --git a/ios/Images.xcassets/badges/lineaBadgeNoShadow.imageset/lineaBadgeNoShadow@3x.png b/ios/Images.xcassets/badges/lineaBadgeNoShadow.imageset/lineaBadgeNoShadow@3x.png new file mode 100644 index 00000000000..22007385103 Binary files /dev/null and b/ios/Images.xcassets/badges/lineaBadgeNoShadow.imageset/lineaBadgeNoShadow@3x.png differ diff --git a/ios/Images.xcassets/badges/sankBadgeDark.imageset/Contents.json b/ios/Images.xcassets/badges/sankBadgeDark.imageset/Contents.json new file mode 100644 index 00000000000..da70d3d22ef --- /dev/null +++ b/ios/Images.xcassets/badges/sankBadgeDark.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "sankBadgeDark.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "sankBadgeDark@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "sankBadgeDark@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/sankBadgeDark.imageset/sankBadgeDark.png b/ios/Images.xcassets/badges/sankBadgeDark.imageset/sankBadgeDark.png new file mode 100644 index 00000000000..6ab341257ab Binary files /dev/null and b/ios/Images.xcassets/badges/sankBadgeDark.imageset/sankBadgeDark.png differ diff --git a/ios/Images.xcassets/badges/sankBadgeDark.imageset/sankBadgeDark@2x.png b/ios/Images.xcassets/badges/sankBadgeDark.imageset/sankBadgeDark@2x.png new file mode 100644 index 00000000000..d4e5beded3f Binary files /dev/null and b/ios/Images.xcassets/badges/sankBadgeDark.imageset/sankBadgeDark@2x.png differ diff --git a/ios/Images.xcassets/badges/sankBadgeDark.imageset/sankBadgeDark@3x.png b/ios/Images.xcassets/badges/sankBadgeDark.imageset/sankBadgeDark@3x.png new file mode 100644 index 00000000000..9b5eba8fe7a Binary files /dev/null and b/ios/Images.xcassets/badges/sankBadgeDark.imageset/sankBadgeDark@3x.png differ diff --git a/ios/Images.xcassets/badges/sanko.imageset/Contents.json b/ios/Images.xcassets/badges/sanko.imageset/Contents.json new file mode 100644 index 00000000000..ba52a5b3aeb --- /dev/null +++ b/ios/Images.xcassets/badges/sanko.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "sanko.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "sanko@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "sanko@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/sanko.imageset/sanko.png b/ios/Images.xcassets/badges/sanko.imageset/sanko.png new file mode 100644 index 00000000000..e0eff636cac Binary files /dev/null and b/ios/Images.xcassets/badges/sanko.imageset/sanko.png differ diff --git a/ios/Images.xcassets/badges/sanko.imageset/sanko@2x.png b/ios/Images.xcassets/badges/sanko.imageset/sanko@2x.png new file mode 100644 index 00000000000..399f9ad13e6 Binary files /dev/null and b/ios/Images.xcassets/badges/sanko.imageset/sanko@2x.png differ diff --git a/ios/Images.xcassets/badges/sanko.imageset/sanko@3x.png b/ios/Images.xcassets/badges/sanko.imageset/sanko@3x.png new file mode 100644 index 00000000000..c5c5e42e575 Binary files /dev/null and b/ios/Images.xcassets/badges/sanko.imageset/sanko@3x.png differ diff --git a/ios/Images.xcassets/badges/sankoBadge.imageset/Contents.json b/ios/Images.xcassets/badges/sankoBadge.imageset/Contents.json new file mode 100644 index 00000000000..e34f3e90e70 --- /dev/null +++ b/ios/Images.xcassets/badges/sankoBadge.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "sankoBadge.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "sankoBadge@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "sankoBadge@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/sankoBadge.imageset/sankoBadge.png b/ios/Images.xcassets/badges/sankoBadge.imageset/sankoBadge.png new file mode 100644 index 00000000000..3e44d659f3a Binary files /dev/null and b/ios/Images.xcassets/badges/sankoBadge.imageset/sankoBadge.png differ diff --git a/ios/Images.xcassets/badges/sankoBadge.imageset/sankoBadge@2x.png b/ios/Images.xcassets/badges/sankoBadge.imageset/sankoBadge@2x.png new file mode 100644 index 00000000000..39a74fcdc8d Binary files /dev/null and b/ios/Images.xcassets/badges/sankoBadge.imageset/sankoBadge@2x.png differ diff --git a/ios/Images.xcassets/badges/sankoBadge.imageset/sankoBadge@3x.png b/ios/Images.xcassets/badges/sankoBadge.imageset/sankoBadge@3x.png new file mode 100644 index 00000000000..a9729e07af3 Binary files /dev/null and b/ios/Images.xcassets/badges/sankoBadge.imageset/sankoBadge@3x.png differ diff --git a/ios/Images.xcassets/badges/sankoBadgeLarge.imageset/Contents.json b/ios/Images.xcassets/badges/sankoBadgeLarge.imageset/Contents.json new file mode 100644 index 00000000000..8d3d05e697d --- /dev/null +++ b/ios/Images.xcassets/badges/sankoBadgeLarge.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "sankoBadgeLarge.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "sankoBadgeLarge@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "sankoBadgeLarge@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/sankoBadgeLarge.imageset/sankoBadgeLarge.png b/ios/Images.xcassets/badges/sankoBadgeLarge.imageset/sankoBadgeLarge.png new file mode 100644 index 00000000000..e2ead662090 Binary files /dev/null and b/ios/Images.xcassets/badges/sankoBadgeLarge.imageset/sankoBadgeLarge.png differ diff --git a/ios/Images.xcassets/badges/sankoBadgeLarge.imageset/sankoBadgeLarge@2x.png b/ios/Images.xcassets/badges/sankoBadgeLarge.imageset/sankoBadgeLarge@2x.png new file mode 100644 index 00000000000..726dfc00978 Binary files /dev/null and b/ios/Images.xcassets/badges/sankoBadgeLarge.imageset/sankoBadgeLarge@2x.png differ diff --git a/ios/Images.xcassets/badges/sankoBadgeLarge.imageset/sankoBadgeLarge@3x.png b/ios/Images.xcassets/badges/sankoBadgeLarge.imageset/sankoBadgeLarge@3x.png new file mode 100644 index 00000000000..897a700db31 Binary files /dev/null and b/ios/Images.xcassets/badges/sankoBadgeLarge.imageset/sankoBadgeLarge@3x.png differ diff --git a/ios/Images.xcassets/badges/sankoBadgeLargeDark.imageset/Contents.json b/ios/Images.xcassets/badges/sankoBadgeLargeDark.imageset/Contents.json new file mode 100644 index 00000000000..969adc60502 --- /dev/null +++ b/ios/Images.xcassets/badges/sankoBadgeLargeDark.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "sankoBadgeLargeDark.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "sankoBadgeLargeDark@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "sankoBadgeLargeDark@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/sankoBadgeLargeDark.imageset/sankoBadgeLargeDark.png b/ios/Images.xcassets/badges/sankoBadgeLargeDark.imageset/sankoBadgeLargeDark.png new file mode 100644 index 00000000000..0218596d5bb Binary files /dev/null and b/ios/Images.xcassets/badges/sankoBadgeLargeDark.imageset/sankoBadgeLargeDark.png differ diff --git a/ios/Images.xcassets/badges/sankoBadgeLargeDark.imageset/sankoBadgeLargeDark@2x.png b/ios/Images.xcassets/badges/sankoBadgeLargeDark.imageset/sankoBadgeLargeDark@2x.png new file mode 100644 index 00000000000..40c50ffecf6 Binary files /dev/null and b/ios/Images.xcassets/badges/sankoBadgeLargeDark.imageset/sankoBadgeLargeDark@2x.png differ diff --git a/ios/Images.xcassets/badges/sankoBadgeLargeDark.imageset/sankoBadgeLargeDark@3x.png b/ios/Images.xcassets/badges/sankoBadgeLargeDark.imageset/sankoBadgeLargeDark@3x.png new file mode 100644 index 00000000000..f683ef22d4b Binary files /dev/null and b/ios/Images.xcassets/badges/sankoBadgeLargeDark.imageset/sankoBadgeLargeDark@3x.png differ diff --git a/ios/Images.xcassets/badges/sankoBadgeNoShadow.imageset/Contents.json b/ios/Images.xcassets/badges/sankoBadgeNoShadow.imageset/Contents.json new file mode 100644 index 00000000000..3b1ea006654 --- /dev/null +++ b/ios/Images.xcassets/badges/sankoBadgeNoShadow.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "sankoBadgeNoShadow.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "sankoBadgeNoShadow@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "sankoBadgeNoShadow@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/sankoBadgeNoShadow.imageset/sankoBadgeNoShadow.png b/ios/Images.xcassets/badges/sankoBadgeNoShadow.imageset/sankoBadgeNoShadow.png new file mode 100644 index 00000000000..b0b2c0385ac Binary files /dev/null and b/ios/Images.xcassets/badges/sankoBadgeNoShadow.imageset/sankoBadgeNoShadow.png differ diff --git a/ios/Images.xcassets/badges/sankoBadgeNoShadow.imageset/sankoBadgeNoShadow@2x.png b/ios/Images.xcassets/badges/sankoBadgeNoShadow.imageset/sankoBadgeNoShadow@2x.png new file mode 100644 index 00000000000..990e00a88b0 Binary files /dev/null and b/ios/Images.xcassets/badges/sankoBadgeNoShadow.imageset/sankoBadgeNoShadow@2x.png differ diff --git a/ios/Images.xcassets/badges/sankoBadgeNoShadow.imageset/sankoBadgeNoShadow@3x.png b/ios/Images.xcassets/badges/sankoBadgeNoShadow.imageset/sankoBadgeNoShadow@3x.png new file mode 100644 index 00000000000..f79b957c903 Binary files /dev/null and b/ios/Images.xcassets/badges/sankoBadgeNoShadow.imageset/sankoBadgeNoShadow@3x.png differ diff --git a/ios/Images.xcassets/badges/scroll.imageset/Contents.json b/ios/Images.xcassets/badges/scroll.imageset/Contents.json new file mode 100644 index 00000000000..2496dd78ca3 --- /dev/null +++ b/ios/Images.xcassets/badges/scroll.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "scroll.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "scroll@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "scroll@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/scroll.imageset/scroll.png b/ios/Images.xcassets/badges/scroll.imageset/scroll.png new file mode 100644 index 00000000000..b074e4e54f3 Binary files /dev/null and b/ios/Images.xcassets/badges/scroll.imageset/scroll.png differ diff --git a/ios/Images.xcassets/badges/scroll.imageset/scroll@2x.png b/ios/Images.xcassets/badges/scroll.imageset/scroll@2x.png new file mode 100644 index 00000000000..1dab422416c Binary files /dev/null and b/ios/Images.xcassets/badges/scroll.imageset/scroll@2x.png differ diff --git a/ios/Images.xcassets/badges/scroll.imageset/scroll@3x.png b/ios/Images.xcassets/badges/scroll.imageset/scroll@3x.png new file mode 100644 index 00000000000..04482628c63 Binary files /dev/null and b/ios/Images.xcassets/badges/scroll.imageset/scroll@3x.png differ diff --git a/ios/Images.xcassets/badges/scrollBadge.imageset/Contents.json b/ios/Images.xcassets/badges/scrollBadge.imageset/Contents.json new file mode 100644 index 00000000000..764ef1d584d --- /dev/null +++ b/ios/Images.xcassets/badges/scrollBadge.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "scrollBadge.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "scrollBadge@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "scrollBadge@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/scrollBadge.imageset/scrollBadge.png b/ios/Images.xcassets/badges/scrollBadge.imageset/scrollBadge.png new file mode 100644 index 00000000000..3266ab33b57 Binary files /dev/null and b/ios/Images.xcassets/badges/scrollBadge.imageset/scrollBadge.png differ diff --git a/ios/Images.xcassets/badges/scrollBadge.imageset/scrollBadge@2x.png b/ios/Images.xcassets/badges/scrollBadge.imageset/scrollBadge@2x.png new file mode 100644 index 00000000000..aea2e050f18 Binary files /dev/null and b/ios/Images.xcassets/badges/scrollBadge.imageset/scrollBadge@2x.png differ diff --git a/ios/Images.xcassets/badges/scrollBadge.imageset/scrollBadge@3x.png b/ios/Images.xcassets/badges/scrollBadge.imageset/scrollBadge@3x.png new file mode 100644 index 00000000000..40f77762f36 Binary files /dev/null and b/ios/Images.xcassets/badges/scrollBadge.imageset/scrollBadge@3x.png differ diff --git a/ios/Images.xcassets/badges/scrollBadgeDark.imageset/Contents.json b/ios/Images.xcassets/badges/scrollBadgeDark.imageset/Contents.json new file mode 100644 index 00000000000..a11922fe560 --- /dev/null +++ b/ios/Images.xcassets/badges/scrollBadgeDark.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "scrollBadgeDark.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "scrollBadgeDark@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "scrollBadgeDark@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/scrollBadgeDark.imageset/scrollBadgeDark.png b/ios/Images.xcassets/badges/scrollBadgeDark.imageset/scrollBadgeDark.png new file mode 100644 index 00000000000..71927e891e8 Binary files /dev/null and b/ios/Images.xcassets/badges/scrollBadgeDark.imageset/scrollBadgeDark.png differ diff --git a/ios/Images.xcassets/badges/scrollBadgeDark.imageset/scrollBadgeDark@2x.png b/ios/Images.xcassets/badges/scrollBadgeDark.imageset/scrollBadgeDark@2x.png new file mode 100644 index 00000000000..53095e21774 Binary files /dev/null and b/ios/Images.xcassets/badges/scrollBadgeDark.imageset/scrollBadgeDark@2x.png differ diff --git a/ios/Images.xcassets/badges/scrollBadgeDark.imageset/scrollBadgeDark@3x.png b/ios/Images.xcassets/badges/scrollBadgeDark.imageset/scrollBadgeDark@3x.png new file mode 100644 index 00000000000..5bfd03fdd2b Binary files /dev/null and b/ios/Images.xcassets/badges/scrollBadgeDark.imageset/scrollBadgeDark@3x.png differ diff --git a/ios/Images.xcassets/badges/scrollBadgeLarge.imageset/Contents.json b/ios/Images.xcassets/badges/scrollBadgeLarge.imageset/Contents.json new file mode 100644 index 00000000000..94fc4d4b6e8 --- /dev/null +++ b/ios/Images.xcassets/badges/scrollBadgeLarge.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "scrollBadgeLarge.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "scrollBadgeLarge@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "scrollBadgeLarge@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/scrollBadgeLarge.imageset/scrollBadgeLarge.png b/ios/Images.xcassets/badges/scrollBadgeLarge.imageset/scrollBadgeLarge.png new file mode 100644 index 00000000000..cc1dbc31e63 Binary files /dev/null and b/ios/Images.xcassets/badges/scrollBadgeLarge.imageset/scrollBadgeLarge.png differ diff --git a/ios/Images.xcassets/badges/scrollBadgeLarge.imageset/scrollBadgeLarge@2x.png b/ios/Images.xcassets/badges/scrollBadgeLarge.imageset/scrollBadgeLarge@2x.png new file mode 100644 index 00000000000..c60eca2ff99 Binary files /dev/null and b/ios/Images.xcassets/badges/scrollBadgeLarge.imageset/scrollBadgeLarge@2x.png differ diff --git a/ios/Images.xcassets/badges/scrollBadgeLarge.imageset/scrollBadgeLarge@3x.png b/ios/Images.xcassets/badges/scrollBadgeLarge.imageset/scrollBadgeLarge@3x.png new file mode 100644 index 00000000000..8be695f8247 Binary files /dev/null and b/ios/Images.xcassets/badges/scrollBadgeLarge.imageset/scrollBadgeLarge@3x.png differ diff --git a/ios/Images.xcassets/badges/scrollBadgeLargeDark.imageset/Contents.json b/ios/Images.xcassets/badges/scrollBadgeLargeDark.imageset/Contents.json new file mode 100644 index 00000000000..e6b3dcb2f44 --- /dev/null +++ b/ios/Images.xcassets/badges/scrollBadgeLargeDark.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "scrollBadgeLargeDark.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "scrollBadgeLargeDark@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "scrollBadgeLargeDark@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/scrollBadgeLargeDark.imageset/scrollBadgeLargeDark.png b/ios/Images.xcassets/badges/scrollBadgeLargeDark.imageset/scrollBadgeLargeDark.png new file mode 100644 index 00000000000..5ecf4f2dff7 Binary files /dev/null and b/ios/Images.xcassets/badges/scrollBadgeLargeDark.imageset/scrollBadgeLargeDark.png differ diff --git a/ios/Images.xcassets/badges/scrollBadgeLargeDark.imageset/scrollBadgeLargeDark@2x.png b/ios/Images.xcassets/badges/scrollBadgeLargeDark.imageset/scrollBadgeLargeDark@2x.png new file mode 100644 index 00000000000..5c6b5d6a50c Binary files /dev/null and b/ios/Images.xcassets/badges/scrollBadgeLargeDark.imageset/scrollBadgeLargeDark@2x.png differ diff --git a/ios/Images.xcassets/badges/scrollBadgeLargeDark.imageset/scrollBadgeLargeDark@3x.png b/ios/Images.xcassets/badges/scrollBadgeLargeDark.imageset/scrollBadgeLargeDark@3x.png new file mode 100644 index 00000000000..0e508374d35 Binary files /dev/null and b/ios/Images.xcassets/badges/scrollBadgeLargeDark.imageset/scrollBadgeLargeDark@3x.png differ diff --git a/ios/Images.xcassets/badges/scrollBadgeNoShadow.imageset/Contents.json b/ios/Images.xcassets/badges/scrollBadgeNoShadow.imageset/Contents.json new file mode 100644 index 00000000000..6a6f34f28ca --- /dev/null +++ b/ios/Images.xcassets/badges/scrollBadgeNoShadow.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "scrollBadgeNoShadow.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "scrollBadgeNoShadow@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "scrollBadgeNoShadow@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/scrollBadgeNoShadow.imageset/scrollBadgeNoShadow.png b/ios/Images.xcassets/badges/scrollBadgeNoShadow.imageset/scrollBadgeNoShadow.png new file mode 100644 index 00000000000..cfdef2d77c9 Binary files /dev/null and b/ios/Images.xcassets/badges/scrollBadgeNoShadow.imageset/scrollBadgeNoShadow.png differ diff --git a/ios/Images.xcassets/badges/scrollBadgeNoShadow.imageset/scrollBadgeNoShadow@2x.png b/ios/Images.xcassets/badges/scrollBadgeNoShadow.imageset/scrollBadgeNoShadow@2x.png new file mode 100644 index 00000000000..79c1aa6e3b0 Binary files /dev/null and b/ios/Images.xcassets/badges/scrollBadgeNoShadow.imageset/scrollBadgeNoShadow@2x.png differ diff --git a/ios/Images.xcassets/badges/scrollBadgeNoShadow.imageset/scrollBadgeNoShadow@3x.png b/ios/Images.xcassets/badges/scrollBadgeNoShadow.imageset/scrollBadgeNoShadow@3x.png new file mode 100644 index 00000000000..d140debde92 Binary files /dev/null and b/ios/Images.xcassets/badges/scrollBadgeNoShadow.imageset/scrollBadgeNoShadow@3x.png differ diff --git a/ios/Images.xcassets/badges/zkSyncBadge.imageset/Contents.json b/ios/Images.xcassets/badges/zkSyncBadge.imageset/Contents.json new file mode 100644 index 00000000000..0a103fcddc5 --- /dev/null +++ b/ios/Images.xcassets/badges/zkSyncBadge.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "zkSyncBadge.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "zkSyncBadge@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "zkSyncBadge@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/zkSyncBadge.imageset/zkSyncBadge.png b/ios/Images.xcassets/badges/zkSyncBadge.imageset/zkSyncBadge.png new file mode 100644 index 00000000000..f84a89c233f Binary files /dev/null and b/ios/Images.xcassets/badges/zkSyncBadge.imageset/zkSyncBadge.png differ diff --git a/ios/Images.xcassets/badges/zkSyncBadge.imageset/zkSyncBadge@2x.png b/ios/Images.xcassets/badges/zkSyncBadge.imageset/zkSyncBadge@2x.png new file mode 100644 index 00000000000..02a0f753727 Binary files /dev/null and b/ios/Images.xcassets/badges/zkSyncBadge.imageset/zkSyncBadge@2x.png differ diff --git a/ios/Images.xcassets/badges/zkSyncBadge.imageset/zkSyncBadge@3x.png b/ios/Images.xcassets/badges/zkSyncBadge.imageset/zkSyncBadge@3x.png new file mode 100644 index 00000000000..db578e63d79 Binary files /dev/null and b/ios/Images.xcassets/badges/zkSyncBadge.imageset/zkSyncBadge@3x.png differ diff --git a/ios/Images.xcassets/badges/zksync.imageset/Contents.json b/ios/Images.xcassets/badges/zksync.imageset/Contents.json new file mode 100644 index 00000000000..c6ca19bfaf8 --- /dev/null +++ b/ios/Images.xcassets/badges/zksync.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "zksync.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "zksync@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "zksync@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/zksync.imageset/zksync.png b/ios/Images.xcassets/badges/zksync.imageset/zksync.png new file mode 100644 index 00000000000..1225b4e6c6e Binary files /dev/null and b/ios/Images.xcassets/badges/zksync.imageset/zksync.png differ diff --git a/ios/Images.xcassets/badges/zksync.imageset/zksync@2x.png b/ios/Images.xcassets/badges/zksync.imageset/zksync@2x.png new file mode 100644 index 00000000000..b437d430a93 Binary files /dev/null and b/ios/Images.xcassets/badges/zksync.imageset/zksync@2x.png differ diff --git a/ios/Images.xcassets/badges/zksync.imageset/zksync@3x.png b/ios/Images.xcassets/badges/zksync.imageset/zksync@3x.png new file mode 100644 index 00000000000..2e433247e12 Binary files /dev/null and b/ios/Images.xcassets/badges/zksync.imageset/zksync@3x.png differ diff --git a/ios/Images.xcassets/badges/zksyncBadgeDark.imageset/Contents.json b/ios/Images.xcassets/badges/zksyncBadgeDark.imageset/Contents.json new file mode 100644 index 00000000000..c595c48304b --- /dev/null +++ b/ios/Images.xcassets/badges/zksyncBadgeDark.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "zksyncBadgeDark.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "zksyncBadgeDark@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "zksyncBadgeDark@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/zksyncBadgeDark.imageset/zksyncBadgeDark.png b/ios/Images.xcassets/badges/zksyncBadgeDark.imageset/zksyncBadgeDark.png new file mode 100644 index 00000000000..b6947dbcd88 Binary files /dev/null and b/ios/Images.xcassets/badges/zksyncBadgeDark.imageset/zksyncBadgeDark.png differ diff --git a/ios/Images.xcassets/badges/zksyncBadgeDark.imageset/zksyncBadgeDark@2x.png b/ios/Images.xcassets/badges/zksyncBadgeDark.imageset/zksyncBadgeDark@2x.png new file mode 100644 index 00000000000..77f075eb22e Binary files /dev/null and b/ios/Images.xcassets/badges/zksyncBadgeDark.imageset/zksyncBadgeDark@2x.png differ diff --git a/ios/Images.xcassets/badges/zksyncBadgeDark.imageset/zksyncBadgeDark@3x.png b/ios/Images.xcassets/badges/zksyncBadgeDark.imageset/zksyncBadgeDark@3x.png new file mode 100644 index 00000000000..a7ea118d5ce Binary files /dev/null and b/ios/Images.xcassets/badges/zksyncBadgeDark.imageset/zksyncBadgeDark@3x.png differ diff --git a/ios/Images.xcassets/badges/zksyncBadgeLarge.imageset/Contents.json b/ios/Images.xcassets/badges/zksyncBadgeLarge.imageset/Contents.json new file mode 100644 index 00000000000..8df41d41eeb --- /dev/null +++ b/ios/Images.xcassets/badges/zksyncBadgeLarge.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "zksyncBadgeLarge.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "zksyncBadgeLarge@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "zksyncBadgeLarge@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/zksyncBadgeLarge.imageset/zksyncBadgeLarge.png b/ios/Images.xcassets/badges/zksyncBadgeLarge.imageset/zksyncBadgeLarge.png new file mode 100644 index 00000000000..02190afd30f Binary files /dev/null and b/ios/Images.xcassets/badges/zksyncBadgeLarge.imageset/zksyncBadgeLarge.png differ diff --git a/ios/Images.xcassets/badges/zksyncBadgeLarge.imageset/zksyncBadgeLarge@2x.png b/ios/Images.xcassets/badges/zksyncBadgeLarge.imageset/zksyncBadgeLarge@2x.png new file mode 100644 index 00000000000..420b0f8531e Binary files /dev/null and b/ios/Images.xcassets/badges/zksyncBadgeLarge.imageset/zksyncBadgeLarge@2x.png differ diff --git a/ios/Images.xcassets/badges/zksyncBadgeLarge.imageset/zksyncBadgeLarge@3x.png b/ios/Images.xcassets/badges/zksyncBadgeLarge.imageset/zksyncBadgeLarge@3x.png new file mode 100644 index 00000000000..25aef546ecf Binary files /dev/null and b/ios/Images.xcassets/badges/zksyncBadgeLarge.imageset/zksyncBadgeLarge@3x.png differ diff --git a/ios/Images.xcassets/badges/zksyncBadgeLargeDark.imageset/Contents.json b/ios/Images.xcassets/badges/zksyncBadgeLargeDark.imageset/Contents.json new file mode 100644 index 00000000000..aae27eaf7dc --- /dev/null +++ b/ios/Images.xcassets/badges/zksyncBadgeLargeDark.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "zksyncBadgeLargeDark.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "zksyncBadgeLargeDark@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "zksyncBadgeLargeDark@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/zksyncBadgeLargeDark.imageset/zksyncBadgeLargeDark.png b/ios/Images.xcassets/badges/zksyncBadgeLargeDark.imageset/zksyncBadgeLargeDark.png new file mode 100644 index 00000000000..19a58296e9a Binary files /dev/null and b/ios/Images.xcassets/badges/zksyncBadgeLargeDark.imageset/zksyncBadgeLargeDark.png differ diff --git a/ios/Images.xcassets/badges/zksyncBadgeLargeDark.imageset/zksyncBadgeLargeDark@2x.png b/ios/Images.xcassets/badges/zksyncBadgeLargeDark.imageset/zksyncBadgeLargeDark@2x.png new file mode 100644 index 00000000000..ea8d6389607 Binary files /dev/null and b/ios/Images.xcassets/badges/zksyncBadgeLargeDark.imageset/zksyncBadgeLargeDark@2x.png differ diff --git a/ios/Images.xcassets/badges/zksyncBadgeLargeDark.imageset/zksyncBadgeLargeDark@3x.png b/ios/Images.xcassets/badges/zksyncBadgeLargeDark.imageset/zksyncBadgeLargeDark@3x.png new file mode 100644 index 00000000000..71a30293a2e Binary files /dev/null and b/ios/Images.xcassets/badges/zksyncBadgeLargeDark.imageset/zksyncBadgeLargeDark@3x.png differ diff --git a/ios/Images.xcassets/badges/zksyncBadgeNoShadow.imageset/Contents.json b/ios/Images.xcassets/badges/zksyncBadgeNoShadow.imageset/Contents.json new file mode 100644 index 00000000000..caf3f48aeb6 --- /dev/null +++ b/ios/Images.xcassets/badges/zksyncBadgeNoShadow.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "zksyncBadgeNoShadow.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "zksyncBadgeNoShadow@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "zksyncBadgeNoShadow@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/Images.xcassets/badges/zksyncBadgeNoShadow.imageset/zksyncBadgeNoShadow.png b/ios/Images.xcassets/badges/zksyncBadgeNoShadow.imageset/zksyncBadgeNoShadow.png new file mode 100644 index 00000000000..47b5500b5d0 Binary files /dev/null and b/ios/Images.xcassets/badges/zksyncBadgeNoShadow.imageset/zksyncBadgeNoShadow.png differ diff --git a/ios/Images.xcassets/badges/zksyncBadgeNoShadow.imageset/zksyncBadgeNoShadow@2x.png b/ios/Images.xcassets/badges/zksyncBadgeNoShadow.imageset/zksyncBadgeNoShadow@2x.png new file mode 100644 index 00000000000..97f1bc72954 Binary files /dev/null and b/ios/Images.xcassets/badges/zksyncBadgeNoShadow.imageset/zksyncBadgeNoShadow@2x.png differ diff --git a/ios/Images.xcassets/badges/zksyncBadgeNoShadow.imageset/zksyncBadgeNoShadow@3x.png b/ios/Images.xcassets/badges/zksyncBadgeNoShadow.imageset/zksyncBadgeNoShadow@3x.png new file mode 100644 index 00000000000..ed087b5f411 Binary files /dev/null and b/ios/Images.xcassets/badges/zksyncBadgeNoShadow.imageset/zksyncBadgeNoShadow@3x.png differ diff --git a/src/App.tsx b/src/App.tsx index a0121bab7f2..1a749b8ce6d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -38,6 +38,8 @@ import { IS_ANDROID, IS_DEV } from '@/env'; import { prefetchDefaultFavorites } from '@/resources/favorites'; import Routes from '@/navigation/Routes'; import { BackupsSync } from '@/state/sync/BackupsSync'; +import { BackendNetworks } from '@/components/BackendNetworks'; +import { AbsolutePortalRoot } from './components/AbsolutePortal'; if (IS_DEV) { reactNativeDisableYellowBox && LogBox.ignoreAllLogs(); @@ -78,6 +80,8 @@ function App({ walletReady }: AppProps) { + + ); } diff --git a/src/__swaps__/screens/Swap/components/AnimatedChainImage.android.tsx b/src/__swaps__/screens/Swap/components/AnimatedChainImage.android.tsx index fef6de976fd..b8e24ae905a 100644 --- a/src/__swaps__/screens/Swap/components/AnimatedChainImage.android.tsx +++ b/src/__swaps__/screens/Swap/components/AnimatedChainImage.android.tsx @@ -10,15 +10,15 @@ const BlastBadge = require('@/assets/badges/blast.png'); const BscBadge = require('@/assets/badges/bsc.png'); const DegenBadge = require('@/assets/badges/degen.png'); const EthereumBadge = require('@/assets/badges/ethereum.png'); -// const GnosisBadge = require('@/assets/badges/gnosis.png'); -// const GravityBadge = require('@/assets/badges/gravity.png'); +const GnosisBadge = require('@/assets/badges/gnosis.png'); +const GravityBadge = require('@/assets/badges/gravity.png'); const InkBadge = require('@/assets/badges/ink.png'); -// const LineaBadge = require('@/assets/badges/linea.png'); +const LineaBadge = require('@/assets/badges/linea.png'); const OptimismBadge = require('@/assets/badges/optimism.png'); const PolygonBadge = require('@/assets/badges/polygon.png'); -// const SankoBadge = require('@/assets/badges/sanko.png'); -// const ScrollBadge = require('@/assets/badges/scroll.png'); -// const ZksyncBadge = require('@/assets/badges/zksync.png'); +const SankoBadge = require('@/assets/badges/sanko.png'); +const ScrollBadge = require('@/assets/badges/scroll.png'); +const ZksyncBadge = require('@/assets/badges/zksync.png'); const ZoraBadge = require('@/assets/badges/zora.png'); import { ChainId } from '@/state/backendNetworks/types'; @@ -39,20 +39,20 @@ const networkBadges = { [ChainId.bsc]: BscBadge, [ChainId.bscTestnet]: BscBadge, [ChainId.degen]: DegenBadge, - // [ChainId.gnosis]: GnosisBadge, - // [ChainId.gravity]: GravityBadge, + [ChainId.gnosis]: GnosisBadge, + [ChainId.gravity]: GravityBadge, [ChainId.holesky]: EthereumBadge, [ChainId.ink]: InkBadge, - // [ChainId.linea]: LineaBadge, + [ChainId.linea]: LineaBadge, [ChainId.mainnet]: EthereumBadge, [ChainId.optimism]: OptimismBadge, [ChainId.optimismSepolia]: OptimismBadge, [ChainId.polygon]: PolygonBadge, [ChainId.polygonAmoy]: PolygonBadge, - // [ChainId.sanko]: SankoBadge, - // [ChainId.scroll]: ScrollBadge, + [ChainId.sanko]: SankoBadge, + [ChainId.scroll]: ScrollBadge, [ChainId.sepolia]: EthereumBadge, - // [ChainId.zksync]: ZksyncBadge, + [ChainId.zksync]: ZksyncBadge, [ChainId.zora]: ZoraBadge, [ChainId.zoraSepolia]: ZoraBadge, }; diff --git a/src/__swaps__/screens/Swap/components/AnimatedChainImage.ios.tsx b/src/__swaps__/screens/Swap/components/AnimatedChainImage.ios.tsx index bf382327e4e..15285091a15 100644 --- a/src/__swaps__/screens/Swap/components/AnimatedChainImage.ios.tsx +++ b/src/__swaps__/screens/Swap/components/AnimatedChainImage.ios.tsx @@ -17,15 +17,15 @@ import BlastBadge from '@/assets/badges/blast.png'; import BscBadge from '@/assets/badges/bsc.png'; import DegenBadge from '@/assets/badges/degen.png'; import EthereumBadge from '@/assets/badges/ethereum.png'; -// import GnosisBadge from '@/assets/badges/gnosis.png'; -// import GravityBadge from '@/assets/badges/gravity.png'; +import GnosisBadge from '@/assets/badges/gnosis.png'; +import GravityBadge from '@/assets/badges/gravity.png'; import InkBadge from '@/assets/badges/ink.png'; -// import LineaBadge from '@/assets/badges/linea.png'; +import LineaBadge from '@/assets/badges/linea.png'; import OptimismBadge from '@/assets/badges/optimism.png'; import PolygonBadge from '@/assets/badges/polygon.png'; -// import SankoBadge from '@/assets/badges/sanko.png'; -// import ScrollBadge from '@/assets/badges/scroll.png'; -// import ZksyncBadge from '@/assets/badges/zksync.png'; +import SankoBadge from '@/assets/badges/sanko.png'; +import ScrollBadge from '@/assets/badges/scroll.png'; +import ZksyncBadge from '@/assets/badges/zksync.png'; import ZoraBadge from '@/assets/badges/zora.png'; const networkBadges = { @@ -41,20 +41,20 @@ const networkBadges = { [ChainId.bsc]: Image.resolveAssetSource(BscBadge).uri, [ChainId.bscTestnet]: Image.resolveAssetSource(BscBadge).uri, [ChainId.degen]: Image.resolveAssetSource(DegenBadge).uri, - // [ChainId.gnosis]: Image.resolveAssetSource(GnosisBadge).uri, - // [ChainId.gravity]: Image.resolveAssetSource(GravityBadge).uri, + [ChainId.gnosis]: Image.resolveAssetSource(GnosisBadge).uri, + [ChainId.gravity]: Image.resolveAssetSource(GravityBadge).uri, [ChainId.holesky]: Image.resolveAssetSource(EthereumBadge).uri, [ChainId.ink]: Image.resolveAssetSource(InkBadge).uri, - // [ChainId.linea]: Image.resolveAssetSource(LineaBadge).uri, + [ChainId.linea]: Image.resolveAssetSource(LineaBadge).uri, [ChainId.mainnet]: Image.resolveAssetSource(EthereumBadge).uri, [ChainId.optimism]: Image.resolveAssetSource(OptimismBadge).uri, [ChainId.optimismSepolia]: Image.resolveAssetSource(OptimismBadge).uri, [ChainId.polygon]: Image.resolveAssetSource(PolygonBadge).uri, [ChainId.polygonAmoy]: Image.resolveAssetSource(PolygonBadge).uri, - // [ChainId.sanko]: Image.resolveAssetSource(SankoBadge).uri, - // [ChainId.scroll]: Image.resolveAssetSource(ScrollBadge).uri, + [ChainId.sanko]: Image.resolveAssetSource(SankoBadge).uri, + [ChainId.scroll]: Image.resolveAssetSource(ScrollBadge).uri, [ChainId.sepolia]: Image.resolveAssetSource(EthereumBadge).uri, - // [ChainId.zksync]: Image.resolveAssetSource(ZksyncBadge).uri, + [ChainId.zksync]: Image.resolveAssetSource(ZksyncBadge).uri, [ChainId.zora]: Image.resolveAssetSource(ZoraBadge).uri, [ChainId.zoraSepolia]: Image.resolveAssetSource(ZoraBadge).uri, }; diff --git a/src/__swaps__/screens/Swap/components/AnimatedSwapCoinIcon.tsx b/src/__swaps__/screens/Swap/components/AnimatedSwapCoinIcon.tsx index 2c8ba92b2ea..7d8ec66e8e1 100644 --- a/src/__swaps__/screens/Swap/components/AnimatedSwapCoinIcon.tsx +++ b/src/__swaps__/screens/Swap/components/AnimatedSwapCoinIcon.tsx @@ -14,37 +14,19 @@ import { IS_ANDROID, IS_IOS } from '@/env'; import { PIXEL_RATIO } from '@/utils/deviceUtils'; import { useSwapContext } from '../providers/swap-provider'; -const fallbackIconStyle = { - ...borders.buildCircleAsObject(32), - position: 'absolute' as ViewStyle['position'], -}; - -const largeFallbackIconStyle = { - ...borders.buildCircleAsObject(36), - position: 'absolute' as ViewStyle['position'], -}; - -const smallFallbackIconStyle = { - ...borders.buildCircleAsObject(16), - position: 'absolute' as ViewStyle['position'], -}; - export const AnimatedSwapCoinIcon = memo(function AnimatedSwapCoinIcon({ assetType, - large = true, - small, + size = 32, showBadge = true, }: { assetType: 'input' | 'output'; - large?: boolean; - small?: boolean; + size?: number; showBadge?: boolean; }) { const { isDarkMode, colors } = useTheme(); const { internalSelectedInputAsset, internalSelectedOutputAsset } = useSwapContext(); const asset = assetType === 'input' ? internalSelectedInputAsset : internalSelectedOutputAsset; - const size = small ? 16 : large ? 36 : 32; const didErrorForUniqueId = useSharedValue(undefined); @@ -91,15 +73,8 @@ export const AnimatedSwapCoinIcon = memo(function AnimatedSwapCoinIcon({ })); return ( - - + + {/* ⚠️ TODO: This works but we should figure out how to type this correctly to avoid this error */} {/* @ts-expect-error: Doesn't pick up that it's getting a source prop via animatedProps */} @@ -122,29 +97,14 @@ export const AnimatedSwapCoinIcon = memo(function AnimatedSwapCoinIcon({ /> - - + + @@ -153,28 +113,28 @@ export const AnimatedSwapCoinIcon = memo(function AnimatedSwapCoinIcon({ ); }); +const fallbackIconStyle = (size: number) => ({ + ...borders.buildCircleAsObject(size), + position: 'absolute' as ViewStyle['position'], +}); + +const coinIconFallbackStyle = (size: number) => ({ + borderRadius: size / 2, + height: size, + width: size, + overflow: 'visible' as const, +}); + +const containerStyle = (size: number) => ({ + elevation: 6, + height: size, + overflow: 'visible' as const, +}); + const sx = StyleSheet.create({ coinIcon: { overflow: 'hidden', }, - coinIconFallback: { - borderRadius: 16, - height: 32, - overflow: 'visible', - width: 32, - }, - coinIconFallbackLarge: { - borderRadius: 18, - height: 36, - overflow: 'visible', - width: 36, - }, - coinIconFallbackSmall: { - borderRadius: 8, - height: 16, - overflow: 'visible', - width: 16, - }, container: { elevation: 6, height: 32, diff --git a/src/__swaps__/screens/Swap/components/CoinRow.tsx b/src/__swaps__/screens/Swap/components/CoinRow.tsx index c3fb98919b1..dc1894bddf1 100644 --- a/src/__swaps__/screens/Swap/components/CoinRow.tsx +++ b/src/__swaps__/screens/Swap/components/CoinRow.tsx @@ -131,7 +131,7 @@ export function CoinRow({ isFavorite, onPress, output, uniqueId, testID, ...asse iconUrl={icon_url} address={address} mainnetAddress={mainnetAddress} - large + size={36} chainId={chainId} symbol={symbol || ''} color={colors?.primary} diff --git a/src/__swaps__/screens/Swap/components/SwapCoinIcon.tsx b/src/__swaps__/screens/Swap/components/SwapCoinIcon.tsx index bb5069c5092..f5e15d41c8d 100644 --- a/src/__swaps__/screens/Swap/components/SwapCoinIcon.tsx +++ b/src/__swaps__/screens/Swap/components/SwapCoinIcon.tsx @@ -24,20 +24,10 @@ const fallbackTextStyles = { textAlign: 'center', }; -const fallbackIconStyle = { - ...borders.buildCircleAsObject(32), +const fallbackIconStyle = (size: number) => ({ + ...borders.buildCircleAsObject(size), position: 'absolute', -}; - -const largeFallbackIconStyle = { - ...borders.buildCircleAsObject(36), - position: 'absolute', -}; - -const smallFallbackIconStyle = { - ...borders.buildCircleAsObject(16), - position: 'absolute', -}; +}); /** * If mainnet asset is available, get the token under /ethereum/ (token) url. @@ -63,22 +53,22 @@ export const SwapCoinIcon = React.memo(function FeedCoinIcon({ iconUrl, disableShadow = true, forceDarkMode, - large, mainnetAddress, chainId, - small, symbol, + size = 32, + chainSize, }: { address: string; color?: string; iconUrl?: string; disableShadow?: boolean; forceDarkMode?: boolean; - large?: boolean; mainnetAddress?: string; chainId: ChainId; - small?: boolean; symbol: string; + size?: number; + chainSize?: number; }) { const theme = useTheme(); @@ -92,52 +82,52 @@ export const SwapCoinIcon = React.memo(function FeedCoinIcon({ const eth = isETH(resolvedAddress); return ( - + {eth ? ( - + ) : ( - + {() => ( )} )} - {chainId && chainId !== ChainId.mainnet && !small && ( + {chainId && chainId !== ChainId.mainnet && size > 16 && ( - + )} ); }); +const styles = { + container: (size: number) => ({ + elevation: 6, + height: size, + overflow: 'visible' as const, + }), + coinIcon: (size: number) => ({ + borderRadius: size / 2, + height: size, + width: size, + overflow: 'visible' as const, + }), +}; + const sx = StyleSheet.create({ badge: { bottom: -0, @@ -151,39 +141,6 @@ const sx = StyleSheet.create({ shadowRadius: 6, shadowOpacity: 0.2, }, - coinIconFallback: { - borderRadius: 16, - height: 32, - overflow: 'visible', - width: 32, - }, - coinIconFallbackLarge: { - borderRadius: 18, - height: 36, - overflow: 'visible', - width: 36, - }, - coinIconFallbackSmall: { - borderRadius: 8, - height: 16, - overflow: 'visible', - width: 16, - }, - container: { - elevation: 6, - height: 32, - overflow: 'visible', - }, - containerLarge: { - elevation: 6, - height: 36, - overflow: 'visible', - }, - containerSmall: { - elevation: 6, - height: 16, - overflow: 'visible', - }, reactCoinIconContainer: { alignItems: 'center', justifyContent: 'center', diff --git a/src/__swaps__/screens/Swap/components/SwapInputAsset.tsx b/src/__swaps__/screens/Swap/components/SwapInputAsset.tsx index af94a152e8a..23734d39ce8 100644 --- a/src/__swaps__/screens/Swap/components/SwapInputAsset.tsx +++ b/src/__swaps__/screens/Swap/components/SwapInputAsset.tsx @@ -96,7 +96,7 @@ function SwapInputAmount() { function SwapInputIcon() { return ( - + ); } diff --git a/src/__swaps__/screens/Swap/components/SwapOutputAsset.tsx b/src/__swaps__/screens/Swap/components/SwapOutputAsset.tsx index de15b46bee6..93130066142 100644 --- a/src/__swaps__/screens/Swap/components/SwapOutputAsset.tsx +++ b/src/__swaps__/screens/Swap/components/SwapOutputAsset.tsx @@ -108,7 +108,7 @@ function SwapOutputAmount({ handleTapWhileDisabled }: { handleTapWhileDisabled: function SwapOutputIcon() { return ( - + ); } diff --git a/src/__swaps__/screens/Swap/components/SwapSlider.tsx b/src/__swaps__/screens/Swap/components/SwapSlider.tsx index 572f9eb6e80..90ac3ac724c 100644 --- a/src/__swaps__/screens/Swap/components/SwapSlider.tsx +++ b/src/__swaps__/screens/Swap/components/SwapSlider.tsx @@ -412,7 +412,7 @@ export const SwapSlider = ({ - + { const isBridge = swapsStore.getState().inputAsset?.mainnetAddress === swapsStore.getState().outputAsset?.mainnetAddress; const isDegenModeEnabled = swapsStore.getState().degenMode; const isSwappingToPopularAsset = swapsStore.getState().outputAsset?.sectionId === 'popular'; + const lastNavigatedTrendingToken = swapsStore.getState().lastNavigatedTrendingToken; + const isSwappingToTrendingAsset = + lastNavigatedTrendingToken === parameters.assetToBuy.uniqueId || lastNavigatedTrendingToken === parameters.assetToSell.uniqueId; const selectedGas = getSelectedGas(parameters.chainId); if (!selectedGas) { @@ -325,6 +328,7 @@ export const SwapProvider = ({ children }: SwapProviderProps) => { tradeAmountUSD: parameters.quote.tradeAmountUSD, degenMode: isDegenModeEnabled, isSwappingToPopularAsset, + isSwappingToTrendingAsset, errorMessage, isHardwareWallet, }); @@ -389,6 +393,7 @@ export const SwapProvider = ({ children }: SwapProviderProps) => { tradeAmountUSD: parameters.quote.tradeAmountUSD, degenMode: isDegenModeEnabled, isSwappingToPopularAsset, + isSwappingToTrendingAsset, isHardwareWallet, }); } catch (error) { @@ -403,6 +408,11 @@ export const SwapProvider = ({ children }: SwapProviderProps) => { }, }); } + + // reset the last navigated trending token after a swap has taken place + swapsStore.setState({ + lastNavigatedTrendingToken: undefined, + }); }; const executeSwap = performanceTracking.getState().executeFn({ diff --git a/src/analytics/event.ts b/src/analytics/event.ts index adfcbee8a6d..673e71a810d 100644 --- a/src/analytics/event.ts +++ b/src/analytics/event.ts @@ -9,6 +9,7 @@ import { RequestSource } from '@/utils/requestNavigationHandlers'; import { CrosschainQuote, Quote, QuoteError } from '@rainbow-me/swaps'; import { AnyPerformanceLog, Screen } from '../state/performance/operations'; import { FavoritedSite } from '@/state/browser/favoriteDappsStore'; +import { TrendingToken } from '@/resources/trendingTokens/trendingTokens'; /** * All events, used by `analytics.track()` @@ -167,6 +168,14 @@ export const event = { // token details tokenDetailsErc20: 'token_details.erc20', tokenDetailsNFT: 'token_details.nft', + + // trending tokens + viewTrendingToken: 'trending_tokens.view_trending_token', + viewRankedCategory: 'trending_tokens.view_ranked_category', + changeNetworkFilter: 'trending_tokens.change_network_filter', + changeTimeframeFilter: 'trending_tokens.change_timeframe_filter', + changeSortFilter: 'trending_tokens.change_sort_filter', + hasLinkedFarcaster: 'trending_tokens.has_linked_farcaster', } as const; type SwapEventParameters = { @@ -186,6 +195,7 @@ type SwapEventParameters = { tradeAmountUSD: number; degenMode: boolean; isSwappingToPopularAsset: boolean; + isSwappingToTrendingAsset: boolean; isHardwareWallet: boolean; }; @@ -706,4 +716,37 @@ export type EventProperties = { eventSentAfterMs: number; available_data: { description: boolean; image_url: boolean; floorPrice: boolean }; }; + + [event.viewTrendingToken]: { + address: TrendingToken['address']; + chainId: TrendingToken['chainId']; + symbol: TrendingToken['symbol']; + name: TrendingToken['name']; + highlightedFriends: number; + }; + + [event.viewRankedCategory]: { + category: string; + chainId: ChainId | undefined; + isLimited: boolean; + isEmpty: boolean; + }; + + [event.changeNetworkFilter]: { + chainId: ChainId | undefined; + }; + + [event.changeTimeframeFilter]: { + timeframe: string; + }; + + [event.changeSortFilter]: { + sort: string | undefined; + }; + + [event.hasLinkedFarcaster]: { + hasFarcaster: boolean; + personalizedTrending: boolean; + walletHash: string; + }; }; diff --git a/src/analytics/userProperties.ts b/src/analytics/userProperties.ts index b42d5518a61..8a467e4b09a 100644 --- a/src/analytics/userProperties.ts +++ b/src/analytics/userProperties.ts @@ -1,3 +1,4 @@ +import { ChainId } from '@/state/backendNetworks/types'; import { NativeCurrencyKey } from '@/entities'; import { Language } from '@/languages'; @@ -36,6 +37,9 @@ export interface UserProperties { hiddenCOins?: string[]; appIcon?: string; + // most used networks at the time the user first opens the network switcher + mostUsedNetworks?: ChainId[]; + // assets NFTs?: number; poaps?: number; diff --git a/src/assets/badges/gnosis.png b/src/assets/badges/gnosis.png new file mode 100644 index 00000000000..afb08cb40e6 Binary files /dev/null and b/src/assets/badges/gnosis.png differ diff --git a/src/assets/badges/gnosis@2x.png b/src/assets/badges/gnosis@2x.png new file mode 100644 index 00000000000..3a021929690 Binary files /dev/null and b/src/assets/badges/gnosis@2x.png differ diff --git a/src/assets/badges/gnosis@3x.png b/src/assets/badges/gnosis@3x.png new file mode 100644 index 00000000000..09946eb88a5 Binary files /dev/null and b/src/assets/badges/gnosis@3x.png differ diff --git a/src/assets/badges/gnosisBadge.png b/src/assets/badges/gnosisBadge.png new file mode 100644 index 00000000000..961610867dd Binary files /dev/null and b/src/assets/badges/gnosisBadge.png differ diff --git a/src/assets/badges/gnosisBadge@2x.png b/src/assets/badges/gnosisBadge@2x.png new file mode 100644 index 00000000000..1355360aca0 Binary files /dev/null and b/src/assets/badges/gnosisBadge@2x.png differ diff --git a/src/assets/badges/gnosisBadge@3x.png b/src/assets/badges/gnosisBadge@3x.png new file mode 100644 index 00000000000..19592fc8d64 Binary files /dev/null and b/src/assets/badges/gnosisBadge@3x.png differ diff --git a/src/assets/badges/gnosisBadgeDark.png b/src/assets/badges/gnosisBadgeDark.png new file mode 100644 index 00000000000..cd7d26152c2 Binary files /dev/null and b/src/assets/badges/gnosisBadgeDark.png differ diff --git a/src/assets/badges/gnosisBadgeDark@2x.png b/src/assets/badges/gnosisBadgeDark@2x.png new file mode 100644 index 00000000000..029c07d9ddb Binary files /dev/null and b/src/assets/badges/gnosisBadgeDark@2x.png differ diff --git a/src/assets/badges/gnosisBadgeDark@3x.png b/src/assets/badges/gnosisBadgeDark@3x.png new file mode 100644 index 00000000000..5c8ed229375 Binary files /dev/null and b/src/assets/badges/gnosisBadgeDark@3x.png differ diff --git a/src/assets/badges/gnosisBadgeLarge.png b/src/assets/badges/gnosisBadgeLarge.png new file mode 100644 index 00000000000..9cf5511d8f1 Binary files /dev/null and b/src/assets/badges/gnosisBadgeLarge.png differ diff --git a/src/assets/badges/gnosisBadgeLarge@2x.png b/src/assets/badges/gnosisBadgeLarge@2x.png new file mode 100644 index 00000000000..301ddfb2914 Binary files /dev/null and b/src/assets/badges/gnosisBadgeLarge@2x.png differ diff --git a/src/assets/badges/gnosisBadgeLarge@3x.png b/src/assets/badges/gnosisBadgeLarge@3x.png new file mode 100644 index 00000000000..e787754b713 Binary files /dev/null and b/src/assets/badges/gnosisBadgeLarge@3x.png differ diff --git a/src/assets/badges/gnosisBadgeLargeDark.png b/src/assets/badges/gnosisBadgeLargeDark.png new file mode 100644 index 00000000000..4f3b0c859cb Binary files /dev/null and b/src/assets/badges/gnosisBadgeLargeDark.png differ diff --git a/src/assets/badges/gnosisBadgeLargeDark@2x.png b/src/assets/badges/gnosisBadgeLargeDark@2x.png new file mode 100644 index 00000000000..79768e5d97e Binary files /dev/null and b/src/assets/badges/gnosisBadgeLargeDark@2x.png differ diff --git a/src/assets/badges/gnosisBadgeLargeDark@3x.png b/src/assets/badges/gnosisBadgeLargeDark@3x.png new file mode 100644 index 00000000000..4975e795ef0 Binary files /dev/null and b/src/assets/badges/gnosisBadgeLargeDark@3x.png differ diff --git a/src/assets/badges/gnosisBadgeNoShadow.png b/src/assets/badges/gnosisBadgeNoShadow.png new file mode 100644 index 00000000000..baa5ee94397 Binary files /dev/null and b/src/assets/badges/gnosisBadgeNoShadow.png differ diff --git a/src/assets/badges/gnosisBadgeNoShadow@2x.png b/src/assets/badges/gnosisBadgeNoShadow@2x.png new file mode 100644 index 00000000000..57e1e098b6a Binary files /dev/null and b/src/assets/badges/gnosisBadgeNoShadow@2x.png differ diff --git a/src/assets/badges/gnosisBadgeNoShadow@3x.png b/src/assets/badges/gnosisBadgeNoShadow@3x.png new file mode 100644 index 00000000000..42a52730e27 Binary files /dev/null and b/src/assets/badges/gnosisBadgeNoShadow@3x.png differ diff --git a/src/assets/badges/gravity.png b/src/assets/badges/gravity.png new file mode 100644 index 00000000000..a515d5551c5 Binary files /dev/null and b/src/assets/badges/gravity.png differ diff --git a/src/assets/badges/gravity@2x.png b/src/assets/badges/gravity@2x.png new file mode 100644 index 00000000000..29e60cbad1c Binary files /dev/null and b/src/assets/badges/gravity@2x.png differ diff --git a/src/assets/badges/gravity@3x.png b/src/assets/badges/gravity@3x.png new file mode 100644 index 00000000000..55108967dea Binary files /dev/null and b/src/assets/badges/gravity@3x.png differ diff --git a/src/assets/badges/gravityBadge.png b/src/assets/badges/gravityBadge.png new file mode 100644 index 00000000000..ad033ad3691 Binary files /dev/null and b/src/assets/badges/gravityBadge.png differ diff --git a/src/assets/badges/gravityBadge@2x.png b/src/assets/badges/gravityBadge@2x.png new file mode 100644 index 00000000000..2264da68ec9 Binary files /dev/null and b/src/assets/badges/gravityBadge@2x.png differ diff --git a/src/assets/badges/gravityBadge@3x.png b/src/assets/badges/gravityBadge@3x.png new file mode 100644 index 00000000000..8d6bdddc381 Binary files /dev/null and b/src/assets/badges/gravityBadge@3x.png differ diff --git a/src/assets/badges/gravityBadgeDark.png b/src/assets/badges/gravityBadgeDark.png new file mode 100644 index 00000000000..02fb9e0677f Binary files /dev/null and b/src/assets/badges/gravityBadgeDark.png differ diff --git a/src/assets/badges/gravityBadgeDark@2x.png b/src/assets/badges/gravityBadgeDark@2x.png new file mode 100644 index 00000000000..9aadd9549ae Binary files /dev/null and b/src/assets/badges/gravityBadgeDark@2x.png differ diff --git a/src/assets/badges/gravityBadgeDark@3x.png b/src/assets/badges/gravityBadgeDark@3x.png new file mode 100644 index 00000000000..5218bf5b88e Binary files /dev/null and b/src/assets/badges/gravityBadgeDark@3x.png differ diff --git a/src/assets/badges/gravityBadgeLarge.png b/src/assets/badges/gravityBadgeLarge.png new file mode 100644 index 00000000000..ccfed23d64b Binary files /dev/null and b/src/assets/badges/gravityBadgeLarge.png differ diff --git a/src/assets/badges/gravityBadgeLarge@2x.png b/src/assets/badges/gravityBadgeLarge@2x.png new file mode 100644 index 00000000000..51e00178021 Binary files /dev/null and b/src/assets/badges/gravityBadgeLarge@2x.png differ diff --git a/src/assets/badges/gravityBadgeLarge@3x.png b/src/assets/badges/gravityBadgeLarge@3x.png new file mode 100644 index 00000000000..805d9fcd7b9 Binary files /dev/null and b/src/assets/badges/gravityBadgeLarge@3x.png differ diff --git a/src/assets/badges/gravityBadgeLargeDark.png b/src/assets/badges/gravityBadgeLargeDark.png new file mode 100644 index 00000000000..ab9ee2fcbae Binary files /dev/null and b/src/assets/badges/gravityBadgeLargeDark.png differ diff --git a/src/assets/badges/gravityBadgeLargeDark@2x.png b/src/assets/badges/gravityBadgeLargeDark@2x.png new file mode 100644 index 00000000000..067b373a7e4 Binary files /dev/null and b/src/assets/badges/gravityBadgeLargeDark@2x.png differ diff --git a/src/assets/badges/gravityBadgeLargeDark@3x.png b/src/assets/badges/gravityBadgeLargeDark@3x.png new file mode 100644 index 00000000000..362d6f3d772 Binary files /dev/null and b/src/assets/badges/gravityBadgeLargeDark@3x.png differ diff --git a/src/assets/badges/gravityBadgeNoShadow.png b/src/assets/badges/gravityBadgeNoShadow.png new file mode 100644 index 00000000000..9492a525822 Binary files /dev/null and b/src/assets/badges/gravityBadgeNoShadow.png differ diff --git a/src/assets/badges/gravityBadgeNoShadow@2x.png b/src/assets/badges/gravityBadgeNoShadow@2x.png new file mode 100644 index 00000000000..5052d829f1e Binary files /dev/null and b/src/assets/badges/gravityBadgeNoShadow@2x.png differ diff --git a/src/assets/badges/gravityBadgeNoShadow@3x.png b/src/assets/badges/gravityBadgeNoShadow@3x.png new file mode 100644 index 00000000000..474f948bf99 Binary files /dev/null and b/src/assets/badges/gravityBadgeNoShadow@3x.png differ diff --git a/src/assets/badges/linea.png b/src/assets/badges/linea.png new file mode 100644 index 00000000000..14e4a7fface Binary files /dev/null and b/src/assets/badges/linea.png differ diff --git a/src/assets/badges/linea@2x.png b/src/assets/badges/linea@2x.png new file mode 100644 index 00000000000..42f41b35f9d Binary files /dev/null and b/src/assets/badges/linea@2x.png differ diff --git a/src/assets/badges/linea@3x.png b/src/assets/badges/linea@3x.png new file mode 100644 index 00000000000..4cc7abd0cdc Binary files /dev/null and b/src/assets/badges/linea@3x.png differ diff --git a/src/assets/badges/lineaBadge.png b/src/assets/badges/lineaBadge.png new file mode 100644 index 00000000000..267723587ca Binary files /dev/null and b/src/assets/badges/lineaBadge.png differ diff --git a/src/assets/badges/lineaBadge@2x.png b/src/assets/badges/lineaBadge@2x.png new file mode 100644 index 00000000000..70bb69fae24 Binary files /dev/null and b/src/assets/badges/lineaBadge@2x.png differ diff --git a/src/assets/badges/lineaBadge@3x.png b/src/assets/badges/lineaBadge@3x.png new file mode 100644 index 00000000000..814892f7fdb Binary files /dev/null and b/src/assets/badges/lineaBadge@3x.png differ diff --git a/src/assets/badges/lineaBadgeDark.png b/src/assets/badges/lineaBadgeDark.png new file mode 100644 index 00000000000..1fa46075d00 Binary files /dev/null and b/src/assets/badges/lineaBadgeDark.png differ diff --git a/src/assets/badges/lineaBadgeDark@2x.png b/src/assets/badges/lineaBadgeDark@2x.png new file mode 100644 index 00000000000..152eb8d6177 Binary files /dev/null and b/src/assets/badges/lineaBadgeDark@2x.png differ diff --git a/src/assets/badges/lineaBadgeDark@3x.png b/src/assets/badges/lineaBadgeDark@3x.png new file mode 100644 index 00000000000..a58ff5b93ac Binary files /dev/null and b/src/assets/badges/lineaBadgeDark@3x.png differ diff --git a/src/assets/badges/lineaBadgeLarge.png b/src/assets/badges/lineaBadgeLarge.png new file mode 100644 index 00000000000..93a23a92347 Binary files /dev/null and b/src/assets/badges/lineaBadgeLarge.png differ diff --git a/src/assets/badges/lineaBadgeLarge@2x.png b/src/assets/badges/lineaBadgeLarge@2x.png new file mode 100644 index 00000000000..0fe5d25acdf Binary files /dev/null and b/src/assets/badges/lineaBadgeLarge@2x.png differ diff --git a/src/assets/badges/lineaBadgeLarge@3x.png b/src/assets/badges/lineaBadgeLarge@3x.png new file mode 100644 index 00000000000..4f3a3c0ce1c Binary files /dev/null and b/src/assets/badges/lineaBadgeLarge@3x.png differ diff --git a/src/assets/badges/lineaBadgeLargeDark.png b/src/assets/badges/lineaBadgeLargeDark.png new file mode 100644 index 00000000000..f463c5abcc7 Binary files /dev/null and b/src/assets/badges/lineaBadgeLargeDark.png differ diff --git a/src/assets/badges/lineaBadgeLargeDark@2x.png b/src/assets/badges/lineaBadgeLargeDark@2x.png new file mode 100644 index 00000000000..f417f8f1f16 Binary files /dev/null and b/src/assets/badges/lineaBadgeLargeDark@2x.png differ diff --git a/src/assets/badges/lineaBadgeLargeDark@3x.png b/src/assets/badges/lineaBadgeLargeDark@3x.png new file mode 100644 index 00000000000..86c51a9e20b Binary files /dev/null and b/src/assets/badges/lineaBadgeLargeDark@3x.png differ diff --git a/src/assets/badges/lineaBadgeNoShadow.png b/src/assets/badges/lineaBadgeNoShadow.png new file mode 100644 index 00000000000..1af3c5fd42d Binary files /dev/null and b/src/assets/badges/lineaBadgeNoShadow.png differ diff --git a/src/assets/badges/lineaBadgeNoShadow@2x.png b/src/assets/badges/lineaBadgeNoShadow@2x.png new file mode 100644 index 00000000000..cddfa99c67f Binary files /dev/null and b/src/assets/badges/lineaBadgeNoShadow@2x.png differ diff --git a/src/assets/badges/lineaBadgeNoShadow@3x.png b/src/assets/badges/lineaBadgeNoShadow@3x.png new file mode 100644 index 00000000000..22007385103 Binary files /dev/null and b/src/assets/badges/lineaBadgeNoShadow@3x.png differ diff --git a/src/assets/badges/sankBadgeDark.png b/src/assets/badges/sankBadgeDark.png new file mode 100644 index 00000000000..6ab341257ab Binary files /dev/null and b/src/assets/badges/sankBadgeDark.png differ diff --git a/src/assets/badges/sankBadgeDark@2x.png b/src/assets/badges/sankBadgeDark@2x.png new file mode 100644 index 00000000000..d4e5beded3f Binary files /dev/null and b/src/assets/badges/sankBadgeDark@2x.png differ diff --git a/src/assets/badges/sankBadgeDark@3x.png b/src/assets/badges/sankBadgeDark@3x.png new file mode 100644 index 00000000000..9b5eba8fe7a Binary files /dev/null and b/src/assets/badges/sankBadgeDark@3x.png differ diff --git a/src/assets/badges/sanko.png b/src/assets/badges/sanko.png new file mode 100644 index 00000000000..e0eff636cac Binary files /dev/null and b/src/assets/badges/sanko.png differ diff --git a/src/assets/badges/sanko@2x.png b/src/assets/badges/sanko@2x.png new file mode 100644 index 00000000000..399f9ad13e6 Binary files /dev/null and b/src/assets/badges/sanko@2x.png differ diff --git a/src/assets/badges/sanko@3x.png b/src/assets/badges/sanko@3x.png new file mode 100644 index 00000000000..c5c5e42e575 Binary files /dev/null and b/src/assets/badges/sanko@3x.png differ diff --git a/src/assets/badges/sankoBadge.png b/src/assets/badges/sankoBadge.png new file mode 100644 index 00000000000..3e44d659f3a Binary files /dev/null and b/src/assets/badges/sankoBadge.png differ diff --git a/src/assets/badges/sankoBadge@2x.png b/src/assets/badges/sankoBadge@2x.png new file mode 100644 index 00000000000..39a74fcdc8d Binary files /dev/null and b/src/assets/badges/sankoBadge@2x.png differ diff --git a/src/assets/badges/sankoBadge@3x.png b/src/assets/badges/sankoBadge@3x.png new file mode 100644 index 00000000000..a9729e07af3 Binary files /dev/null and b/src/assets/badges/sankoBadge@3x.png differ diff --git a/src/assets/badges/sankoBadgeLarge.png b/src/assets/badges/sankoBadgeLarge.png new file mode 100644 index 00000000000..e2ead662090 Binary files /dev/null and b/src/assets/badges/sankoBadgeLarge.png differ diff --git a/src/assets/badges/sankoBadgeLarge@2x.png b/src/assets/badges/sankoBadgeLarge@2x.png new file mode 100644 index 00000000000..726dfc00978 Binary files /dev/null and b/src/assets/badges/sankoBadgeLarge@2x.png differ diff --git a/src/assets/badges/sankoBadgeLarge@3x.png b/src/assets/badges/sankoBadgeLarge@3x.png new file mode 100644 index 00000000000..897a700db31 Binary files /dev/null and b/src/assets/badges/sankoBadgeLarge@3x.png differ diff --git a/src/assets/badges/sankoBadgeLargeDark.png b/src/assets/badges/sankoBadgeLargeDark.png new file mode 100644 index 00000000000..0218596d5bb Binary files /dev/null and b/src/assets/badges/sankoBadgeLargeDark.png differ diff --git a/src/assets/badges/sankoBadgeLargeDark@2x.png b/src/assets/badges/sankoBadgeLargeDark@2x.png new file mode 100644 index 00000000000..40c50ffecf6 Binary files /dev/null and b/src/assets/badges/sankoBadgeLargeDark@2x.png differ diff --git a/src/assets/badges/sankoBadgeLargeDark@3x.png b/src/assets/badges/sankoBadgeLargeDark@3x.png new file mode 100644 index 00000000000..f683ef22d4b Binary files /dev/null and b/src/assets/badges/sankoBadgeLargeDark@3x.png differ diff --git a/src/assets/badges/sankoBadgeNoShadow.png b/src/assets/badges/sankoBadgeNoShadow.png new file mode 100644 index 00000000000..b0b2c0385ac Binary files /dev/null and b/src/assets/badges/sankoBadgeNoShadow.png differ diff --git a/src/assets/badges/sankoBadgeNoShadow@2x.png b/src/assets/badges/sankoBadgeNoShadow@2x.png new file mode 100644 index 00000000000..990e00a88b0 Binary files /dev/null and b/src/assets/badges/sankoBadgeNoShadow@2x.png differ diff --git a/src/assets/badges/sankoBadgeNoShadow@3x.png b/src/assets/badges/sankoBadgeNoShadow@3x.png new file mode 100644 index 00000000000..f79b957c903 Binary files /dev/null and b/src/assets/badges/sankoBadgeNoShadow@3x.png differ diff --git a/src/assets/badges/scroll.png b/src/assets/badges/scroll.png new file mode 100644 index 00000000000..b074e4e54f3 Binary files /dev/null and b/src/assets/badges/scroll.png differ diff --git a/src/assets/badges/scroll@2x.png b/src/assets/badges/scroll@2x.png new file mode 100644 index 00000000000..1dab422416c Binary files /dev/null and b/src/assets/badges/scroll@2x.png differ diff --git a/src/assets/badges/scroll@3x.png b/src/assets/badges/scroll@3x.png new file mode 100644 index 00000000000..04482628c63 Binary files /dev/null and b/src/assets/badges/scroll@3x.png differ diff --git a/src/assets/badges/scrollBadge.png b/src/assets/badges/scrollBadge.png new file mode 100644 index 00000000000..3266ab33b57 Binary files /dev/null and b/src/assets/badges/scrollBadge.png differ diff --git a/src/assets/badges/scrollBadge@2x.png b/src/assets/badges/scrollBadge@2x.png new file mode 100644 index 00000000000..aea2e050f18 Binary files /dev/null and b/src/assets/badges/scrollBadge@2x.png differ diff --git a/src/assets/badges/scrollBadge@3x.png b/src/assets/badges/scrollBadge@3x.png new file mode 100644 index 00000000000..40f77762f36 Binary files /dev/null and b/src/assets/badges/scrollBadge@3x.png differ diff --git a/src/assets/badges/scrollBadgeDark.png b/src/assets/badges/scrollBadgeDark.png new file mode 100644 index 00000000000..71927e891e8 Binary files /dev/null and b/src/assets/badges/scrollBadgeDark.png differ diff --git a/src/assets/badges/scrollBadgeDark@2x.png b/src/assets/badges/scrollBadgeDark@2x.png new file mode 100644 index 00000000000..53095e21774 Binary files /dev/null and b/src/assets/badges/scrollBadgeDark@2x.png differ diff --git a/src/assets/badges/scrollBadgeDark@3x.png b/src/assets/badges/scrollBadgeDark@3x.png new file mode 100644 index 00000000000..5bfd03fdd2b Binary files /dev/null and b/src/assets/badges/scrollBadgeDark@3x.png differ diff --git a/src/assets/badges/scrollBadgeLarge.png b/src/assets/badges/scrollBadgeLarge.png new file mode 100644 index 00000000000..cc1dbc31e63 Binary files /dev/null and b/src/assets/badges/scrollBadgeLarge.png differ diff --git a/src/assets/badges/scrollBadgeLarge@2x.png b/src/assets/badges/scrollBadgeLarge@2x.png new file mode 100644 index 00000000000..c60eca2ff99 Binary files /dev/null and b/src/assets/badges/scrollBadgeLarge@2x.png differ diff --git a/src/assets/badges/scrollBadgeLarge@3x.png b/src/assets/badges/scrollBadgeLarge@3x.png new file mode 100644 index 00000000000..8be695f8247 Binary files /dev/null and b/src/assets/badges/scrollBadgeLarge@3x.png differ diff --git a/src/assets/badges/scrollBadgeLargeDark.png b/src/assets/badges/scrollBadgeLargeDark.png new file mode 100644 index 00000000000..5ecf4f2dff7 Binary files /dev/null and b/src/assets/badges/scrollBadgeLargeDark.png differ diff --git a/src/assets/badges/scrollBadgeLargeDark@2x.png b/src/assets/badges/scrollBadgeLargeDark@2x.png new file mode 100644 index 00000000000..5c6b5d6a50c Binary files /dev/null and b/src/assets/badges/scrollBadgeLargeDark@2x.png differ diff --git a/src/assets/badges/scrollBadgeLargeDark@3x.png b/src/assets/badges/scrollBadgeLargeDark@3x.png new file mode 100644 index 00000000000..0e508374d35 Binary files /dev/null and b/src/assets/badges/scrollBadgeLargeDark@3x.png differ diff --git a/src/assets/badges/scrollBadgeNoShadow.png b/src/assets/badges/scrollBadgeNoShadow.png new file mode 100644 index 00000000000..cfdef2d77c9 Binary files /dev/null and b/src/assets/badges/scrollBadgeNoShadow.png differ diff --git a/src/assets/badges/scrollBadgeNoShadow@2x.png b/src/assets/badges/scrollBadgeNoShadow@2x.png new file mode 100644 index 00000000000..79c1aa6e3b0 Binary files /dev/null and b/src/assets/badges/scrollBadgeNoShadow@2x.png differ diff --git a/src/assets/badges/scrollBadgeNoShadow@3x.png b/src/assets/badges/scrollBadgeNoShadow@3x.png new file mode 100644 index 00000000000..d140debde92 Binary files /dev/null and b/src/assets/badges/scrollBadgeNoShadow@3x.png differ diff --git a/src/assets/badges/zkSyncBadge.png b/src/assets/badges/zkSyncBadge.png new file mode 100644 index 00000000000..f84a89c233f Binary files /dev/null and b/src/assets/badges/zkSyncBadge.png differ diff --git a/src/assets/badges/zkSyncBadge@2x.png b/src/assets/badges/zkSyncBadge@2x.png new file mode 100644 index 00000000000..02a0f753727 Binary files /dev/null and b/src/assets/badges/zkSyncBadge@2x.png differ diff --git a/src/assets/badges/zkSyncBadge@3x.png b/src/assets/badges/zkSyncBadge@3x.png new file mode 100644 index 00000000000..db578e63d79 Binary files /dev/null and b/src/assets/badges/zkSyncBadge@3x.png differ diff --git a/src/assets/badges/zksync.png b/src/assets/badges/zksync.png new file mode 100644 index 00000000000..1225b4e6c6e Binary files /dev/null and b/src/assets/badges/zksync.png differ diff --git a/src/assets/badges/zksync@2x.png b/src/assets/badges/zksync@2x.png new file mode 100644 index 00000000000..b437d430a93 Binary files /dev/null and b/src/assets/badges/zksync@2x.png differ diff --git a/src/assets/badges/zksync@3x.png b/src/assets/badges/zksync@3x.png new file mode 100644 index 00000000000..2e433247e12 Binary files /dev/null and b/src/assets/badges/zksync@3x.png differ diff --git a/src/assets/badges/zksyncBadgeDark.png b/src/assets/badges/zksyncBadgeDark.png new file mode 100644 index 00000000000..b6947dbcd88 Binary files /dev/null and b/src/assets/badges/zksyncBadgeDark.png differ diff --git a/src/assets/badges/zksyncBadgeDark@2x.png b/src/assets/badges/zksyncBadgeDark@2x.png new file mode 100644 index 00000000000..77f075eb22e Binary files /dev/null and b/src/assets/badges/zksyncBadgeDark@2x.png differ diff --git a/src/assets/badges/zksyncBadgeDark@3x.png b/src/assets/badges/zksyncBadgeDark@3x.png new file mode 100644 index 00000000000..a7ea118d5ce Binary files /dev/null and b/src/assets/badges/zksyncBadgeDark@3x.png differ diff --git a/src/assets/badges/zksyncBadgeLarge.png b/src/assets/badges/zksyncBadgeLarge.png new file mode 100644 index 00000000000..02190afd30f Binary files /dev/null and b/src/assets/badges/zksyncBadgeLarge.png differ diff --git a/src/assets/badges/zksyncBadgeLarge@2x.png b/src/assets/badges/zksyncBadgeLarge@2x.png new file mode 100644 index 00000000000..420b0f8531e Binary files /dev/null and b/src/assets/badges/zksyncBadgeLarge@2x.png differ diff --git a/src/assets/badges/zksyncBadgeLarge@3x.png b/src/assets/badges/zksyncBadgeLarge@3x.png new file mode 100644 index 00000000000..25aef546ecf Binary files /dev/null and b/src/assets/badges/zksyncBadgeLarge@3x.png differ diff --git a/src/assets/badges/zksyncBadgeLargeDark.png b/src/assets/badges/zksyncBadgeLargeDark.png new file mode 100644 index 00000000000..19a58296e9a Binary files /dev/null and b/src/assets/badges/zksyncBadgeLargeDark.png differ diff --git a/src/assets/badges/zksyncBadgeLargeDark@2x.png b/src/assets/badges/zksyncBadgeLargeDark@2x.png new file mode 100644 index 00000000000..ea8d6389607 Binary files /dev/null and b/src/assets/badges/zksyncBadgeLargeDark@2x.png differ diff --git a/src/assets/badges/zksyncBadgeLargeDark@3x.png b/src/assets/badges/zksyncBadgeLargeDark@3x.png new file mode 100644 index 00000000000..71a30293a2e Binary files /dev/null and b/src/assets/badges/zksyncBadgeLargeDark@3x.png differ diff --git a/src/assets/badges/zksyncBadgeNoShadow.png b/src/assets/badges/zksyncBadgeNoShadow.png new file mode 100644 index 00000000000..47b5500b5d0 Binary files /dev/null and b/src/assets/badges/zksyncBadgeNoShadow.png differ diff --git a/src/assets/badges/zksyncBadgeNoShadow@2x.png b/src/assets/badges/zksyncBadgeNoShadow@2x.png new file mode 100644 index 00000000000..97f1bc72954 Binary files /dev/null and b/src/assets/badges/zksyncBadgeNoShadow@2x.png differ diff --git a/src/assets/badges/zksyncBadgeNoShadow@3x.png b/src/assets/badges/zksyncBadgeNoShadow@3x.png new file mode 100644 index 00000000000..ed087b5f411 Binary files /dev/null and b/src/assets/badges/zksyncBadgeNoShadow@3x.png differ diff --git a/src/components/AbsolutePortal.tsx b/src/components/AbsolutePortal.tsx index 809aec392f5..a992e84c11c 100644 --- a/src/components/AbsolutePortal.tsx +++ b/src/components/AbsolutePortal.tsx @@ -32,17 +32,15 @@ export const AbsolutePortalRoot = ({ style }: { style?: StyleProp }) return () => unsubscribe(); }, []); - return ( - - {nodes} - - ); + return {nodes}; }; export const AbsolutePortal = ({ children }: PropsWithChildren) => { useEffect(() => { absolutePortal.addNode(children); - return () => absolutePortal.removeNode(children); + return () => { + absolutePortal.removeNode(children); + }; }, [children]); return null; diff --git a/src/components/DappBrowser/control-panel/ControlPanel.tsx b/src/components/DappBrowser/control-panel/ControlPanel.tsx index 99c24dd0597..94977e35f14 100644 --- a/src/components/DappBrowser/control-panel/ControlPanel.tsx +++ b/src/components/DappBrowser/control-panel/ControlPanel.tsx @@ -311,7 +311,7 @@ export const ControlPanel = () => { ); }; -const TapToDismiss = memo(function TapToDismiss() { +export const TapToDismiss = memo(function TapToDismiss() { const { goBack } = useNavigation(); return ( diff --git a/src/screens/discover/components/DiscoverFeaturedResultsCard.tsx b/src/components/Discover/DiscoverFeaturedResultsCard.tsx similarity index 100% rename from src/screens/discover/components/DiscoverFeaturedResultsCard.tsx rename to src/components/Discover/DiscoverFeaturedResultsCard.tsx diff --git a/src/screens/discover/components/DiscoverHome.tsx b/src/components/Discover/DiscoverHome.tsx similarity index 89% rename from src/screens/discover/components/DiscoverHome.tsx rename to src/components/Discover/DiscoverHome.tsx index 7132c19c016..019328a92b6 100644 --- a/src/screens/discover/components/DiscoverHome.tsx +++ b/src/components/Discover/DiscoverHome.tsx @@ -6,9 +6,10 @@ import useExperimentalFlag, { MINTS, NFT_OFFERS, FEATURED_RESULTS, + TRENDING_TOKENS, } from '@rainbow-me/config/experimentalHooks'; import { isTestnetChain } from '@/handlers/web3'; -import { Inline, Inset, Stack, Box } from '@/design-system'; +import { Inline, Inset, Stack, Box, Separator } from '@/design-system'; import { useAccountSettings, useWallets } from '@/hooks'; import { ENSCreateProfileCard } from '@/components/cards/ENSCreateProfileCard'; import { ENSSearchCard } from '@/components/cards/ENSSearchCard'; @@ -28,11 +29,12 @@ import { FeaturedResultStack } from '@/components/FeaturedResult/FeaturedResultS import Routes from '@/navigation/routesNames'; import { useNavigation } from '@/navigation'; import { DiscoverFeaturedResultsCard } from './DiscoverFeaturedResultsCard'; +import { TrendingTokens } from '@/components/Discover/TrendingTokens'; export const HORIZONTAL_PADDING = 20; export default function DiscoverHome() { - const { profiles_enabled, mints_enabled, op_rewards_enabled, featured_results } = useRemoteConfig(); + const { profiles_enabled, mints_enabled, op_rewards_enabled, featured_results, trending_tokens_enabled } = useRemoteConfig(); const { chainId } = useAccountSettings(); const profilesEnabledLocalFlag = useExperimentalFlag(PROFILES); const profilesEnabledRemoteFlag = profiles_enabled; @@ -42,6 +44,7 @@ export default function DiscoverHome() { const mintsEnabled = (useExperimentalFlag(MINTS) || mints_enabled) && !IS_TEST; const opRewardsLocalFlag = useExperimentalFlag(OP_REWARDS); const opRewardsRemoteFlag = op_rewards_enabled; + const trendingTokensEnabled = (useExperimentalFlag(TRENDING_TOKENS) || trending_tokens_enabled) && !IS_TEST; const testNetwork = isTestnetChain({ chainId }); const { navigate } = useNavigation(); const isProfilesEnabled = profilesEnabledLocalFlag && profilesEnabledRemoteFlag; @@ -67,6 +70,12 @@ export default function DiscoverHome() { {isProfilesEnabled && } + {trendingTokensEnabled && ( + <> + + + + )} {mintsEnabled && ( diff --git a/src/screens/discover/components/DiscoverScreenContent.tsx b/src/components/Discover/DiscoverScreenContent.tsx similarity index 76% rename from src/screens/discover/components/DiscoverScreenContent.tsx rename to src/components/Discover/DiscoverScreenContent.tsx index 1e3a7650013..99271271ded 100644 --- a/src/screens/discover/components/DiscoverScreenContent.tsx +++ b/src/components/Discover/DiscoverScreenContent.tsx @@ -1,12 +1,12 @@ import React from 'react'; import { View } from 'react-native'; import { FlexItem, Page } from '@/components/layout'; -import DiscoverHome from './DiscoverHome'; -import DiscoverSearch from './DiscoverSearch'; -import DiscoverSearchContainer from './DiscoverSearchContainer'; +import DiscoverHome from '@/components/Discover/DiscoverHome'; +import DiscoverSearch from '@/components/Discover/DiscoverSearch'; +import DiscoverSearchContainer from '@/components/Discover/DiscoverSearchContainer'; import { Box, Inset } from '@/design-system'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; -import { useDiscoverScreenContext } from '../DiscoverScreenContext'; +import { useDiscoverScreenContext } from '@/components/Discover/DiscoverScreenContext'; function Switcher({ children }: { children: React.ReactNode[] }) { const { isSearching } = useDiscoverScreenContext(); diff --git a/src/screens/discover/DiscoverScreenContext.tsx b/src/components/Discover/DiscoverScreenContext.tsx similarity index 96% rename from src/screens/discover/DiscoverScreenContext.tsx rename to src/components/Discover/DiscoverScreenContext.tsx index eb9b276443d..31a8e89106b 100644 --- a/src/screens/discover/DiscoverScreenContext.tsx +++ b/src/components/Discover/DiscoverScreenContext.tsx @@ -2,6 +2,7 @@ import { analytics } from '@/analytics'; import React, { createContext, Dispatch, SetStateAction, RefObject, useState, useRef, useCallback } from 'react'; import { SectionList, TextInput } from 'react-native'; import Animated from 'react-native-reanimated'; +import { useTrackDiscoverScreenTime } from './useTrackDiscoverScreenTime'; type DiscoverScreenContextType = { scrollViewRef: RefObject; @@ -80,6 +81,8 @@ const DiscoverScreenProvider = ({ children }: { children: React.ReactNode }) => setIsSearching(false); }, [searchQuery]); + useTrackDiscoverScreenTime(); + return ( { + pressed.value = true; + if (onPress) runOnJS(onPress)(); + }) + .onFinalize(() => (pressed.value = false)); + + const animatedStyles = useAnimatedStyle(() => ({ + transform: [{ scale: withTiming(pressed.value ? 0.95 : 1, { duration: 100 }) }], + })); + + const backgroundColor = useBackgroundColor('fillTertiary'); + const borderColor = useBackgroundColor('fillSecondary'); + + const iconColor = useForegroundColor('labelQuaternary'); + + return ( + + + {typeof icon === 'string' ? ( + + {icon} + + ) : ( + icon + )} + + {label} + + + 􀆏 + + + + ); +} + +function useTrendingTokensData() { + const { nativeCurrency } = useAccountSettings(); + const remoteConfig = useRemoteConfig(); + const { chainId, category, timeframe, sort } = useTrendingTokensStore(state => ({ + chainId: state.chainId, + category: state.category, + timeframe: state.timeframe, + sort: state.sort, + })); + + const walletAddress = useFarcasterAccountForWallets(); + + return useTrendingTokens({ + chainId, + category, + timeframe, + sortBy: sort, + sortDirection: SortDirection.Desc, + limit: remoteConfig.trending_tokens_limit, + walletAddress: walletAddress, + currency: nativeCurrency, + }); +} + +function ReportAnalytics() { + const activeSwipeRoute = useNavigationStore(state => state.activeSwipeRoute); + const { category, chainId } = useTrendingTokensStore(state => ({ category: state.category, chainId: state.chainId })); + const { data: trendingTokens, isLoading } = useTrendingTokensData(); + + useEffect(() => { + if (isLoading || activeSwipeRoute !== Routes.DISCOVER_SCREEN) return; + + const isEmpty = (trendingTokens?.length ?? 0) === 0; + const isLimited = !isEmpty && (trendingTokens?.length ?? 0) < 6; + + analyticsV2.track(analyticsV2.event.viewRankedCategory, { + category, + chainId, + isLimited, + isEmpty, + }); + }, [isLoading, activeSwipeRoute, trendingTokens?.length, category, chainId]); + + return null; +} + +function CategoryFilterButton({ + category, + icon, + iconWidth = 16, + iconColor, + label, + highlightedBackgroundColor, +}: { + category: TrendingCategory; + icon: string; + iconColor: string; + highlightedBackgroundColor: string; + iconWidth?: number; + label: string; +}) { + const { isDarkMode } = useTheme(); + const fillTertiary = useBackgroundColor('fillTertiary'); + const fillSecondary = useBackgroundColor('fillSecondary'); + + const selected = useTrendingTokensStore(state => state.category === category); + + const borderColor = selected && isDarkMode ? globalColors.white80 : fillSecondary; + + const pressed = useSharedValue(false); + + const selectCategory = useCallback(() => { + useTrendingTokensStore.getState().setCategory(category); + }, [category]); + + const tap = Gesture.Tap() + .onBegin(() => { + pressed.value = true; + }) + .onEnd(() => { + pressed.value = false; + runOnJS(selectCategory)(); + }); + + const animatedStyles = useAnimatedStyle(() => ({ + transform: [{ scale: withTiming(pressed.value ? 0.95 : 1, { duration: 100 }) }], + })); + + return ( + + + + {icon} + + + {label} + + + + ); +} + +function FriendPfp({ pfp_url }: { pfp_url: string }) { + const backgroundColor = useBackgroundColor('surfacePrimary'); + return ( + + ); +} +function FriendHolders({ friends }: { friends: FarcasterUser[] }) { + if (friends.length === 0) return null; + const howManyOthers = Math.max(1, friends.length - 2); + const separator = howManyOthers === 1 && friends.length === 2 ? ` ${i18n.t(t.and)} ` : ', '; + + return ( + + + + {friends[1] && } + + + + + {friends[0].username} + {friends[1] && ( + <> + + {separator} + + {friends[1].username} + + )} + + {friends.length > 2 && ( + + {' '} + {i18n.t('trending_tokens.and_others', { count: howManyOthers })} + + )} + + + ); +} + +function TrendingTokenLoadingRow() { + const backgroundColor = useBackgroundColor('surfacePrimary'); + const { isDarkMode } = useTheme(); + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +} + +function getPriceChangeColor(priceChange: number) { + if (priceChange === 0) return 'labelTertiary'; + return priceChange > 0 ? 'green' : 'red'; +} + +function TrendingTokenRow({ token }: { token: TrendingToken }) { + const separatorColor = useForegroundColor('separator'); + + const price = formatCurrency(token.price); + const marketCap = formatNumber(token.marketCap, { useOrderSuffix: true, decimals: 1, style: '$' }); + const volume = formatNumber(token.volume, { useOrderSuffix: true, decimals: 1, style: '$' }); + + const handleNavigateToToken = useCallback(() => { + analyticsV2.track(analyticsV2.event.viewTrendingToken, { + address: token.address, + chainId: token.chainId, + symbol: token.symbol, + name: token.name, + highlightedFriends: token.highlightedFriends.length, + }); + + swapsStore.setState({ + lastNavigatedTrendingToken: token.uniqueId, + }); + + Navigation.handleAction(Routes.EXPANDED_ASSET_SHEET, { + asset: token, + type: 'token', + }); + }, [token]); + + if (!token) return null; + + return ( + + + + + + + + + + + + {token.name} + + + {token.symbol} + + + {price} + + + + + + + VOL + + + {volume} + + + + + | + + + + + MCAP + + + {marketCap} + + + + + + + + + {formatNumber(token.priceChange.day, { decimals: 2, useOrderSuffix: true })}% + + + + + 1H + + + {formatNumber(token.priceChange.hr, { decimals: 2, useOrderSuffix: true })}% + + + + + + + + ); +} + +function NoResults() { + const { isDarkMode } = useTheme(); + const fillQuaternary = useBackgroundColor('fillQuaternary'); + const backgroundColor = isDarkMode ? '#191A1C' : fillQuaternary; + + return ( + + + + {i18n.t(t.no_results.title)} + + + {i18n.t(t.no_results.body)} + + + + + 􀙭 + + + + ); +} + +function NetworkFilter() { + const selected = useSharedValue(undefined); + + const { chainId, setChainId } = useTrendingTokensStore(state => ({ + chainId: state.chainId, + setChainId: state.setChainId, + })); + + const setSelected = useCallback( + (chainId: ChainId | undefined) => { + 'worklet'; + selected.value = chainId; + runOnJS(setChainId)(chainId); + }, + [selected, setChainId] + ); + + const label = !chainId ? i18n.t(t.all) : useBackendNetworksStore.getState().getChainsLabel()[chainId]; + + const icon = useMemo(() => { + if (!chainId) return '􀤆'; + return ; + }, [chainId]); + + const navigateToNetworkSelector = useCallback(() => { + Navigation.handleAction(Routes.NETWORK_SELECTOR, { + selected, + setSelected, + }); + }, [selected, setSelected]); + + return ; +} + +function TimeFilter() { + const timeframe = useTrendingTokensStore(state => state.timeframe); + + return ( + ({ + actionTitle: i18n.t(t.filters.time[time]), + actionKey: time, + })), + }} + side="bottom" + onPressMenuItem={timeframe => useTrendingTokensStore.getState().setTimeframe(timeframe)} + > + + + ); +} + +function SortFilter() { + const sort = useTrendingTokensStore(state => state.sort); + + const iconColor = useForegroundColor('labelQuaternary'); + + return ( + s !== 'RECOMMENDED') + .map(sort => ({ + actionTitle: i18n.t(t.filters.sort[sort]), + actionKey: sort, + })), + }} + side="bottom" + onPressMenuItem={selection => { + if (selection === sort) return useTrendingTokensStore.getState().setSort(TrendingSort.Recommended); + useTrendingTokensStore.getState().setSort(selection); + }} + > + + 􀄬 + + } + /> + + ); +} + +function TrendingTokensLoader() { + const { trending_tokens_limit } = useRemoteConfig(); + + return ( + + {Array.from({ length: trending_tokens_limit }).map((_, index) => ( + + ))} + + ); +} + +function TrendingTokenData() { + const { data: trendingTokens, isLoading } = useTrendingTokensData(); + if (isLoading) return ; + + return ( + } + data={trendingTokens} + renderItem={({ item }) => } + /> + ); +} + +const padding = 20; + +export function TrendingTokens() { + return ( + + + + + + + + + + + + + + + + + + + ); +} diff --git a/src/components/Discover/useTrackDiscoverScreenTime.ts b/src/components/Discover/useTrackDiscoverScreenTime.ts new file mode 100644 index 00000000000..64e96a50fa1 --- /dev/null +++ b/src/components/Discover/useTrackDiscoverScreenTime.ts @@ -0,0 +1,21 @@ +import { useNavigationStore } from '@/state/navigation/navigationStore'; +import { useEffect } from 'react'; +import Routes from '@/navigation/routesNames'; +import { PerformanceTracking, currentlyTrackedMetrics } from '@/performance/tracking'; +import { PerformanceMetrics } from '@/performance/tracking/types/PerformanceMetrics'; + +export const useTrackDiscoverScreenTime = () => { + const activeSwipeRoute = useNavigationStore(state => state.activeSwipeRoute); + useEffect(() => { + const isOnDiscoverScreen = activeSwipeRoute === Routes.DISCOVER_SCREEN; + const data = currentlyTrackedMetrics.get(PerformanceMetrics.timeSpentOnDiscoverScreen); + + if (!isOnDiscoverScreen && data?.startTimestamp) { + PerformanceTracking.finishMeasuring(PerformanceMetrics.timeSpentOnDiscoverScreen); + } + + if (isOnDiscoverScreen) { + PerformanceTracking.startMeasuring(PerformanceMetrics.timeSpentOnDiscoverScreen); + } + }, [activeSwipeRoute]); +}; diff --git a/src/components/NetworkSwitcher.tsx b/src/components/NetworkSwitcher.tsx new file mode 100644 index 00000000000..50c4e13d639 --- /dev/null +++ b/src/components/NetworkSwitcher.tsx @@ -0,0 +1,805 @@ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +import { getChainColorWorklet } from '@/__swaps__/utils/swaps'; +import { useBackendNetworksStore } from '@/state/backendNetworks/backendNetworks'; +import { ChainId } from '@/state/backendNetworks/types'; +import { AnimatedBlurView } from '@/components/AnimatedComponents/AnimatedBlurView'; +import { ButtonPressAnimation } from '@/components/animations'; +import { SPRING_CONFIGS, TIMING_CONFIGS } from '@/components/animations/animationConfigs'; +import { AnimatedChainImage, ChainImage } from '@/components/coin-icon/ChainImage'; +import { AnimatedText, Box, DesignSystemProvider, globalColors, Separator, Text, useBackgroundColor, useColorMode } from '@/design-system'; +import { useForegroundColor } from '@/design-system/color/useForegroundColor'; +import * as i18n from '@/languages'; +import { useTheme } from '@/theme'; +import deviceUtils, { DEVICE_WIDTH } from '@/utils/deviceUtils'; +import MaskedView from '@react-native-masked-view/masked-view'; +import chroma from 'chroma-js'; +import { PropsWithChildren, useEffect } from 'react'; +import React, { Pressable, StyleSheet, View } from 'react-native'; +import { RouteProp, useRoute } from '@react-navigation/native'; +import { Gesture, GestureDetector } from 'react-native-gesture-handler'; +import LinearGradient from 'react-native-linear-gradient'; +import Animated, { + FadeIn, + FadeOutUp, + LinearTransition, + runOnJS, + SharedValue, + useAnimatedReaction, + useAnimatedStyle, + useDerivedValue, + useSharedValue, + withDelay, + withSequence, + withSpring, + withTiming, +} from 'react-native-reanimated'; +import Svg, { Path } from 'react-native-svg'; +import { + customizeNetworksBannerStore, + defaultPinnedNetworks, + dismissCustomizeNetworksBanner, + networkSwitcherStore, + shouldShowCustomizeNetworksBanner, +} from '@/state/networkSwitcher/networkSwitcher'; +import { RootStackParamList } from '@/navigation/types'; +import { IS_IOS } from '@/env'; +import { safeAreaInsetValues } from '@/utils'; +import { noop } from 'lodash'; +import { TapToDismiss } from './DappBrowser/control-panel/ControlPanel'; + +const t = i18n.l.network_switcher; + +const translations = { + edit: i18n.t(t.edit), + done: i18n.t(i18n.l.done), + networks: i18n.t(t.networks), + more: i18n.t(t.more), + show_more: i18n.t(t.show_more), + show_less: i18n.t(t.show_less), + drag_to_rearrange: i18n.t(t.drag_to_rearrange), +}; + +function EditButton({ editing }: { editing: SharedValue }) { + const blue = useForegroundColor('blue'); + const borderColor = chroma(blue).alpha(0.08).hex(); + + const text = useDerivedValue(() => (editing.value ? translations.done : translations.edit)); + + return ( + { + 'worklet'; + editing.value = !editing.value; + }} + scaleTo={0.95} + style={[ + { position: 'absolute', right: 0 }, + { paddingHorizontal: 10, height: 28, justifyContent: 'center' }, + { borderColor, borderWidth: 1.33, borderRadius: 14 }, + ]} + > + + {text} + + + ); +} + +function Header({ editing }: { editing: SharedValue }) { + const separatorTertiary = useForegroundColor('separatorTertiary'); + const fill = useForegroundColor('fill'); + + const title = useDerivedValue(() => { + return editing.value ? translations.edit : translations.networks; + }); + + return ( + + + + + + + + {title} + + + + + + ); +} + +const CustomizeNetworksBanner = !shouldShowCustomizeNetworksBanner(customizeNetworksBannerStore.getState().dismissedAt) + ? () => null + : function CustomizeNetworksBanner({ editing }: { editing: SharedValue }) { + useAnimatedReaction( + () => editing.value, + (editing, prev) => { + if (!prev && editing) runOnJS(dismissCustomizeNetworksBanner)(); + } + ); + + const dismissedAt = customizeNetworksBannerStore(s => s.dismissedAt); + if (!shouldShowCustomizeNetworksBanner(dismissedAt)) return null; + + const height = 75; + const blue = '#268FFF'; + + return ( + + + + + + } + > + + + + + 􀍱 + + + + + {i18n.t(t.customize_networks_banner.title)} + + + {i18n.t(t.customize_networks_banner.tap_the)}{' '} + + {i18n.t(t.edit)} + {' '} + {i18n.t(t.customize_networks_banner.button_to_set_up)} + + + + + 􀆄 + + + + + + + + ); + }; + +const useNetworkOptionStyle = (isSelected: SharedValue, color?: string) => { + const { isDarkMode } = useColorMode(); + const label = useForegroundColor('labelTertiary'); + + const surfacePrimary = useBackgroundColor('surfacePrimary'); + const networkSwitcherBackgroundColor = isDarkMode ? '#191A1C' : surfacePrimary; + + const defaultStyle = { + backgroundColor: isDarkMode ? globalColors.white10 : globalColors.grey20, + borderColor: '#F5F8FF05', + }; + const selectedStyle = { + backgroundColor: chroma + .scale([networkSwitcherBackgroundColor, color || label])(0.16) + .hex(), + borderColor: chroma(color || label) + .alpha(0.16) + .hex(), + }; + + const scale = useSharedValue(1); + useAnimatedReaction( + () => isSelected.value, + current => { + if (current === true) { + scale.value = withSequence(withTiming(0.95, { duration: 50 }), withTiming(1, { duration: 80 })); + } + } + ); + + const animatedStyle = useAnimatedStyle(() => { + const colors = isSelected.value ? selectedStyle : defaultStyle; + return { + backgroundColor: colors.backgroundColor, + borderColor: colors.borderColor, + transform: [{ scale: scale.value }], + }; + }); + + return { + animatedStyle, + selectedStyle, + defaultStyle, + }; +}; + +function AllNetworksOption({ + selected, + setSelected, +}: { + selected: SharedValue; + setSelected: (chainId: ChainId | undefined) => void; +}) { + const blue = useForegroundColor('blue'); + + const isSelected = useDerivedValue(() => selected.value === undefined); + const { animatedStyle, selectedStyle, defaultStyle } = useNetworkOptionStyle(isSelected, blue); + + const overlappingBadge = useAnimatedStyle(() => { + return { + borderColor: isSelected.value ? selectedStyle.backgroundColor : defaultStyle.backgroundColor, + borderWidth: 1.67, + borderRadius: 16, + marginLeft: -9, + width: 16 + 1.67 * 2, // size + borders + height: 16 + 1.67 * 2, + }; + }); + + const tapGesture = Gesture.Tap().onTouchesDown(() => { + 'worklet'; + setSelected(undefined); + }); + + return ( + + + + + + + + + + {i18n.t(t.all_networks)} + + + + ); +} + +function AllNetworksSection({ + editing, + setSelected, + selected, +}: { + editing: SharedValue; + setSelected: (chainId: ChainId | undefined) => void; + selected: SharedValue; +}) { + const style = useAnimatedStyle(() => ({ + opacity: editing.value ? withTiming(0, TIMING_CONFIGS.fastFadeConfig) : withTiming(1, TIMING_CONFIGS.fastFadeConfig), + height: withTiming( + editing.value ? 0 : ITEM_HEIGHT + 14, // 14 is the gap to the separator + TIMING_CONFIGS.fastFadeConfig + ), + marginTop: editing.value ? 0 : 14, + pointerEvents: editing.value ? 'none' : 'auto', + })); + return ( + + + + + ); +} + +function NetworkOption({ chainId, selected }: { chainId: ChainId; selected: SharedValue }) { + const chainName = useBackendNetworksStore.getState().getChainsLabel()[chainId]; + const chainColor = getChainColorWorklet(chainId, true); + const isSelected = useDerivedValue(() => selected.value === chainId); + const { animatedStyle } = useNetworkOptionStyle(isSelected, chainColor); + + return ( + + + + {chainName} + + + ); +} + +const SHEET_OUTER_INSET = 8; +const SHEET_INNER_PADDING = 16; +const GAP = 12; +const ITEM_WIDTH = (DEVICE_WIDTH - SHEET_INNER_PADDING * 2 - SHEET_OUTER_INSET * 2 - GAP) / 2; +const ITEM_HEIGHT = 48; +const SEPARATOR_HEIGHT = 68; +const enum Section { + pinned, + separator, + unpinned, +} + +function Draggable({ + children, + dragging, + chainId, + networks, + sectionsOffsets, + isUnpinnedHidden, +}: PropsWithChildren<{ + chainId: ChainId; + dragging: SharedValue; + networks: SharedValue>; + sectionsOffsets: SharedValue>; + isUnpinnedHidden: SharedValue; +}>) { + const zIndex = useSharedValue(0); + useAnimatedReaction( + () => dragging.value?.chainId, + (current, prev) => { + if (current === prev) return; + if (current === chainId) zIndex.value = 2; + if (prev === chainId) zIndex.value = 1; + } + ); + + const draggableStyles = useAnimatedStyle(() => { + const section = networks.value[Section.pinned].includes(chainId) ? Section.pinned : Section.unpinned; + const itemIndex = networks.value[section].indexOf(chainId); + const slotPosition = positionFromIndex(itemIndex, sectionsOffsets.value[section]); + + const opacity = + section === Section.unpinned && isUnpinnedHidden.value + ? withTiming(0, TIMING_CONFIGS.fastFadeConfig) + : withDelay(100, withTiming(1, TIMING_CONFIGS.fadeConfig)); + + const isBeingDragged = dragging.value?.chainId === chainId; + const position = isBeingDragged ? dragging.value!.position : slotPosition; + + return { + opacity, + zIndex: zIndex.value, + transform: [ + { scale: withSpring(isBeingDragged ? 1.05 : 1, SPRING_CONFIGS.springConfig) }, + { translateX: isBeingDragged ? position.x : withSpring(position.x, SPRING_CONFIGS.springConfig) }, + { translateY: isBeingDragged ? position.y : withSpring(position.y, SPRING_CONFIGS.springConfig) }, + ], + }; + }); + + return {children}; +} + +const indexFromPosition = (x: number, y: number, offset: { y: number }) => { + 'worklet'; + const yoffsets = y > offset.y ? offset.y : 0; + const column = x > ITEM_WIDTH + GAP / 2 ? 1 : 0; + const row = Math.floor((y - yoffsets) / (ITEM_HEIGHT + GAP)); + const index = row * 2 + column; + return index < 0 ? 0 : index; // row can be negative if the dragged item is above the first row +}; + +const positionFromIndex = (index: number, offset: { y: number }) => { + 'worklet'; + const column = index % 2; + const row = Math.floor(index / 2); + const position = { x: column * (ITEM_WIDTH + GAP), y: row * (ITEM_HEIGHT + GAP) + offset.y }; + return position; +}; + +type Point = { x: number; y: number }; +type DraggingState = { + chainId: ChainId; + position: Point; +}; + +function SectionSeparator({ + sectionsOffsets, + editing, + expanded, + networks, +}: { + sectionsOffsets: SharedValue>; + editing: SharedValue; + expanded: SharedValue; + networks: SharedValue>; +}) { + const pressed = useSharedValue(false); + + const showExpandButtonAsNetworkChip = useDerivedValue(() => { + return !expanded.value && !editing.value && networks.value[Section.pinned].length % 2 !== 0; + }); + + const visible = useDerivedValue(() => { + return networks.value[Section.unpinned].length > 0 || editing.value; + }); + + const tapExpand = Gesture.Tap() + .onTouchesDown((e, s) => { + if (editing.value || !visible.value) return s.fail(); + pressed.value = true; + }) + .onEnd(() => { + pressed.value = false; + expanded.value = !expanded.value; + }); + + const text = useDerivedValue(() => { + if (editing.value) return translations.drag_to_rearrange; + if (showExpandButtonAsNetworkChip.value) return translations.more; + return expanded.value ? translations.show_less : translations.show_more; + }); + + const unpinnedNetworksLength = useDerivedValue(() => networks.value[Section.unpinned].length.toString()); + const showMoreAmountStyle = useAnimatedStyle(() => ({ + opacity: expanded.value || editing.value ? 0 : 1, + })); + const showMoreOrLessIcon = useDerivedValue(() => (expanded.value ? '􀆇' : '􀆈') as string); + const showMoreOrLessIconStyle = useAnimatedStyle(() => ({ opacity: editing.value ? 0 : 1 })); + + const { isDarkMode } = useTheme(); + + const separatorContainerStyles = useAnimatedStyle(() => { + if (showExpandButtonAsNetworkChip.value) { + const position = positionFromIndex(networks.value[Section.pinned].length, sectionsOffsets.value[Section.pinned]); + return { + backgroundColor: isDarkMode ? globalColors.white10 : globalColors.grey20, + borderColor: '#F5F8FF05', + height: ITEM_HEIGHT, + width: ITEM_WIDTH, + flexDirection: 'row', + alignItems: 'center', + borderRadius: 24, + borderWidth: 1.33, + transform: [{ translateX: position.x }, { translateY: position.y }], + }; + } + + return { + backgroundColor: 'transparent', + opacity: visible.value ? 1 : 0, + transform: [{ translateY: sectionsOffsets.value[Section.separator].y }, { scale: withTiming(pressed.value ? 0.95 : 1) }], + position: 'absolute', + width: '100%', + height: SEPARATOR_HEIGHT, + }; + }); + + return ( + + + + + {unpinnedNetworksLength} + + + + {text} + + + + {showMoreOrLessIcon} + + + + + ); +} + +function EmptyUnpinnedPlaceholder({ + sectionsOffsets, + networks, + isUnpinnedHidden, +}: { + sectionsOffsets: SharedValue>; + networks: SharedValue>; + isUnpinnedHidden: SharedValue; +}) { + const styles = useAnimatedStyle(() => { + const isVisible = networks.value[Section.unpinned].length === 0 && !isUnpinnedHidden.value; + return { + opacity: isVisible ? withTiming(1, { duration: 800 }) : 0, + transform: [{ translateY: sectionsOffsets.value[Section.unpinned].y }], + }; + }); + const { isDarkMode } = useTheme(); + return ( + + + {i18n.t(t.drag_here_to_unpin)} + + + ); +} + +function NetworksGrid({ + editing, + setSelected, + selected, +}: { + editing: SharedValue; + setSelected: (chainId: ChainId | undefined) => void; + selected: SharedValue; +}) { + const initialPinned = networkSwitcherStore.getState().pinnedNetworks; + const sortedSupportedChainIds = useBackendNetworksStore.getState().getSortedSupportedChainIds(); + const initialUnpinned = sortedSupportedChainIds.filter(chainId => !initialPinned.includes(chainId)); + const networks = useSharedValue({ [Section.pinned]: initialPinned, [Section.unpinned]: initialUnpinned }); + + useEffect(() => { + // persists pinned networks when closing the sheet + // should be the only time this component is unmounted + return () => { + if (networks.value[Section.pinned].length > 0) { + networkSwitcherStore.setState({ pinnedNetworks: networks.value[Section.pinned] }); + } else { + networkSwitcherStore.setState({ pinnedNetworks: defaultPinnedNetworks }); + } + }; + }, [networks]); + + const expanded = useSharedValue(false); + const isUnpinnedHidden = useDerivedValue(() => !expanded.value && !editing.value); + + const dragging = useSharedValue(null); + + const sectionsOffsets = useDerivedValue(() => { + const pinnedHeight = Math.ceil(networks.value[Section.pinned].length / 2) * (ITEM_HEIGHT + GAP) - GAP; + return { + [Section.pinned]: { y: 0 }, + [Section.separator]: { y: pinnedHeight }, + [Section.unpinned]: { y: pinnedHeight + SEPARATOR_HEIGHT }, + }; + }); + const containerHeight = useDerivedValue(() => { + const length = networks.value[Section.unpinned].length; + const paddingBottom = 32; + const unpinnedHeight = isUnpinnedHidden.value + ? length === 0 + ? -SEPARATOR_HEIGHT + paddingBottom + : 0 + : length === 0 + ? ITEM_HEIGHT + paddingBottom + : Math.ceil((length + 1) / 2) * (ITEM_HEIGHT + GAP) - GAP + paddingBottom; + const height = sectionsOffsets.value[Section.unpinned].y + unpinnedHeight; + return height; + }); + const containerStyle = useAnimatedStyle(() => ({ + height: withDelay(expanded.value ? 0 : 25, withTiming(containerHeight.value, TIMING_CONFIGS.slowerFadeConfig)), + })); + + const dragNetwork = Gesture.Pan() + .maxPointers(1) + .onTouchesDown((e, s) => { + if (!editing.value) { + s.fail(); + return; + } + const touch = e.allTouches[0]; + const section = touch.y > sectionsOffsets.value[Section.unpinned].y ? Section.unpinned : Section.pinned; + const sectionOffset = sectionsOffsets.value[section]; + const index = indexFromPosition(touch.x, touch.y, sectionOffset); + const sectionNetworks = networks.value[section]; + const chainId = sectionNetworks[index]; + + if (!chainId || (section === Section.pinned && sectionNetworks.length === 1)) { + s.fail(); + return; + } + + const position = positionFromIndex(index, sectionOffset); + dragging.value = { chainId, position }; + }) + .onChange(e => { + if (!dragging.value) return; + const chainId = dragging.value.chainId; + if (!chainId) return; + + const section = e.y > sectionsOffsets.value[Section.unpinned].y - SEPARATOR_HEIGHT / 2 ? Section.unpinned : Section.pinned; + const sectionArray = networks.value[section]; + + const currentIndex = sectionArray.indexOf(chainId); + const newIndex = Math.min(indexFromPosition(e.x, e.y, sectionsOffsets.value[section]), sectionArray.length - 1); + + networks.modify(networks => { + if (currentIndex === -1) { + // Pin/Unpin + if (section === Section.unpinned) networks[Section.pinned].splice(currentIndex, 1); + else networks[Section.pinned].push(chainId); + networks[Section.unpinned] = sortedSupportedChainIds.filter(chainId => !networks[Section.pinned].includes(chainId)); + } else if (section === Section.pinned && newIndex !== currentIndex) { + // Reorder + networks[Section.pinned].splice(currentIndex, 1); + networks[Section.pinned].splice(newIndex, 0, chainId); + } + return networks; + }); + dragging.modify(dragging => { + if (!dragging) return dragging; + dragging.position.x += e.changeX; + dragging.position.y += e.changeY; + return dragging; + }); + }) + .onFinalize(() => { + dragging.value = null; + }); + + const tapNetwork = Gesture.Tap() + .onTouchesDown((e, s) => { + if (editing.value) return s.fail(); + }) + .onEnd(e => { + const section = e.y > sectionsOffsets.value[Section.unpinned].y ? Section.unpinned : Section.pinned; + const index = indexFromPosition(e.x, e.y, sectionsOffsets.value[section]); + const chainId = networks.value[section][index]; + if (!chainId) return; + + setSelected(chainId); + }); + + const gridGesture = Gesture.Exclusive(dragNetwork, tapNetwork); + + return ( + + + {initialPinned.map(chainId => ( + + + + ))} + + + + + + {initialUnpinned.map(chainId => ( + + + + ))} + + + ); +} + +function Sheet({ children, editing, onClose }: PropsWithChildren<{ editing: SharedValue; onClose: VoidFunction }>) { + const { isDarkMode } = useTheme(); + const surfacePrimary = useBackgroundColor('surfacePrimary'); + const backgroundColor = isDarkMode ? '#191A1C' : surfacePrimary; + const separatorSecondary = useForegroundColor('separatorSecondary'); + + // make sure the onClose function is called when the sheet unmounts + useEffect(() => { + return () => onClose?.(); + }, [onClose]); + + return ( + <> + +
+ {children} + + + + ); +} + +export function NetworkSelector() { + const { + params: { onClose = noop, selected, setSelected }, + } = useRoute>(); + + const editing = useSharedValue(false); + + return ( + + + + + + ); +} + +const sx = StyleSheet.create({ + sheet: { + flex: 1, + width: deviceUtils.dimensions.width - 16, + bottom: Math.max(safeAreaInsetValues.bottom + 5, IS_IOS ? 8 : 30), + pointerEvents: 'box-none', + position: 'absolute', + zIndex: 30000, + left: 8, + right: 8, + paddingHorizontal: 16, + borderRadius: 42, + borderWidth: 1.33, + }, +}); diff --git a/src/components/asset-list/RecyclerAssetList2/FastComponents/FastCoinBadge.tsx b/src/components/asset-list/RecyclerAssetList2/FastComponents/FastCoinBadge.tsx index 4ea959efb7c..3239c50dbda 100644 --- a/src/components/asset-list/RecyclerAssetList2/FastComponents/FastCoinBadge.tsx +++ b/src/components/asset-list/RecyclerAssetList2/FastComponents/FastCoinBadge.tsx @@ -16,24 +16,23 @@ import BscBadge from '@/assets/badges/bscBadge.png'; import BscBadgeDark from '@/assets/badges/bscBadgeDark.png'; import DegenBadge from '@/assets/badges/degenBadge.png'; import DegenBadgeDark from '@/assets/badges/degenBadgeDark.png'; -// import GnosisBadge from '@/assets/badges/gnosisBadge.png'; -// import GnosisBadgeDark from '@/assets/badges/gnosisBadgeDark.png'; -// import GravityBadge from '@/assets/badges/gravityBadge.png'; -// import GravityBadgeDark from '@/assets/badges/gravityBadgeDark.png'; +import GnosisBadge from '@/assets/badges/gnosisBadge.png'; +import GnosisBadgeDark from '@/assets/badges/gnosisBadgeDark.png'; +import GravityBadge from '@/assets/badges/gravityBadge.png'; +import GravityBadgeDark from '@/assets/badges/gravityBadgeDark.png'; import InkBadge from '@/assets/badges/inkBadge.png'; import InkBadgeDark from '@/assets/badges/inkBadgeDark.png'; -// import LineaBadge from '@/assets/badges/lineaBadge.png'; -// import LineaBadgeDark from '@/assets/badges/lineaBadgeDark.png'; +import LineaBadge from '@/assets/badges/lineaBadge.png'; +import LineaBadgeDark from '@/assets/badges/lineaBadgeDark.png'; import OptimismBadge from '@/assets/badges/optimismBadge.png'; import OptimismBadgeDark from '@/assets/badges/optimismBadgeDark.png'; import PolygonBadge from '@/assets/badges/polygonBadge.png'; import PolygonBadgeDark from '@/assets/badges/polygonBadgeDark.png'; -// import SankoBadge from '@/assets/badges/sankoBadge.png'; -// import SankoBadgeDark from '@/assets/badges/sankoBadgeDark.png'; -// import ScrollBadge from '@/assets/badges/scrollBadge.png'; -// import ScrollBadgeDark from '@/assets/badges/scrollBadgeDark.png'; -// import ZksyncBadge from '@/assets/badges/zksyncBadge.png'; -// import ZksyncBadgeDark from '@/assets/badges/zksyncBadgeDark.png'; +import SankoBadge from '@/assets/badges/sankoBadge.png'; +import ScrollBadge from '@/assets/badges/scrollBadge.png'; +import ScrollBadgeDark from '@/assets/badges/scrollBadgeDark.png'; +import ZksyncBadge from '@/assets/badges/zkSyncBadge.png'; +import ZksyncBadgeDark from '@/assets/badges/zksyncBadgeDark.png'; import ZoraBadge from '@/assets/badges/zoraBadge.png'; import ZoraBadgeDark from '@/assets/badges/zoraBadgeDark.png'; @@ -76,22 +75,22 @@ const AssetIconsByTheme: { dark: DegenBadgeDark, light: DegenBadge, }, - // [ChainId.gnosis]: { - // dark: GnosisBadgeDark, - // light: GnosisBadge, - // }, - // [ChainId.gravity]: { - // dark: GravityBadgeDark, - // light: GravityBadge, - // }, + [ChainId.gnosis]: { + dark: GnosisBadgeDark, + light: GnosisBadge, + }, + [ChainId.gravity]: { + dark: GravityBadgeDark, + light: GravityBadge, + }, [ChainId.ink]: { dark: InkBadgeDark, light: InkBadge, }, - // [ChainId.linea]: { - // dark: LineaBadgeDark, - // light: LineaBadge, - // }, + [ChainId.linea]: { + dark: LineaBadgeDark, + light: LineaBadge, + }, [ChainId.optimism]: { dark: OptimismBadgeDark, light: OptimismBadge, @@ -100,18 +99,18 @@ const AssetIconsByTheme: { dark: PolygonBadgeDark, light: PolygonBadge, }, - // [ChainId.sanko]: { - // dark: SankoBadgeDark, - // light: SankoBadge, - // }, - // [ChainId.scroll]: { - // dark: ScrollBadgeDark, - // light: ScrollBadge, - // }, - // [ChainId.zksync]: { - // dark: ZksyncBadgeDark, - // light: ZksyncBadge, - // }, + [ChainId.sanko]: { + dark: SankoBadge, + light: SankoBadge, + }, + [ChainId.scroll]: { + dark: ScrollBadgeDark, + light: ScrollBadge, + }, + [ChainId.zksync]: { + dark: ZksyncBadgeDark, + light: ZksyncBadge, + }, [ChainId.zora]: { dark: ZoraBadgeDark, light: ZoraBadge, diff --git a/src/components/coin-icon/ChainBadge.js b/src/components/coin-icon/ChainBadge.js index 8babe5015a6..2dbd8061cf2 100644 --- a/src/components/coin-icon/ChainBadge.js +++ b/src/components/coin-icon/ChainBadge.js @@ -29,22 +29,22 @@ import DegenBadge from '@/assets/badges/degenBadge.png'; import DegenBadgeDark from '@/assets/badges/degenBadgeDark.png'; import DegenBadgeLarge from '@/assets/badges/degenBadgeLarge.png'; import DegenBadgeLargeDark from '@/assets/badges/degenBadgeLargeDark.png'; -// import GnosisBadge from '@/assets/badges/gnosisBadge.png'; -// import GnosisBadgeDark from '@/assets/badges/gnosisBadgeDark.png'; -// import GnosisBadgeLarge from '@/assets/badges/gnosisBadgeLarge.png'; -// import GnosisBadgeLargeDark from '@/assets/badges/gnosisBadgeLargeDark.png'; -// import GravityBadge from '@/assets/badges/gravityBadge.png'; -// import GravityBadgeDark from '@/assets/badges/gravityBadgeDark.png'; -// import GravityBadgeLarge from '@/assets/badges/gravityBadgeLarge.png'; -// import GravityBadgeLargeDark from '@/assets/badges/gravityBadgeLargeDark.png'; +import GnosisBadge from '@/assets/badges/gnosisBadge.png'; +import GnosisBadgeDark from '@/assets/badges/gnosisBadgeDark.png'; +import GnosisBadgeLarge from '@/assets/badges/gnosisBadgeLarge.png'; +import GnosisBadgeLargeDark from '@/assets/badges/gnosisBadgeLargeDark.png'; +import GravityBadge from '@/assets/badges/gravityBadge.png'; +import GravityBadgeDark from '@/assets/badges/gravityBadgeDark.png'; +import GravityBadgeLarge from '@/assets/badges/gravityBadgeLarge.png'; +import GravityBadgeLargeDark from '@/assets/badges/gravityBadgeLargeDark.png'; import InkBadge from '@/assets/badges/inkBadge.png'; import InkBadgeDark from '@/assets/badges/inkBadgeDark.png'; import InkBadgeLarge from '@/assets/badges/inkBadgeLarge.png'; import InkBadgeLargeDark from '@/assets/badges/inkBadgeLargeDark.png'; -// import LineaBadge from '@/assets/badges/lineaBadge.png'; -// import LineaBadgeDark from '@/assets/badges/lineaBadgeDark.png'; -// import LineaBadgeLarge from '@/assets/badges/lineaBadgeLarge.png'; -// import LineaBadgeLargeDark from '@/assets/badges/lineaBadgeLargeDark.png'; +import LineaBadge from '@/assets/badges/lineaBadge.png'; +import LineaBadgeDark from '@/assets/badges/lineaBadgeDark.png'; +import LineaBadgeLarge from '@/assets/badges/lineaBadgeLarge.png'; +import LineaBadgeLargeDark from '@/assets/badges/lineaBadgeLargeDark.png'; import OptimismBadge from '@/assets/badges/optimismBadge.png'; import OptimismBadgeDark from '@/assets/badges/optimismBadgeDark.png'; import OptimismBadgeLarge from '@/assets/badges/optimismBadgeLarge.png'; @@ -53,18 +53,17 @@ import PolygonBadge from '@/assets/badges/polygonBadge.png'; import PolygonBadgeDark from '@/assets/badges/polygonBadgeDark.png'; import PolygonBadgeLarge from '@/assets/badges/polygonBadgeLarge.png'; import PolygonBadgeLargeDark from '@/assets/badges/polygonBadgeLargeDark.png'; -// import SankoBadge from '@/assets/badges/sankoBadge.png'; -// import SankoBadgeDark from '@/assets/badges/sankoBadgeDark.png'; -// import SankoBadgeLarge from '@/assets/badges/sankoBadgeLarge.png'; -// import SankoBadgeLargeDark from '@/assets/badges/sankoBadgeLargeDark.png'; -// import ScrollBadge from '@/assets/badges/scrollBadge.png'; -// import ScrollBadgeDark from '@/assets/badges/scrollBadgeDark.png'; -// import ScrollBadgeLarge from '@/assets/badges/scrollBadgeLarge.png'; -// import ScrollBadgeLargeDark from '@/assets/badges/scrollBadgeLargeDark.png'; -// import ZksyncBadge from '@/assets/badges/zksyncBadge.png'; -// import ZksyncBadgeDark from '@/assets/badges/zksyncBadgeDark.png'; -// import ZksyncBadgeLarge from '@/assets/badges/zksyncBadgeLarge.png'; -// import ZksyncBadgeLargeDark from '@/assets/badges/zksyncBadgeLargeDark.png'; +import SankoBadge from '@/assets/badges/sankoBadge.png'; +import SankoBadgeLarge from '@/assets/badges/sankoBadgeLarge.png'; +import SankoBadgeLargeDark from '@/assets/badges/sankoBadgeLargeDark.png'; +import ScrollBadge from '@/assets/badges/scrollBadge.png'; +import ScrollBadgeDark from '@/assets/badges/scrollBadgeDark.png'; +import ScrollBadgeLarge from '@/assets/badges/scrollBadgeLarge.png'; +import ScrollBadgeLargeDark from '@/assets/badges/scrollBadgeLargeDark.png'; +import ZksyncBadge from '@/assets/badges/zkSyncBadge.png'; +import ZksyncBadgeDark from '@/assets/badges/zksyncBadgeDark.png'; +import ZksyncBadgeLarge from '@/assets/badges/zksyncBadgeLarge.png'; +import ZksyncBadgeLargeDark from '@/assets/badges/zksyncBadgeLargeDark.png'; import ZoraBadge from '@/assets/badges/zoraBadge.png'; import ZoraBadgeDark from '@/assets/badges/zoraBadgeDark.png'; import ZoraBadgeLarge from '@/assets/badges/zoraBadgeLarge.png'; @@ -124,24 +123,24 @@ export default function ChainBadge({ val = isDarkMode ? BscBadgeLargeDark : BscBadgeLarge; } else if (chainId === ChainId.degen) { val = isDarkMode ? DegenBadgeLargeDark : DegenBadgeLarge; - // } else if (chainId === ChainId.gnosis) { - // val = isDarkMode ? GnosisBadgeLargeDark : GnosisBadgeLarge; - // } else if (chainId === ChainId.gravity) { - // val = isDarkMode ? GravityBadgeLargeDark : GravityBadgeLarge; + } else if (chainId === ChainId.gnosis) { + val = isDarkMode ? GnosisBadgeLargeDark : GnosisBadgeLarge; + } else if (chainId === ChainId.gravity) { + val = isDarkMode ? GravityBadgeLargeDark : GravityBadgeLarge; } else if (chainId === ChainId.ink) { val = isDarkMode ? InkBadgeLargeDark : InkBadgeLarge; - // } else if (chainId === ChainId.linea) { - // val = isDarkMode ? LineaBadgeLargeDark : LineaBadgeLarge; + } else if (chainId === ChainId.linea) { + val = isDarkMode ? LineaBadgeLargeDark : LineaBadgeLarge; } else if (chainId === ChainId.optimism) { val = isDarkMode ? OptimismBadgeLargeDark : OptimismBadgeLarge; } else if (chainId === ChainId.polygon) { val = isDarkMode ? PolygonBadgeLargeDark : PolygonBadgeLarge; - // } else if (chainId === ChainId.sanko) { - // val = isDarkMode ? SankoBadgeLargeDark : SankoBadgeLarge; - // } else if (chainId === ChainId.scroll) { - // val = isDarkMode ? ScrollBadgeLargeDark : ScrollBadgeLarge; - // } else if (chainId === ChainId.zksync) { - // val = isDarkMode ? ZksyncBadgeLargeDark : ZksyncBadgeLarge; + } else if (chainId === ChainId.sanko) { + val = isDarkMode ? SankoBadgeLargeDark : SankoBadgeLarge; + } else if (chainId === ChainId.scroll) { + val = isDarkMode ? ScrollBadgeLargeDark : ScrollBadgeLarge; + } else if (chainId === ChainId.zksync) { + val = isDarkMode ? ZksyncBadgeLargeDark : ZksyncBadgeLarge; } else if (chainId === ChainId.zora) { val = isDarkMode ? ZoraBadgeLargeDark : ZoraBadgeLarge; } @@ -160,24 +159,24 @@ export default function ChainBadge({ val = isDarkMode ? BscBadgeDark : BscBadge; } else if (chainId === ChainId.degen) { val = isDarkMode ? DegenBadgeDark : DegenBadge; - // } else if (chainId === ChainId.gnosis) { - // val = isDarkMode ? GnosisBadgeDark : GnosisBadge; - // } else if (chainId === ChainId.gravity) { - // val = isDarkMode ? GravityBadgeDark : GravityBadge; + } else if (chainId === ChainId.gnosis) { + val = isDarkMode ? GnosisBadgeDark : GnosisBadge; + } else if (chainId === ChainId.gravity) { + val = isDarkMode ? GravityBadgeDark : GravityBadge; } else if (chainId === ChainId.ink) { val = isDarkMode ? InkBadgeDark : InkBadge; - // } else if (chainId === ChainId.linea) { - // val = isDarkMode ? LineaBadgeDark : LineaBadge; + } else if (chainId === ChainId.linea) { + val = isDarkMode ? LineaBadgeDark : LineaBadge; } else if (chainId === ChainId.optimism) { val = isDarkMode ? OptimismBadgeDark : OptimismBadge; } else if (chainId === ChainId.polygon) { val = isDarkMode ? PolygonBadgeDark : PolygonBadge; - // } else if (chainId === ChainId.sanko) { - // val = isDarkMode ? SankoBadgeDark : SankoBadge; - // } else if (chainId === ChainId.scroll) { - // val = isDarkMode ? ScrollBadgeDark : ScrollBadge; - // } else if (chainId === ChainId.zksync) { - // val = isDarkMode ? ZksyncBadgeDark : ZksyncBadge; + } else if (chainId === ChainId.sanko) { + val = SankoBadge; + } else if (chainId === ChainId.scroll) { + val = isDarkMode ? ScrollBadgeDark : ScrollBadge; + } else if (chainId === ChainId.zksync) { + val = isDarkMode ? ZksyncBadgeDark : ZksyncBadge; } else if (chainId === ChainId.zora) { val = isDarkMode ? ZoraBadgeDark : ZoraBadge; } diff --git a/src/components/coin-icon/ChainImage.tsx b/src/components/coin-icon/ChainImage.tsx index 1aa5c479b8e..671296c8445 100644 --- a/src/components/coin-icon/ChainImage.tsx +++ b/src/components/coin-icon/ChainImage.tsx @@ -1,4 +1,4 @@ -import React, { useMemo } from 'react'; +import React, { useMemo, forwardRef } from 'react'; import { ChainId } from '@/state/backendNetworks/types'; import ApechainBadge from '@/assets/badges/apechain.png'; @@ -9,20 +9,31 @@ import BlastBadge from '@/assets/badges/blast.png'; import BscBadge from '@/assets/badges/bsc.png'; import DegenBadge from '@/assets/badges/degen.png'; import EthereumBadge from '@/assets/badges/ethereum.png'; -// import GnosisBadge from '@/assets/badges/gnosis.png'; -// import GravityBadge from '@/assets/badges/gravity.png'; +import GnosisBadge from '@/assets/badges/gnosis.png'; +import GravityBadge from '@/assets/badges/gravity.png'; import InkBadge from '@/assets/badges/ink.png'; -// import LineaBadge from '@/assets/badges/linea.png'; +import LineaBadge from '@/assets/badges/linea.png'; import OptimismBadge from '@/assets/badges/optimism.png'; import PolygonBadge from '@/assets/badges/polygon.png'; -// import SankoBadge from '@/assets/badges/sanko.png'; -// import ScrollBadge from '@/assets/badges/scroll.png'; -// import ZksyncBadge from '@/assets/badges/zksync.png'; +import SankoBadge from '@/assets/badges/sanko.png'; +import ScrollBadge from '@/assets/badges/scroll.png'; +import ZksyncBadge from '@/assets/badges/zksync.png'; import ZoraBadge from '@/assets/badges/zora.png'; +import FastImage, { FastImageProps, Source } from 'react-native-fast-image'; +import Animated from 'react-native-reanimated'; -import FastImage, { Source } from 'react-native-fast-image'; - -export function ChainImage({ chainId, size = 20 }: { chainId: ChainId | null | undefined; size?: number }) { +export const ChainImage = forwardRef(function ChainImage( + { + chainId, + size = 20, + style, + }: { + chainId: ChainId | null | undefined; + size?: number; + style?: FastImageProps['style']; + }, + ref +) { const source = useMemo(() => { switch (chainId) { case ChainId.apechain: @@ -39,26 +50,26 @@ export function ChainImage({ chainId, size = 20 }: { chainId: ChainId | null | u return BscBadge; case ChainId.degen: return DegenBadge; - // case ChainId.gnosis: - // return GnosisBadge; - // case ChainId.gravity: - // return GravityBadge; + case ChainId.gnosis: + return GnosisBadge; + case ChainId.gravity: + return GravityBadge; case ChainId.ink: return InkBadge; - // case ChainId.linea: - // return LineaBadge; + case ChainId.linea: + return LineaBadge; case ChainId.mainnet: return EthereumBadge; case ChainId.optimism: return OptimismBadge; case ChainId.polygon: return PolygonBadge; - // case ChainId.sanko: - // return SankoBadge; - // case ChainId.scroll: - // return ScrollBadge; - // case ChainId.zksync: - // return ZksyncBadge; + case ChainId.sanko: + return SankoBadge; + case ChainId.scroll: + return ScrollBadge; + case ChainId.zksync: + return ZksyncBadge; case ChainId.zora: return ZoraBadge; default: @@ -69,6 +80,14 @@ export function ChainImage({ chainId, size = 20 }: { chainId: ChainId | null | u if (!chainId) return null; return ( - + ); -} +}); + +export const AnimatedChainImage = Animated.createAnimatedComponent(ChainImage); diff --git a/src/components/sheet/sheet-action-buttons/SwapActionButton.tsx b/src/components/sheet/sheet-action-buttons/SwapActionButton.tsx index 9a7ea341748..81f82de844b 100644 --- a/src/components/sheet/sheet-action-buttons/SwapActionButton.tsx +++ b/src/components/sheet/sheet-action-buttons/SwapActionButton.tsx @@ -31,7 +31,7 @@ function SwapActionButton({ asset, color: givenColor, inputType, label, weight = const goToSwap = useCallback(async () => { const chainsIdByName = useBackendNetworksStore.getState().getChainsIdByName(); const chainsName = useBackendNetworksStore.getState().getChainsName(); - const chainId = chainsIdByName[asset.network]; + const chainId = asset.chainId || chainsIdByName[asset.network]; const uniqueId = `${asset.address}_${chainId}`; const userAsset = userAssetsStore.getState().userAssets.get(uniqueId); diff --git a/src/config/experimental.ts b/src/config/experimental.ts index b68e23260ff..cef7e04d7d7 100644 --- a/src/config/experimental.ts +++ b/src/config/experimental.ts @@ -29,6 +29,7 @@ export const DEGEN_MODE = 'Degen Mode'; export const FEATURED_RESULTS = 'Featured Results'; export const CLAIMABLES = 'Claimables'; export const NFTS_ENABLED = 'Nfts Enabled'; +export const TRENDING_TOKENS = 'Trending Tokens'; /** * A developer setting that pushes log lines to an array in-memory so that @@ -66,6 +67,7 @@ export const defaultConfig: Record = { [FEATURED_RESULTS]: { settings: true, value: false }, [CLAIMABLES]: { settings: true, value: false }, [NFTS_ENABLED]: { settings: true, value: !!IS_TEST }, + [TRENDING_TOKENS]: { settings: true, value: false }, }; export const defaultConfigValues: Record = Object.fromEntries( diff --git a/src/graphql/queries/arc.graphql b/src/graphql/queries/arc.graphql index 68e797864e5..17dccca539c 100644 --- a/src/graphql/queries/arc.graphql +++ b/src/graphql/queries/arc.graphql @@ -522,6 +522,7 @@ query trendingTokens( $sortBy: TrendingSort $sortDirection: SortDirection $walletAddress: String + $limit: Int ) { trendingTokens( chainId: $chainId @@ -531,6 +532,7 @@ query trendingTokens( sortBy: $sortBy sortDirection: $sortDirection walletAddress: $walletAddress + limit: $limit ) { data { colors { diff --git a/src/helpers/strings.ts b/src/helpers/strings.ts index 4e7fd76ab91..986c23a665a 100644 --- a/src/helpers/strings.ts +++ b/src/helpers/strings.ts @@ -1,4 +1,8 @@ +import store from '@/redux/store'; import { memoFn } from '../utils/memoFn'; +import { supportedNativeCurrencies } from '@/references'; +import { NativeCurrencyKey } from '@/entities'; +import { convertAmountToNativeDisplayWorklet } from './utilities'; /** * @desc subtracts two numbers * @param {String} str @@ -10,3 +14,127 @@ export const containsEmoji = memoFn(str => { // @ts-expect-error ts-migrate(2571) FIXME: Object is of type 'unknown'. return !!str.match(ranges.join('|')); }); + +/* + * Return the given number as a formatted string. The default format is a plain + * integer with thousands-separator commas. The optional parameters facilitate + * other formats: + * - decimals = the number of decimals places to round to and show + * - valueIfNaN = the value to show for non-numeric input + * - style + * - '%': multiplies by 100 and appends a percent symbol + * - '$': prepends a dollar sign + * - useOrderSuffix = whether to use suffixes like k for 1,000, etc. + * - orderSuffixes = the list of suffixes to use + * - minOrder and maxOrder allow the order to be constrained. Examples: + * - minOrder = 1 means the k suffix should be used for numbers < 1,000 + * - maxOrder = 1 means the k suffix should be used for numbers >= 1,000,000 + */ +export function formatNumber( + number: string | number, + { + decimals = 0, + valueIfNaN = '', + style = '', + useOrderSuffix = false, + orderSuffixes = ['', 'K', 'M', 'B', 'T'], + minOrder = 0, + maxOrder = Infinity, + } = {} +) { + let x = parseFloat(`${number}`); + + if (isNaN(x)) return valueIfNaN; + + if (style === '%') x *= 100.0; + + let order; + if (!isFinite(x) || !useOrderSuffix) order = 0; + else if (minOrder === maxOrder) order = minOrder; + else { + const unboundedOrder = Math.floor(Math.log10(Math.abs(x)) / 3); + order = Math.max(0, minOrder, Math.min(unboundedOrder, maxOrder, orderSuffixes.length - 1)); + } + + const orderSuffix = orderSuffixes[order]; + if (order !== 0) x /= Math.pow(10, order * 3); + + return ( + (style === '$' ? '$' : '') + + x.toLocaleString('en-US', { + style: 'decimal', + minimumFractionDigits: decimals, + maximumFractionDigits: decimals, + }) + + orderSuffix + + (style === '%' ? '%' : '') + ); +} + +type CurrencyFormatterOptions = { + decimals?: number; + valueIfNaN?: string; + currency?: NativeCurrencyKey; +}; + +const toSubscript = (str: string | number) => str.toString().replace(/[0-9]/g, num => String.fromCharCode(0x2080 + +num)); + +/* + converts 6.9e-7 to 0.00000069 +*/ +const toDecimalString = (num: number): string => { + const [coefficient, exponent] = num.toExponential(20).split('e'); + const exp = parseInt(exponent); + const digits = coefficient.replace('.', '').replace(/0+$/, ''); + + if (exp >= 0) { + const position = exp + 1; + if (position >= digits.length) return digits + '0'.repeat(position - digits.length); + return digits.slice(0, position) + (digits.slice(position) && '.' + digits.slice(position)); + } + return '0.' + '0'.repeat(Math.abs(exp) - 1) + digits; +}; + +/* + formats a numeric string like 0000069 to 0₅69 +*/ +function formatFraction(fraction: string) { + const leadingZeros = fraction.match(/^[0]+/)?.[0].length || 0; + if (+fraction === 0) return '00'; + + const significantDigits = fraction.slice(leadingZeros, leadingZeros + 2); + if (+significantDigits === 0) return '00'; + + if (leadingZeros >= 4) return `0${toSubscript(leadingZeros)}${significantDigits}`; + return `${'0'.repeat(leadingZeros)}${significantDigits}`; +} + +export function formatCurrency( + value: string | number, + { valueIfNaN = '', currency = store.getState().settings.nativeCurrency }: CurrencyFormatterOptions = {} +): string { + const numericString = typeof value === 'number' ? toDecimalString(value) : String(value); + if (isNaN(+numericString)) return valueIfNaN; + + const currencySymbol = supportedNativeCurrencies[currency].symbol; + const [whole, fraction = ''] = numericString.split('.'); + + if (fraction === '') { + // if the fraction is empty and the numeric string is less than 6 characters, we can just run it through our native currency display worklet + if (numericString.length <= 6) { + return convertAmountToNativeDisplayWorklet(numericString, currency, false, true); + } + + const decimals = supportedNativeCurrencies[currency].decimals; + // otherwise for > 6 figs native value we need to format in compact notation + const formattedWhole = formatNumber(numericString, { decimals, useOrderSuffix: true }); + return `${currencySymbol}${formattedWhole}`; + } + + const formattedWhole = formatNumber(whole, { decimals: 0, useOrderSuffix: true }); + const formattedFraction = formatFraction(fraction); + // if it ends with a non-numeric character, it's in compact notation like '1.2K' + if (isNaN(+formattedWhole[formattedWhole.length - 1])) return `${currencySymbol}${formattedWhole}`; + + return `${currencySymbol}${formattedWhole}.${formattedFraction}`; +} diff --git a/src/hooks/reanimated/useSyncSharedValue.ts b/src/hooks/reanimated/useSyncSharedValue.ts index f8c19c71a0c..c48f83a3643 100644 --- a/src/hooks/reanimated/useSyncSharedValue.ts +++ b/src/hooks/reanimated/useSyncSharedValue.ts @@ -9,14 +9,14 @@ interface BaseSyncParams { /** A boolean or shared value boolean that controls whether synchronization is paused. */ pauseSync?: DerivedValue | SharedValue | boolean; /** The JS state to be synchronized. */ - state: T | undefined; + state: T; } interface SharedToStateParams extends BaseSyncParams { /** The setter function for the JS state (only applicable when `syncDirection` is `'sharedValueToState'`). */ setState: (value: T) => void; /** The shared value to be synchronized. */ - sharedValue: DerivedValue | DerivedValue | SharedValue | SharedValue; + sharedValue: DerivedValue | SharedValue; /** The direction of synchronization. */ syncDirection: 'sharedValueToState'; } @@ -24,7 +24,7 @@ interface SharedToStateParams extends BaseSyncParams { interface StateToSharedParams extends BaseSyncParams { setState?: never; /** The shared value to be synchronized. */ - sharedValue: SharedValue | SharedValue; + sharedValue: SharedValue; /** The direction of synchronization. */ syncDirection: 'stateToSharedValue'; } @@ -73,7 +73,7 @@ export function useSyncSharedValue({ compareDepth = 'deep', pauseSync, setSta }, shouldSync => { if (shouldSync) { - if (syncDirection === 'sharedValueToState' && sharedValue.value !== undefined) { + if (syncDirection === 'sharedValueToState') { runOnJS(setState)(sharedValue.value); } else if (syncDirection === 'stateToSharedValue') { sharedValue.value = state; diff --git a/src/hooks/useFarcasterAccountForWallets.ts b/src/hooks/useFarcasterAccountForWallets.ts index 4c5702051b7..80873b867e3 100644 --- a/src/hooks/useFarcasterAccountForWallets.ts +++ b/src/hooks/useFarcasterAccountForWallets.ts @@ -12,12 +12,12 @@ import { AllRainbowWallets } from '@/model/wallet'; type SummaryData = ReturnType['data']; -const getWalletForAddress = (wallets: AllRainbowWallets, address: string) => { +const getWalletForAddress = (wallets: AllRainbowWallets | null, address: string) => { return Object.values(wallets || {}).find(wallet => wallet.addresses.some(addr => isLowerCaseMatch(addr.address, address))); }; -export const useFarcasterWalletAddress = () => { - const [farcasterWalletAddress, setFarcasterWalletAddress] = useState(null); +export const useFarcasterAccountForWallets = () => { + const [farcasterWalletAddress, setFarcasterWalletAddress] = useState
(); const { accountAddress } = useAccountSettings(); const { wallets } = useWallets(); @@ -33,31 +33,32 @@ export const useFarcasterWalletAddress = () => { currency: store.getState().settings.nativeCurrency, }) ); - if (isEmpty(summaryData?.data.addresses) || isEmpty(wallets)) { - setFarcasterWalletAddress(null); + const addresses = summaryData?.data.addresses; + + if (!addresses || isEmpty(addresses) || isEmpty(wallets)) { + setFarcasterWalletAddress(undefined); return; } - const selectedAddressFid = summaryData?.data.addresses[accountAddress as Address]?.meta?.farcaster?.fid; - - if (selectedAddressFid && getWalletForAddress(wallets || {}, accountAddress)?.type !== walletTypes.readOnly) { + const selectedAddressFid = addresses[accountAddress]?.meta?.farcaster?.fid; + if (selectedAddressFid && getWalletForAddress(wallets, accountAddress)?.type !== walletTypes.readOnly) { setFarcasterWalletAddress(accountAddress); return; } - const farcasterWalletAddress = Object.keys(summaryData?.data.addresses || {}).find(addr => { + const farcasterWalletAddress = Object.keys(addresses).find(addr => { const address = addr as Address; const faracsterId = summaryData?.data.addresses[address]?.meta?.farcaster?.fid; - if (faracsterId && getWalletForAddress(wallets || {}, address)?.type !== walletTypes.readOnly) { - return faracsterId; + if (faracsterId && getWalletForAddress(wallets, address)?.type !== walletTypes.readOnly) { + return address; } - }); + }) as Address | undefined; if (farcasterWalletAddress) { setFarcasterWalletAddress(farcasterWalletAddress); return; } - setFarcasterWalletAddress(null); + setFarcasterWalletAddress(undefined); }, [wallets, allAddresses, accountAddress]); return farcasterWalletAddress; diff --git a/src/languages/en_US.json b/src/languages/en_US.json index 22f790f1f88..13044d44f18 100644 --- a/src/languages/en_US.json +++ b/src/languages/en_US.json @@ -3033,6 +3033,54 @@ "new_tab": "New Tab" } }, + "trending_tokens": { + "all": "All", + "no_results": { + "title": "No results", + "body": "Try browsing a larger timeframe or a different network or category." + }, + "and": "and", + "and_others": { + "one": "and %{count} other", + "other": "and %{count} others" + }, + "filters": { + "categories": { + "TRENDING": "Trending", + "NEW": "New", + "FARCASTER": "Farcaster" + }, + "sort": { + "RECOMMENDED": "Sort", + "VOLUME": "Volume", + "MARKET_CAP": "Market Cap", + "TOP_GAINERS": "Top Gainers", + "TOP_LOSERS": "Top Losers" + }, + "time": { + "H12": "12h", + "H24": "24h", + "D7": "1 Week", + "D3": "1 Month" + } + } + }, + "network_switcher": { + "customize_networks_banner": { + "title": "Customize Networks", + "tap_the": "Tap the", + "button_to_set_up": "button below to set up" + }, + "drag_here_to_unpin": "Drag here to unpin networks", + "edit": "Edit", + "networks": "Networks", + "drag_to_rearrange": "Drag to rearrange", + "show_less": "Show less", + "more": "More", + "show_more": "More Networks", + "all_networks": "All Networks" + }, + "done": "Done", "copy": "Copy", "paste": "Paste" } diff --git a/src/model/remoteConfig.ts b/src/model/remoteConfig.ts index 40382af707b..3341a3a0000 100644 --- a/src/model/remoteConfig.ts +++ b/src/model/remoteConfig.ts @@ -57,6 +57,8 @@ export interface RainbowConfig extends Record featured_results: boolean; claimables: boolean; nfts_enabled: boolean; + + trending_tokens_limit: number; } export const DEFAULT_CONFIG: RainbowConfig = { @@ -147,6 +149,8 @@ export const DEFAULT_CONFIG: RainbowConfig = { featured_results: true, claimables: true, nfts_enabled: true, + + trending_tokens_limit: 10, }; export async function fetchRemoteConfig(): Promise { @@ -205,6 +209,8 @@ export async function fetchRemoteConfig(): Promise { key === 'nfts_enabled' ) { config[key] = entry.asBoolean(); + } else if (key === 'trending_tokens_limit') { + config[key] = entry.asNumber(); } else { config[key] = entry.asString(); } diff --git a/src/navigation/Routes.android.tsx b/src/navigation/Routes.android.tsx index 2669a4031a1..1e03c2d96a3 100644 --- a/src/navigation/Routes.android.tsx +++ b/src/navigation/Routes.android.tsx @@ -92,6 +92,7 @@ import { ClaimClaimablePanel } from '@/screens/claimables/ClaimPanel'; import { RootStackParamList } from './types'; import WalletLoadingListener from '@/components/WalletLoadingListener'; import { Portal as CMPortal } from '@/react-native-cool-modals/Portal'; +import { NetworkSelector } from '@/components/NetworkSwitcher'; const Stack = createStackNavigator(); const OuterStack = createStackNavigator(); @@ -244,6 +245,7 @@ function BSNavigator() { + diff --git a/src/navigation/Routes.ios.tsx b/src/navigation/Routes.ios.tsx index a55215a13e6..201eb3aa374 100644 --- a/src/navigation/Routes.ios.tsx +++ b/src/navigation/Routes.ios.tsx @@ -70,6 +70,7 @@ import { swapConfig, checkIdentifierSheetConfig, recieveModalSheetConfig, + networkSelectorConfig, } from './config'; import { addCashSheet, emojiPreset, emojiPresetWallet, overlayExpandedPreset, sheetPreset } from './effects'; import { InitialRouteContext } from './initialRoute'; @@ -104,6 +105,7 @@ import { ClaimClaimablePanel } from '@/screens/claimables/ClaimPanel'; import { RootStackParamList } from './types'; import WalletLoadingListener from '@/components/WalletLoadingListener'; import { Portal as CMPortal } from '@/react-native-cool-modals/Portal'; +import { NetworkSelector } from '@/components/NetworkSwitcher'; const Stack = createStackNavigator(); const NativeStack = createNativeStackNavigator(); @@ -275,6 +277,7 @@ function NativeStackNavigator() { + diff --git a/src/navigation/SwipeNavigator.tsx b/src/navigation/SwipeNavigator.tsx index 33f84504828..781ca8932d4 100644 --- a/src/navigation/SwipeNavigator.tsx +++ b/src/navigation/SwipeNavigator.tsx @@ -15,7 +15,7 @@ import RecyclerListViewScrollToTopProvider, { useRecyclerListViewScrollToTopContext, } from '@/navigation/RecyclerListViewScrollToTopContext'; import DappBrowserScreen from '@/screens/dapp-browser/DappBrowserScreen'; -import { discoverOpenSearchFnRef } from '@/screens/discover/components/DiscoverSearchContainer'; +import { discoverOpenSearchFnRef } from '@/components/Discover/DiscoverSearchContainer'; import { PointsScreen } from '@/screens/points/PointsScreen'; import WalletScreen from '@/screens/WalletScreen'; import { useTheme } from '@/theme'; @@ -39,7 +39,7 @@ import { TIMING_CONFIGS } from '@/components/animations/animationConfigs'; import { useBrowserStore } from '@/state/browser/browserStore'; import { opacityWorklet } from '@/__swaps__/utils/swaps'; import ProfileScreen from '../screens/ProfileScreen'; -import DiscoverScreen, { discoverScrollToTopFnRef } from '../screens/discover/DiscoverScreen'; +import DiscoverScreen, { discoverScrollToTopFnRef } from '@/screens/DiscoverScreen'; import { ScrollPositionContext } from './ScrollPositionContext'; import SectionListScrollToTopProvider, { useSectionListScrollToTopContext } from './SectionListScrollToTopContext'; import Routes from './routesNames'; diff --git a/src/navigation/config.tsx b/src/navigation/config.tsx index b515f93df8c..9097c84e1d6 100644 --- a/src/navigation/config.tsx +++ b/src/navigation/config.tsx @@ -246,6 +246,20 @@ export const consoleSheetConfig = { }), }; +export const networkSelectorConfig = { + options: ({ route: { params = {} } }) => ({ + ...buildCoolModalConfig({ + ...params, + backgroundColor: '#000000B2', + backgroundOpacity: 0.7, + cornerRadius: 0, + springDamping: 1, + topOffset: 0, + transitionDuration: 0.3, + }), + }), +}; + export const panelConfig = { options: ({ route: { params = {} } }) => ({ ...buildCoolModalConfig({ diff --git a/src/navigation/routesNames.ts b/src/navigation/routesNames.ts index 96cc67fb146..ff4372906e3 100644 --- a/src/navigation/routesNames.ts +++ b/src/navigation/routesNames.ts @@ -100,6 +100,7 @@ const Routes = { SETTINGS_SECTION_NOTIFICATIONS: 'NotificationsSection', SETTINGS_SECTION_PRIVACY: 'PrivacySection', DAPP_BROWSER_CONTROL_PANEL: 'DappBrowserControlPanel', + NETWORK_SELECTOR: 'NetworkSelector', CLAIM_REWARDS_PANEL: 'ClaimRewardsPanel', } as const; diff --git a/src/navigation/types.ts b/src/navigation/types.ts index cc2c8842ab5..c1877d015da 100644 --- a/src/navigation/types.ts +++ b/src/navigation/types.ts @@ -10,6 +10,9 @@ import { Claimable } from '@/resources/addys/claimables/types'; import { WalletconnectApprovalSheetRouteParams, WalletconnectResultType } from '@/walletConnect/types'; import { WalletConnectApprovalSheetType } from '@/helpers/walletConnectApprovalSheetTypes'; import { RainbowPosition } from '@/resources/defi/types'; +import { Address } from 'viem'; +import { SharedValue } from 'react-native-reanimated'; +import { ChainId } from '@/state/backendNetworks/types'; export type PartialNavigatorConfigOptions = Pick['Screen']>[0]>, 'options'>; @@ -31,7 +34,7 @@ export type RootStackParamList = { [Routes.CHANGE_WALLET_SHEET]: { watchOnly: boolean; currentAccountAddress: string; - onChangeWallet: (address: string) => void; + onChangeWallet: (address: Address) => void; }; [Routes.SPEED_UP_AND_CANCEL_BOTTOM_SHEET]: { accentColor?: string; @@ -104,4 +107,9 @@ export type RootStackParamList = { [Routes.POSITION_SHEET]: { position: RainbowPosition; }; + [Routes.NETWORK_SELECTOR]: { + onClose?: VoidFunction; + selected: SharedValue; + setSelected: (chainId: ChainId | undefined) => void; + }; }; diff --git a/src/performance/tracking/index.ts b/src/performance/tracking/index.ts index 425faba867e..81b8fb5e73a 100644 --- a/src/performance/tracking/index.ts +++ b/src/performance/tracking/index.ts @@ -18,7 +18,7 @@ function logDurationIfAppropriate(metric: PerformanceMetricsType, durationInMs: } } -const currentlyTrackedMetrics = new Map(); +export const currentlyTrackedMetrics = new Map(); interface AdditionalParams extends Record { tag?: PerformanceTagsType; diff --git a/src/performance/tracking/types/PerformanceMetrics.ts b/src/performance/tracking/types/PerformanceMetrics.ts index 3baf050eb54..3d272e1e71b 100644 --- a/src/performance/tracking/types/PerformanceMetrics.ts +++ b/src/performance/tracking/types/PerformanceMetrics.ts @@ -11,6 +11,7 @@ export const PerformanceMetrics = { initializeWalletconnect: 'Performance WalletConnect Initialize Time', quoteFetching: 'Performance Quote Fetching Time', + timeSpentOnDiscoverScreen: 'Time spent on the Discover screen', } as const; export type PerformanceMetricsType = (typeof PerformanceMetrics)[keyof typeof PerformanceMetrics]; diff --git a/src/redux/settings.ts b/src/redux/settings.ts index ce19a5f6131..4535437ea7c 100644 --- a/src/redux/settings.ts +++ b/src/redux/settings.ts @@ -24,6 +24,7 @@ import { getProvider } from '@/handlers/web3'; import { AppState } from '@/redux/store'; import { logger, RainbowError } from '@/logger'; import { Network, ChainId } from '@/state/backendNetworks/types'; +import { Address } from 'viem'; // -- Constants ------------------------------------------------------------- // const SETTINGS_UPDATE_SETTINGS_ADDRESS = 'settings/SETTINGS_UPDATE_SETTINGS_ADDRESS'; @@ -41,7 +42,7 @@ const SETTINGS_UPDATE_ACCOUNT_SETTINGS_SUCCESS = 'settings/SETTINGS_UPDATE_ACCOU */ interface SettingsState { appIcon: string; - accountAddress: string; + accountAddress: Address; chainId: number; language: Language; nativeCurrency: NativeCurrencyKey; @@ -205,7 +206,7 @@ export const settingsChangeAppIcon = (appIcon: string) => (dispatch: Dispatch async (dispatch: Dispatch) => { dispatch({ - payload: accountAddress, + payload: accountAddress as Address, type: SETTINGS_UPDATE_SETTINGS_ADDRESS, }); }; @@ -254,7 +255,7 @@ export const settingsChangeNativeCurrency = // -- Reducer --------------------------------------------------------------- // export const INITIAL_STATE: SettingsState = { - accountAddress: '', + accountAddress: '' as Address, appIcon: 'og', chainId: 1, language: Language.EN_US, diff --git a/src/resources/trendingTokens/trendingTokens.ts b/src/resources/trendingTokens/trendingTokens.ts index 169a24ab6f4..4bbb62e9308 100644 --- a/src/resources/trendingTokens/trendingTokens.ts +++ b/src/resources/trendingTokens/trendingTokens.ts @@ -2,23 +2,117 @@ import { QueryConfigWithSelect, createQueryKey } from '@/react-query'; import { useQuery } from '@tanstack/react-query'; import { arcClient } from '@/graphql'; -export type TrendingTokensVariables = Parameters['0']; -export type TrendingTokens = Awaited>; +import { TrendingCategory, TrendingSort, TrendingTimeframe } from '@/state/trendingTokens/trendingTokens'; +import { Address } from 'viem'; +import { NativeCurrencyKey } from '@/entities'; +import store from '@/redux/store'; +import { SortDirection } from '@/graphql/__generated__/arc'; +import { UniqueId } from '@/__swaps__/types/assets'; +import { ChainId } from '@/state/backendNetworks/types'; + +export type FarcasterUser = { + username: string; + pfp_url: string; +}; +export type TrendingToken = { + uniqueId: UniqueId; + chainId: ChainId; + address: string; + name: string; + symbol: string; + decimals: number; + price: number; + priceChange: { + hr: number; + day: number; + }; + marketCap: number; + volume: number; + highlightedFriends: FarcasterUser[]; + colors: { + primary: string; + }; + icon_url: string; +}; // /////////////////////////////////////////////// // Query Key -export const trendingTokensQueryKey = (props: TrendingTokensVariables) => createQueryKey('trending-tokens', props, { persisterVersion: 0 }); +export const trendingTokensQueryKey = (props: FetchTrendingTokensArgs) => createQueryKey('trending-tokens', props, { persisterVersion: 2 }); export type TrendingTokensQueryKey = ReturnType; +type FetchTrendingTokensArgs = { + chainId?: ChainId; + category: TrendingCategory; + sortBy: TrendingSort; + sortDirection: SortDirection | undefined; + timeframe: TrendingTimeframe; + walletAddress: Address | undefined; + limit?: number; + currency?: NativeCurrencyKey; +}; + +async function fetchTrendingTokens({ + queryKey: [ + { currency = store.getState().settings.nativeCurrency, category, sortBy, sortDirection, timeframe, walletAddress, chainId, limit }, + ], +}: { + queryKey: TrendingTokensQueryKey; +}) { + const response = await arcClient.trendingTokens({ + category, + sortBy, + sortDirection, + timeframe, + walletAddress, + limit, + chainId, + currency: currency.toLowerCase(), + }); + const trendingTokens: TrendingToken[] = []; + + for (const token of response.trendingTokens.data) { + const { uniqueId, address, name, symbol, chainId, decimals, trending, market, icon_url, colors } = token; + const { bought_stats } = trending.swap_data; + const highlightedFriends = (bought_stats.farcaster_users || []).reduce((friends, friend) => { + const { username, pfp_url } = friend; + if (username && pfp_url) friends.push({ username, pfp_url }); + return friends; + }, [] as FarcasterUser[]); + + trendingTokens.push({ + uniqueId, + chainId: chainId as ChainId, + address, + name, + symbol, + decimals, + price: market.price?.value || 0, + priceChange: { + hr: trending.pool_data.h1_price_change || 0, + day: trending.pool_data.h24_price_change || 0, + }, + marketCap: market.market_cap?.value || 0, + volume: market.volume_24h || 0, + highlightedFriends, + icon_url, + colors: { + primary: colors.primary, + }, + }); + } + + return trendingTokens; +} + // /////////////////////////////////////////////// // Query Hook -export function useTrendingTokens( - props: TrendingTokensVariables, - config: QueryConfigWithSelect = {} +export function useTrendingTokens( + args: FetchTrendingTokensArgs, + config: QueryConfigWithSelect = {} ) { - return useQuery(trendingTokensQueryKey(props), () => arcClient.trendingTokens(props), { + return useQuery(trendingTokensQueryKey(args), fetchTrendingTokens, { ...config, staleTime: 60_000, // 1 minute cacheTime: 60_000 * 30, // 30 minutes diff --git a/src/screens/discover/DiscoverScreen.tsx b/src/screens/DiscoverScreen.tsx similarity index 95% rename from src/screens/discover/DiscoverScreen.tsx rename to src/screens/DiscoverScreen.tsx index 601066d6260..2a0d43df6a2 100644 --- a/src/screens/discover/DiscoverScreen.tsx +++ b/src/screens/DiscoverScreen.tsx @@ -4,7 +4,7 @@ import { useIsFocused } from '@react-navigation/native'; import { Box } from '@/design-system'; import { Page } from '@/components/layout'; import { Navbar } from '@/components/navbar/Navbar'; -import DiscoverScreenContent from './components/DiscoverScreenContent'; +import DiscoverScreenContent from '@/components/Discover/DiscoverScreenContent'; import { ButtonPressAnimation } from '@/components/animations'; import { ContactAvatar } from '@/components/contacts'; import ImageAvatar from '@/components/contacts/ImageAvatar'; @@ -14,7 +14,7 @@ import { useNavigation } from '@/navigation'; import { safeAreaInsetValues } from '@/utils'; import * as i18n from '@/languages'; import Animated, { useAnimatedScrollHandler, useSharedValue } from 'react-native-reanimated'; -import DiscoverScreenProvider, { useDiscoverScreenContext } from './DiscoverScreenContext'; +import DiscoverScreenProvider, { useDiscoverScreenContext } from '@/components/Discover/DiscoverScreenContext'; export let discoverScrollToTopFnRef: () => number | null = () => null; @@ -30,18 +30,18 @@ const Content = () => { navigate(Routes.CHANGE_WALLET_SHEET); }, [navigate]); - React.useEffect(() => { - if (isSearching && !isFocused) { - Keyboard.dismiss(); - } - }, [isFocused, isSearching]); - const scrollHandler = useAnimatedScrollHandler({ onScroll: event => { scrollY.value = event.contentOffset.y; }, }); + useEffect(() => { + if (isSearching && !isFocused) { + Keyboard.dismiss(); + } + }, [isFocused, isSearching]); + useEffect(() => { discoverScrollToTopFnRef = scrollToTop; }, [scrollToTop]); diff --git a/src/state/backendNetworks/backendNetworks.ts b/src/state/backendNetworks/backendNetworks.ts index 9e1882f2601..60736773864 100644 --- a/src/state/backendNetworks/backendNetworks.ts +++ b/src/state/backendNetworks/backendNetworks.ts @@ -19,6 +19,7 @@ export interface BackendNetworksState { getBackendChains: () => Chain[]; getSupportedChains: () => Chain[]; + getSortedSupportedChainIds: () => number[]; getDefaultChains: () => Record; getSupportedChainIds: () => ChainId[]; @@ -75,6 +76,11 @@ export const useBackendNetworksStore = createRainbowStore( return IS_TEST ? [...backendChains, chainHardhat, chainHardhatOptimism] : backendChains; }, + getSortedSupportedChainIds: () => { + const supportedChains = get().getSupportedChains(); + return supportedChains.sort((a, b) => a.name.localeCompare(b.name)).map(c => c.id); + }, + getDefaultChains: () => { const supportedChains = get().getSupportedChains(); return supportedChains.reduce( diff --git a/src/state/internal/createRainbowStore.ts b/src/state/internal/createRainbowStore.ts index 9b7d9a39dd7..e0c14b79ead 100644 --- a/src/state/internal/createRainbowStore.ts +++ b/src/state/internal/createRainbowStore.ts @@ -43,6 +43,12 @@ interface RainbowPersistConfig { * This function will be called when persisted state versions mismatch with the one specified here. */ migrate?: (persistedState: unknown, version: number) => S | Promise; + /** + * A function returning another (optional) function. + * The main function will be called before the state rehydration. + * The returned function will be called after the state rehydration or when an error occurred. + */ + onRehydrateStorage?: PersistOptions>['onRehydrateStorage']; } /** @@ -157,6 +163,7 @@ export function createRainbowStore( storage: persistStorage, version, migrate: persistConfig.migrate, + onRehydrateStorage: persistConfig.onRehydrateStorage, }) ) ); diff --git a/src/state/networkSwitcher/networkSwitcher.ts b/src/state/networkSwitcher/networkSwitcher.ts new file mode 100644 index 00000000000..aa82dc85a44 --- /dev/null +++ b/src/state/networkSwitcher/networkSwitcher.ts @@ -0,0 +1,57 @@ +import { ChainId } from '@/state/backendNetworks/types'; +import { createRainbowStore } from '../internal/createRainbowStore'; +import { analyticsV2 } from '@/analytics'; +import { nonceStore } from '@/state/nonces'; +import { logger } from '@/logger'; + +export const defaultPinnedNetworks = [ChainId.base, ChainId.mainnet, ChainId.optimism, ChainId.arbitrum, ChainId.polygon, ChainId.zora]; + +function getMostUsedChains() { + try { + const noncesByAddress = nonceStore.getState().nonces; + const summedNoncesByChainId: Record = {}; + for (const addressNonces of Object.values(noncesByAddress)) { + for (const [chainId, { currentNonce }] of Object.entries(addressNonces)) { + summedNoncesByChainId[chainId] ??= 0; + summedNoncesByChainId[chainId] += currentNonce || 0; + } + } + + const mostUsedNetworks = Object.entries(summedNoncesByChainId) + .sort((a, b) => b[1] - a[1]) + .map(([chainId]) => parseInt(chainId)); + + return mostUsedNetworks.length ? mostUsedNetworks.slice(0, 5) : defaultPinnedNetworks; + } catch (error) { + logger.warn('[networkSwitcher]: Error getting most used chains', { error }); + return defaultPinnedNetworks; + } +} + +export const networkSwitcherStore = createRainbowStore<{ + pinnedNetworks: ChainId[]; +}>(() => ({ pinnedNetworks: getMostUsedChains().slice(0, 5) }), { + storageKey: 'network-switcher', + version: 0, + onRehydrateStorage(state) { + // if we are missing pinned networks, use the user most used chains + if (state.pinnedNetworks.length === 0) { + const mostUsedNetworks = getMostUsedChains(); + state.pinnedNetworks = mostUsedNetworks.slice(0, 5); + analyticsV2.identify({ mostUsedNetworks: mostUsedNetworks.filter(Boolean) }); + } + }, +}); + +export const customizeNetworksBannerStore = createRainbowStore<{ + dismissedAt: number; // timestamp +}>(() => ({ dismissedAt: 0 }), { + storageKey: 'CustomizeNetworksBanner', + version: 0, +}); + +const twoWeeks = 1000 * 60 * 60 * 24 * 7 * 2; +export const shouldShowCustomizeNetworksBanner = (dismissedAt: number) => Date.now() - dismissedAt > twoWeeks; +export const dismissCustomizeNetworksBanner = () => { + customizeNetworksBannerStore.setState({ dismissedAt: Date.now() }); +}; diff --git a/src/state/swaps/swapsStore.ts b/src/state/swaps/swapsStore.ts index 49cc99d0268..7d4d0d99f4b 100644 --- a/src/state/swaps/swapsStore.ts +++ b/src/state/swaps/swapsStore.ts @@ -1,5 +1,5 @@ import { INITIAL_SLIDER_POSITION } from '@/__swaps__/screens/Swap/constants'; -import { ExtendedAnimatedAssetWithColors, ParsedSearchAsset } from '@/__swaps__/types/assets'; +import { ExtendedAnimatedAssetWithColors, ParsedSearchAsset, UniqueId } from '@/__swaps__/types/assets'; import { ChainId } from '@/state/backendNetworks/types'; import { RecentSwap } from '@/__swaps__/types/swap'; import { getDefaultSlippage } from '@/__swaps__/utils/swaps'; @@ -42,6 +42,8 @@ export interface SwapsState { // degen mode preferences preferredNetwork: ChainId | undefined; setPreferredNetwork: (preferredNetwork: ChainId | undefined) => void; + + lastNavigatedTrendingToken: UniqueId | undefined; } type StateWithTransforms = Omit, 'latestSwapAt' | 'recentSwaps'> & { @@ -156,6 +158,8 @@ export const swapsStore = createRainbowStore( latestSwapAt: new Map(latestSwapAt), }); }, + + lastNavigatedTrendingToken: undefined, }), { storageKey: 'swapsStore', diff --git a/src/state/trendingTokens/trendingTokens.ts b/src/state/trendingTokens/trendingTokens.ts new file mode 100644 index 00000000000..644ccd45fba --- /dev/null +++ b/src/state/trendingTokens/trendingTokens.ts @@ -0,0 +1,59 @@ +import { analyticsV2 } from '@/analytics'; +import { ChainId } from '@/state/backendNetworks/types'; +import { createRainbowStore } from '../internal/createRainbowStore'; +import { + TrendingCategory as ArcTrendingCategory, + Timeframe as ArcTimeframe, + TrendingSort as ArcTrendingSort, +} from '@/graphql/__generated__/arc'; + +export const categories = [ArcTrendingCategory.Trending, ArcTrendingCategory.New, ArcTrendingCategory.Farcaster] as const; +export type TrendingCategory = (typeof categories)[number]; +export const sortFilters = [ + ArcTrendingSort.Recommended, + ArcTrendingSort.Volume, + ArcTrendingSort.MarketCap, + ArcTrendingSort.TopGainers, + ArcTrendingSort.TopLosers, +] as const; +export type TrendingSort = (typeof sortFilters)[number]; +export const timeFilters = [ArcTimeframe.H24, ArcTimeframe.D7, ArcTimeframe.D3] as const; +export type TrendingTimeframe = (typeof timeFilters)[number]; + +type TrendingTokensState = { + category: (typeof categories)[number]; + chainId: undefined | ChainId; + timeframe: (typeof timeFilters)[number]; + sort: (typeof sortFilters)[number]; + + setCategory: (category: TrendingTokensState['category']) => void; + setChainId: (chainId: TrendingTokensState['chainId']) => void; + setTimeframe: (timeframe: TrendingTokensState['timeframe']) => void; + setSort: (sort: TrendingTokensState['sort']) => void; +}; + +export const useTrendingTokensStore = createRainbowStore( + set => ({ + category: ArcTrendingCategory.Trending, + chainId: undefined, + timeframe: ArcTimeframe.H24, + sort: ArcTrendingSort.Recommended, + setCategory: category => set({ category }), + setChainId: chainId => { + analyticsV2.track(analyticsV2.event.changeNetworkFilter, { chainId }); + set({ chainId }); + }, + setTimeframe: timeframe => { + analyticsV2.track(analyticsV2.event.changeTimeframeFilter, { timeframe }); + set({ timeframe }); + }, + setSort: sort => { + analyticsV2.track(analyticsV2.event.changeSortFilter, { sort }); + set({ sort }); + }, + }), + { + storageKey: 'trending-tokens', + version: 1, + } +); diff --git a/src/walletConnect/sheets/AuthRequest.tsx b/src/walletConnect/sheets/AuthRequest.tsx index 338acad39b4..724cae00de2 100644 --- a/src/walletConnect/sheets/AuthRequest.tsx +++ b/src/walletConnect/sheets/AuthRequest.tsx @@ -149,7 +149,7 @@ export function AuthRequest({ navigate(Routes.CHANGE_WALLET_SHEET, { watchOnly: true, currentAccountAddress: address, - onChangeWallet(address: string) { + onChangeWallet(address) { setAddress(address); goBack(); },