Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
I
interface
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
LuckySwap
interface
Commits
e3a712f2
Commit
e3a712f2
authored
Aug 08, 2024
by
Uniswap Labs Service Account
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ci(release): publish latest release
parent
48a0bb2c
Changes
28
Hide whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
223 additions
and
490 deletions
+223
-490
RELEASE
RELEASE
+7
-2
VERSION
VERSION
+1
-1
PopupApp.tsx
apps/extension/src/app/PopupApp.tsx
+0
-149
utils.ts
apps/extension/src/app/navigation/utils.ts
+1
-39
sentry.ts
apps/extension/src/app/sentry.ts
+0
-1
chromeSidePanelUtils.ts
apps/extension/src/background/utils/chromeSidePanelUtils.ts
+0
-5
manifest.json
apps/extension/src/manifest.json
+1
-1
popup.html
apps/extension/src/popup.html
+0
-68
popup.tsx
apps/extension/src/popup/popup.tsx
+0
-45
store.ts
apps/extension/src/store/store.ts
+1
-7
webpack.config.js
apps/extension/webpack.config.js
+0
-1
App.tsx
apps/mobile/src/app/App.tsx
+53
-54
AccountSwitcherModal.tsx
apps/mobile/src/app/modals/AccountSwitcherModal.tsx
+3
-1
AccountSwitcherModal.test.tsx.snap
...p/modals/__snapshots__/AccountSwitcherModal.test.tsx.snap
+44
-38
AccountList.tsx
apps/mobile/src/components/accounts/AccountList.tsx
+55
-23
AccountList.test.tsx.snap
...mponents/accounts/__snapshots__/AccountList.test.tsx.snap
+49
-29
TokenDetailsScreen.tsx
apps/mobile/src/screens/TokenDetailsScreen.tsx
+1
-1
index.ts
packages/ui/src/assets/index.ts
+0
-1
chrome-logo.png
packages/ui/src/assets/logos/png/chrome-logo.png
+0
-0
fonts.ts
packages/ui/src/theme/fonts.ts
+3
-4
BottomSheetModal.native.tsx
...uniswap/src/components/modals/BottomSheetModal.native.tsx
+1
-3
trace.ts
packages/uniswap/src/features/telemetry/constants/trace.ts
+0
-1
en-US.json
packages/uniswap/src/i18n/locales/source/en-US.json
+0
-3
es-ES.json
packages/uniswap/src/i18n/locales/translations/es-ES.json
+0
-3
fr-FR.json
packages/uniswap/src/i18n/locales/translations/fr-FR.json
+0
-3
extension.ts
packages/uniswap/src/types/screens/extension.ts
+0
-1
LandingBackground.tsx
packages/wallet/src/components/landing/LandingBackground.tsx
+2
-2
saga.ts
packages/wallet/src/features/language/saga.ts
+1
-4
No files found.
RELEASE
View file @
e3a712f2
- Onboarding improvements
- Adds fallback support method for opening the side panel on chrome failure
Here are the latest updates:
Native Asset Top Up: Easily access our fiat on ramp feature if you don’t have enough native asset on a network to complete a transaction.
Other changes:
- Various bug fixes and performance improvements
- Improved gas estimation for Send transactions
VERSION
View file @
e3a712f2
extension/1.2.1
\ No newline at end of file
mobile/1.32
\ No newline at end of file
apps/extension/src/app/PopupApp.tsx
deleted
100644 → 0
View file @
48a0bb2c
import
'
@tamagui/core/reset.css
'
import
'
src/app/Global.css
'
import
{
useEffect
}
from
'
react
'
import
{
I18nextProvider
,
useTranslation
}
from
'
react-i18next
'
import
{
useDispatch
}
from
'
react-redux
'
import
{
RouterProvider
}
from
'
react-router-dom
'
import
{
PersistGate
}
from
'
redux-persist/integration/react
'
import
{
ExtensionStatsigProvider
}
from
'
src/app/StatsigProvider
'
import
{
GraphqlProvider
}
from
'
src/app/apollo
'
import
{
ErrorElement
}
from
'
src/app/components/ErrorElement
'
import
{
TraceUserProperties
}
from
'
src/app/components/Trace/TraceUserProperties
'
import
{
DappContextProvider
}
from
'
src/app/features/dapp/DappContext
'
import
{
SentryAppNameTag
,
initializeSentry
,
sentryCreateHashRouter
}
from
'
src/app/sentry
'
import
{
initExtensionAnalytics
}
from
'
src/app/utils/analytics
'
import
{
getLocalUserId
}
from
'
src/app/utils/storage
'
import
{
getReduxPersistor
,
getReduxStore
}
from
'
src/store/store
'
import
{
Button
,
Flex
,
Image
,
Text
}
from
'
ui/src
'
import
{
CHROME_LOGO
,
UNISWAP_LOGO
}
from
'
ui/src/assets
'
import
{
iconSizes
,
spacing
}
from
'
ui/src/theme
'
import
Trace
from
'
uniswap/src/features/telemetry/Trace
'
import
{
ElementName
}
from
'
uniswap/src/features/telemetry/constants
'
import
{
UnitagUpdaterContextProvider
}
from
'
uniswap/src/features/unitags/context
'
import
i18n
from
'
uniswap/src/i18n/i18n
'
import
{
ExtensionScreens
}
from
'
uniswap/src/types/screens/extension
'
import
{
logger
}
from
'
utilities/src/logger/logger
'
import
{
ErrorBoundary
}
from
'
wallet/src/components/ErrorBoundary/ErrorBoundary
'
import
{
LocalizationContextProvider
}
from
'
wallet/src/features/language/LocalizationContext
'
import
{
syncAppWithDeviceLanguage
}
from
'
wallet/src/features/language/slice
'
import
{
SharedProvider
}
from
'
wallet/src/provider
'
getLocalUserId
()
.
then
((
userId
)
=>
{
initializeSentry
(
SentryAppNameTag
.
Popup
,
userId
)
})
.
catch
((
error
)
=>
{
logger
.
error
(
error
,
{
tags
:
{
file
:
'
PopupApp.tsx
'
,
function
:
'
getLocalUserId
'
},
})
})
const
router
=
sentryCreateHashRouter
([
{
path
:
''
,
element
:
<
PopupContent
/>,
errorElement
:
<
ErrorElement
/>,
},
])
function
PopupContent
():
JSX
.
Element
{
const
{
t
}
=
useTranslation
()
const
dispatch
=
useDispatch
()
useEffect
(()
=>
{
dispatch
(
syncAppWithDeviceLanguage
())
},
[
dispatch
])
const
searchParams
=
new
URLSearchParams
(
window
.
location
.
search
)
const
tabId
=
searchParams
.
get
(
'
tabId
'
)
const
windowId
=
searchParams
.
get
(
'
windowId
'
)
const
tabIdNumber
=
tabId
?
Number
(
tabId
)
:
undefined
const
windowIdNumber
=
windowId
?
Number
(
windowId
)
:
undefined
return
(
<
Trace
logImpression
screen=
{
ExtensionScreens
.
PopupOpenExtension
}
>
<
Flex
fill
gap=
"$spacing16"
height=
"100%"
px=
"$spacing24"
py=
"$spacing24"
>
<
Flex
row
>
<
Flex
position=
"relative"
>
<
Image
height=
{
iconSizes
.
icon40
}
source=
{
UNISWAP_LOGO
}
width=
{
iconSizes
.
icon40
}
/>
<
Flex
backgroundColor=
"$surface1"
borderColor=
"$surface3"
borderRadius=
{
6
}
borderWidth=
{
1
}
bottom=
{
-
spacing
.
spacing4
}
p=
"$spacing2"
position=
"absolute"
right=
{
-
spacing
.
spacing4
}
>
<
Image
height=
{
iconSizes
.
icon12
}
source=
{
CHROME_LOGO
}
width=
{
iconSizes
.
icon12
}
/>
</
Flex
>
</
Flex
>
</
Flex
>
<
Flex
gap=
"$spacing4"
>
<
Text
color=
"$neutral1"
variant=
"subheading1"
>
{
t
(
'
extension.popup.chrome.title
'
)
}
</
Text
>
<
Text
color=
"$neutral2"
variant=
"body2"
>
{
t
(
'
extension.popup.chrome.description
'
)
}
</
Text
>
</
Flex
>
<
Flex
fill
/>
<
Trace
logPress
element=
{
ElementName
.
ExtensionPopupOpenButton
}
>
<
Button
theme=
"primary"
width=
"100%"
onPress=
{
async
()
=>
{
if
(
windowIdNumber
)
{
// eslint-disable-next-line security/detect-non-literal-fs-filename
await
chrome
.
sidePanel
.
open
({
tabId
:
tabIdNumber
,
windowId
:
windowIdNumber
})
window
.
close
()
}
}
}
>
{
t
(
'
extension.popup.chrome.button
'
)
}
</
Button
>
</
Trace
>
</
Flex
>
</
Trace
>
)
}
// TODO WALL-4313 - Backup for some broken chrome.sidePanel.open functionality
// Consider removing this once the issue is resolved or leaving as fallback
export
default
function
PopupApp
():
JSX
.
Element
{
// initialize analytics on load
useEffect
(()
=>
{
initExtensionAnalytics
().
catch
(()
=>
undefined
)
},
[])
return
(
<
Trace
>
<
PersistGate
persistor=
{
getReduxPersistor
()
}
>
<
ExtensionStatsigProvider
>
<
I18nextProvider
i18n=
{
i18n
}
>
<
SharedProvider
reduxStore=
{
getReduxStore
()
}
>
<
ErrorBoundary
>
<
GraphqlProvider
>
<
LocalizationContextProvider
>
<
UnitagUpdaterContextProvider
>
<
TraceUserProperties
/>
<
DappContextProvider
>
<
RouterProvider
router=
{
router
}
/>
</
DappContextProvider
>
</
UnitagUpdaterContextProvider
>
</
LocalizationContextProvider
>
</
GraphqlProvider
>
</
ErrorBoundary
>
</
SharedProvider
>
</
I18nextProvider
>
</
ExtensionStatsigProvider
>
</
PersistGate
>
</
Trace
>
)
}
apps/extension/src/app/navigation/utils.ts
View file @
e3a712f2
...
...
@@ -36,7 +36,7 @@ export const useExtensionNavigation = (): {
export
async
function
focusOrCreateOnboardingTab
(
page
?:
string
):
Promise
<
void
>
{
const
extension
=
await
chrome
.
management
.
getSelf
()
const
tabs
=
await
chrome
.
tabs
.
query
({
url
:
`chrome-extension://
${
extension
.
id
}
/
onboarding.html
*`
})
const
tabs
=
await
chrome
.
tabs
.
query
({
url
:
`chrome-extension://
${
extension
.
id
}
/*`
})
const
tab
=
tabs
[
0
]
const
url
=
'
onboarding.html#/
'
+
(
page
?
page
:
TopLevelRoutes
.
Onboarding
)
...
...
@@ -68,44 +68,6 @@ export async function focusOrCreateOnboardingTab(page?: string): Promise<void> {
})
}
export
async
function
focusOrCreateDappRequestWindow
(
tabId
:
number
|
undefined
,
windowId
:
number
):
Promise
<
void
>
{
const
extension
=
await
chrome
.
management
.
getSelf
()
const
window
=
await
chrome
.
windows
.
getCurrent
()
const
tabs
=
await
chrome
.
tabs
.
query
({
url
:
`chrome-extension://
${
extension
.
id
}
/popup.html*`
})
const
tab
=
tabs
[
0
]
// Centering within current window
const
height
=
410
const
width
=
330
const
top
=
Math
.
round
((
window
.
top
??
0
)
+
((
window
.
height
??
height
)
-
height
)
/
2
)
const
left
=
Math
.
round
((
window
.
left
??
0
)
+
((
window
.
width
??
width
)
-
width
)
/
2
)
let
url
=
`popup.html?windowId=
${
windowId
}
`
if
(
tabId
)
{
url
+=
`&tabId=
${
tabId
}
`
}
if
(
!
tab
?.
id
)
{
await
chrome
.
windows
.
create
({
url
,
type
:
'
popup
'
,
top
,
left
,
width
,
height
,
})
return
}
await
chrome
.
tabs
.
update
(
tab
.
id
,
{
url
,
active
:
true
,
highlighted
:
true
,
})
await
chrome
.
windows
.
update
(
tab
.
windowId
,
{
focused
:
true
,
top
,
left
,
width
,
height
})
}
/**
* To avoid opening too many tabs while also ensuring that we don't take over the user's active tab,
* we only update the URL of the active tab if it's already in a specific route of the Uniswap interface.
...
...
apps/extension/src/app/sentry.ts
View file @
e3a712f2
...
...
@@ -19,7 +19,6 @@ export const enum SentryAppNameTag {
Onboarding
=
'
onboarding
'
,
ContentScript
=
'
content-script
'
,
Background
=
'
background
'
,
Popup
=
'
popup
'
,
}
export
function
initializeSentry
(
appNameTag
:
SentryAppNameTag
,
sentryUserId
:
string
):
void
{
...
...
apps/extension/src/background/utils/chromeSidePanelUtils.ts
View file @
e3a712f2
import
{
focusOrCreateDappRequestWindow
}
from
'
src/app/navigation/utils
'
import
{
logger
}
from
'
utilities/src/logger/logger
'
export
async
function
openSidePanel
(
tabId
:
number
|
undefined
,
windowId
:
number
):
Promise
<
void
>
{
...
...
@@ -9,10 +8,6 @@ export async function openSidePanel(tabId: number | undefined, windowId: number)
windowId
,
})
}
catch
(
error
)
{
// TODO WALL-4313 - Backup for some broken chrome.sidePanel.open functionality
// Consider removing this once the issue is resolved or leaving as fallback
await
focusOrCreateDappRequestWindow
(
tabId
,
windowId
)
logger
.
error
(
error
,
{
tags
:
{
file
:
'
background/background.ts
'
,
...
...
apps/extension/src/manifest.json
View file @
e3a712f2
...
...
@@ -2,7 +2,7 @@
"manifest_version"
:
3
,
"name"
:
"Uniswap Extension"
,
"description"
:
"The Uniswap Extension is a self-custody crypto wallet that's built for swapping."
,
"version"
:
"1.2.
1
"
,
"version"
:
"1.2.
0
"
,
"minimum_chrome_version"
:
"116"
,
"icons"
:
{
"16"
:
"assets/icon16.png"
,
...
...
apps/extension/src/popup.html
deleted
100644 → 0
View file @
48a0bb2c
<!DOCTYPE html>
<html
lang=
"en"
>
<head>
<meta
charset=
"UTF-8"
/>
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
/>
<link
rel=
"preload"
href=
"assets/fonts/Basel-Book.woff"
as=
"font"
type=
"font/woff"
crossorigin
/>
<link
rel=
"preload"
href=
"assets/fonts/Basel-Medium.woff"
as=
"font"
type=
"font/woff"
crossorigin
/>
<style>
html
,
body
,
#popup-root
{
min-height
:
100%
;
}
*
{
font-family
:
'Basel'
,
sans-serif
;
box-sizing
:
border-box
;
}
/**
Explicitly load Basel var from public/ so it does not block LCP's critical path.
*/
@font-face
{
font-family
:
'Basel'
;
font-weight
:
500
;
font-style
:
normal
;
font-display
:
block
;
font-named-instance
:
'Medium'
;
src
:
url(assets/fonts/Basel-Medium.woff)
format
(
'woff'
);
}
@font-face
{
font-family
:
'Basel'
;
font-weight
:
400
;
font-style
:
normal
;
font-display
:
block
;
font-named-instance
:
'Book'
;
src
:
url(assets/fonts/Basel-Book.woff)
format
(
'woff'
);
}
@supports
(
font-variation-settings
:
normal
)
{
*
{
font-family
:
'Basel'
,
sans-serif
;
}
}
html
{
font-variant
:
none
;
font-smooth
:
always
;
text-rendering
:
optimizeLegibility
;
-webkit-font-smoothing
:
antialiased
;
}
</style>
<title>
Uniswap Extension
</title>
</head>
<body>
<div
id=
"popup-root"
></div>
<script
type=
"module"
src=
"popup.js"
></script>
</body>
</html>
apps/extension/src/popup/popup.tsx
deleted
100644 → 0
View file @
48a0bb2c
// eslint-disable-next-line @typescript-eslint/triple-slash-reference
/// <reference path="../../../../index.d.ts" />
import
{
createRoot
}
from
'
react-dom/client
'
import
{
OptionalStrictMode
}
from
'
src/app/components/OptionalStrictMode
'
import
PopupApp
from
'
src/app/PopupApp
'
import
{
initializeSentry
,
SentryAppNameTag
}
from
'
src/app/sentry
'
import
{
getLocalUserId
}
from
'
src/app/utils/storage
'
import
{
initializeReduxStore
}
from
'
src/store/store
'
import
{
logger
}
from
'
utilities/src/logger/logger
'
;(
globalThis
as
any
).
regeneratorRuntime
=
undefined
// eslint-disable-line @typescript-eslint/no-explicit-any
// The globalThis.regeneratorRuntime = undefined addresses a potentially unsafe-eval problem
// see https://github.com/facebook/regenerator/issues/378#issuecomment-802628326
getLocalUserId
()
.
then
((
userId
)
=>
{
initializeSentry
(
SentryAppNameTag
.
Popup
,
userId
)
})
.
catch
((
error
)
=>
{
logger
.
error
(
error
,
{
tags
:
{
file
:
'
popup.tsx
'
,
function
:
'
getLocalUserId
'
},
})
})
async
function
initPopup
():
Promise
<
void
>
{
await
initializeReduxStore
({
readOnly
:
true
})
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const
container
=
document
.
getElementById
(
'
popup-root
'
)
!
const
root
=
createRoot
(
container
)
root
.
render
(
<
OptionalStrictMode
>
<
PopupApp
/>
</
OptionalStrictMode
>,
)
}
initPopup
().
catch
((
error
)
=>
{
logger
.
error
(
error
,
{
tags
:
{
file
:
'
popup.tsx
'
,
function
:
'
initPopup
'
,
},
})
})
apps/extension/src/store/store.ts
View file @
e3a712f2
...
...
@@ -58,7 +58,7 @@ const setupStore = (preloadedState?: PreloadedState<ExtensionState>): ReturnType
let
store
:
ReturnType
<
typeof
setupStore
>
|
undefined
let
persistor
:
ReturnType
<
typeof
persistStore
>
|
undefined
export
async
function
initializeReduxStore
(
args
?:
{
readOnly
?:
boolean
}
):
Promise
<
{
export
async
function
initializeReduxStore
():
Promise
<
{
store
:
ReturnType
<
typeof
setupStore
>
persistor
:
ReturnType
<
typeof
persistStore
>
}
>
{
...
...
@@ -69,12 +69,6 @@ export async function initializeReduxStore(args?: { readOnly?: boolean }): Promi
store
=
setupStore
(
oldStore
)
persistor
=
persistStore
(
store
)
if
(
args
?.
readOnly
)
{
// This means the store will be initialized with the persisted state from disk, but it won't persist any changes.
// Only useful for use cases where we don't want to modify the state (for example, a popup window instead of the sidebar).
persistor
.
pause
()
}
// We wait a few seconds to make sure the store is fully initialized and persisted before deleting the old storage.
// This is needed because otherwise the background script might think the user is not onboarded if it reads the storage while it's being migrated.
if
(
oldStore
)
{
...
...
apps/extension/webpack.config.js
View file @
e3a712f2
...
...
@@ -172,7 +172,6 @@ module.exports = (env) => {
sidebar
:
'
./src/sidebar/sidebar.tsx
'
,
injected
:
'
./src/contentScript/injected.ts
'
,
ethereum
:
'
./src/contentScript/ethereum.ts
'
,
popup
:
'
./src/popup/popup.tsx
'
,
},
output
:
{
filename
:
'
[name].js
'
,
...
...
apps/mobile/src/app/App.tsx
View file @
e3a712f2
...
...
@@ -93,8 +93,7 @@ if (!__DEV__ && !isDetoxBuild) {
environment
:
getSentryEnvironment
(),
dsn
:
config
.
sentryDsn
,
attachViewHierarchy
:
true
,
// DataDog would do this for us now
enableCaptureFailedRequests
:
false
,
enableCaptureFailedRequests
:
true
,
tracesSampleRate
:
getSentryTracesSamplingRate
(),
integrations
:
[
new
Sentry
.
ReactNativeTracing
({
...
...
@@ -175,26 +174,24 @@ function App(): JSX.Element | null {
return
(
<
StatsigProvider
{
...
statSigOptions
}
>
<
DatadogProviderWrapper
>
<
Trace
>
<
StrictMode
>
<
I18nextProvider
i18n=
{
i18n
}
>
<
SentryTags
>
<
SafeAreaProvider
>
<
SharedProvider
reduxStore=
{
store
}
>
<
AnalyticsNavigationContextProvider
shouldLogScreen=
{
shouldLogScreen
}
useIsPartOfNavigationTree=
{
useIsPartOfNavigationTree
}
>
<
AppOuter
/>
</
AnalyticsNavigationContextProvider
>
</
SharedProvider
>
</
SafeAreaProvider
>
</
SentryTags
>
</
I18nextProvider
>
</
StrictMode
>
</
Trace
>
</
DatadogProviderWrapper
>
<
Trace
>
<
StrictMode
>
<
I18nextProvider
i18n=
{
i18n
}
>
<
SentryTags
>
<
SafeAreaProvider
>
<
SharedProvider
reduxStore=
{
store
}
>
<
AnalyticsNavigationContextProvider
shouldLogScreen=
{
shouldLogScreen
}
useIsPartOfNavigationTree=
{
useIsPartOfNavigationTree
}
>
<
AppOuter
/>
</
AnalyticsNavigationContextProvider
>
</
SharedProvider
>
</
SafeAreaProvider
>
</
SentryTags
>
</
I18nextProvider
>
</
StrictMode
>
</
Trace
>
</
StatsigProvider
>
)
}
...
...
@@ -248,38 +245,40 @@ function AppOuter(): JSX.Element | null {
<
ApolloProvider
client=
{
client
}
>
<
PersistGate
loading=
{
null
}
persistor=
{
persistor
}
>
<
ErrorBoundary
>
<
LocalizationContextProvider
>
<
GestureHandlerRootView
style=
{
flexStyles
.
fill
}
>
<
WalletContextProvider
>
<
UnitagUpdaterContextProvider
>
<
BiometricContextProvider
>
<
LockScreenContextProvider
>
<
Sentry
.
TouchEventBoundary
>
<
DataUpdaters
/>
<
NavigationContainer
onReady=
{
(
navigationRef
):
void
=>
{
routingInstrumentation
.
registerNavigationContainer
(
navigationRef
)
}
}
>
<
MobileWalletNavigationProvider
>
<
OpenAIContextProvider
>
<
BottomSheetModalProvider
>
<
AppModals
/>
<
PerformanceProfiler
onReportPrepared=
{
onReportPrepared
}
>
<
AppInner
/>
</
PerformanceProfiler
>
</
BottomSheetModalProvider
>
<
NotificationToastWrapper
/>
</
OpenAIContextProvider
>
</
MobileWalletNavigationProvider
>
</
NavigationContainer
>
</
Sentry
.
TouchEventBoundary
>
</
LockScreenContextProvider
>
</
BiometricContextProvider
>
</
UnitagUpdaterContextProvider
>
</
WalletContextProvider
>
</
GestureHandlerRootView
>
</
LocalizationContextProvider
>
<
DatadogProviderWrapper
>
<
LocalizationContextProvider
>
<
GestureHandlerRootView
style=
{
flexStyles
.
fill
}
>
<
WalletContextProvider
>
<
UnitagUpdaterContextProvider
>
<
BiometricContextProvider
>
<
LockScreenContextProvider
>
<
Sentry
.
TouchEventBoundary
>
<
DataUpdaters
/>
<
NavigationContainer
onReady=
{
(
navigationRef
):
void
=>
{
routingInstrumentation
.
registerNavigationContainer
(
navigationRef
)
}
}
>
<
MobileWalletNavigationProvider
>
<
OpenAIContextProvider
>
<
BottomSheetModalProvider
>
<
AppModals
/>
<
PerformanceProfiler
onReportPrepared=
{
onReportPrepared
}
>
<
AppInner
/>
</
PerformanceProfiler
>
</
BottomSheetModalProvider
>
<
NotificationToastWrapper
/>
</
OpenAIContextProvider
>
</
MobileWalletNavigationProvider
>
</
NavigationContainer
>
</
Sentry
.
TouchEventBoundary
>
</
LockScreenContextProvider
>
</
BiometricContextProvider
>
</
UnitagUpdaterContextProvider
>
</
WalletContextProvider
>
</
GestureHandlerRootView
>
</
LocalizationContextProvider
>
</
DatadogProviderWrapper
>
</
ErrorBoundary
>
</
PersistGate
>
</
ApolloProvider
>
...
...
apps/mobile/src/app/modals/AccountSwitcherModal.tsx
View file @
e3a712f2
...
...
@@ -269,7 +269,9 @@ export function AccountSwitcher({ onClose }: { onClose: () => void }): JSX.Eleme
</
Button
>
</
Flex
>
</
Flex
>
<
AccountList
accounts=
{
accountsWithoutActive
}
isVisible=
{
modalState
.
isOpen
}
onPress=
{
onPressAccount
}
/>
<
Flex
maxHeight=
{
fullScreenContentHeight
/
2
}
>
<
AccountList
accounts=
{
accountsWithoutActive
}
isVisible=
{
modalState
.
isOpen
}
onPress=
{
onPressAccount
}
/>
</
Flex
>
<
TouchableArea
hapticFeedback
mt=
"$spacing16"
onPress=
{
onPressAddWallet
}
>
<
Flex
row
alignItems=
"center"
gap=
"$spacing8"
ml=
"$spacing24"
>
<
PlusCircle
/>
...
...
apps/mobile/src/app/modals/__snapshots__/AccountSwitcherModal.test.tsx.snap
View file @
e3a712f2
...
...
@@ -363,51 +363,57 @@ exports[`AccountSwitcher renders correctly 1`] = `
style={
{
"flexDirection": "column",
"
flexShrink": 1
,
"
maxHeight": NaN
,
}
}
>
ExpoLinearGradient
<RCTScrollView
CellRendererComponent={[Function]}
ListHeaderComponent={<React.Fragment />}
bounces={false}
collapsable={false}
data={[]}
getItem={[Function]}
getItemCount={[Function]}
jestAnimatedStyle={
<View
style={
{
"value": {},
"flexDirection": "column",
"flexShrink": 1,
}
}
keyExtractor={[Function]}
keyboardShouldPersistTaps="always"
onContentSizeChange={[Function]}
onLayout={[Function]}
onMomentumScrollBegin={[Function]}
onMomentumScrollEnd={[Function]}
onScroll={[Function]}
onScrollBeginDrag={[Function]}
onScrollEndDrag={[Function]}
removeClippedSubviews={false}
renderItem={[Function]}
scrollEnabled={false}
scrollEventThrottle={16}
sentry-label="VirtualizedList"
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
stickyHeaderIndices={[]}
viewabilityConfigCallbackPairs={[]}
>
<View>
<View
collapsable={false}
onLayout={[Function]}
/>
</View>
</RCTScrollView>
ExpoLinearGradient
ExpoLinearGradient
<RCTScrollView
collapsable={false}
data={[]}
getItem={[Function]}
getItemCount={[Function]}
handlerTag={1}
handlerType="NativeViewGestureHandler"
keyExtractor={[Function]}
onContentSizeChange={[Function]}
onGestureHandlerEvent={[Function]}
onGestureHandlerStateChange={[Function]}
onLayout={[Function]}
onMomentumScrollBegin={[Function]}
onMomentumScrollEnd={[Function]}
onScroll={[Function]}
onScrollBeginDrag={[Function]}
onScrollEndDrag={[Function]}
removeClippedSubviews={false}
renderItem={[Function]}
renderScrollComponent={[Function]}
scrollEventThrottle={0.0001}
stickyHeaderIndices={[]}
viewabilityConfigCallbackPairs={[]}
waitFor={
[
{
"current": null,
},
{
"current": null,
},
]
}
>
<View />
</RCTScrollView>
ExpoLinearGradient
</View>
</View>
<View
cancelable={true}
...
...
apps/mobile/src/components/accounts/AccountList.tsx
View file @
e3a712f2
...
...
@@ -2,8 +2,8 @@ import { LinearGradient } from 'expo-linear-gradient'
import
{
ComponentProps
,
default
as
React
,
useCallback
,
useMemo
}
from
'
react
'
import
{
useTranslation
}
from
'
react-i18next
'
import
{
StyleSheet
}
from
'
react-native
'
import
{
FlatList
}
from
'
react-native-gesture-handler
'
import
{
AccountCardItem
}
from
'
src/components/accounts/AccountCardItem
'
import
{
VirtualizedList
}
from
'
src/components/layout/VirtualizedList
'
import
{
Flex
,
Text
,
useSporeColors
}
from
'
ui/src
'
import
{
opacify
,
spacing
}
from
'
ui/src/theme
'
import
{
PollingInterval
}
from
'
uniswap/src/constants/misc
'
...
...
@@ -12,9 +12,6 @@ import { isNonPollingRequestInFlight } from 'wallet/src/data/utils'
import
{
useAccountList
}
from
'
wallet/src/features/accounts/hooks
'
import
{
Account
,
AccountType
}
from
'
wallet/src/features/wallet/accounts/types
'
// Most screens can fit more but this is set conservatively
const
MIN_ACCOUNTS_TO_ENABLE_SCROLL
=
5
type
AccountListProps
=
Pick
<
ComponentProps
<
typeof
AccountCardItem
>
,
'
onPress
'
>
&
{
accounts
:
Account
[]
isVisible
?:
boolean
...
...
@@ -26,7 +23,7 @@ type AccountWithPortfolioValue = {
portfolioValue
:
number
|
undefined
}
const
ViewOnlyHeader
=
():
JSX
.
Element
=>
{
const
ViewOnlyHeader
Content
=
():
JSX
.
Element
=>
{
const
{
t
}
=
useTranslation
()
return
(
<
Flex
fill
px=
"$spacing24"
py=
"$spacing8"
>
...
...
@@ -37,6 +34,19 @@ const ViewOnlyHeader = (): JSX.Element => {
)
}
enum
AccountListItemType
{
SignerHeader
,
SignerAccount
,
ViewOnlyHeader
,
ViewOnlyAccount
,
}
type
AccountListItem
=
|
{
type
:
AccountListItemType
.
SignerHeader
}
|
{
type
:
AccountListItemType
.
SignerAccount
;
account
:
AccountWithPortfolioValue
}
|
{
type
:
AccountListItemType
.
ViewOnlyHeader
}
|
{
type
:
AccountListItemType
.
ViewOnlyAccount
;
account
:
AccountWithPortfolioValue
}
const
SignerHeader
=
():
JSX
.
Element
=>
{
const
{
t
}
=
useTranslation
()
return
(
...
...
@@ -107,6 +117,45 @@ export function AccountList({ accounts, onPress, isVisible }: AccountListProps):
[
onPress
],
)
const
accountsToRender
=
useMemo
(()
=>
{
const
items
:
AccountListItem
[]
=
[]
if
(
hasSignerAccounts
)
{
items
.
push
({
type
:
AccountListItemType
.
SignerHeader
})
items
.
push
(...
signerAccounts
.
map
((
account
)
=>
({
type
:
AccountListItemType
.
SignerAccount
,
account
})))
}
if
(
hasViewOnlyAccounts
)
{
items
.
push
({
type
:
AccountListItemType
.
ViewOnlyHeader
})
items
.
push
(...
viewOnlyAccounts
.
map
((
account
)
=>
({
type
:
AccountListItemType
.
ViewOnlyAccount
,
account
})))
}
return
items
},
[
hasSignerAccounts
,
hasViewOnlyAccounts
,
signerAccounts
,
viewOnlyAccounts
])
const
renderItem
=
useCallback
(
({
item
}:
{
item
:
AccountListItem
})
=>
{
switch
(
item
.
type
)
{
case
AccountListItemType
.
SignerHeader
:
return
<
SignerHeader
/>
case
AccountListItemType
.
ViewOnlyHeader
:
return
<
ViewOnlyHeaderContent
/>
case
AccountListItemType
.
SignerAccount
:
case
AccountListItemType
.
ViewOnlyAccount
:
return
renderAccountCardItem
(
item
.
account
)
}
},
[
renderAccountCardItem
],
)
const
keyExtractor
=
useCallback
(
(
item
:
AccountListItem
,
index
:
number
)
=>
item
.
type
===
AccountListItemType
.
SignerAccount
||
item
.
type
===
AccountListItemType
.
ViewOnlyAccount
?
item
.
account
.
account
.
address
:
item
.
type
.
toString
()
+
index
,
[],
)
return
(
<
Flex
shrink
>
{
/* TODO(MOB-646): attempt to switch gradients to react-native-svg#LinearGradient and avoid new clear color */
}
...
...
@@ -116,24 +165,7 @@ export function AccountList({ accounts, onPress, isVisible }: AccountListProps):
start=
{
{
x
:
0
,
y
:
1
}
}
style=
{
ListSheet
.
topGradient
}
/>
<
VirtualizedList
bounces=
{
false
}
scrollEnabled=
{
accountsWithPortfolioValue
.
length
>=
MIN_ACCOUNTS_TO_ENABLE_SCROLL
}
showsVerticalScrollIndicator=
{
false
}
>
{
hasSignerAccounts
&&
(
<>
<
SignerHeader
/>
{
signerAccounts
.
map
(
renderAccountCardItem
)
}
</>
)
}
{
hasViewOnlyAccounts
&&
(
<>
<
ViewOnlyHeader
/>
{
viewOnlyAccounts
.
map
(
renderAccountCardItem
)
}
</>
)
}
</
VirtualizedList
>
<
FlatList
data=
{
accountsToRender
}
keyExtractor=
{
keyExtractor
}
renderItem=
{
renderItem
}
/>
<
LinearGradient
colors=
{
[
opacify
(
0
,
colors
.
surface1
.
val
),
colors
.
surface1
.
val
]
}
end=
{
{
x
:
0
,
y
:
1
}
}
...
...
apps/mobile/src/components/accounts/__snapshots__/AccountList.test.tsx.snap
View file @
e3a712f2
...
...
@@ -11,34 +11,40 @@ exports[`AccountList renders without error 1`] = `
>
ExpoLinearGradient
<RCTScrollView
CellRendererComponent={[Function]}
ListHeaderComponent={
<React.Fragment>
<React.Fragment>
<SignerHeader />
<AccountCardItem
address="0x82D56A352367453f74FC0dC7B071b311da373Fa6"
isPortfolioValueLoading={false}
isViewOnly={false}
onPress={[MockFunction]}
portfolioValue={55}
/>
</React.Fragment>
</React.Fragment>
}
bounces={false}
collapsable={false}
data={[]}
data={
[
{
"type": 0,
},
{
"account": {
"account": {
"address": "0x82D56A352367453f74FC0dC7B071b311da373Fa6",
"backups": [
"cloud",
],
"derivationIndex": 0,
"mnemonicId": "0x82D56A352367453f74FC0dC7B071b311da373Fa6",
"name": "Test Account",
"timeImportedMs": 10,
"type": "signerMnemonic",
},
"isPortfolioValueLoading": false,
"portfolioValue": 55,
},
"type": 1,
},
]
}
getItem={[Function]}
getItemCount={[Function]}
jestAnimatedStyle={
{
"value": {},
}
}
handlerTag={1}
handlerType="NativeViewGestureHandler"
keyExtractor={[Function]}
keyboardShouldPersistTaps="always"
onContentSizeChange={[Function]}
onGestureHandlerEvent={[Function]}
onGestureHandlerStateChange={[Function]}
onLayout={[Function]}
onMomentumScrollBegin={[Function]}
onMomentumScrollEnd={[Function]}
...
...
@@ -47,18 +53,26 @@ exports[`AccountList renders without error 1`] = `
onScrollEndDrag={[Function]}
removeClippedSubviews={false}
renderItem={[Function]}
scrollEnabled={false}
scrollEventThrottle={16}
sentry-label="VirtualizedList"
showsHorizontalScrollIndicator={false}
showsVerticalScrollIndicator={false}
renderScrollComponent={[Function]}
scrollEventThrottle={0.0001}
stickyHeaderIndices={[]}
viewabilityConfigCallbackPairs={[]}
waitFor={
[
{
"current": null,
},
{
"current": null,
},
]
}
>
<View>
<View
collapsable={false
}
onFocusCapture={[Function]
}
onLayout={[Function]}
style={null}
>
<View
style={
...
...
@@ -88,6 +102,12 @@ exports[`AccountList renders without error 1`] = `
Your other wallets
</Text>
</View>
</View>
<View
onFocusCapture={[Function]}
onLayout={[Function]}
style={null}
>
<View
actions={
[
...
...
apps/mobile/src/screens/TokenDetailsScreen.tsx
View file @
e3a712f2
...
...
@@ -377,7 +377,7 @@ function TokenDetails({
chainId=
{
currencyChainId
}
currencyId=
{
_currencyId
}
onClose=
{
():
void
=>
{
setShow
Warning
Modal
(
false
)
setShow
BuyNativeToken
Modal
(
false
)
}
}
/>
)
}
...
...
packages/ui/src/assets/index.ts
View file @
e3a712f2
...
...
@@ -21,7 +21,6 @@ export const AVATARS_LIGHT = require('./misc/avatars-light.png')
export
const
AVATARS_DARK
=
require
(
'
./misc/avatars-dark.png
'
)
export
const
APP_SCREENSHOT_LIGHT
=
require
(
'
./misc/app-screenshot-light.png
'
)
export
const
APP_SCREENSHOT_DARK
=
require
(
'
./misc/app-screenshot-dark.png
'
)
export
const
CHROME_LOGO
=
require
(
'
./logos/png/chrome-logo.png
'
)
export
const
DOT_GRID
=
require
(
'
./misc/dot-grid.png
'
)
export
const
UNITAGS_BANNER_VERTICAL_LIGHT
=
require
(
'
./graphics/unitags-banner-v-light.png
'
)
export
const
UNITAGS_BANNER_VERTICAL_DARK
=
require
(
'
./graphics/unitags-banner-v-dark.png
'
)
...
...
packages/ui/src/assets/logos/png/chrome-logo.png
deleted
100644 → 0
View file @
48a0bb2c
1.29 KB
packages/ui/src/theme/fonts.ts
View file @
e3a712f2
...
...
@@ -2,7 +2,6 @@
// eslint-disable-next-line no-restricted-imports
import
{
createFont
,
isWeb
}
from
'
@tamagui/core
'
import
{
needsSmallFont
}
from
'
ui/src/utils/needs-small-font
'
import
{
isInterface
}
from
'
utilities/src/platform
'
// TODO(EXT-148): remove this type and use Tamagui's FontTokens
export
type
TextVariantTokens
=
keyof
typeof
fonts
...
...
@@ -48,9 +47,9 @@ const MEDIUM_WEIGHT = '500'
const
MEDIUM_WEIGHT_WEB
=
'
535
'
const
defaultWeights
=
{
book
:
is
Interface
?
BOOK_WEIGHT_WEB
:
BOOK_WEIGHT
,
true
:
is
Interface
?
BOOK_WEIGHT_WEB
:
BOOK_WEIGHT
,
medium
:
is
Interface
?
MEDIUM_WEIGHT_WEB
:
MEDIUM_WEIGHT
,
book
:
is
Web
?
BOOK_WEIGHT_WEB
:
BOOK_WEIGHT
,
true
:
is
Web
?
BOOK_WEIGHT_WEB
:
BOOK_WEIGHT
,
medium
:
is
Web
?
MEDIUM_WEIGHT_WEB
:
MEDIUM_WEIGHT
,
}
export
const
fonts
=
{
...
...
packages/uniswap/src/components/modals/BottomSheetModal.native.tsx
View file @
e3a712f2
...
...
@@ -19,7 +19,7 @@ import { BottomSheetModalProps } from 'uniswap/src/components/modals/BottomSheet
import
{
HandleBar
}
from
'
uniswap/src/components/modals/HandleBar
'
import
Trace
from
'
uniswap/src/features/telemetry/Trace
'
import
{
useKeyboardLayout
}
from
'
uniswap/src/utils/useKeyboardLayout
'
import
{
is
Android
,
is
IOS
}
from
'
utilities/src/platform
'
import
{
isIOS
}
from
'
utilities/src/platform
'
/**
* (android only)
...
...
@@ -250,8 +250,6 @@ function BottomSheetModalContents({
{
...
background
}
{
...
backdrop
}
ref=
{
modalRef
}
// Adds vertical pan gesture activate offset to avoid nested scroll gesture handler conflicts on android
activeOffsetY=
{
isAndroid
?
12
:
undefined
}
animatedPosition=
{
animatedPosition
}
backgroundStyle=
{
backgroundStyle
}
containerComponent=
{
containerComponent
}
...
...
packages/uniswap/src/features/telemetry/constants/trace.ts
View file @
e3a712f2
...
...
@@ -127,7 +127,6 @@ export const ElementName = {
EmptyStateReceive
:
'
empty-state-receive
'
,
Enable
:
'
enable
'
,
EtherscanView
:
'
etherscan-view
'
,
ExtensionPopupOpenButton
:
'
extension-popup-open-button
'
,
FiatOnRampTokenSelector
:
'
fiat-on-ramp-token-selector
'
,
FiatOnRampWidgetButton
:
'
fiat-on-ramp-widget-button
'
,
FiatOnRampCountryPicker
:
'
fiat-on-ramp-country-picker
'
,
...
...
packages/uniswap/src/i18n/locales/source/en-US.json
View file @
e3a712f2
...
...
@@ -258,9 +258,6 @@
"extension.lock.subtitle"
:
"Enter your password to unlock"
,
"extension.lock.title"
:
"Welcome back"
,
"extension.network.notSupported"
:
"Unsupported network"
,
"extension.popup.chrome.button"
:
"Open extension"
,
"extension.popup.chrome.description"
:
"Complete this action by opening the Uniswap extension."
,
"extension.popup.chrome.title"
:
"Continue in Uniswap"
,
"extension.settings.password.enter.title"
:
"Enter your current password"
,
"extension.settings.password.error.wrong"
:
"Wrong password"
,
"extension.settings.password.placeholder"
:
"Current password"
,
...
...
packages/uniswap/src/i18n/locales/translations/es-ES.json
View file @
e3a712f2
...
...
@@ -258,9 +258,6 @@
"extension.lock.subtitle"
:
"Ingresa tu contraseña para desbloquear"
,
"extension.lock.title"
:
"Bienvenido de nuevo"
,
"extension.network.notSupported"
:
"Red no compatible"
,
"extension.popup.chrome.button"
:
"Abrir extensión"
,
"extension.popup.chrome.description"
:
"Completa esta acción abriendo la extensión de Uniswap."
,
"extension.popup.chrome.title"
:
"Continua en Uniswap"
,
"extension.settings.password.enter.title"
:
"Ingresa tu contraseña actual"
,
"extension.settings.password.error.wrong"
:
"Contraseña incorrecta"
,
"extension.settings.password.placeholder"
:
"Contraseña actual"
,
...
...
packages/uniswap/src/i18n/locales/translations/fr-FR.json
View file @
e3a712f2
...
...
@@ -258,9 +258,6 @@
"extension.lock.subtitle"
:
"Saisissez votre mot de passe pour déverrouiller"
,
"extension.lock.title"
:
"Content de vous revoir"
,
"extension.network.notSupported"
:
"Réseau non pris en charge"
,
"extension.popup.chrome.button"
:
"Ouvre l'extension"
,
"extension.popup.chrome.description"
:
"Complète cette action en ouvrant l'extension Uniswap."
,
"extension.popup.chrome.title"
:
"Continue sur Uniswap"
,
"extension.settings.password.enter.title"
:
"Saisissez votre mot de passe actuel"
,
"extension.settings.password.error.wrong"
:
"Mot de passe incorrect"
,
"extension.settings.password.placeholder"
:
"Mot de passe actuel"
,
...
...
packages/uniswap/src/types/screens/extension.ts
View file @
e3a712f2
...
...
@@ -6,7 +6,6 @@ export enum HomeTabs {
export
enum
ExtensionScreens
{
Home
=
'
home
'
,
PopupOpenExtension
=
'
PopupOpenExtension
'
,
UnsupportedBrowserScreen
=
'
UnsupportedBrowserScreen
'
}
...
...
packages/wallet/src/components/landing/LandingBackground.tsx
View file @
e3a712f2
...
...
@@ -19,7 +19,7 @@ import { ONBOARDING_LANDING_DARK, ONBOARDING_LANDING_LIGHT, UNISWAP_LOGO } from
import
{
AnimatedFlex
}
from
'
ui/src/components/layout/AnimatedFlex
'
import
{
useDeviceDimensions
}
from
'
ui/src/hooks/useDeviceDimensions
'
import
{
imageSizes
}
from
'
ui/src/theme
'
import
{
isAndroid
,
isMobile
}
from
'
utilities/src/platform
'
import
{
isAndroid
}
from
'
utilities/src/platform
'
import
{
ONE_SECOND_MS
}
from
'
utilities/src/time/time
'
import
{
useTimeout
}
from
'
utilities/src/time/timing
'
import
{
...
...
@@ -355,7 +355,7 @@ export const LandingBackground = ({
if
(
// Android Platform.Version is always a number
(
isAndroid
&&
typeof
Platform
.
Version
===
'
number
'
&&
Platform
.
Version
<
30
)
||
(
language
!==
Language
.
English
&&
isMobile
)
language
!==
Language
.
English
)
{
return
<
OnboardingStaticImage
/>
}
...
...
packages/wallet/src/features/language/saga.ts
View file @
e3a712f2
...
...
@@ -4,7 +4,6 @@ import { call, put, select, takeLatest } from 'typed-redux-saga'
import
i18n
from
'
uniswap/src/i18n/i18n
'
import
{
getDeviceLocales
}
from
'
utilities/src/device/locales
'
import
{
logger
}
from
'
utilities/src/logger/logger
'
import
{
isMobile
}
from
'
utilities/src/platform
'
import
{
Language
,
Locale
,
...
...
@@ -39,9 +38,7 @@ function* appLanguageSaga(action: ReturnType<typeof updateLanguage>) {
logger
.
warn
(
'
language/saga
'
,
'
appLanguageSaga
'
,
'
Sync of language setting state and i18n instance failed
'
)
}
if
(
isMobile
)
{
yield
*
call
(
restartAppIfRTL
,
localeToSet
)
}
yield
*
call
(
restartAppIfRTL
,
localeToSet
)
}
function
getDeviceLanguage
():
Language
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment