ci(release): publish latest release

parent 174ed1e2
...@@ -2,7 +2,6 @@ ignores: [ ...@@ -2,7 +2,6 @@ ignores: [
# Dependencies that depcheck thinks are unused but are actually used # Dependencies that depcheck thinks are unused but are actually used
'@graphql-codegen/*', '@graphql-codegen/*',
'@commitlint/*', '@commitlint/*',
'@uniswap/eslint-config',
'i18next', 'i18next',
'moti', 'moti',
# Dependencies that depcheck thinks are missing but are actually present or never used # Dependencies that depcheck thinks are missing but are actually present or never used
......
diff --git a/src/components/bottomSheet/BottomSheet.tsx b/src/components/bottomSheet/BottomSheet.tsx
index 1050af591cedd3395c3f21553f9b125d85ca9d11..0761eb562be2af0ebccfda02f06a9ec79289d4ae 100644
--- a/src/components/bottomSheet/BottomSheet.tsx
+++ b/src/components/bottomSheet/BottomSheet.tsx
@@ -501,7 +501,7 @@ const BottomSheetComponent = forwardRef<BottomSheet, BottomSheetProps>(
animatedAnimationSource.value === ANIMATION_SOURCE.SNAP_POINT_CHANGE &&
animatedAnimationState.value === ANIMATION_STATE.RUNNING
) {
- return animatedNextPositionIndex.value;
+ return Math.max(animatedCurrentIndex.value, currentIndex);
}
return currentIndex;
diff --git a/ios/ReactNativePerformance/ReactNativePerformance.m b/ios/ReactNativePerformance/ReactNativePerformance.m
index 485211356fc14de4205e6d0c7e06eb5116992e0b..dbb4bb5637656b7f62fc88249b4ed5402c22290d 100644
--- a/ios/ReactNativePerformance/ReactNativePerformance.m
+++ b/ios/ReactNativePerformance/ReactNativePerformance.m
@@ -1,5 +1,5 @@
#import "ReactNativePerformance.h"
-#import "ReactNativePerformance-Swift.h"
+#import <ReactNativePerformance/ReactNativePerformance-Swift.h>
static NSTimeInterval startupTimestamp = -1.0;
* @uniswap/web-admins
IPFS hash of the deployment: We’ve got some minor updates and improvements!
- CIDv0: `QmReiE84jPE7A2a52oNhxkyR1S9hZDgR9ENHdBpsqxM4vA`
- CIDv1: `bafybeibrgn7bxrw5utokbemws52rnuwiexakexjw5n4fq35fp66lnuqla4` - Balances update more quickly in your wallet after a transaction!
- Various bug fixes and performance improvements around sending, usernames, and more.
The latest release is always mirrored at [app.uniswap.org](https://app.uniswap.org).
You can also access the Uniswap Interface from an IPFS gateway.
**BEWARE**: The Uniswap interface uses [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) to remember your settings, such as which tokens you have imported.
**You should always use an IPFS gateway that enforces origin separation**, or our hosted deployment of the latest release at [app.uniswap.org](https://app.uniswap.org).
Your Uniswap settings are never remembered across different URLs.
IPFS gateways:
- https://bafybeibrgn7bxrw5utokbemws52rnuwiexakexjw5n4fq35fp66lnuqla4.ipfs.dweb.link/
- https://bafybeibrgn7bxrw5utokbemws52rnuwiexakexjw5n4fq35fp66lnuqla4.ipfs.cf-ipfs.com/
- [ipfs://QmReiE84jPE7A2a52oNhxkyR1S9hZDgR9ENHdBpsqxM4vA/](ipfs://QmReiE84jPE7A2a52oNhxkyR1S9hZDgR9ENHdBpsqxM4vA/)
## 5.60.0 (2024-11-26)
### Features
* **web:** add an error state for trading api errors for create flow (#13954) 155c273
* **web:** add deadline settings to create flow (#13876) 2ef89c1
* **web:** add error / no data state to liq range input component (#13847) 6f3180f
* **web:** add loading state to mini price charts (#13826) c0656c1
* **web:** add migrate to position dropdown (#13829) 48b4d13
* **web:** add settings to add/remove liq (#13864) d178851
* **web:** gate v4 features behind feature flag (#13877) 7c59740
* **web:** integrate LiquidityRangeInput to create flow (#13804) f41b2c6
* **web:** mvp of new price range input (#13803) 5bb8579
* **web:** refactor flags into redesign flag and v4data flag (#13867) bf39790
* **web:** set max height for create position bottomsheet (#13979) 21b486c
### Bug Fixes
* **web:** add current page to pool position breadcrumbs (#13737) 6124764
* **web:** add trading api error to all the flows (#13961) 81f5359
* **web:** add wrapper to fix info icon alignment (#13740) 700a749
* **web:** aligns icon colors and fix info buttons (#13957) b97d130
* **web:** button sizing on mweb TDP (#13942) 89f83fc
* **web:** create swap settings context (#13929) b3bc846
* **web:** DEATH TO THE HORIZONTAL SCROLLBAR (#14026) a27e5a6
* **web:** fix closed positions cta container (#13988) 6d27f16
* **web:** fix explore chart colors (#13902) 1168e7e
* **web:** fix incorrect pairs on v2 (#13985) da75ba5
* **web:** fix limits form button text color (#13828) 4edb362
* **web:** fix overflow in unconnected menu (#13939) 34c15af
* **web:** fix price chart range calculations (#13970) 20fe90b
* **web:** improve autoscaling and zooming in price range input (#13940) efea0bb
* **web:** increase + create ui fixes (#13943) 4a9e536
* **web:** initialize uniswap wc modal on click (#13975) 944900e
* **web:** LP create form - fix text overflow and design change (#13830) 12988b7
* **web:** mock datadog in jest tests (#13913) 81bb64a
* **web:** more improvements to price range input (#14000) 19d7fb3
* **web:** only pad preference menu instead of all nav (#13995) 279e5c7
* **web:** overflow bug on empty positions page (#13842) 5d7b242
* **web:** part 1 of polling uniswap x orders (#14032) 594f090
* **web:** polyfill roundRect calls (#13971) 42bfa61
* **web:** reduce nft/swap test flakiness (#13924) 8739af5
* **web:** remove hover behavior on mweb (#13888) 12c97dc
* **web:** reset chain id and multichain context (#14014) fef3f96
* **web:** reset to default state when testnet mode is toggled (#14011) 6086f4d
* **web:** revert pr 12277 (#13851) f562f7a
* **web:** scroll to top of posdp (#13860) 2d47c65
* **web:** single step creation review treatment (#13993) dc09d73
* **web:** small UI nits (#13879) 62282b1
* **web:** tdp e2e test fixes (#13861) 566a721
* **web:** update create modal padding (#14019) 6321752
* **web:** use sepolia eth as default token when in testnet mode (#13856) 6e4f6b8
* **web:** v4 mobile web fixes (#13831) ff816b5
* **web:** v4 ui nits (#13927) f3efa1c
### Continuous Integration
* **web:** update sitemaps de8bd02
web/5.60.0 mobile/1.39
\ No newline at end of file \ No newline at end of file
...@@ -14,8 +14,8 @@ ...@@ -14,8 +14,8 @@
"@svgr/webpack": "8.0.1", "@svgr/webpack": "8.0.1",
"@tamagui/core": "1.108.4", "@tamagui/core": "1.108.4",
"@types/uuid": "9.0.1", "@types/uuid": "9.0.1",
"@uniswap/analytics-events": "2.39.0", "@uniswap/analytics-events": "2.38.0",
"@uniswap/uniswapx-sdk": "2.1.0-beta.18", "@uniswap/uniswapx-sdk": "^2.1.0-beta.14",
"@uniswap/universal-router-sdk": "4.5.2", "@uniswap/universal-router-sdk": "4.5.2",
"@uniswap/v3-sdk": "3.18.1", "@uniswap/v3-sdk": "3.18.1",
"@uniswap/v4-sdk": "1.10.3", "@uniswap/v4-sdk": "1.10.3",
...@@ -51,37 +51,37 @@ ...@@ -51,37 +51,37 @@
"zod": "3.22.4" "zod": "3.22.4"
}, },
"devDependencies": { "devDependencies": {
"@pmmmwh/react-refresh-webpack-plugin": "0.5.11", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.10",
"@testing-library/dom": "7.31.2", "@testing-library/dom": "^7.11.0",
"@testing-library/react": "13.4.0", "@testing-library/react": "13.4.0",
"@types/chrome": "0.0.254", "@types/chrome": "0.0.254",
"@types/jest": "29.5.0", "@types/jest": "29.5.0",
"@types/react": "18.0.38", "@types/react": "^18.0.15",
"@types/react-dom": "18.2.15", "@types/react-dom": "^18.0.6",
"@types/redux-logger": "3.0.9", "@types/redux-logger": "3.0.9",
"@types/redux-persist-webextension-storage": "1.0.3", "@types/redux-persist-webextension-storage": "1.0.3",
"@types/ua-parser-js": "0.7.31", "@types/ua-parser-js": "0.7.31",
"@uniswap/eslint-config": "workspace:^", "@uniswap/eslint-config": "workspace:^",
"@welldone-software/why-did-you-render": "8.0.1", "@welldone-software/why-did-you-render": "8.0.1",
"clean-webpack-plugin": "4.0.0", "clean-webpack-plugin": "^4.0.0",
"concurrently": "8.2.2", "concurrently": "^8.0.1",
"copy-webpack-plugin": "11.0.0", "copy-webpack-plugin": "^11.0.0",
"esbuild-loader": "3.2.0", "esbuild-loader": "^3.0.1",
"eslint": "8.44.0", "eslint": "8.44.0",
"jest": "29.7.0", "jest": "29.7.0",
"jest-chrome": "0.8.0", "jest-chrome": "0.8.0",
"jest-environment-jsdom": "29.5.0", "jest-environment-jsdom": "29.5.0",
"jest-extended": "4.0.1", "jest-extended": "4.0.1",
"mini-css-extract-plugin": "2.9.1", "mini-css-extract-plugin": "^2.7.6",
"react-refresh": "0.14.0", "react-refresh": "^0.14.0",
"serve": "14.2.4", "serve": "^14.2.0",
"statsig-js": "4.41.0", "statsig-js": "4.41.0",
"swc-loader": "0.2.6", "swc-loader": "^0.2.3",
"tamagui-loader": "1.108.4", "tamagui-loader": "1.108.4",
"typescript": "5.3.3", "typescript": "5.3.3",
"webpack": "5.90.0", "webpack": "5.90.0",
"webpack-cli": "5.1.4", "webpack-cli": "^5.0.1",
"webpack-dev-server": "4.15.1" "webpack-dev-server": "^4.13.1"
}, },
"private": true, "private": true,
"scripts": { "scripts": {
......
...@@ -39,7 +39,6 @@ import { initExtensionAnalytics } from 'src/app/utils/analytics' ...@@ -39,7 +39,6 @@ import { initExtensionAnalytics } from 'src/app/utils/analytics'
import { checksIfSupportsSidePanel } from 'src/app/utils/chrome' import { checksIfSupportsSidePanel } from 'src/app/utils/chrome'
import { PrimaryAppInstanceDebuggerLazy } from 'src/store/PrimaryAppInstanceDebuggerLazy' import { PrimaryAppInstanceDebuggerLazy } from 'src/store/PrimaryAppInstanceDebuggerLazy'
import { getReduxPersistor, getReduxStore } from 'src/store/store' import { getReduxPersistor, getReduxStore } from 'src/store/store'
import { BlankUrlProvider } from 'uniswap/src/contexts/UrlContext'
import { LocalizationContextProvider } from 'uniswap/src/features/language/LocalizationContext' import { LocalizationContextProvider } from 'uniswap/src/features/language/LocalizationContext'
import Trace from 'uniswap/src/features/telemetry/Trace' import Trace from 'uniswap/src/features/telemetry/Trace'
import { ExtensionEventName } from 'uniswap/src/features/telemetry/constants' import { ExtensionEventName } from 'uniswap/src/features/telemetry/constants'
...@@ -193,14 +192,12 @@ export default function OnboardingApp(): JSX.Element { ...@@ -193,14 +192,12 @@ export default function OnboardingApp(): JSX.Element {
<SharedWalletProvider reduxStore={getReduxStore()}> <SharedWalletProvider reduxStore={getReduxStore()}>
<ErrorBoundary> <ErrorBoundary>
<GraphqlProvider> <GraphqlProvider>
<BlankUrlProvider> <LocalizationContextProvider>
<LocalizationContextProvider> <UnitagUpdaterContextProvider>
<UnitagUpdaterContextProvider> <PrimaryAppInstanceDebuggerLazy />
<PrimaryAppInstanceDebuggerLazy /> <RouterProvider router={router} />
<RouterProvider router={router} /> </UnitagUpdaterContextProvider>
</UnitagUpdaterContextProvider> </LocalizationContextProvider>
</LocalizationContextProvider>
</BlankUrlProvider>
</GraphqlProvider> </GraphqlProvider>
</ErrorBoundary> </ErrorBoundary>
</SharedWalletProvider> </SharedWalletProvider>
......
...@@ -17,7 +17,6 @@ import { getReduxPersistor, getReduxStore } from 'src/store/store' ...@@ -17,7 +17,6 @@ import { getReduxPersistor, getReduxStore } from 'src/store/store'
import { Button, Flex, Image, Text } from 'ui/src' import { Button, Flex, Image, Text } from 'ui/src'
import { CHROME_LOGO, UNISWAP_LOGO } from 'ui/src/assets' import { CHROME_LOGO, UNISWAP_LOGO } from 'ui/src/assets'
import { iconSizes, spacing } from 'ui/src/theme' import { iconSizes, spacing } from 'ui/src/theme'
import { BlankUrlProvider } from 'uniswap/src/contexts/UrlContext'
import { LocalizationContextProvider } from 'uniswap/src/features/language/LocalizationContext' import { LocalizationContextProvider } from 'uniswap/src/features/language/LocalizationContext'
import { syncAppWithDeviceLanguage } from 'uniswap/src/features/settings/slice' import { syncAppWithDeviceLanguage } from 'uniswap/src/features/settings/slice'
import Trace from 'uniswap/src/features/telemetry/Trace' import Trace from 'uniswap/src/features/telemetry/Trace'
...@@ -133,16 +132,14 @@ export default function PopupApp(): JSX.Element { ...@@ -133,16 +132,14 @@ export default function PopupApp(): JSX.Element {
<SharedWalletProvider reduxStore={getReduxStore()}> <SharedWalletProvider reduxStore={getReduxStore()}>
<ErrorBoundary> <ErrorBoundary>
<GraphqlProvider> <GraphqlProvider>
<BlankUrlProvider> <LocalizationContextProvider>
<LocalizationContextProvider> <UnitagUpdaterContextProvider>
<UnitagUpdaterContextProvider> <TraceUserProperties />
<TraceUserProperties /> <DappContextProvider>
<DappContextProvider> <RouterProvider router={router} />
<RouterProvider router={router} /> </DappContextProvider>
</DappContextProvider> </UnitagUpdaterContextProvider>
</UnitagUpdaterContextProvider> </LocalizationContextProvider>
</LocalizationContextProvider>
</BlankUrlProvider>
</GraphqlProvider> </GraphqlProvider>
</ErrorBoundary> </ErrorBoundary>
</SharedWalletProvider> </SharedWalletProvider>
......
...@@ -39,7 +39,6 @@ import { ...@@ -39,7 +39,6 @@ import {
import { BackgroundToSidePanelRequestType } from 'src/background/messagePassing/types/requests' import { BackgroundToSidePanelRequestType } from 'src/background/messagePassing/types/requests'
import { PrimaryAppInstanceDebuggerLazy } from 'src/store/PrimaryAppInstanceDebuggerLazy' import { PrimaryAppInstanceDebuggerLazy } from 'src/store/PrimaryAppInstanceDebuggerLazy'
import { getReduxPersistor, getReduxStore } from 'src/store/store' import { getReduxPersistor, getReduxStore } from 'src/store/store'
import { BlankUrlProvider } from 'uniswap/src/contexts/UrlContext'
import { LocalizationContextProvider } from 'uniswap/src/features/language/LocalizationContext' import { LocalizationContextProvider } from 'uniswap/src/features/language/LocalizationContext'
import { syncAppWithDeviceLanguage } from 'uniswap/src/features/settings/slice' import { syncAppWithDeviceLanguage } from 'uniswap/src/features/settings/slice'
import Trace from 'uniswap/src/features/telemetry/Trace' import Trace from 'uniswap/src/features/telemetry/Trace'
...@@ -263,17 +262,15 @@ export default function SidebarApp(): JSX.Element { ...@@ -263,17 +262,15 @@ export default function SidebarApp(): JSX.Element {
<SharedWalletProvider reduxStore={getReduxStore()}> <SharedWalletProvider reduxStore={getReduxStore()}>
<ErrorBoundary> <ErrorBoundary>
<GraphqlProvider> <GraphqlProvider>
<BlankUrlProvider> <LocalizationContextProvider>
<LocalizationContextProvider> <UnitagUpdaterContextProvider>
<UnitagUpdaterContextProvider> <TraceUserProperties />
<TraceUserProperties /> <DappContextProvider>
<DappContextProvider> <PrimaryAppInstanceDebuggerLazy />
<PrimaryAppInstanceDebuggerLazy /> <RouterProvider router={router} />
<RouterProvider router={router} /> </DappContextProvider>
</DappContextProvider> </UnitagUpdaterContextProvider>
</UnitagUpdaterContextProvider> </LocalizationContextProvider>
</LocalizationContextProvider>
</BlankUrlProvider>
</GraphqlProvider> </GraphqlProvider>
</ErrorBoundary> </ErrorBoundary>
</SharedWalletProvider> </SharedWalletProvider>
......
...@@ -27,7 +27,6 @@ import { SentryAppNameTag, initializeSentry, sentryCreateHashRouter } from 'src/ ...@@ -27,7 +27,6 @@ import { SentryAppNameTag, initializeSentry, sentryCreateHashRouter } from 'src/
import { initExtensionAnalytics } from 'src/app/utils/analytics' import { initExtensionAnalytics } from 'src/app/utils/analytics'
import { getReduxPersistor, getReduxStore } from 'src/store/store' import { getReduxPersistor, getReduxStore } from 'src/store/store'
import { Flex } from 'ui/src' import { Flex } from 'ui/src'
import { BlankUrlProvider } from 'uniswap/src/contexts/UrlContext'
import { LocalizationContextProvider } from 'uniswap/src/features/language/LocalizationContext' import { LocalizationContextProvider } from 'uniswap/src/features/language/LocalizationContext'
import Trace from 'uniswap/src/features/telemetry/Trace' import Trace from 'uniswap/src/features/telemetry/Trace'
import { UnitagUpdaterContextProvider } from 'uniswap/src/features/unitags/context' import { UnitagUpdaterContextProvider } from 'uniswap/src/features/unitags/context'
...@@ -167,14 +166,12 @@ export default function UnitagClaimApp(): JSX.Element { ...@@ -167,14 +166,12 @@ export default function UnitagClaimApp(): JSX.Element {
<SharedWalletProvider reduxStore={getReduxStore()}> <SharedWalletProvider reduxStore={getReduxStore()}>
<ErrorBoundary> <ErrorBoundary>
<GraphqlProvider> <GraphqlProvider>
<BlankUrlProvider> <LocalizationContextProvider>
<LocalizationContextProvider> <UnitagUpdaterContextProvider>
<UnitagUpdaterContextProvider> <TraceUserProperties />
<TraceUserProperties /> <RouterProvider router={router} />
<RouterProvider router={router} /> </UnitagUpdaterContextProvider>
</UnitagUpdaterContextProvider> </LocalizationContextProvider>
</LocalizationContextProvider>
</BlankUrlProvider>
</GraphqlProvider> </GraphqlProvider>
</ErrorBoundary> </ErrorBoundary>
</SharedWalletProvider> </SharedWalletProvider>
......
import { useEffect } from 'react' import { useEffect } from 'react'
import { useColorScheme } from 'react-native' import { useColorScheme } from 'react-native'
import { useEnabledChains } from 'uniswap/src/features/chains/hooks/useEnabledChains' import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
import { useAppFiatCurrencyInfo } from 'uniswap/src/features/fiatCurrency/hooks' import { useAppFiatCurrencyInfo } from 'uniswap/src/features/fiatCurrency/hooks'
import { useCurrentLanguage } from 'uniswap/src/features/language/hooks' import { useCurrentLanguage } from 'uniswap/src/features/language/hooks'
import { useHideSmallBalancesSetting, useHideSpamTokensSetting } from 'uniswap/src/features/settings/hooks' import { useHideSmallBalancesSetting, useHideSpamTokensSetting } from 'uniswap/src/features/settings/hooks'
......
...@@ -31,9 +31,6 @@ export async function initializeDatadog(appName: string): Promise<void> { ...@@ -31,9 +31,6 @@ export async function initializeDatadog(appName: string): Promise<void> {
// otherwise DataDog will ignore error events // otherwise DataDog will ignore error events
event.view.url = event.view.url.replace(/^chrome-extension:\/\/[a-z]{32}\//i, '') event.view.url = event.view.url.replace(/^chrome-extension:\/\/[a-z]{32}\//i, '')
if (event.error && event.type === 'error') { if (event.error && event.type === 'error') {
if (event.error.source === 'console') {
return false
}
Object.defineProperty(event.error, 'stack', { Object.defineProperty(event.error, 'stack', {
value: event.error.stack?.replace(/chrome-extension:\/\/[a-z]{32}/gi, ''), value: event.error.stack?.replace(/chrome-extension:\/\/[a-z]{32}/gi, ''),
writable: false, writable: false,
......
...@@ -6,7 +6,7 @@ import { iconSizes, opacify } from 'ui/src/theme' ...@@ -6,7 +6,7 @@ import { iconSizes, opacify } from 'ui/src/theme'
import { TextInput } from 'uniswap/src/components/input/TextInput' import { TextInput } from 'uniswap/src/components/input/TextInput'
import { Modal } from 'uniswap/src/components/modals/Modal' import { Modal } from 'uniswap/src/components/modals/Modal'
import { ModalName } from 'uniswap/src/features/telemetry/constants' import { ModalName } from 'uniswap/src/features/telemetry/constants'
import { shortenAddress } from 'utilities/src/addresses' import { shortenAddress } from 'uniswap/src/utils/addresses'
import { AccountIcon } from 'wallet/src/components/accounts/AccountIcon' import { AccountIcon } from 'wallet/src/components/accounts/AccountIcon'
import { SignerMnemonicAccount } from 'wallet/src/features/wallet/accounts/types' import { SignerMnemonicAccount } from 'wallet/src/features/wallet/accounts/types'
......
...@@ -12,10 +12,10 @@ import { FeatureFlags } from 'uniswap/src/features/gating/flags' ...@@ -12,10 +12,10 @@ import { FeatureFlags } from 'uniswap/src/features/gating/flags'
import { useFeatureFlag } from 'uniswap/src/features/gating/hooks' import { useFeatureFlag } from 'uniswap/src/features/gating/hooks'
import { ModalName } from 'uniswap/src/features/telemetry/constants' import { ModalName } from 'uniswap/src/features/telemetry/constants'
import { OnboardingCardLoggingName } from 'uniswap/src/features/telemetry/types' import { OnboardingCardLoggingName } from 'uniswap/src/features/telemetry/types'
import { UNITAG_SUFFIX_NO_LEADING_DOT } from 'uniswap/src/features/unitags/constants'
import { shortenAddress } from 'utilities/src/addresses' import { shortenAddress } from 'utilities/src/addresses'
import { AccountIcon } from 'wallet/src/components/accounts/AccountIcon' import { AccountIcon } from 'wallet/src/components/accounts/AccountIcon'
import { CardType, IntroCard, IntroCardGraphicType } from 'wallet/src/components/introCards/IntroCard' import { CardType, IntroCard, IntroCardGraphicType } from 'wallet/src/components/introCards/IntroCard'
import { UNITAG_SUFFIX_NO_LEADING_DOT } from 'wallet/src/features/unitags/constants'
import { useCanActiveAddressClaimUnitag } from 'wallet/src/features/unitags/hooks' import { useCanActiveAddressClaimUnitag } from 'wallet/src/features/unitags/hooks'
import { EditAccountAction, editAccountActions } from 'wallet/src/features/wallet/accounts/editAccountSaga' import { EditAccountAction, editAccountActions } from 'wallet/src/features/wallet/accounts/editAccountSaga'
import { useDisplayName } from 'wallet/src/features/wallet/hooks' import { useDisplayName } from 'wallet/src/features/wallet/hooks'
......
...@@ -150,7 +150,7 @@ exports[`AccountSwitcherScreen renders correctly 1`] = ` ...@@ -150,7 +150,7 @@ exports[`AccountSwitcherScreen renders correctly 1`] = `
class="font_body _display-inline _boxSizing-border-box _whiteSpace-pre-wrap _mt-0px _mr-0px _mb-0px _ml-0px _color-843135005 _fontFamily-299667014 _wordWrap-break-word _fontSize-229441158 _lineHeight-222976511 _fontWeight-233016202" class="font_body _display-inline _boxSizing-border-box _whiteSpace-pre-wrap _mt-0px _mr-0px _mb-0px _ml-0px _color-843135005 _fontFamily-299667014 _wordWrap-break-word _fontSize-229441158 _lineHeight-222976511 _fontWeight-233016202"
data-disable-theme="true" data-disable-theme="true"
> >
0x​9EB67f...D9A2Ca 0x​9eb6...a2ca
</span> </span>
<svg <svg
fill="none" fill="none"
...@@ -382,7 +382,7 @@ exports[`AccountSwitcherScreen renders correctly 1`] = ` ...@@ -382,7 +382,7 @@ exports[`AccountSwitcherScreen renders correctly 1`] = `
class="font_body _display-inline _boxSizing-border-box _whiteSpace-pre-wrap _mt-0px _mr-0px _mb-0px _ml-0px _color-843135005 _fontFamily-299667014 _wordWrap-break-word _fontSize-229441158 _lineHeight-222976511 _fontWeight-233016202" class="font_body _display-inline _boxSizing-border-box _whiteSpace-pre-wrap _mt-0px _mr-0px _mb-0px _ml-0px _color-843135005 _fontFamily-299667014 _wordWrap-break-word _fontSize-229441158 _lineHeight-222976511 _fontWeight-233016202"
data-disable-theme="true" data-disable-theme="true"
> >
0x​9EB67f...D9A2Ca 0x​9eb6...a2ca
</span> </span>
<svg <svg
fill="none" fill="none"
......
...@@ -6,7 +6,7 @@ import { DappRequestStoreItem } from 'src/app/features/dappRequests/slice' ...@@ -6,7 +6,7 @@ import { DappRequestStoreItem } from 'src/app/features/dappRequests/slice'
import { DappRequestType } from 'src/app/features/dappRequests/types/DappRequestTypes' import { DappRequestType } from 'src/app/features/dappRequests/types/DappRequestTypes'
import { Anchor, AnimatePresence, Button, Flex, Text, UniversalImage, UniversalImageResizeMode, styled } from 'ui/src' import { Anchor, AnimatePresence, Button, Flex, Text, UniversalImage, UniversalImageResizeMode, styled } from 'ui/src'
import { borderRadii, iconSizes } from 'ui/src/theme' import { borderRadii, iconSizes } from 'ui/src/theme'
import { useEnabledChains } from 'uniswap/src/features/chains/hooks/useEnabledChains' import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
import { UniverseChainId } from 'uniswap/src/features/chains/types' import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { GasFeeResult } from 'uniswap/src/features/gas/types' import { GasFeeResult } from 'uniswap/src/features/gas/types'
import { hasSufficientFundsIncludingGas } from 'uniswap/src/features/gas/utils' import { hasSufficientFundsIncludingGas } from 'uniswap/src/features/gas/utils'
......
import { BigNumber } from 'ethers'
import { useCallback } from 'react' import { useCallback } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { useDappLastChainId } from 'src/app/features/dapp/hooks' import { useDappLastChainId } from 'src/app/features/dapp/hooks'
import { DappRequestContent } from 'src/app/features/dappRequests/DappRequestContent' import { DappRequestContent } from 'src/app/features/dappRequests/DappRequestContent'
import { useDappRequestQueueContext } from 'src/app/features/dappRequests/DappRequestQueueContext' import { useDappRequestQueueContext } from 'src/app/features/dappRequests/DappRequestQueueContext'
import { isNonZeroBigNumber } from 'src/app/features/dappRequests/requestContent/EthSend/Swap/utils'
import { SendTransactionRequest } from 'src/app/features/dappRequests/types/DappRequestTypes' import { SendTransactionRequest } from 'src/app/features/dappRequests/types/DappRequestTypes'
import { useCopyToClipboard } from 'src/app/hooks/useOnCopyToClipboard' import { useCopyToClipboard } from 'src/app/hooks/useOnCopyToClipboard'
import { Anchor, Flex, Text, TouchableArea } from 'ui/src' import { Anchor, Flex, Text, TouchableArea } from 'ui/src'
...@@ -55,7 +55,6 @@ export function FallbackEthSendRequestContent({ ...@@ -55,7 +55,6 @@ export function FallbackEthSendRequestContent({
) )
const { parsedTransactionData } = useNoYoloParser(dappRequest.transaction, chainId) const { parsedTransactionData } = useNoYoloParser(dappRequest.transaction, chainId)
const transactionCurrencies = useTransactionCurrencies({ chainId, to: toAddress, parsedTransactionData }) const transactionCurrencies = useTransactionCurrencies({ chainId, to: toAddress, parsedTransactionData })
const showSpendingEthDetails = isNonZeroBigNumber(sending) && chainId
return ( return (
<DappRequestContent <DappRequestContent
...@@ -75,7 +74,9 @@ export function FallbackEthSendRequestContent({ ...@@ -75,7 +74,9 @@ export function FallbackEthSendRequestContent({
p="$spacing16" p="$spacing16"
width="100%" width="100%"
> >
{showSpendingEthDetails && <SpendingEthDetails chainId={chainId} value={sending} />} {sending && !BigNumber.from(sending).eq(0) && chainId && (
<SpendingEthDetails chainId={chainId} value={sending} />
)}
{transactionCurrencies?.map((currencyInfo, i) => ( {transactionCurrencies?.map((currencyInfo, i) => (
<SpendingDetails <SpendingDetails
key={currencyInfo.currencyId} key={currencyInfo.currencyId}
......
...@@ -5,7 +5,7 @@ import { ETH_ADDRESS } from 'src/app/features/dappRequests/requestContent/EthSen ...@@ -5,7 +5,7 @@ import { ETH_ADDRESS } from 'src/app/features/dappRequests/requestContent/EthSen
import { formatUnits, useSwapDetails } from 'src/app/features/dappRequests/requestContent/EthSend/Swap/utils' import { formatUnits, useSwapDetails } from 'src/app/features/dappRequests/requestContent/EthSend/Swap/utils'
import { SignTypedDataRequest, SwapSendTransactionRequest } from 'src/app/features/dappRequests/types/DappRequestTypes' import { SignTypedDataRequest, SwapSendTransactionRequest } from 'src/app/features/dappRequests/types/DappRequestTypes'
import { DEFAULT_NATIVE_ADDRESS } from 'uniswap/src/features/chains/chainInfo' import { DEFAULT_NATIVE_ADDRESS } from 'uniswap/src/features/chains/chainInfo'
import { useEnabledChains } from 'uniswap/src/features/chains/hooks/useEnabledChains' import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
import { toSupportedChainId } from 'uniswap/src/features/chains/utils' import { toSupportedChainId } from 'uniswap/src/features/chains/utils'
import { CurrencyInfo } from 'uniswap/src/features/dataApi/types' import { CurrencyInfo } from 'uniswap/src/features/dataApi/types'
import { GasFeeResult } from 'uniswap/src/features/gas/types' import { GasFeeResult } from 'uniswap/src/features/gas/types'
......
...@@ -162,6 +162,20 @@ function extractTokenAddresses(commands: UniversalRouterCommand[]): { ...@@ -162,6 +162,20 @@ function extractTokenAddresses(commands: UniversalRouterCommand[]): {
return { inputAddress, outputAddress } return { inputAddress, outputAddress }
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function isZeroBigNumber(bigNumberObj: any): boolean {
// The true type of bigNumberObj is { type: string; hex: string } but param.value is any type
try {
if (!bigNumberObj) {
return true
}
const bigNumber = BigNumber.from(bigNumberObj.hex)
return bigNumber.isZero()
} catch (error) {
return true // Treat as zero if there's any error
}
}
function getTokenAmounts(commands: UniversalRouterCommand[]): { function getTokenAmounts(commands: UniversalRouterCommand[]): {
inputValue: string inputValue: string
outputValue: string outputValue: string
...@@ -191,9 +205,7 @@ function getTokenAmounts(commands: UniversalRouterCommand[]): { ...@@ -191,9 +205,7 @@ function getTokenAmounts(commands: UniversalRouterCommand[]): {
const inputValue = firstAmountInParam?.value const inputValue = firstAmountInParam?.value
const fallbackOutputValue = sweepAmountOutParam?.value || unwrapWethAmountOutParam?.value const fallbackOutputValue = sweepAmountOutParam?.value || unwrapWethAmountOutParam?.value
const outputValue = const outputValue =
fallbackOutputValue && isZeroBigNumberParam(lastAmountOutParam?.value) fallbackOutputValue && isZeroBigNumber(lastAmountOutParam?.value) ? fallbackOutputValue : lastAmountOutParam?.value
? fallbackOutputValue
: lastAmountOutParam?.value
return { return {
inputValue: inputValue || '0', // Safe due to assert inputValue: inputValue || '0', // Safe due to assert
...@@ -372,34 +384,3 @@ export function getTokenDetailsFromV4SwapCommands(command: UniversalRouterComman ...@@ -372,34 +384,3 @@ export function getTokenDetailsFromV4SwapCommands(command: UniversalRouterComman
return { inputAddress, outputAddress, inputValue, outputValue } return { inputAddress, outputAddress, inputValue, outputValue }
} }
export function isNonZeroBigNumber(value: string | undefined): boolean {
if (!value) {
return false
}
try {
const valueBN = BigNumber.from(value)
return !valueBN.isZero()
} catch {
return false
}
}
interface BigNumberParam {
type: string
hex: string
}
const isBigNumberParam = (obj: unknown): obj is BigNumberParam =>
typeof obj === 'object' && !!obj && 'hex' in obj && typeof (obj as BigNumberParam).hex === 'string'
// We have to type this as unknown because BigNumberSchema is any (as defined in apps/extension/src/app/features/dappRequests/types/EthersTypes.ts)
function isZeroBigNumberParam(bigNumberObj: unknown): boolean {
// We treat an undefined or badly formatted param as zero
if (!bigNumberObj || !isBigNumberParam(bigNumberObj)) {
return true
}
return !isNonZeroBigNumber(bigNumberObj.hex)
}
...@@ -4,7 +4,7 @@ import { useDappLastChainId } from 'src/app/features/dapp/hooks' ...@@ -4,7 +4,7 @@ import { useDappLastChainId } from 'src/app/features/dapp/hooks'
import { DappRequestStoreItem } from 'src/app/features/dappRequests/slice' import { DappRequestStoreItem } from 'src/app/features/dappRequests/slice'
import { SendTransactionRequest } from 'src/app/features/dappRequests/types/DappRequestTypes' import { SendTransactionRequest } from 'src/app/features/dappRequests/types/DappRequestTypes'
import { Flex, Text } from 'ui/src' import { Flex, Text } from 'ui/src'
import { useEnabledChains } from 'uniswap/src/features/chains/hooks/useEnabledChains' import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
import { useGasFeeFormattedAmounts, useTransactionGasFee } from 'uniswap/src/features/gas/hooks' import { useGasFeeFormattedAmounts, useTransactionGasFee } from 'uniswap/src/features/gas/hooks'
import { useActiveAccountAddressWithThrow, useDisplayName } from 'wallet/src/features/wallet/hooks' import { useActiveAccountAddressWithThrow, useDisplayName } from 'wallet/src/features/wallet/hooks'
......
...@@ -6,7 +6,7 @@ import { AppRoutes } from 'src/app/navigation/constants' ...@@ -6,7 +6,7 @@ import { AppRoutes } from 'src/app/navigation/constants'
import { navigate } from 'src/app/navigation/state' import { navigate } from 'src/app/navigation/state'
import { Flex, Text, getTokenValue, useMedia } from 'ui/src' import { Flex, Text, getTokenValue, useMedia } from 'ui/src'
import { ArrowDownCircle, Buy, CoinConvert, SendAction } from 'ui/src/components/icons' import { ArrowDownCircle, Buy, CoinConvert, SendAction } from 'ui/src/components/icons'
import { useEnabledChains } from 'uniswap/src/features/chains/hooks/useEnabledChains' import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
import { ElementName } from 'uniswap/src/features/telemetry/constants' import { ElementName } from 'uniswap/src/features/telemetry/constants'
import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send' import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
import { TestnetModeModal } from 'uniswap/src/features/testnets/TestnetModeModal' import { TestnetModeModal } from 'uniswap/src/features/testnets/TestnetModeModal'
......
...@@ -22,9 +22,8 @@ import { ElementName } from 'uniswap/src/features/telemetry/constants' ...@@ -22,9 +22,8 @@ import { ElementName } from 'uniswap/src/features/telemetry/constants'
import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send' import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
import { TestID } from 'uniswap/src/test/fixtures/testIDs' import { TestID } from 'uniswap/src/test/fixtures/testIDs'
import { ExtensionScreens } from 'uniswap/src/types/screens/extension' import { ExtensionScreens } from 'uniswap/src/types/screens/extension'
import { sanitizeAddressText } from 'uniswap/src/utils/addresses' import { sanitizeAddressText, shortenAddress } from 'uniswap/src/utils/addresses'
import { setClipboard } from 'uniswap/src/utils/clipboard' import { setClipboard } from 'uniswap/src/utils/clipboard'
import { shortenAddress } from 'utilities/src/addresses'
import { extractNameFromUrl } from 'utilities/src/format/extractNameFromUrl' import { extractNameFromUrl } from 'utilities/src/format/extractNameFromUrl'
import { DappIconPlaceholder } from 'wallet/src/components/WalletConnect/DappIconPlaceholder' import { DappIconPlaceholder } from 'wallet/src/components/WalletConnect/DappIconPlaceholder'
import { AccountIcon } from 'wallet/src/components/accounts/AccountIcon' import { AccountIcon } from 'wallet/src/components/accounts/AccountIcon'
......
...@@ -9,7 +9,7 @@ import { Check, Power } from 'ui/src/components/icons' ...@@ -9,7 +9,7 @@ import { Check, Power } from 'ui/src/components/icons'
import { usePreventOverflowBelowFold } from 'ui/src/hooks/usePreventOverflowBelowFold' import { usePreventOverflowBelowFold } from 'ui/src/hooks/usePreventOverflowBelowFold'
import { iconSizes } from 'ui/src/theme' import { iconSizes } from 'ui/src/theme'
import { NetworkLogo } from 'uniswap/src/components/CurrencyLogo/NetworkLogo' import { NetworkLogo } from 'uniswap/src/components/CurrencyLogo/NetworkLogo'
import { useEnabledChains } from 'uniswap/src/features/chains/hooks/useEnabledChains' import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
import { UniverseChainId } from 'uniswap/src/features/chains/types' import { UniverseChainId } from 'uniswap/src/features/chains/types'
import { getChainLabel } from 'uniswap/src/features/chains/utils' import { getChainLabel } from 'uniswap/src/features/chains/utils'
import { pushNotification } from 'uniswap/src/features/notifications/slice' import { pushNotification } from 'uniswap/src/features/notifications/slice'
......
...@@ -10,7 +10,7 @@ import { BaseCard } from 'uniswap/src/components/BaseCard/BaseCard' ...@@ -10,7 +10,7 @@ import { BaseCard } from 'uniswap/src/components/BaseCard/BaseCard'
import { InfoLinkModal } from 'uniswap/src/components/modals/InfoLinkModal' import { InfoLinkModal } from 'uniswap/src/components/modals/InfoLinkModal'
import { uniswapUrls } from 'uniswap/src/constants/urls' import { uniswapUrls } from 'uniswap/src/constants/urls'
import { SafetyLevel } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks' import { SafetyLevel } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks'
import { useEnabledChains } from 'uniswap/src/features/chains/hooks/useEnabledChains' import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
import { PortfolioBalance } from 'uniswap/src/features/dataApi/types' import { PortfolioBalance } from 'uniswap/src/features/dataApi/types'
import { ElementName, ModalName, SectionName, WalletEventName } from 'uniswap/src/features/telemetry/constants' import { ElementName, ModalName, SectionName, WalletEventName } from 'uniswap/src/features/telemetry/constants'
import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send' import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
......
...@@ -9,7 +9,7 @@ import { fonts, iconSizes } from 'ui/src/theme' ...@@ -9,7 +9,7 @@ import { fonts, iconSizes } from 'ui/src/theme'
import { UNISWAP_WEB_URL } from 'uniswap/src/constants/urls' import { UNISWAP_WEB_URL } from 'uniswap/src/constants/urls'
import Trace from 'uniswap/src/features/telemetry/Trace' import Trace from 'uniswap/src/features/telemetry/Trace'
import { ExtensionOnboardingFlow, ExtensionOnboardingScreens } from 'uniswap/src/types/screens/extension' import { ExtensionOnboardingFlow, ExtensionOnboardingScreens } from 'uniswap/src/types/screens/extension'
import { shortenAddress } from 'utilities/src/addresses' import { shortenAddress } from 'uniswap/src/utils/addresses'
import { useOnboardingContext } from 'wallet/src/features/onboarding/OnboardingContext' import { useOnboardingContext } from 'wallet/src/features/onboarding/OnboardingContext'
export function NameWallet(): JSX.Element { export function NameWallet(): JSX.Element {
......
...@@ -2,13 +2,14 @@ import { useCallback, useMemo } from 'react' ...@@ -2,13 +2,14 @@ import { useCallback, useMemo } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { useDispatch } from 'react-redux' import { useDispatch } from 'react-redux'
import { ScreenHeader } from 'src/app/components/layout/ScreenHeader' import { ScreenHeader } from 'src/app/components/layout/ScreenHeader'
import { removeAllDappConnectionsForAccount, removeDappConnection } from 'src/app/features/dapp/actions' import { removeDappConnection } from 'src/app/features/dapp/actions'
import { useAllDappConnectionsForActiveAccount } from 'src/app/features/dapp/hooks' import { useAllDappConnectionsForActiveAccount } from 'src/app/features/dapp/hooks'
import { dappStore } from 'src/app/features/dapp/store' import { dappStore } from 'src/app/features/dapp/store'
import { EllipsisDropdown } from 'src/app/features/settings/SettingsManageConnectionsScreen/internal/EllipsisDropdown'
import { NoDappConnections } from 'src/app/features/settings/SettingsManageConnectionsScreen/internal/NoDappConnections' import { NoDappConnections } from 'src/app/features/settings/SettingsManageConnectionsScreen/internal/NoDappConnections'
import { Flex, Text, TouchableArea, UniversalImage, useSporeColors } from 'ui/src' import { Flex, Text, TouchableArea, UniversalImage, useSporeColors } from 'ui/src'
import { MinusCircle } from 'ui/src/components/icons' import { MinusCircle } from 'ui/src/components/icons'
import { borderRadii, breakpoints, fonts, gap, iconSizes } from 'ui/src/theme' import { borderRadii, breakpoints, iconSizes } from 'ui/src/theme'
import { pushNotification } from 'uniswap/src/features/notifications/slice' import { pushNotification } from 'uniswap/src/features/notifications/slice'
import { AppNotificationType } from 'uniswap/src/features/notifications/types' import { AppNotificationType } from 'uniswap/src/features/notifications/types'
import Trace from 'uniswap/src/features/telemetry/Trace' import Trace from 'uniswap/src/features/telemetry/Trace'
...@@ -18,7 +19,6 @@ import { ExtensionScreens } from 'uniswap/src/types/screens/extension' ...@@ -18,7 +19,6 @@ import { ExtensionScreens } from 'uniswap/src/types/screens/extension'
import { extractNameFromUrl } from 'utilities/src/format/extractNameFromUrl' import { extractNameFromUrl } from 'utilities/src/format/extractNameFromUrl'
import { extractUrlHost } from 'utilities/src/format/urls' import { extractUrlHost } from 'utilities/src/format/urls'
import { DappIconPlaceholder } from 'wallet/src/components/WalletConnect/DappIconPlaceholder' import { DappIconPlaceholder } from 'wallet/src/components/WalletConnect/DappIconPlaceholder'
import { DappEllipsisDropdown } from 'wallet/src/components/settings/DappEllipsisDropdown/DappEllipsisDropdown'
import { useActiveAccountWithThrow } from 'wallet/src/features/wallet/hooks' import { useActiveAccountWithThrow } from 'wallet/src/features/wallet/hooks'
const MIN_SCREEN_WIDTH = breakpoints.xxs const MIN_SCREEN_WIDTH = breakpoints.xxs
...@@ -26,11 +26,6 @@ const HORIZONTAL_SPACING = 12 ...@@ -26,11 +26,6 @@ const HORIZONTAL_SPACING = 12
// when sidebar is at the minimum width (360px), this will allow 2 cards to cleanly fit per row // when sidebar is at the minimum width (360px), this will allow 2 cards to cleanly fit per row
const TILE_WIDTH = (MIN_SCREEN_WIDTH - 3 * HORIZONTAL_SPACING) / 2 const TILE_WIDTH = (MIN_SCREEN_WIDTH - 3 * HORIZONTAL_SPACING) / 2
const titleVariant: keyof typeof fonts = 'body3'
const subtitleVariant: keyof typeof fonts = 'body4'
const textGap: number = gap.gap4
const textAreaHeight = fonts[titleVariant].lineHeight + fonts[subtitleVariant].lineHeight + textGap
export function SettingsManageConnectionsScreen(): JSX.Element { export function SettingsManageConnectionsScreen(): JSX.Element {
const colors = useSporeColors() const colors = useSporeColors()
const dispatch = useDispatch() const dispatch = useDispatch()
...@@ -65,67 +60,11 @@ export function SettingsManageConnectionsScreen(): JSX.Element { ...@@ -65,67 +60,11 @@ export function SettingsManageConnectionsScreen(): JSX.Element {
dappUrls.map((dappUrl) => { dappUrls.map((dappUrl) => {
const dappInfo = dappStore.getDappInfo(dappUrl) const dappInfo = dappStore.getDappInfo(dappUrl)
const name = extractNameFromUrl(dappUrl) const name = extractNameFromUrl(dappUrl)
const hostName = extractUrlHost(dappUrl)
const title = dappInfo?.displayName || hostName
const DeleteDappButton = (
<TouchableArea
$group-hover={{ display: 'flex' }}
display="none"
p="$spacing2"
position="absolute"
right="$padding8"
top="$padding8"
onPress={getHandleRemoveConnection(dappUrl)}
>
<MinusCircle size="$icon.20" fill={colors.neutral3.get()} />
</TouchableArea>
)
const DappIcon = (
<UniversalImage
fallback={<DappIconPlaceholder iconSize={iconSizes.icon32} name={name.toUpperCase()} />}
size={{
height: iconSizes.icon32,
width: iconSizes.icon32,
}}
style={{ image: { borderRadius: borderRadii.rounded8 } }}
uri={dappInfo?.iconUrl}
/>
)
/**
* TEXT AREA; TITLE/SUBTITLE
*
* we only need to set the text area height because it is the only section with optional fields
*/
const Title = (
<Flex alignItems="center" gap={textGap} maxWidth="100%" height={textAreaHeight}>
<Text variant={titleVariant} maxWidth="100%" textAlign="center" numberOfLines={1} title={title}>
{title}
</Text>
{hostName !== title && (
<Text
color="$neutral2"
maxWidth="100%"
variant={subtitleVariant}
wordWrap="break-word"
textAlign="center"
numberOfLines={1}
title={hostName}
>
{hostName}
</Text>
)}
</Flex>
)
return ( return (
<Flex <Flex
key={dappUrl} key={dappUrl}
group group
alignItems="center" centered
backgroundColor="$surface2" backgroundColor="$surface2"
borderRadius="$rounded16" borderRadius="$rounded16"
flexGrow={0} flexGrow={0}
...@@ -135,9 +74,33 @@ export function SettingsManageConnectionsScreen(): JSX.Element { ...@@ -135,9 +74,33 @@ export function SettingsManageConnectionsScreen(): JSX.Element {
// when sidebar is at the minimum width (360px), this will allow 2 cards to cleanly fit per row // when sidebar is at the minimum width (360px), this will allow 2 cards to cleanly fit per row
width={TILE_WIDTH} width={TILE_WIDTH}
> >
{DeleteDappButton} <TouchableArea
{DappIcon} $group-hover={{ display: 'flex' }}
{Title} display="none"
p="$spacing2"
position="absolute"
right="$padding8"
top="$padding8"
onPress={getHandleRemoveConnection(dappUrl)}
>
<MinusCircle size="$icon.20" fill={colors.neutral3.get()} />
</TouchableArea>
<UniversalImage
fallback={<DappIconPlaceholder iconSize={iconSizes.icon32} name={name.toUpperCase()} />}
size={{
height: iconSizes.icon32,
width: iconSizes.icon32,
}}
style={{ image: { borderRadius: borderRadii.rounded8 } }}
uri={dappInfo?.iconUrl}
/>
<Flex alignItems="center" gap="$gap4" maxWidth="100%">
<Text variant="body3">{dappInfo?.displayName || name}</Text>
<Text color="$neutral2" maxWidth="100%" variant="body4" wordWrap="break-word">
{extractUrlHost(dappUrl)}
</Text>
</Flex>
</Flex> </Flex>
) )
}), }),
...@@ -149,11 +112,7 @@ export function SettingsManageConnectionsScreen(): JSX.Element { ...@@ -149,11 +112,7 @@ export function SettingsManageConnectionsScreen(): JSX.Element {
return ( return (
<Trace logImpression screen={ExtensionScreens.ManageDappConnectionsScreen}> <Trace logImpression screen={ExtensionScreens.ManageDappConnectionsScreen}>
<ScreenHeader <ScreenHeader
rightColumn={ rightColumn={hasConnections ? <EllipsisDropdown /> : undefined}
hasConnections ? (
<DappEllipsisDropdown removeAllDappConnections={removeAllDappConnectionsForAccount} />
) : undefined
}
title={t('settings.setting.wallet.connections.title')} title={t('settings.setting.wallet.connections.title')}
/> />
<Flex row flexWrap="wrap" gap="$gap12"> <Flex row flexWrap="wrap" gap="$gap12">
......
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { useDispatch } from 'react-redux' import { useDispatch } from 'react-redux'
import { Flex } from 'ui/src' import { removeAllDappConnectionsForAccount } from 'src/app/features/dapp/actions'
import { Power } from 'ui/src/components/icons' import { Flex, TouchableArea } from 'ui/src'
import { Ellipsis, Power } from 'ui/src/components/icons'
import { pushNotification } from 'uniswap/src/features/notifications/slice' import { pushNotification } from 'uniswap/src/features/notifications/slice'
import { AppNotificationType } from 'uniswap/src/features/notifications/types' import { AppNotificationType } from 'uniswap/src/features/notifications/types'
import { ExtensionEventName } from 'uniswap/src/features/telemetry/constants' import { ExtensionEventName } from 'uniswap/src/features/telemetry/constants'
import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send' import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
import { logger } from 'utilities/src/logger/logger'
import { ContextMenu } from 'wallet/src/components/menu/ContextMenu' import { ContextMenu } from 'wallet/src/components/menu/ContextMenu'
import { type DappEllipsisDropdownProps } from 'wallet/src/components/settings/DappEllipsisDropdown/DappEllipsisDropdown' import { useActiveAccountAddress, useActiveAccountWithThrow } from 'wallet/src/features/wallet/hooks'
import { DappEllipsisDropdownIcon } from 'wallet/src/components/settings/DappEllipsisDropdown/internal/DappEllipsisDropdownIcon'
import { useActiveAccountWithThrow } from 'wallet/src/features/wallet/hooks'
const PowerCircle = (): JSX.Element => ( const PowerCircle = (): JSX.Element => (
<Flex centered backgroundColor="red" borderRadius="$roundedFull" p="$spacing2" pt="$spacing1"> <Flex centered backgroundColor="red" borderRadius="$roundedFull" p="$spacing2" pt="$spacing1">
...@@ -18,23 +16,12 @@ const PowerCircle = (): JSX.Element => ( ...@@ -18,23 +16,12 @@ const PowerCircle = (): JSX.Element => (
</Flex> </Flex>
) )
export function DappEllipsisDropdown({ export function EllipsisDropdown(): JSX.Element {
isEditing,
setIsEditing,
removeAllDappConnections,
}: DappEllipsisDropdownProps): JSX.Element {
const { t } = useTranslation() const { t } = useTranslation()
const dispatch = useDispatch() const dispatch = useDispatch()
// use undefined instead of null for typing
const activeAccount = useActiveAccountWithThrow() const activeAccount = useActiveAccountWithThrow()
const activeConnectedAddress = useActiveAccountAddress() ?? undefined
if (isEditing !== undefined || setIsEditing) {
logger.warn(
'DappEllipsisDropdown.web.tsx',
'render',
'`isEditing` and/or `setIsEditing` are not expected to be defined',
)
}
return ( return (
<ContextMenu <ContextMenu
...@@ -44,9 +31,9 @@ export function DappEllipsisDropdown({ ...@@ -44,9 +31,9 @@ export function DappEllipsisDropdown({
{ {
label: t('settings.setting.connections.disconnectAll'), label: t('settings.setting.connections.disconnectAll'),
onPress: async (): Promise<void> => { onPress: async (): Promise<void> => {
await removeAllDappConnections(activeAccount) await removeAllDappConnectionsForAccount(activeAccount)
sendAnalyticsEvent(ExtensionEventName.DappDisconnectAll, { sendAnalyticsEvent(ExtensionEventName.DappDisconnectAll, {
activeConnectedAddress: activeAccount.address, activeConnectedAddress,
}) })
dispatch( dispatch(
pushNotification({ pushNotification({
...@@ -62,7 +49,9 @@ export function DappEllipsisDropdown({ ...@@ -62,7 +49,9 @@ export function DappEllipsisDropdown({
offset={{ mainAxis: 2 }} offset={{ mainAxis: 2 }}
onLeftClick={true} onLeftClick={true}
> >
<DappEllipsisDropdownIcon /> <TouchableArea borderRadius="$roundedFull" hoverStyle={{ backgroundColor: '$surface2Hovered' }} p="$spacing8">
<Ellipsis color="$neutral2" size="$icon.16" />
</TouchableArea>
</ContextMenu> </ContextMenu>
) )
} }
...@@ -32,12 +32,11 @@ import { ...@@ -32,12 +32,11 @@ import {
RotatableChevron, RotatableChevron,
Settings, Settings,
ShieldQuestion, ShieldQuestion,
Wrench,
} from 'ui/src/components/icons' } from 'ui/src/components/icons'
import { iconSizes } from 'ui/src/theme' import { iconSizes } from 'ui/src/theme'
import { uniswapUrls } from 'uniswap/src/constants/urls' import { uniswapUrls } from 'uniswap/src/constants/urls'
import { resetUniswapBehaviorHistory } from 'uniswap/src/features/behaviorHistory/slice' import { resetUniswapBehaviorHistory } from 'uniswap/src/features/behaviorHistory/slice'
import { useEnabledChains } from 'uniswap/src/features/chains/hooks/useEnabledChains' import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
import { FiatCurrency, ORDERED_CURRENCIES } from 'uniswap/src/features/fiatCurrency/constants' import { FiatCurrency, ORDERED_CURRENCIES } from 'uniswap/src/features/fiatCurrency/constants'
import { getFiatCurrencyName, useAppFiatCurrencyInfo } from 'uniswap/src/features/fiatCurrency/hooks' import { getFiatCurrencyName, useAppFiatCurrencyInfo } from 'uniswap/src/features/fiatCurrency/hooks'
import { useCurrentLanguageInfo } from 'uniswap/src/features/language/hooks' import { useCurrentLanguageInfo } from 'uniswap/src/features/language/hooks'
...@@ -192,7 +191,7 @@ export function SettingsScreen(): JSX.Element { ...@@ -192,7 +191,7 @@ export function SettingsScreen(): JSX.Element {
onPress={(): void => navigateTo(`${AppRoutes.Settings}/${SettingsRoutes.Privacy}`)} onPress={(): void => navigateTo(`${AppRoutes.Settings}/${SettingsRoutes.Privacy}`)}
/> />
<SettingsToggleRow <SettingsToggleRow
Icon={Wrench} Icon={ShieldQuestion}
checked={isTestnetModeEnabled} checked={isTestnetModeEnabled}
title={t('settings.setting.wallet.testnetMode.title')} title={t('settings.setting.wallet.testnetMode.title')}
onCheckedChange={handleTestnetModeToggle} onCheckedChange={handleTestnetModeToggle}
......
import { useState } from 'react'
import { useExtensionNavigation } from 'src/app/navigation/utils' import { useExtensionNavigation } from 'src/app/navigation/utils'
import { Flex } from 'ui/src' import { Flex } from 'ui/src'
import { useEnabledChains } from 'uniswap/src/features/chains/hooks/useEnabledChains' import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
import { useHighestBalanceNativeCurrencyId } from 'uniswap/src/features/dataApi/balances' import { useHighestBalanceNativeCurrencyId } from 'uniswap/src/features/dataApi/balances'
import { useSwapPrefilledState } from 'uniswap/src/features/transactions/swap/hooks/useSwapPrefilledState' import { useSwapPrefilledState } from 'uniswap/src/features/transactions/swap/hooks/useSwapPrefilledState'
import { prepareSwapFormState } from 'uniswap/src/features/transactions/types/transactionState' import { prepareSwapFormState } from 'uniswap/src/features/transactions/types/transactionState'
...@@ -15,10 +14,7 @@ export function SwapFlowScreen(): JSX.Element { ...@@ -15,10 +14,7 @@ export function SwapFlowScreen(): JSX.Element {
const inputCurrencyId = useHighestBalanceNativeCurrencyId(account.address) const inputCurrencyId = useHighestBalanceNativeCurrencyId(account.address)
const initialState = prepareSwapFormState({ inputCurrencyId, defaultChainId }) const initialState = prepareSwapFormState({ inputCurrencyId, defaultChainId })
/** Initialize the initial state once. On navigation the locationState changes causing an unwanted re-render. */ const swapPrefilledState = useSwapPrefilledState(locationState?.initialTransactionState ?? initialState)
const [initialTransactionState] = useState(() => locationState?.initialTransactionState ?? initialState)
const swapPrefilledState = useSwapPrefilledState(initialTransactionState)
return ( return (
<Flex fill p="$spacing12"> <Flex fill p="$spacing12">
......
...@@ -5,9 +5,9 @@ import { useOnboardingSteps } from 'src/app/features/onboarding/OnboardingStepsC ...@@ -5,9 +5,9 @@ import { useOnboardingSteps } from 'src/app/features/onboarding/OnboardingStepsC
import { useUnitagClaimContext } from 'src/app/features/unitags/UnitagClaimContext' import { useUnitagClaimContext } from 'src/app/features/unitags/UnitagClaimContext'
import { closeCurrentTab } from 'src/app/navigation/utils' import { closeCurrentTab } from 'src/app/navigation/utils'
import { Button, Flex, Text } from 'ui/src' import { Button, Flex, Text } from 'ui/src'
import { UNITAG_SUFFIX } from 'uniswap/src/features/unitags/constants'
import { logger } from 'utilities/src/logger/logger' import { logger } from 'utilities/src/logger/logger'
import { UnitagWithProfilePicture } from 'wallet/src/features/unitags/UnitagWithProfilePicture' import { UnitagWithProfilePicture } from 'wallet/src/features/unitags/UnitagWithProfilePicture'
import { UNITAG_SUFFIX } from 'wallet/src/features/unitags/constants'
import { useAccountAddressFromUrlWithThrow } from 'wallet/src/features/wallet/hooks' import { useAccountAddressFromUrlWithThrow } from 'wallet/src/features/wallet/hooks'
export function UnitagConfirmationScreen(): JSX.Element { export function UnitagConfirmationScreen(): JSX.Element {
......
...@@ -5,7 +5,7 @@ import { useCopyToClipboard } from 'src/app/hooks/useOnCopyToClipboard' ...@@ -5,7 +5,7 @@ import { useCopyToClipboard } from 'src/app/hooks/useOnCopyToClipboard'
import { AppRoutes, HomeQueryParams, HomeTabs } from 'src/app/navigation/constants' import { AppRoutes, HomeQueryParams, HomeTabs } from 'src/app/navigation/constants'
import { navigate } from 'src/app/navigation/state' import { navigate } from 'src/app/navigation/state'
import { SidebarLocationState, focusOrCreateTokensExploreTab } from 'src/app/navigation/utils' import { SidebarLocationState, focusOrCreateTokensExploreTab } from 'src/app/navigation/utils'
import { useEnabledChains } from 'uniswap/src/features/chains/hooks/useEnabledChains' import { useEnabledChains } from 'uniswap/src/features/chains/hooks'
import { CopyNotificationType } from 'uniswap/src/features/notifications/types' import { CopyNotificationType } from 'uniswap/src/features/notifications/types'
import { WalletEventName } from 'uniswap/src/features/telemetry/constants' import { WalletEventName } from 'uniswap/src/features/telemetry/constants'
import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send' import { sendAnalyticsEvent } from 'uniswap/src/features/telemetry/send'
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"manifest_version": 3, "manifest_version": 3,
"name": "Uniswap Extension", "name": "Uniswap Extension",
"description": "The Uniswap Extension is a self-custody crypto wallet that's built for swapping.", "description": "The Uniswap Extension is a self-custody crypto wallet that's built for swapping.",
"version": "1.11.0", "version": "1.9.0",
"minimum_chrome_version": "116", "minimum_chrome_version": "116",
"icons": { "icons": {
"16": "assets/icon16.png", "16": "assets/icon16.png",
......
...@@ -218,20 +218,6 @@ You can also run the app from Xcode, which is necessary for any Swift related ch ...@@ -218,20 +218,6 @@ You can also run the app from Xcode, which is necessary for any Swift related ch
Hopefully you now (after a few minutes) see the Uniswap Wallet running in the iOS Simulator! Hopefully you now (after a few minutes) see the Uniswap Wallet running in the iOS Simulator!
### Using Radon IDE (VSCode/Cursor Extension)
[Radon IDE](https://marketplace.visualstudio.com/items?itemName=swmansion.react-native-ide&ssr=false#review-details) is a relatively new VSCode extension build by Software Mansion. TLDR; its tagline is
> A better developer experience for React Native developers
It's not perfect, but it's great to have in the toolbox. One noteworthy feature is the ability to click on any piece of UI and be able to inspect the component hierarchy + jump straight into the relevant code. There's also support for breakpoints in VSCode/Cursor, better logging, instant replay of your session, and the ability to adjust common device settings on the fly.
To get started, you should already be able to build the iOS app (either in XCode or via the cli). Install the extension, open it, and follow the onboarding instructions.
One you have a device configured, it will start to build. If/when successful, you'll see the device simulator/emulator in the sidebar.
In `.vscode/launch.json`, you will see configurations for each platform. This is where you can specify the fingerprint command. The fingerprint is a hash of the build environment, and Radon uses it to determine if the build has changed so that it knows when to re-run the build process (i.e. only on native code changes). There are more complex implementations of this, but this is a simple first step.
#### Running on a Physical iOS Device #### Running on a Physical iOS Device
1. Follow all steps listed above. 1. Follow all steps listed above.
......
...@@ -89,9 +89,9 @@ if (isCI && datadogPropertiesAvailable && !isDetox) { ...@@ -89,9 +89,9 @@ if (isCI && datadogPropertiesAvailable && !isDetox) {
apply from: "../../../../node_modules/@datadog/mobile-react-native/datadog-sourcemaps.gradle" apply from: "../../../../node_modules/@datadog/mobile-react-native/datadog-sourcemaps.gradle"
} }
def devVersionName = "1.41" def devVersionName = "1.39"
def betaVersionName = "1.41" def betaVersionName = "1.39"
def prodVersionName = "1.41" def prodVersionName = "1.39"
android { android {
ndkVersion rootProject.ext.ndkVersion ndkVersion rootProject.ext.ndkVersion
......
...@@ -24,15 +24,14 @@ import androidx.compose.runtime.mutableStateOf ...@@ -24,15 +24,14 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextRange import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.text.input.KeyboardCapitalization
...@@ -40,7 +39,6 @@ import androidx.compose.ui.text.input.KeyboardType ...@@ -40,7 +39,6 @@ import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.focus.focusRequester
import com.uniswap.R import com.uniswap.R
import com.uniswap.onboarding.import.SeedPhraseInputViewModel.MnemonicError.InvalidPhrase import com.uniswap.onboarding.import.SeedPhraseInputViewModel.MnemonicError.InvalidPhrase
import com.uniswap.onboarding.import.SeedPhraseInputViewModel.MnemonicError.InvalidWord import com.uniswap.onboarding.import.SeedPhraseInputViewModel.MnemonicError.InvalidWord
...@@ -54,7 +52,6 @@ import com.uniswap.theme.UniswapTheme ...@@ -54,7 +52,6 @@ import com.uniswap.theme.UniswapTheme
import com.uniswap.theme.relativeOffset import com.uniswap.theme.relativeOffset
import kotlin.math.abs import kotlin.math.abs
@OptIn(ExperimentalComposeUiApi::class)
@Composable @Composable
fun SeedPhraseInput( fun SeedPhraseInput(
viewModel: SeedPhraseInputViewModel viewModel: SeedPhraseInputViewModel
...@@ -62,15 +59,9 @@ fun SeedPhraseInput( ...@@ -62,15 +59,9 @@ fun SeedPhraseInput(
val focusRequester = remember { FocusRequester() } val focusRequester = remember { FocusRequester() }
val density = LocalDensity.current.density val density = LocalDensity.current.density
var buttonOffset by remember { mutableStateOf(20.dp) } var buttonOffset by remember { mutableStateOf(20.dp) }
val keyboardController = LocalSoftwareKeyboardController.current
LaunchedEffect(viewModel.isFocused) { LaunchedEffect(Unit) {
if (viewModel.isFocused) { focusRequester.requestFocus()
focusRequester.requestFocus()
} else {
focusRequester.freeFocus()
keyboardController?.hide()
}
} }
Column( Column(
......
...@@ -122,15 +122,7 @@ class SeedPhraseInputViewManager : ViewGroupManager<ComposeView>() { ...@@ -122,15 +122,7 @@ class SeedPhraseInputViewManager : ViewGroupManager<ComposeView>() {
override fun receiveCommand(root: ComposeView, commandId: String?, args: ReadableArray?) { override fun receiveCommand(root: ComposeView, commandId: String?, args: ReadableArray?) {
super.receiveCommand(root, commandId, args) super.receiveCommand(root, commandId, args)
when (commandId) { when (commandId) {
COMMAND_HANDLE_SUBMIT -> { COMMAND_HANDLE_SUBMIT -> viewModel.handleSubmit()
viewModel.handleSubmit()
}
COMMAND_FOCUS -> {
viewModel.focus()
}
COMMAND_BLUR -> {
viewModel.blur()
}
else -> Unit else -> Unit
} }
} }
...@@ -158,8 +150,6 @@ class SeedPhraseInputViewManager : ViewGroupManager<ComposeView>() { ...@@ -158,8 +150,6 @@ class SeedPhraseInputViewManager : ViewGroupManager<ComposeView>() {
private const val EVENT_MNEMONIC_STORED = "onMnemonicStored" private const val EVENT_MNEMONIC_STORED = "onMnemonicStored"
private const val EVENT_HEIGHT_MEASURED = "onHeightMeasured" private const val EVENT_HEIGHT_MEASURED = "onHeightMeasured"
private const val COMMAND_HANDLE_SUBMIT = "handleSubmit" private const val COMMAND_HANDLE_SUBMIT = "handleSubmit"
private const val COMMAND_FOCUS = "focus"
private const val COMMAND_BLUR = "blur"
private const val FIELD_MNEMONIC_ID = "mnemonicId" private const val FIELD_MNEMONIC_ID = "mnemonicId"
private const val FIELD_CAN_SUBMIT = "canSubmit" private const val FIELD_CAN_SUBMIT = "canSubmit"
private const val FIELD_HEIGHT = "height" private const val FIELD_HEIGHT = "height"
......
...@@ -13,9 +13,6 @@ import kotlinx.coroutines.Dispatchers ...@@ -13,9 +13,6 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import android.content.Context
import android.view.inputmethod.InputMethodManager
import android.view.View
class SeedPhraseInputViewModel( class SeedPhraseInputViewModel(
private val ethersRs: RnEthersRs, private val ethersRs: RnEthersRs,
...@@ -66,17 +63,6 @@ class SeedPhraseInputViewModel( ...@@ -66,17 +63,6 @@ class SeedPhraseInputViewModel(
private var validateLastWordTimeout: Long = 1000 private var validateLastWordTimeout: Long = 1000
private var validateLastWordJob: Job? = null private var validateLastWordJob: Job? = null
var isFocused by mutableStateOf(false)
private set
fun focus() {
isFocused = true
}
fun blur() {
isFocused = false
}
fun handleInputChange(value: TextFieldValue) { fun handleInputChange(value: TextFieldValue) {
input = value input = value
...@@ -168,5 +154,4 @@ class SeedPhraseInputViewModel( ...@@ -168,5 +154,4 @@ class SeedPhraseInputViewModel(
private const val MIN_LENGTH = 12 private const val MIN_LENGTH = 12
private const val MAX_LENGTH = 24 private const val MAX_LENGTH = 24
} }
} }
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/splashscreen_background" /> <item android:drawable="@color/splashscreen_background"/>
<item <item>
android:drawable="@drawable/uniswap_logo" <bitmap android:gravity="center" android:src="@drawable/ic_launcher_foreground" />
android:width="150dp" </item>
android:height="150dp"
android:gravity="center" />
</layer-list> </layer-list>
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item <item>
android:width="110dp" <inset
android:height="110dp" android:drawable="@drawable/ic_launcher_foreground"
android:gravity="center"> android:insetLeft="25%"
<inset android:insetTop="25%"
android:insetLeft="15%" android:insetRight="25%"
android:insetTop="15%" android:insetBottom="25%" />
android:insetRight="15%" </item>
android:insetBottom="15%"
android:drawable="@drawable/splash_logo"
/>
</item>
</layer-list> </layer-list>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="1024dp"
android:height="1024dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M808.1,154.8C809.5,130.6 812.8,114.6 819.4,100C822,94.3 824.5,89.5 824.9,89.5C825.2,89.5 824.1,93.8 822.3,99C817.5,113.2 816.7,132.5 820,155C824.2,183.6 826.6,187.7 857,218.6C871.2,233 887.7,251.3 893.7,259.1L904.6,273.4L893.7,263.2C880.4,250.8 849.7,226.5 843,223C838.4,220.7 837.7,220.7 834.9,223.5C832.3,226 831.8,229.9 831.4,248.1C830.9,276.4 827,294.6 817.6,312.8C812.6,322.6 811.8,320.5 816.4,309.4C819.8,301.1 820.1,297.5 820.1,270C820.1,214.9 813.5,201.7 775,179C765.2,173.2 749.1,164.9 739.2,160.6C729.3,156.2 721.5,152.4 721.7,152.1C722.8,151 760.4,161.9 775.5,167.7C798,176.3 801.7,177.4 804.5,176.4C806.3,175.7 807.2,170.4 808.1,154.8Z"
android:fillColor="#F50DB4"/>
<path
android:pathData="M332.7,74.6C319.4,72.6 318.8,72.3 325.1,71.4C337.1,69.5 365.5,72 385.1,76.6C430.8,87.4 472.5,115.1 516.9,164.3L528.7,177.3L545.5,174.6C616.7,163.3 689,172.3 749.5,200.1C766.1,207.7 792.4,222.9 795.7,226.8C796.7,228.1 798.6,236.1 799.9,244.6C804.4,274.2 802.2,296.9 793.1,313.9C788.1,323.1 787.8,326 791.2,333.9C793.8,340.2 801.2,344.9 808.6,344.9C823.6,344.9 839.8,320.7 847.3,287.1L850.3,273.7L856.2,280.4C888.6,316.8 914,366.5 918.3,401.9L919.5,411.1L914,402.7C904.7,388.3 895.3,378.5 883.2,370.6C861.5,356.3 838.5,351.4 777.7,348.2C722.8,345.4 691.7,340.7 660.9,330.7C608.5,313.7 582,291.1 519.7,209.9C492.1,173.8 475,153.9 458,137.8C419.3,101.3 381.3,82.1 332.7,74.6Z"
android:fillColor="#F50DB4"/>
<path
android:pathData="M358.6,249.3C331.5,212.2 314.8,155.4 318.4,112.9L319.5,99.8L325.7,100.9C337.3,103 357.2,110.4 366.6,116C392.3,131.5 403.4,151.9 414.7,204.2C418,219.6 422.3,236.9 424.3,242.8C427.5,252.3 439.7,274.4 449.6,288.7C456.7,299 452,303.9 436.2,302.5C412.2,300.4 379.6,278 358.6,249.3Z"
android:fillColor="#F50DB4"/>
<path
android:pathData="M775.2,525.2C648.6,474.5 604,430.5 604,356.3C604,345.4 604.3,336.5 604.8,336.5C605.3,336.5 610.2,340.1 615.7,344.5C641.4,365 670.1,373.7 749.7,385.2C796.6,392 822.9,397.5 847.2,405.5C924.5,431 972.3,482.7 983.8,553.1C987.1,573.6 985.1,611.9 979.8,632.1C975.5,648.1 962.6,676.9 959.1,678C958.2,678.3 957.2,674.7 957,669.8C955.7,643.3 942.3,617.6 919.7,598.3C894,576.4 859.5,558.9 775.2,525.2Z"
android:fillColor="#F50DB4"/>
<path
android:pathData="M686.3,546.2C684.7,536.9 682,524.9 680.2,519.6L676.9,510L682.9,516.7C691.3,526 697.8,537.9 703.4,553.6C707.6,565.7 708.1,569.3 708.1,588.9C708,608.1 707.5,612.1 703.6,623C697.4,640.1 689.7,652.2 676.9,665.2C653.7,688.6 624,701.5 581.1,706.9C573.6,707.9 551.9,709.4 532.8,710.4C484.6,712.9 452.9,718 424.4,728C420.3,729.4 416.6,730.3 416.3,729.9C415.1,728.8 434.5,717.3 450.5,709.6C473.1,698.8 495.6,692.9 546,684.6C570.9,680.4 596.6,675.5 603.1,673.5C664.8,654.7 696.4,606.2 686.3,546.2Z"
android:fillColor="#F50DB4"/>
<path
android:pathData="M744.3,648.7C727.5,612.7 723.7,578 732.9,545.7C733.9,542.2 735.4,539.4 736.4,539.4C737.3,539.4 741.3,541.5 745.2,544.1C753,549.3 768.5,558.1 809.9,580.5C861.6,608.5 891.1,630.2 911.2,655C928.7,676.7 939.6,701.4 944.8,731.5C947.8,748.6 946,789.7 941.6,806.8C927.7,861 895.4,903.6 849.3,928.5C842.6,932.1 836.5,935.1 835.9,935.1C835.2,935.1 837.7,928.9 841.3,921.3C856.8,889.1 858.6,857.8 846.9,822.9C839.7,801.6 825.1,775.5 795.5,731.5C761.2,680.3 752.8,666.7 744.3,648.7Z"
android:fillColor="#F50DB4"/>
<path
android:pathData="M268.7,842.6C315.7,803.2 374.2,775.2 427.4,766.6C450.4,762.9 488.6,764.3 509.9,769.7C543.9,778.4 574.4,797.8 590.3,820.9C605.8,843.5 612.4,863.2 619.3,907C622.1,924.3 625,941.7 625.9,945.6C631.1,968.3 641.2,986.4 653.8,995.6C673.7,1010 707.9,1010.9 741.6,997.9C747.4,995.7 752.3,994.1 752.7,994.5C753.9,995.7 736.9,1007 724.9,1012.9C708.8,1020.9 696,1024 679,1024C648.1,1024 622.5,1008.4 601.1,976.6C596.9,970.3 587.4,951.5 580.1,934.9C557.5,883.7 546.3,868.1 520.1,851C497.3,836.2 467.9,833.5 445.7,844.3C416.6,858.5 408.5,895.4 429.4,918.8C437.6,928.1 453.1,936.1 465.7,937.7C489.3,940.6 509.6,922.8 509.6,899.1C509.6,883.7 503.7,874.9 488.7,868.2C468.2,859 446.2,869.7 446.3,888.8C446.4,897 449.9,902.1 458.2,905.8C463.4,908.2 463.6,908.4 459.3,907.5C440.5,903.6 436.1,881.1 451.2,866.2C469.3,848.3 506.8,856.2 519.6,880.6C525,890.9 525.7,911.4 521,923.7C510.4,951.4 479.7,965.9 448.5,958C427.2,952.6 418.6,946.8 393,920.6C348.4,875 331.2,866.2 267,856.2L254.7,854.3L268.7,842.6Z"
android:fillColor="#F50DB4"/>
<path
android:pathData="M59.9,27.2C208.5,206.5 310.9,280.5 322.3,296.1C331.6,309 328.1,320.6 312,329.7C303.1,334.7 284.7,339.8 275.5,339.8C265,339.8 261.5,335.9 261.5,335.9C255.4,330.2 252,331.2 221,276.4C177.9,210 141.9,155 140.9,154C138.6,151.9 138.7,152 216.6,290.5C229.2,319.4 219.1,330 219.1,334.1C219.1,342.5 216.8,346.9 206.4,358.4C189.1,377.6 181.4,399.2 175.8,443.8C169.5,493.9 151.9,529.2 103.1,589.7C74.5,625.1 69.8,631.6 62.6,645.9C53.6,663.8 51.1,673.9 50,696.6C49,720.6 51.1,736.1 58.4,759.1C64.9,779.1 71.6,792.4 88.9,818.9C103.8,841.8 112.3,858.8 112.3,865.5C112.3,870.8 113.3,870.8 136.4,865.6C191.5,853.3 236.3,831.5 261.5,804.8C277.1,788.3 280.8,779.2 280.9,756.5C281,741.7 280.4,738.6 276.4,730.1C269.9,716.3 257.9,704.7 231.6,686.9C197.2,663.5 182.5,644.6 178.4,618.7C175.1,597.4 178.9,582.4 198,542.7C217.7,501.7 222.6,484.1 225.9,442.7C228.1,416 231,405.4 238.8,396.9C246.8,388.1 254.1,385.1 274.1,382.4C306.6,378 327.3,369.6 344.4,354C359.2,340.5 365.4,327.4 366.3,307.8L367,292.9L358.8,283.3C328.9,248.7 39.9,0 38,0C37.6,0 47.5,12.3 59.9,27.2ZM129.1,723.8C135.9,711.9 132.3,696.6 121,689.1C110.3,682 93.7,685.3 93.7,694.6C93.7,697.4 95.2,699.4 98.8,701.2C104.7,704.2 105.1,707.7 100.4,714.6C95.7,721.7 96.1,727.9 101.5,732.1C110.3,738.9 122.6,735.2 129.1,723.8Z"
android:fillColor="#F50DB4"
android:fillType="evenOdd"/>
<path
android:pathData="M387.6,390.2C372.3,394.9 357.4,411 352.8,427.8C350,438.1 351.6,456.2 355.8,461.8C362.6,470.8 369.2,473.2 387,473C421.8,472.8 452,458 455.5,439.4C458.4,424.2 445.1,403.2 426.8,393.9C417.4,389.1 397.3,387.2 387.6,390.2ZM428.3,421.8C433.6,414.2 431.3,406 422.2,400.5C404.8,390 378.5,398.7 378.5,415C378.5,423.1 392.2,432 404.8,432C413.1,432 424.6,427 428.3,421.8Z"
android:fillColor="#F50DB4"
android:fillType="evenOdd"/>
</vector>
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/> <background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/> <foreground>
<inset android:drawable="@drawable/ic_launcher_foreground"
android:inset="25%"/>
</foreground>
</adaptive-icon> </adaptive-icon>
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
\ No newline at end of file
<resources> <resources>
<color name="splashscreen_background">#131313</color> <color name="splashscreen_background">#000000</color>
<color name="item_background">#303030</color> <color name="item_background">#303030</color>
<color name="text_primary">#ffffff</color> <color name="text_primary">#ffffff</color>
</resources> </resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#FEF4FF</color>
</resources>
...@@ -4,11 +4,7 @@ const inProduction = NODE_ENV === 'production' ...@@ -4,11 +4,7 @@ const inProduction = NODE_ENV === 'production'
module.exports = function (api) { module.exports = function (api) {
api.cache.using(() => process.env.NODE_ENV) api.cache.using(() => process.env.NODE_ENV)
var plugins = [
let plugins = inProduction ? ['transform-remove-console'] : []
plugins = [
...plugins,
// disable for now as its causing ci to hang // disable for now as its causing ci to hang
// process.env.NODE_ENV === 'test' // process.env.NODE_ENV === 'test'
// ? null // ? null
...@@ -37,23 +33,26 @@ module.exports = function (api) { ...@@ -37,23 +33,26 @@ module.exports = function (api) {
allowUndefined: false, allowUndefined: false,
}, },
], ],
'transform-inline-environment-variables',
// TypeScript compiles this, but in production builds, metro doesn't use tsc
'@babel/plugin-proposal-logical-assignment-operators',
// metro doesn't like these
'@babel/plugin-proposal-numeric-separator',
// https://github.com/software-mansion/react-native-reanimated/issues/3364#issuecomment-1268591867 // https://github.com/software-mansion/react-native-reanimated/issues/3364#issuecomment-1268591867
'@babel/plugin-proposal-export-namespace-from', '@babel/plugin-proposal-export-namespace-from',
// 'react-native-reanimated/plugin' must be listed last
// https://arc.net/l/quote/plrvpkad
[ [
'react-native-reanimated/plugin', 'react-native-reanimated/plugin',
{ {
globals: ['__scanCodes', '__scanOCR'], globals: ['__scanCodes', '__scanOCR'],
}, },
], ],
'transform-inline-environment-variables',
// TypeScript compiles this, but in production builds, metro doesn't use tsc
'@babel/plugin-proposal-logical-assignment-operators',
// metro doesn't like these
'@babel/plugin-proposal-numeric-separator',
].filter(Boolean) ].filter(Boolean)
if (inProduction) {
// Remove all console statements in production
plugins = [...plugins, 'transform-remove-console']
}
return { return {
ignore: [ ignore: [
// speeds up compile // speeds up compile
......
...@@ -2,21 +2,14 @@ ...@@ -2,21 +2,14 @@
require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking") require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking")
require_relative '../../../node_modules/react-native/scripts/react_native_pods' require_relative '../../../node_modules/react-native/scripts/react_native_pods'
require_relative '../../../node_modules/@react-native-community/cli-platform-ios/native_modules' require_relative '../../../node_modules/@react-native-community/cli-platform-ios/native_modules'
require_relative '../../../node_modules/react-native-permissions/scripts/setup'
platform :ios, '15.0' platform :ios, '15.0'
prepare_react_native_project! prepare_react_native_project!
setup_permissions([ $FirebaseSDKVersion = '10.15.0'
'FaceID',
'Notifications',
])
$RNFirebaseAsStaticFramework = true
$RNFirebaseAnalyticsWithoutAdIdSupport=true $RNFirebaseAnalyticsWithoutAdIdSupport=true
target 'Uniswap' do target 'Uniswap' do
use_frameworks! :linkage => :static
use_expo_modules! use_expo_modules!
post_integrate do |installer| post_integrate do |installer|
begin begin
...@@ -45,6 +38,12 @@ target 'Uniswap' do ...@@ -45,6 +38,12 @@ target 'Uniswap' do
pod 'EthersRS', :path => '../../../node_modules/@uniswap/ethers-rs-mobile' pod 'EthersRS', :path => '../../../node_modules/@uniswap/ethers-rs-mobile'
pod 'Argon2Swift', '1.0.3' pod 'Argon2Swift', '1.0.3'
permissions_path = '../../../node_modules/react-native-permissions/ios'
pod 'Permission-FaceID', :path => "#{permissions_path}/FaceID"
pod 'Permission-Notifications', :path => "#{permissions_path}/Notifications"
pod 'FirebaseCore', $FirebaseSDKVersion, :modular_headers => true
pod 'GoogleUtilities', '7.11.5', :modular_headers => true
post_install do |installer| post_install do |installer|
react_native_post_install(installer, "../../../node_modules/react-native") react_native_post_install(installer, "../../../node_modules/react-native")
...@@ -58,30 +57,27 @@ target 'Uniswap' do ...@@ -58,30 +57,27 @@ target 'Uniswap' do
end end
target 'OneSignalNotificationServiceExtension' do target 'OneSignalNotificationServiceExtension' do
use_frameworks! :linkage => :static
pod 'OneSignalXCFramework', '3.12.6' pod 'OneSignalXCFramework', '3.12.6'
end end
def prepare_target_commons def widget_pods
use_frameworks! :linkage => :static
pod 'Apollo', '1.2.1' pod 'Apollo', '1.2.1'
pod 'UIImageColors', '2.1.0' pod 'UIImageColors', '2.1.0'
end end
target 'Widgets' do target 'Widgets' do
prepare_target_commons widget_pods
# Pods for widgets # Pods for widgets
end end
target 'WidgetsCore' do target 'WidgetsCore' do
prepare_target_commons widget_pods
# Pods for widgets core # Pods for widgets core
end end
target 'WidgetsCoreTests' do target 'WidgetsCoreTests' do
prepare_target_commons widget_pods
# Pods for widgets core test # Pods for widgets core test
end end
target 'WidgetIntentExtension' do target 'WidgetIntentExtension' do
prepare_target_commons widget_pods
# Pods for intent extension # Pods for intent extension
end end
This diff is collapsed.
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#import <React/RCTBundleURLProvider.h> #import <React/RCTBundleURLProvider.h>
#import <ReactNativePerformance/ReactNativePerformance.h> #import <ReactNativePerformance/ReactNativePerformance.h>
#import <RCTAppSetupUtils.h> #import <RCTAppSetupUtils.h>
#import "RNSplashScreen.h"
@implementation AppDelegate @implementation AppDelegate
...@@ -47,6 +48,8 @@ ...@@ -47,6 +48,8 @@
[super application:application didFinishLaunchingWithOptions:newLaunchOptions]; [super application:application didFinishLaunchingWithOptions:newLaunchOptions];
[RNSplashScreen show];
[[RCTI18nUtil sharedInstance] allowRTL:NO]; [[RCTI18nUtil sharedInstance] allowRTL:NO];
return YES; return YES;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment