Compare commits

...

97 Commits

Author SHA1 Message Date
Greg Bugyis
6f2c09adea feat: NFT Collections: add 24-hour price change and delta arrow (#4913)
* Add 24-hour volume and delta arrow to Collection Stats

* Move 24-hour floor change after Floor stat in row

* Position percent change arrow with styled div

* Use math.round instead of toFixed()

* PR Feedback

* Remove console log
2022-10-18 00:46:03 +03:00
vignesh mohankumar
f9aadbbbdb chore: remove tokenSafety flag (#4944) 2022-10-17 17:30:44 -04:00
vignesh mohankumar
f8c0525512 chore: remove deprecated colors (#4945) 2022-10-17 17:28:33 -04:00
Yadong Zhang
175ffade5e fix: handled undefined circleLogoUrl and failed fetchQuery (#4916)
* fix: handled circleLogoUrl undefined.

* fix: catch error and return empty data.

* fix: added optional chaining for circleLogoUrl in TokenRow file.
2022-10-17 14:26:30 -07:00
vignesh mohankumar
cba30fb0b1 chore: remove navBarFlag (#4941)
* chore: remove navBarFlag

* move Polling
2022-10-17 16:44:11 -04:00
vignesh mohankumar
604b854ef7 chore: remove tokens flag (#4943) 2022-10-17 12:28:16 -04:00
lynn
332843f428 fix: add logging for token details (#4925)
logging for token details
2022-10-13 17:27:30 -04:00
Zach Pomerantz
cee32f9751 fix: display loaded logo on token details (#4922) 2022-10-13 12:15:09 -07:00
cartcrom
cb480706a2 fix: display 0 instead of '-' on explore table (#4892)
* fixed table display
* updated test
2022-10-13 14:00:22 -05:00
Zach Pomerantz
4f74267144 fix: prevent marking x-chain wrapped as native (#4921) 2022-10-13 11:34:27 -07:00
Jordan Frankfurt
f6b08e8ed1 fix: make background opaque (#4895)
* fix: remove old background-color flash (#4890)

remove old background-color

* fix: make background opaque

* refactor to fix dismissal bug and improve code quality

* fix merge errors
2022-10-13 13:33:40 -05:00
Zach Pomerantz
0faaa3f0c4 fix: disallow duplicate currencies in widget (#4919)
fix: currency equality check
2022-10-13 11:20:53 -07:00
lynn
6acc9300c0 fix: add origin to every event (#4918)
* add origin to every event

* remove console log
2022-10-13 13:38:52 -04:00
Zach Pomerantz
70d33fb255 build: upgrade widget (#4917)
* build: upgrade widget

* build: upgrade widget
2022-10-13 10:37:06 -07:00
Charles Bachmeier
c0db592ab5 feat: revised profile card designs (#4901)
* add default style

* update select button styles

* add styles for listed cards

* update index for profile skeleton

Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
2022-10-13 10:13:35 -07:00
lynn
a5c5567936 feat: widget analytics (#4869)
* chore: todos for analytics

* example

* another skeleton logging event

* feat: onSwapApprove

* feat: widget tracing

* feat: better useTrace

* feat: max

* feat: switch

* add trace amd remove onreviewswapclick

* onExpandSwapDetails

* feat: initial quote

* add event properties for wrap

* feat: update ack

* SWAP_SIGNED

* feat: submit

* fix: wrap type

* chore: tracing

* move format fn to utils

* fix: remove old background-color flash (#4890)

remove old background-color

* revert: add back phase0 bug fixes (#4888)

* Revert "revert: removing phase0 bug fixes temporarily (#4886)"

This reverts commit 06291a15a6.

* use token amount

* Revert "use token amount"

This reverts commit f47c00358b.

* dont render if empty

* fix: upgrade pkg to eliminate compile error (#4898)

* upgrade pkg

* dedup

* fix: Remove token selector flash of old ui  (#4896)

remove token selector flash of old view

* fix: Web 1561 logging event for clicking on explore banner toast +  WEB-1543  [Explore Banner] String should be sentence case (#4899)

* explore banner changes

* remove console log

* oops

* test: run tests on all PRs (#4905)

* fix: use correct optimism icon in explore (#4893)

* fix: click area should match button effect (#4887)

* fix: update font-weight values to match spec (#4863)

* fixes. working now verified on console.

* fix: mobile tweaks (#4910)

* update manifest theme colors to magenta

* text spacing and right positioning on very small screens

* feat: load token from query data (#4904)

* fix: do not fetch balances cross-chain

* build: updgrade widget

* feat: cleanly load and switch chains from widget

* fix: load token from query data

* build: trigger checks

* fix: do not override native token from query

* fix: catch error on switch chain

* refactor: useTokenFromActiveNetwork

* refactor: defaultToken behavior clarification

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
Co-authored-by: Jordan Frankfurt <jordanwfrankfurt@gmail.com>
Co-authored-by: vignesh mohankumar <vignesh@vigneshmohankumar.com>
Co-authored-by: cartcrom <39385577+cartcrom@users.noreply.github.com>
2022-10-13 12:20:59 -04:00
Connor McEwen
cdd5b66d1b fix: merge conflict 2022-10-13 11:38:26 -04:00
Zach Pomerantz
b65fffc5f7 feat: load token from query data (#4904)
* fix: do not fetch balances cross-chain

* build: updgrade widget

* feat: cleanly load and switch chains from widget

* fix: load token from query data

* build: trigger checks

* fix: do not override native token from query

* fix: catch error on switch chain

* refactor: useTokenFromActiveNetwork

* refactor: defaultToken behavior clarification
2022-10-13 11:38:26 -04:00
Jordan Frankfurt
a3a3e934a1 fix: mobile tweaks (#4910)
* update manifest theme colors to magenta

* text spacing and right positioning on very small screens
2022-10-13 11:38:26 -04:00
Jordan Frankfurt
8a4e07e6b2 fix: update font-weight values to match spec (#4863) 2022-10-13 11:38:26 -04:00
Jordan Frankfurt
7f4413c79c fix: click area should match button effect (#4887) 2022-10-13 11:38:26 -04:00
cartcrom
55beaf65a2 fix: use correct optimism icon in explore (#4893) 2022-10-13 11:38:26 -04:00
Zach Pomerantz
20fe76ad29 test: run tests on all PRs (#4905) 2022-10-13 11:38:26 -04:00
lynn
0d5bc753ca fix: Web 1561 logging event for clicking on explore banner toast + WEB-1543 [Explore Banner] String should be sentence case (#4899)
* explore banner changes

* remove console log

* oops
2022-10-13 11:38:26 -04:00
lynn
79507a4b03 fix: Remove token selector flash of old ui (#4896)
remove token selector flash of old view
2022-10-13 11:38:26 -04:00
lynn
3a1be04a36 fix: upgrade pkg to eliminate compile error (#4898)
* upgrade pkg

* dedup
2022-10-13 11:38:26 -04:00
vignesh mohankumar
ec523e5235 revert: add back phase0 bug fixes (#4888)
* Revert "revert: removing phase0 bug fixes temporarily (#4886)"

This reverts commit 06291a15a6.

* use token amount

* Revert "use token amount"

This reverts commit f47c00358b.

* dont render if empty
2022-10-13 11:38:26 -04:00
Jordan Frankfurt
c7b1aa2948 fix: remove old background-color flash (#4890)
remove old background-color
2022-10-13 11:38:26 -04:00
Greg Bugyis
9370383f64 feat: Remove value prop from NFT Explore (#4914) 2022-10-13 17:35:56 +03:00
Charles Bachmeier
9856c03566 fix: issues with NFT listing (#4828)
* can approve marketplaces for listing

* add consts

* fix issue with expiration time

* adding api key to env + changing variable

* updating env name to req

* removing console

* use v3 endpoint

* remove unussed util

* uneeded null check

* remove console.log

Co-authored-by: Jack Short <john.short.tj@gmail.com>
Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
2022-10-12 15:24:55 -07:00
vignesh mohankumar
ec686bcaa5 chore: remove phase0 flags (#4833)
* chore: remove phase0 flags

* unused imports

* update snapshots

* fix link test

* use the data cy

* delete lists test

* rm wallet.test

* update snapshot

* fix: update default html background-color (#4881)

* Revert "fix: update default html background-color (#4881)"

This reverts commit 043f844067.

Co-authored-by: Connor McEwen <connor.mcewen@gmail.com>
2022-10-12 10:56:20 -04:00
vignesh mohankumar
06291a15a6 revert: removing phase0 bug fixes temporarily (#4886)
* Revert "fix: handle backspace out of /tokens (#4879)"

This reverts commit 3e40a6f5c6.

* Revert "fix: add padding-bottom to TokenDetailsLayout (#4882)"

This reverts commit f91b48e214.

* Revert "fix: updates outputCurrency link in mobile balance footer (#4885)"

This reverts commit e340f405b4.
2022-10-12 09:34:03 -05:00
vignesh mohankumar
3e40a6f5c6 fix: handle backspace out of /tokens (#4879)
* fix: handle backspace out of /tokens

* simplify banner

* simplify banner more
2022-10-12 09:05:53 -05:00
vignesh mohankumar
f91b48e214 fix: add padding-bottom to TokenDetailsLayout (#4882) 2022-10-12 09:03:14 -05:00
vignesh mohankumar
e340f405b4 fix: updates outputCurrency link in mobile balance footer (#4885) 2022-10-12 09:02:54 -05:00
Connor McEwen
24fc39b016 fix: upgrade widget to fix token selection field (#4878) 2022-10-12 00:41:55 -04:00
Zach Pomerantz
2fc3f3c00e fix: network token memoization (#4877)
* build: upgrade redux-multicall

* fix: memoize network token

* docs: invalid token
2022-10-11 21:41:20 -07:00
Connor McEwen
21e0faeb1e fix: actually fetch token object on page (#4875)
* fix: actually fetch token object on page

* syntax
2022-10-11 20:46:59 -04:00
Zach Pomerantz
4b71a8d5f4 build: upgrade widget (#4873) 2022-10-11 17:00:11 -07:00
Zach Pomerantz
4075965252 revert: "revert: "fix: use widget network connection"" (#4871)
Revert "revert: "fix: use widget network connection" (#4870)"

This reverts commit 3538312769.
2022-10-11 16:21:51 -07:00
Zach Pomerantz
3538312769 revert: "fix: use widget network connection" (#4870)
Revert "fix: use widget network connection (#4866)"

This reverts commit 2924f36970.
2022-10-11 16:06:17 -07:00
Zach Pomerantz
2924f36970 fix: use widget network connection (#4866)
* fix: switch network connector on other network token details

* fix: use jsonRpcUrlMap for widget

* fix: use widget network provider

* build: upgrade widget

* build: upgrade widget

* fix: SwapController typing
2022-10-11 15:45:43 -07:00
lynn
bf16dfa09c fix: fix twitter links (#4868)
* fix twitter links

* fix
2022-10-11 16:42:19 -04:00
Charles Bachmeier
910e86d6a2 feat: Add loading skeleton for profile page (#4823)
* Add loading skeleton for profile page

* add consts for sidebar width and padding

Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
2022-10-11 12:37:55 -07:00
Connor McEwen
537fea103e fix: revert max input formatting change (#4865)
revert max input formatting change
2022-10-11 14:16:52 -04:00
lynn
87a6e2709b fix: remove double $ render (#4864)
remove double $ render
2022-10-11 13:43:11 -04:00
Jack Short
d704e78223 feat: details owner actions (#4851)
* feat: initial pass at price details container

* feat: nft details owners actions

* adding check for bad types
2022-10-11 12:53:33 -04:00
Connor McEwen
8ceabd513c feat: upgrade widget build (#4862) 2022-10-11 11:48:33 -04:00
Zach Pomerantz
4806c69053 fix: map wrapped tokens to native tokens for top/trending (#4855)
* fix: map wrapped to native for trending tokens

* fix: close top tokens subscription

* fix: map wrapped to native for top tokens

* fix: link to native from native

* refactor: unwrapToken.ts

* fix: mv query to effect

* fix: native token logos

* fix: use NATIVE_CHAIN_ID

* fix: rm todo

* fix: include NATIVE_CHAIN_ID

* fix: NATIVE_CHAIN_ID import
2022-10-10 22:34:11 -07:00
github-actions[bot]
c9f333003b chore(i18n): new Crowdin translations (#4713)
* chore(i18n): synchronize translations from crowdin [skip ci]

* empty

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: Vignesh Mohankumar <me@vig.xyz>
2022-10-10 23:23:39 -05:00
vignesh mohankumar
33fa32cb07 chore: remove unused TokensLoading (#4858) 2022-10-10 23:16:06 -05:00
vignesh mohankumar
5d1377af80 fix: track token_list_rank (#4857) 2022-10-10 23:15:47 -05:00
Zach Pomerantz
a75e239fd2 fix: keep search history synced with trending (#4854) 2022-10-10 19:34:27 -07:00
lynn
a663482dc6 fix: second part of price fixes (#4852)
* init

* use named args

* transaction price format

* respond to comments

* 1.00 rounding edge case
2022-10-10 22:09:02 -04:00
lynn
e8d6235529 fix: revise strings on token details + change privacy disclaimer edits to be enabled by phase 1 flag (#4856)
* init

* nft flag name change
2022-10-10 21:58:42 -04:00
cartcrom
d8677d8a6d feat: lazy load sparklines (#4827)
* testing removing sparklines

* fixed build

* filter working

* added lazy loading of sparklines

* fixed bugs

* removed comments

* add back memo

Co-authored-by: Connor McEwen <connor.mcewen@gmail.com>
2022-10-10 16:51:45 -04:00
Callil Capuozzo
351f66a83e fix: Update input placeholder text color (#4848)
Update input placeholder text color
2022-10-10 16:50:35 -04:00
omahs
79c7c01964 fix: minor typo (#4845)
Fix: typo

Fix: typo
2022-10-10 13:25:14 -07:00
Greg Bugyis
f51474b66d feat: [Collection Stats] update listings copy and change value to percentage (#4718) 2022-10-10 21:28:57 +03:00
lynn
14f01905d7 fix: price formatting spot check fixes (#4850)
fix price formatting
2022-10-10 13:49:32 -04:00
vignesh mohankumar
23eb31e6a2 fix: aligns token ranking column (#4849) 2022-10-10 13:28:19 -04:00
lynn
e8d4f00f49 fix: remove no tokens state and replace w loading (#4847)
* remove no tokens state and replace w loading

* update snapshot
2022-10-10 12:23:49 -04:00
aballerr
978e3f945d feat: adding in trait chips (#4807)
* adding in traitchips
2022-10-10 11:23:45 -04:00
Jordan Frankfurt
072f394476 feat(WEB-1457): update banner text (#4841) 2022-10-07 14:06:55 -05:00
lynn
5926d7037d fix: handle tiny numbers (#4842)
* handle tiny numbers

* remove console
2022-10-07 14:43:52 -04:00
lynn
52b51ee7d0 fix: price calculations are wrong (#4840)
* make every duration have latest price point

* simplify

* fix info tip icon regression

* remove unecessary line

* use memo

* fix MASSIVE ERROR in number cal

* bump widget v

* delete unit test failing for some obscure reason, added todo

* fix unit tests
2022-10-07 13:51:31 -04:00
Jordan Frankfurt
54f831ede4 fix(token-details): make breakpoints more consistent and use only theme.breakpoint values (#4836)
* fix(token-details): make breakpoints more consistent and use only theme.breakpoint values

* feat(token-details): design patch for mobile swap button footer

* render mobile balance footer w/ only swap button when user is disconnected

* don't render BalanceSummary if no balances are provided

* full width swap button footer until breakpoints.lg
2022-10-07 12:35:27 -05:00
Fred Zaw
c9ead63ff6 style: increase name column width in token table (#4835)
increase name column width in token table
2022-10-07 13:27:51 -04:00
Fred Zaw
9ca74cf8d2 style: updated crosshair light/dark color and stroke width (#4837)
updated crosshair light/dark color and stroke width
2022-10-07 13:24:21 -04:00
Connor McEwen
2a0d455419 fix: animation on mount wasn't happening (#4839) 2022-10-07 13:20:29 -04:00
Connor McEwen
9e959ca455 fix: import widget font (#4813)
* import widget font

* update comment
2022-10-07 12:00:42 -04:00
lynn
d3f6796bb9 fix: make sure every duration has latest price point (#4832)
* make every duration have latest price point

* simplify

* fix info tip icon regression

* remove unecessary line

* use memo
2022-10-07 11:44:36 -04:00
cartcrom
64d6eeabcb fix: info tip light theme issue (#4825)
fixed light theme issue

Co-authored-by: Jordan Frankfurt <jordanwfrankfurt@gmail.com>
2022-10-07 09:59:58 -04:00
lynn
859258c25c fix: standardize decimals for token prices in explore, token details, search (#4821)
* token prices in explore, token details, search

* use correct dollar format function

* additional price corrections

* remove oopsies

* changes in notion from andy

* use currencyAmountToPreciseFloat everywhere
2022-10-06 20:27:23 -04:00
Jordan Frankfurt
2338255a54 fix(token-details): nits from design re: headers, spacing, layout (#4829)
* fix(token-details): nits from design re: headers, spacing, layout

* pr feedback
2022-10-06 18:26:51 -05:00
Zach Pomerantz
843afa93c3 fix: do not load token list (#4820)
* build: upgrade widgets

* fix: use empty token list

* build: trigger checks
2022-10-06 17:50:33 -05:00
Zach Pomerantz
5441e63825 build: upgrade widgets (#4824) 2022-10-06 14:35:34 -07:00
Charles Bachmeier
7bf741027e feat: profile listing sidebar (#4809)
* Add sell header to Bag

* split bag content to its own file

* empty tag state

* continue button

* file re-arranging and add profile select row content

* update padding

* better null check

Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
2022-10-06 14:23:57 -07:00
Zach Pomerantz
0017e2fcc8 test: use goerli (#4826)
* test: use goerli

* test: skip rinkeby-specific tests

* revert: retain arbitrum rinkeby
2022-10-06 15:16:58 -05:00
cartcrom
5c9c8b4cb7 feat: explore category info icons (#4787)
* added tooltips
* switched to premade tooltip component
* added 'help' cursor
2022-10-06 14:39:41 -04:00
Jack Short
873d0ea2a3 chore: breaking details into two containers (#4822)
* holding

* breaking up code into two areas for development purposes
2022-10-06 13:56:41 -04:00
Charles Bachmeier
db4987f557 feat: Sell Mode Button (#4803)
* remove sort and search functionality

* add sell mode button toggle

* update cards to sell mode

* split wallet asset display file

* remove unused style

* address comments

Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
2022-10-06 10:44:14 -07:00
Jordan Frankfurt
b0b61f886d fix: refactors the way chainId is accessed in some places (#4818)
fix: refactors the way some data is accessed
2022-10-06 11:55:46 -05:00
cartcrom
5d4b25f417 feat: chart states polish (#4819)
* init
* finished missing data component
* finished feature
2022-10-06 12:51:37 -04:00
Callil Capuozzo
c88d7c880b fix: Adjust verified icons to accentAction (#4804)
* Adjust verified icons to accentAction

* Adjust to match designs

* Apply verified icons in all places

* use theme.accentAction

Co-authored-by: Jordan Frankfurt <jordanwfrankfurt@gmail.com>
2022-10-06 11:37:48 -05:00
Jordan Frankfurt
a96d13978b feat(token-details): link between native:wrapped assets in the balance summary (#4817)
* feat(token-details): link between native:wrapped assets in the balance summary

* update pageChainName access method
2022-10-06 11:36:52 -05:00
Jordan Frankfurt
22b26de78d feat(token-details): native/wrapped-native balance UI (#4814)
* feat(token-details): balance hook

* mobile balance UI

* feat(token-details): sidebar balance summary

* pr feedback
2022-10-05 22:46:24 -05:00
lynn
53b57879a3 fix: link to explore table when explore tokens banner clicked (#4811)
* token banner

* responses to jordan
2022-10-05 22:59:35 -04:00
lynn
d794cef770 fix: more explore table fixes (#4806)
* testing

* remove dev dep

* fixed

* fixes

* add developer comments

* link to eth token page when eth clicked in search bar

* undo commit to wrong pr / branch smh

* fix ascending sorted tokens index
2022-10-05 22:51:22 -04:00
lynn
19f175ba89 fix: make eth in search bar navigate to eth token details (#4812)
* make eth in search bar navigate to eth token details

* use local resolving functions
2022-10-05 22:44:27 -04:00
vignesh mohankumar
aaf105ef51 fix: add redirect from /tokens to /tokens/ethereum (#4816) 2022-10-05 20:14:32 -04:00
vignesh mohankumar
974308f939 fix: center TimeButton in PriceChart horizontally (#4795) 2022-10-05 19:28:33 -04:00
vignesh mohankumar
0ec738a48a fix: update hover states in control CurrencyInputSelector (#4815) 2022-10-05 19:27:12 -04:00
cartcrom
904f6e22f4 feat: search attempts route to current chain (#4785)
* finished feature

* added L2 icons

* removed console.log
2022-10-05 15:50:33 -04:00
cartcrom
66fad96e61 perf: improve token details query performance (#4808)
* updated hook
* fixed build error
2022-10-05 15:50:08 -04:00
cartcrom
9037930e56 feat: added widget skeleton to loading state (#4793)
* added widget skeleton to loading state

* removed memo

* made theme inline
2022-10-05 11:19:46 -04:00
cartcrom
d62013177d feat: add 52 w highlow (#4791)
updated query
2022-10-05 10:44:09 -04:00
194 changed files with 7022 additions and 6275 deletions

View File

@@ -5,8 +5,6 @@ on:
branches:
- main
pull_request:
branches:
- main
# manual trigger
workflow_dispatch:

View File

@@ -21,20 +21,20 @@ describe('Add Liquidity', () => {
cy.get('#add-liquidity-input-tokenb .token-symbol-container').should('not.contain.text', 'ETH')
})
it('token not in storage is loaded', () => {
it.skip('token not in storage is loaded', () => {
cy.visit('/add/0xb290b2f9f8f108d03ff2af3ac5c8de6de31cdf6d/0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85')
cy.get('#add-liquidity-input-tokena .token-symbol-container').should('contain.text', 'SKL')
cy.get('#add-liquidity-input-tokenb .token-symbol-container').should('contain.text', 'MKR')
})
it('single token can be selected', () => {
it.skip('single token can be selected', () => {
cy.visit('/add/0xb290b2f9f8f108d03ff2af3ac5c8de6de31cdf6d')
cy.get('#add-liquidity-input-tokena .token-symbol-container').should('contain.text', 'SKL')
cy.visit('/add/0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85')
cy.get('#add-liquidity-input-tokena .token-symbol-container').should('contain.text', 'MKR')
})
it('loads fee tier distribution', () => {
it.skip('loads fee tier distribution', () => {
cy.fixture('feeTierDistribution.json').then((feeTierDistribution) => {
cy.intercept('POST', '/subgraphs/name/uniswap/uniswap-v3', (req: CyHttpMessages.IncomingHttpRequest) => {
if (hasQuery(req, 'FeeTierDistributionQuery')) {

View File

@@ -2,7 +2,7 @@
describe('Link', () => {
it('should update route', () => {
cy.visit('/')
cy.get('[data-cy="pool-nav-link"]').click()
cy.contains('Pool').click()
cy.get('[data-cy="join-pool-button"]').should('exist')
})
})

View File

@@ -1,11 +0,0 @@
describe('Lists', () => {
beforeEach(() => {
cy.visit('/swap')
})
// @TODO check if default lists are active when we have them
it('change list', () => {
cy.get('#swap-currency-output .open-currency-select-button').click()
cy.get('.list-token-manage-button').click()
})
})

View File

@@ -23,7 +23,7 @@ describe('Remove Liquidity', () => {
cy.get('#remove-liquidity-tokenb-symbol').should('contain.text', 'WETH')
})
it('token not in storage is loaded', () => {
it.skip('token not in storage is loaded', () => {
cy.visit('/remove/v2/0xb290b2f9f8f108d03ff2af3ac5c8de6de31cdf6d/0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85')
cy.get('#remove-liquidity-tokena-symbol').should('contain.text', 'SKL')
cy.get('#remove-liquidity-tokenb-symbol').should('contain.text', 'MKR')

View File

@@ -1,31 +0,0 @@
import { TEST_ADDRESS_NEVER_USE_SHORTENED } from '../support/ethereum'
describe('Wallet', () => {
before(() => {
cy.visit('/swap')
})
it('displays account details', () => {
cy.get('[data-testid=web3-status-connected]').contains(TEST_ADDRESS_NEVER_USE_SHORTENED).click()
})
it('displays account view in wallet modal', () => {
cy.get('[data-testid=web3-account-identifier-row]').contains(TEST_ADDRESS_NEVER_USE_SHORTENED)
})
it('changes back to the options grid', () => {
cy.contains('Change').click()
cy.get('[data-testid=option-grid]').should('exist')
})
it('selects injected wallet option', () => {
cy.contains('Injected').click()
cy.get('[data-testid=web3-account-identifier-row]').contains(TEST_ADDRESS_NEVER_USE_SHORTENED)
})
it('shows connect buttons after disconnect', () => {
cy.get('[data-testid=web3-status-connected]').contains(TEST_ADDRESS_NEVER_USE_SHORTENED).click()
cy.contains('Disconnect').click()
cy.get('[data-testid=option-grid]').should('exist')
})
})

View File

@@ -34,7 +34,7 @@ Cypress.Commands.overwrite(
cy.intercept('/service-worker.js', options?.serviceWorker ? undefined : { statusCode: 404 }).then(() => {
original({
...options,
url: (url.startsWith('/') && url.length > 2 && !url.startsWith('/#') ? `/#${url}` : url) + '?chain=rinkeby',
url: (url.startsWith('/') && url.length > 2 && !url.startsWith('/#') ? `/#${url}` : url) + '?chain=goerli',
onBeforeLoad(win) {
options?.onBeforeLoad?.(win)
win.localStorage.clear()

View File

@@ -19,10 +19,10 @@ export const TEST_ADDRESS_NEVER_USE_SHORTENED = `${TEST_ADDRESS_NEVER_USE.substr
6
)}...${TEST_ADDRESS_NEVER_USE.substr(-4, 4)}`
const provider = new JsonRpcProvider('https://rinkeby.infura.io/v3/4bf032f2d38a4ed6bb975b80d6340847', 4)
const provider = new JsonRpcProvider('https://goerli.infura.io/v3/4bf032f2d38a4ed6bb975b80d6340847', 4)
const signer = new Wallet(TEST_PRIVATE_KEY, provider)
export const injected = new (class extends Eip1193Bridge {
chainId = 4
chainId = /* GOERLI= */ 5
async sendAsync(...args: any[]) {
console.debug('sendAsync called', ...args)

View File

@@ -100,8 +100,8 @@
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-better-styled-components": "^1.1.2",
"eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-react": "^7.19.0",
"eslint-plugin-react-hooks": "^4.0.0",
"eslint-plugin-react": "^7.21.5",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-simple-import-sort": "^7.0.0",
"eslint-plugin-unused-imports": "^2.0.0",
"jest-styled-components": "^7.0.8",
@@ -135,7 +135,7 @@
"@uniswap/governance": "^1.0.2",
"@uniswap/liquidity-staker": "^1.0.2",
"@uniswap/merkle-distributor": "1.0.1",
"@uniswap/redux-multicall": "^1.1.5",
"@uniswap/redux-multicall": "^1.1.6",
"@uniswap/router-sdk": "^1.3.0",
"@uniswap/sdk-core": "^3.0.1",
"@uniswap/smart-order-router": "^2.10.0",
@@ -146,7 +146,7 @@
"@uniswap/v3-core": "1.0.0",
"@uniswap/v3-periphery": "^1.1.1",
"@uniswap/v3-sdk": "^3.9.0",
"@uniswap/widgets": "^2.9.2",
"@uniswap/widgets": "^2.16.2",
"@vanilla-extract/css": "^1.7.2",
"@vanilla-extract/css-utils": "^0.1.2",
"@vanilla-extract/dynamic": "^2.0.2",

View File

@@ -1,126 +1,118 @@
<!DOCTYPE html>
<html translate="no">
<head>
<meta charset="utf-8" />
<title>Uniswap Interface</title>
<meta name="description" content="Swap or provide liquidity on the Uniswap Protocol" />
<head>
<meta charset="utf-8" />
<!--
<title>Uniswap Interface</title>
<meta name="description" content="Swap or provide liquidity on the Uniswap Protocol" />
<!--
%PUBLIC_URL% will be replaced with the URL of the `public` folder during build.
Only files inside the `public` folder can be referenced from the HTML.
-->
<link rel="shortcut icon" type="image/png" href="%PUBLIC_URL%/favicon.png" />
<link rel="apple-touch-icon" sizes="192x192" href="%PUBLIC_URL%/images/192x192_App_Icon.png" />
<link rel="apple-touch-icon" sizes="512x512" href="%PUBLIC_URL%/images/512x512_App_Icon.png" />
<link rel="shortcut icon" type="image/png" href="%PUBLIC_URL%/favicon.png" />
<link rel="apple-touch-icon" sizes="192x192" href="%PUBLIC_URL%/images/192x192_App_Icon.png" />
<link rel="apple-touch-icon" sizes="512x512" href="%PUBLIC_URL%/images/512x512_App_Icon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<meta name="theme-color" content="#ff007a" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<meta name="theme-color" content="#FC72FF" />
<!--
<!--
manifest.json provides metadata used when the app is installed as a PWA.
See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link rel="preconnect" href="https://www.google-analytics.com/" />
<link rel="preconnect" href="https://www.google-analytics.com/" />
<link rel="preload" href="%PUBLIC_URL%/fonts/Inter-roman.var.woff2" as="font" type="font/woff2" crossorigin />
<link rel="preload" href="%PUBLIC_URL%/fonts/Inter-roman.var.woff2" as="font" type="font/woff2" crossorigin />
<style>
* {
font-family: 'Inter', sans-serif;
box-sizing: border-box;
}
<style>
* {
font-family: 'Inter', sans-serif;
box-sizing: border-box;
}
/**
/**
Explicitly load Inter var from public/ so it does not block LCP's critical path.
*/
@font-face {
font-family: 'Inter custom';
font-weight: 100 900;
font-style: normal;
font-display: block;
font-named-instance: 'Regular';
src: url(%PUBLIC_URL%/fonts/Inter-roman.var.woff2) format('woff2 supports variations(gvar)'),
url(%PUBLIC_URL%/fonts/Inter-roman.var.woff2) format('woff2-variations'),
url(%PUBLIC_URL%/fonts/Inter-roman.var.woff2) format('woff2');
}
@font-face {
font-family: 'Inter custom';
font-weight: 100 900;
font-style: normal;
font-display: block;
font-named-instance: 'Regular';
src: url(%PUBLIC_URL%/fonts/Inter-roman.var.woff2) format('woff2 supports variations(gvar)'),
url(%PUBLIC_URL%/fonts/Inter-roman.var.woff2) format('woff2-variations'),
url(%PUBLIC_URL%/fonts/Inter-roman.var.woff2) format('woff2');
}
@supports (font-variation-settings: normal) {
* {
font-family: 'Inter custom', sans-serif;
}
@supports (font-variation-settings: normal) {
* {
font-family: 'Inter custom', sans-serif;
}
}
html,
body {
margin: 0;
padding: 0;
}
html,
body {
margin: 0;
padding: 0;
}
button {
user-select: none;
}
button {
user-select: none;
}
html {
font-size: 16px;
font-variant: none;
font-smooth: always;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
#background-radial-gradient {
background: linear-gradient(180deg, #202738 0%, #070816 100%);
position: fixed;
top: 0;
left: 0;
right: 0;
pointer-events: none;
width: 200vw;
height: 200vh;
transform: translate(-50vw, -100vh);
z-index: -1;
}
html {
min-height: 100%;
}
@media (prefers-color-scheme: dark) {
html {
font-size: 16px;
font-variant: none;
font-smooth: always;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
#background-radial-gradient {
position: fixed;
top: 0;
left: 0;
right: 0;
pointer-events: none;
width: 200vw;
height: 200vh;
background: radial-gradient(50% 50% at 50% 50%, #fc077d10 0%, rgba(255, 255, 255, 0) 100%);
transform: translate(-50vw, -100vh);
z-index: -1;
background-color: #212429;
}
}
@media (prefers-color-scheme: light) {
html {
min-height: 100%;
background-color: #f7f8fa;
}
}
</style>
</head>
@media (prefers-color-scheme: dark) {
html {
background-color: #212429;
}
}
@media (prefers-color-scheme: light) {
html {
background-color: #f7f8fa;
}
}
</style>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<!-- The root is the container of the app -->
<div id="root">
<!-- Triggers the font to load immediately and then is replaced by the app -->
<div>&emsp;</div>
</div>
<div id="root">
<!-- Triggers the font to load immediately and then is replaced by the app -->
<div>&emsp;</div>
</div>
<div id="background-radial-gradient"></div>
<div id="background-radial-gradient"></div>
</body>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
</html>

View File

@@ -2,7 +2,10 @@
"background_color": "#fff",
"display": "standalone",
"homepage_url": "https://app.uniswap.org",
"providedBy": { "name": "Uniswap", "url": "https://uniswap.org" },
"providedBy": {
"name": "Uniswap",
"url": "https://uniswap.org"
},
"icons": [
{
"src": "./images/192x192_App_Icon.png",
@@ -23,5 +26,5 @@
"iconPath": "./images/256x256_App_Icon_Pink.svg",
"short_name": "Uniswap",
"start_url": ".",
"theme_color": "#ff007a"
}
"theme_color": "#FC72FFs"
}

View File

@@ -20,6 +20,11 @@ export interface ITraceContext {
export const TraceContext = createContext<ITraceContext>({})
export function useTrace(trace?: ITraceContext): ITraceContext {
const parentTrace = useContext(TraceContext)
return useMemo(() => ({ ...parentTrace, ...trace }), [parentTrace, trace])
}
type TraceProps = {
shouldLogImpression?: boolean // whether to log impression on mount
name?: EventName
@@ -31,25 +36,32 @@ type TraceProps = {
* and propagates the context to child traces.
*/
export const Trace = memo(
({ shouldLogImpression, name, children, page, section, element, properties }: PropsWithChildren<TraceProps>) => {
const parentTrace = useContext(TraceContext)
({
shouldLogImpression,
name,
children,
page,
section,
modal,
element,
properties,
}: PropsWithChildren<TraceProps>) => {
const parentTrace = useTrace()
const combinedProps = useMemo(
() => ({
...parentTrace,
...Object.fromEntries(Object.entries({ page, section, element }).filter(([_, v]) => v !== undefined)),
...Object.fromEntries(Object.entries({ page, section, modal, element }).filter(([_, v]) => v !== undefined)),
}),
[element, parentTrace, page, section]
[element, parentTrace, page, modal, section]
)
useEffect(() => {
if (shouldLogImpression) {
const origin = window.location.origin
const commitHash = process.env.REACT_APP_GIT_COMMIT_HASH
sendAnalyticsEvent(name ?? EventName.PAGE_VIEWED, {
...combinedProps,
...properties,
origin,
git_commit_hash: commitHash,
})
}

View File

@@ -8,6 +8,7 @@ export enum EventName {
APP_LOADED = 'Application Loaded',
APPROVE_TOKEN_TXN_SUBMITTED = 'Approve Token Transaction Submitted',
CONNECT_WALLET_BUTTON_CLICKED = 'Connect Wallet Button Clicked',
EXPLORE_BANNER_CLICKED = 'Explore Banner Clicked',
EXPLORE_SEARCH_SELECTED = 'Explore Search Selected',
EXPLORE_TOKEN_ROW_CLICKED = 'Explore Token Row Clicked',
PAGE_VIEWED = 'Page Viewed',
@@ -64,8 +65,6 @@ export enum WALLET_CONNECTION_RESULT {
FAILED = 'Failed',
}
export const NATIVE_CHAIN_ID = 'NATIVE'
export enum SWAP_PRICE_UPDATE_USER_RESPONSE {
ACCEPTED = 'Accepted',
REJECTED = 'Rejected',
@@ -75,6 +74,7 @@ export enum SWAP_PRICE_UPDATE_USER_RESPONSE {
* Known pages in the app. Highest order context.
*/
export enum PageName {
TOKEN_DETAILS_PAGE = 'token-details',
TOKENS_PAGE = 'tokens-page',
POOL_PAGE = 'pool-page',
SWAP_PAGE = 'swap-page',
@@ -90,6 +90,7 @@ export enum PageName {
export enum SectionName {
CURRENCY_INPUT_PANEL = 'swap-currency-input',
CURRENCY_OUTPUT_PANEL = 'swap-currency-output',
WIDGET = 'widget',
// alphabetize additional section names.
}
@@ -109,6 +110,7 @@ export enum ElementName {
COMMON_BASES_CURRENCY_BUTTON = 'common-bases-currency-button',
CONFIRM_SWAP_BUTTON = 'confirm-swap-or-send',
CONNECT_WALLET_BUTTON = 'connect-wallet-button',
EXPLORE_BANNER = 'explore-banner',
EXPLORE_SEARCH_INPUT = 'explore_search_input',
IMPORT_TOKEN_BUTTON = 'import-token-button',
MAX_TOKEN_AMOUNT_BUTTON = 'max-token-amount-button',

View File

@@ -35,12 +35,13 @@ export function initializeAnalytics() {
/** Sends an event to Amplitude. */
export function sendAnalyticsEvent(eventName: string, eventProperties?: Record<string, unknown>) {
const origin = window.location.origin
if (!API_KEY) {
console.log(`[analytics(${eventName})]: ${JSON.stringify(eventProperties)}`)
return
}
track(eventName, eventProperties)
track(eventName, { ...eventProperties, origin })
}
type Value = string | number | boolean | string[] | number[]

View File

@@ -1,13 +1,16 @@
import { Currency, CurrencyAmount, Percent, Token } from '@uniswap/sdk-core'
import { NATIVE_CHAIN_ID } from './constants'
import { Trade } from '@uniswap/router-sdk'
import { Currency, CurrencyAmount, Percent, Price, Token, TradeType } from '@uniswap/sdk-core'
import { NATIVE_CHAIN_ID } from 'constants/tokens'
import { InterfaceTrade } from 'state/routing/types'
import { computeRealizedPriceImpact } from 'utils/prices'
export const getDurationUntilTimestampSeconds = (futureTimestampInSecondsSinceEpoch?: number): number | undefined => {
if (!futureTimestampInSecondsSinceEpoch) return undefined
return futureTimestampInSecondsSinceEpoch - new Date().getTime() / 1000
}
export const getDurationFromDateMilliseconds = (start: Date): number => {
export const getDurationFromDateMilliseconds = (start?: Date): number | undefined => {
if (!start) return undefined
return new Date().getTime() - start.getTime()
}
@@ -21,3 +24,57 @@ export const getTokenAddress = (currency: Currency) => (currency.isNative ? NATI
export const formatPercentInBasisPointsNumber = (percent: Percent): number => parseFloat(percent.toFixed(2)) * 100
export const formatPercentNumber = (percent: Percent): number => parseFloat(percent.toFixed(2))
export const getPriceUpdateBasisPoints = (
prevPrice: Price<Currency, Currency>,
newPrice: Price<Currency, Currency>
): number => {
const changeFraction = newPrice.subtract(prevPrice).divide(prevPrice)
const changePercentage = new Percent(changeFraction.numerator, changeFraction.denominator)
return formatPercentInBasisPointsNumber(changePercentage)
}
export const formatSwapSignedAnalyticsEventProperties = ({
trade,
txHash,
}: {
trade: InterfaceTrade<Currency, Currency, TradeType> | Trade<Currency, Currency, TradeType>
txHash: string
}) => ({
transaction_hash: txHash,
token_in_address: getTokenAddress(trade.inputAmount.currency),
token_out_address: getTokenAddress(trade.outputAmount.currency),
token_in_symbol: trade.inputAmount.currency.symbol,
token_out_symbol: trade.outputAmount.currency.symbol,
token_in_amount: formatToDecimal(trade.inputAmount, trade.inputAmount.currency.decimals),
token_out_amount: formatToDecimal(trade.outputAmount, trade.outputAmount.currency.decimals),
price_impact_basis_points: formatPercentInBasisPointsNumber(computeRealizedPriceImpact(trade)),
chain_id:
trade.inputAmount.currency.chainId === trade.outputAmount.currency.chainId
? trade.inputAmount.currency.chainId
: undefined,
})
export const formatSwapQuoteReceivedEventProperties = (
trade: Trade<Currency, Currency, TradeType>,
gasUseEstimateUSD?: CurrencyAmount<Token>,
fetchingSwapQuoteStartTime?: Date
) => {
return {
token_in_symbol: trade.inputAmount.currency.symbol,
token_out_symbol: trade.outputAmount.currency.symbol,
token_in_address: getTokenAddress(trade.inputAmount.currency),
token_out_address: getTokenAddress(trade.outputAmount.currency),
price_impact_basis_points: trade ? formatPercentInBasisPointsNumber(computeRealizedPriceImpact(trade)) : undefined,
estimated_network_fee_usd: gasUseEstimateUSD ? formatToDecimal(gasUseEstimateUSD, 2) : undefined,
chain_id:
trade.inputAmount.currency.chainId === trade.outputAmount.currency.chainId
? trade.inputAmount.currency.chainId
: undefined,
token_in_amount: formatToDecimal(trade.inputAmount, trade.inputAmount.currency.decimals),
token_out_amount: formatToDecimal(trade.outputAmount, trade.outputAmount.currency.decimals),
quote_latency_milliseconds: fetchingSwapQuoteStartTime
? getDurationFromDateMilliseconds(fetchingSwapQuoteStartTime)
: undefined,
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -1,4 +1,4 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3.24453 18.0887C3.24331 19.0467 3.47372 19.7558 3.93576 20.2158C4.39658 20.6771 5.09574 20.904 6.03326 20.8967H8.11975C8.20693 20.8934 8.29386 20.9079 8.37521 20.9395C8.45656 20.9711 8.53062 21.019 8.5928 21.0802L10.0779 22.5484C10.7527 23.2226 11.4139 23.5578 12.0617 23.5541C12.7096 23.5504 13.3709 23.2152 14.0456 22.5484L15.5124 21.0802C15.5767 21.0182 15.6529 20.97 15.7365 20.9385C15.82 20.9069 15.9091 20.8927 15.9982 20.8967H18.0719C19.0192 20.8979 19.7251 20.6673 20.1896 20.2048C20.6541 19.7423 20.8864 19.0333 20.8864 18.0777V16.0021C20.8816 15.8222 20.9474 15.6476 21.0697 15.5157L22.5365 14.0475C23.2198 13.3758 23.559 12.7145 23.5541 12.0636C23.5492 11.4127 23.21 10.7508 22.5365 10.0779L21.0697 8.6097C20.9471 8.47802 20.8812 8.30329 20.8864 8.12336V6.04769C20.8851 5.09092 20.6547 4.3819 20.1951 3.92064C19.7355 3.45939 19.0278 3.22875 18.0719 3.22875H15.9982C15.9091 3.23242 15.8201 3.21807 15.7366 3.18653C15.6532 3.155 15.5769 3.10694 15.5124 3.04523L14.0456 1.57703C13.3709 0.902883 12.7096 0.567648 12.0617 0.571319C11.4139 0.574989 10.7527 0.910224 10.0779 1.57703L8.5928 3.04523C8.53043 3.10622 8.45638 3.15393 8.37508 3.18547C8.29377 3.21701 8.20689 3.23173 8.11975 3.22875H6.03326C5.08718 3.22998 4.38373 3.45877 3.92291 3.91513C3.4621 4.3715 3.23168 5.08235 3.23168 6.04769V8.12887C3.23683 8.3088 3.17096 8.48352 3.04833 8.6152L1.58154 10.0834C0.908042 10.7551 0.571289 11.417 0.571289 12.0691C0.571289 12.7213 0.912332 13.3844 1.59439 14.0585L3.06118 15.5267C3.18346 15.6586 3.24928 15.8332 3.24453 16.0131V18.0887Z" fill="#4C82FB"/>
<path d="M3.24453 18.0887C3.24331 19.0467 3.47372 19.7558 3.93576 20.2158C4.39658 20.6771 5.09574 20.904 6.03326 20.8967H8.11975C8.20693 20.8934 8.29386 20.9079 8.37521 20.9395C8.45656 20.9711 8.53062 21.019 8.5928 21.0802L10.0779 22.5484C10.7527 23.2226 11.4139 23.5578 12.0617 23.5541C12.7096 23.5504 13.3709 23.2152 14.0456 22.5484L15.5124 21.0802C15.5767 21.0182 15.6529 20.97 15.7365 20.9385C15.82 20.9069 15.9091 20.8927 15.9982 20.8967H18.0719C19.0192 20.8979 19.7251 20.6673 20.1896 20.2048C20.6541 19.7423 20.8864 19.0333 20.8864 18.0777V16.0021C20.8816 15.8222 20.9474 15.6476 21.0697 15.5157L22.5365 14.0475C23.2198 13.3758 23.559 12.7145 23.5541 12.0636C23.5492 11.4127 23.21 10.7508 22.5365 10.0779L21.0697 8.6097C20.9471 8.47802 20.8812 8.30329 20.8864 8.12336V6.04769C20.8851 5.09092 20.6547 4.3819 20.1951 3.92064C19.7355 3.45939 19.0278 3.22875 18.0719 3.22875H15.9982C15.9091 3.23242 15.8201 3.21807 15.7366 3.18653C15.6532 3.155 15.5769 3.10694 15.5124 3.04523L14.0456 1.57703C13.3709 0.902883 12.7096 0.567648 12.0617 0.571319C11.4139 0.574989 10.7527 0.910224 10.0779 1.57703L8.5928 3.04523C8.53043 3.10622 8.45638 3.15393 8.37508 3.18547C8.29377 3.21701 8.20689 3.23173 8.11975 3.22875H6.03326C5.08718 3.22998 4.38373 3.45877 3.92291 3.91513C3.4621 4.3715 3.23168 5.08235 3.23168 6.04769V8.12887C3.23683 8.3088 3.17096 8.48352 3.04833 8.6152L1.58154 10.0834C0.908042 10.7551 0.571289 11.417 0.571289 12.0691C0.571289 12.7213 0.912332 13.3844 1.59439 14.0585L3.06118 15.5267C3.18346 15.6586 3.24928 15.8332 3.24453 16.0131V18.0887Z" fill="currentColor"/>
<path d="M11.996 15.9909C11.7795 16.3208 11.4599 16.5064 11.0887 16.5064C10.7072 16.5064 10.4083 16.3517 10.1299 15.9909L7.69677 13.0216C7.5215 12.8051 7.42871 12.5783 7.42871 12.3309C7.42871 11.8154 7.82049 11.4133 8.32567 11.4133C8.63497 11.4133 8.8824 11.5267 9.12984 11.8463L11.0475 14.2897L15.1199 7.75329C15.3364 7.40275 15.6147 7.23779 15.924 7.23779C16.4086 7.23779 16.8622 7.57802 16.8622 8.0832C16.8622 8.32033 16.7385 8.56777 16.6045 8.78427L11.996 15.9909Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@@ -8,6 +8,8 @@ import { useTheme } from 'styled-components/macro'
import { LineChartProps } from './LineChart'
type AnimatedInLineChartProps<T> = Omit<LineChartProps<T>, 'height' | 'width' | 'children'>
const config = {
duration: 800,
easing: easeCubicInOut,
@@ -23,10 +25,7 @@ function AnimatedInLineChart<T>({
curve,
color,
strokeWidth,
width,
height,
children,
}: LineChartProps<T>) {
}: AnimatedInLineChartProps<T>) {
const lineRef = useRef<SVGPathElement>(null)
const [lineLength, setLineLength] = useState(0)
const [shouldAnimate, setShouldAnimate] = useState(false)
@@ -41,49 +40,54 @@ function AnimatedInLineChart<T>({
},
})
const effectDependency = lineRef.current
// We need to check to see after the "invisble" line has been drawn
// what the length is to be able to animate in the line for the first time
// This will run on each render to see if there is a new line length
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(() => {
if (lineRef.current) {
setLineLength(lineRef.current.getTotalLength())
setShouldAnimate(true)
const length = lineRef.current.getTotalLength()
if (length !== lineLength) {
setLineLength(length)
}
if (length > 0 && !shouldAnimate && !hasAnimatedIn) {
setShouldAnimate(true)
}
}
}, [effectDependency])
})
const theme = useTheme()
const lineColor = color ?? theme.accentAction
return (
<svg width={width} height={height}>
<Group top={marginTop}>
<LinePath curve={curve} x={getX} y={getY}>
{({ path }) => {
const d = path(data) || ''
return (
<>
<Group top={marginTop}>
<LinePath curve={curve} x={getX} y={getY}>
{({ path }) => {
const d = path(data) || ''
return (
<>
<animated.path
d={d}
ref={lineRef}
strokeWidth={strokeWidth}
strokeOpacity={hasAnimatedIn ? 1 : 0}
fill="none"
stroke={lineColor}
/>
{shouldAnimate && lineLength !== 0 && (
<animated.path
d={d}
ref={lineRef}
strokeWidth={strokeWidth}
strokeOpacity={hasAnimatedIn ? 1 : 0}
fill="none"
stroke={lineColor}
strokeDashoffset={spring.frame.to((v) => v * lineLength)}
strokeDasharray={lineLength}
/>
{shouldAnimate && lineLength !== 0 && (
<animated.path
d={d}
strokeWidth={strokeWidth}
fill="none"
stroke={lineColor}
strokeDashoffset={spring.frame.to((v) => v * lineLength)}
strokeDasharray={lineLength}
/>
)}
</>
)
}}
</LinePath>
</Group>
{children}
</svg>
)}
</>
)
}}
</LinePath>
</Group>
)
}

View File

@@ -1,14 +1,20 @@
import { SparkLineLoadingBubble } from 'components/Tokens/TokenTable/TokenRow'
import { curveCardinal, scaleLinear } from 'd3'
import { filterPrices } from 'graphql/data/Token'
import { TopToken } from 'graphql/data/TopTokens'
import { PricePoint } from 'graphql/data/Token'
import { SparklineMap, TopToken } from 'graphql/data/TopTokens'
import { TimePeriod } from 'graphql/data/util'
import React from 'react'
import { useTheme } from 'styled-components/macro'
import { memo } from 'react'
import styled, { useTheme } from 'styled-components/macro'
import { DATA_EMPTY, getPriceBounds } from '../Tokens/TokenDetails/PriceChart'
import { getPriceBounds } from '../Tokens/TokenDetails/PriceChart'
import LineChart from './LineChart'
type PricePoint = { value: number; timestamp: number }
const LoadingContainer = styled.div`
height: 100%;
display: flex;
justify-content: center;
align-items: center;
`
interface SparklineChartProps {
width: number
@@ -16,15 +22,32 @@ interface SparklineChartProps {
tokenData: TopToken
pricePercentChange: number | undefined | null
timePeriod: TimePeriod
sparklineMap: SparklineMap
}
function SparklineChart({ width, height, tokenData, pricePercentChange, timePeriod }: SparklineChartProps) {
function _SparklineChart({
width,
height,
tokenData,
pricePercentChange,
timePeriod,
sparklineMap,
}: SparklineChartProps) {
const theme = useTheme()
// for sparkline
const pricePoints = filterPrices(tokenData?.market?.priceHistory) ?? []
const hasData = pricePoints.length !== 0
const startingPrice = hasData ? pricePoints[0] : DATA_EMPTY
const endingPrice = hasData ? pricePoints[pricePoints.length - 1] : DATA_EMPTY
const pricePoints = tokenData?.address ? sparklineMap[tokenData.address] : null
// Don't display if there's one or less pricepoints
if (!pricePoints || pricePoints.length <= 1) {
return (
<LoadingContainer>
<SparkLineLoadingBubble />
</LoadingContainer>
)
}
const startingPrice = pricePoints[0]
const endingPrice = pricePoints[pricePoints.length - 1]
const widthScale = scaleLinear()
.domain(
// the range of possible input values
@@ -52,4 +75,4 @@ function SparklineChart({ width, height, tokenData, pricePercentChange, timePeri
)
}
export default React.memo(SparklineChart)
export default memo(_SparklineChart)

View File

@@ -104,11 +104,11 @@ const CurrencySelect = styled(ButtonGray)<{
!redesignFlag &&
css`
&:hover {
background-color: ${({ theme }) => (selected ? darken(0.05, theme.deprecated_primary1) : theme.deprecated_bg3)};
background-color: ${({ theme }) => (selected ? theme.deprecated_bg3 : darken(0.05, theme.deprecated_primary1))};
}
&:active {
background-color: ${({ theme }) => (selected ? darken(0.05, theme.deprecated_primary1) : theme.deprecated_bg3)};
background-color: ${({ theme }) => (selected ? theme.deprecated_bg3 : darken(0.05, theme.deprecated_primary1))};
}
`}

View File

@@ -37,7 +37,7 @@ export default function CurrencyLogo({
src?: string | null
}) {
const logoURIs = useCurrencyLogoURIs(currency)
const srcs = useMemo(() => (src ? [src] : logoURIs), [src, logoURIs])
const srcs = useMemo(() => (src ? [src, ...logoURIs] : logoURIs), [src, logoURIs])
const props = {
alt: `${currency?.symbol ?? 'token'} logo`,
size,

View File

@@ -1,10 +1,6 @@
import { BaseVariant, FeatureFlag, featureFlagSettings, useUpdateFlag } from 'featureFlags'
import { FavoriteTokensVariant, useFavoriteTokensFlag } from 'featureFlags/flags/favoriteTokens'
import { NavBarVariant, useNavBarFlag } from 'featureFlags/flags/navBar'
import { NftVariant, useNftFlag } from 'featureFlags/flags/nft'
import { RedesignVariant, useRedesignFlag } from 'featureFlags/flags/redesign'
import { TokensVariant, useTokensFlag } from 'featureFlags/flags/tokens'
import { TokenSafetyVariant, useTokenSafetyFlag } from 'featureFlags/flags/tokenSafety'
import { TraceJsonRpcVariant, useTraceJsonRpcFlag } from 'featureFlags/flags/traceJsonRpc'
import { useAtomValue, useUpdateAtom } from 'jotai/utils'
import { Children, PropsWithChildren, ReactElement, ReactNode, useCallback, useState } from 'react'
@@ -207,32 +203,6 @@ export default function FeatureFlagModal() {
<X size={24} />
</CloseButton>
</Header>
<FeatureFlagGroup name="Phase 0">
<FeatureFlagOption
variant={RedesignVariant}
value={useRedesignFlag()}
featureFlag={FeatureFlag.redesign}
label="Redesign"
/>
<FeatureFlagOption
variant={NavBarVariant}
value={useNavBarFlag()}
featureFlag={FeatureFlag.navBar}
label="NavBar"
/>
<FeatureFlagOption
variant={TokensVariant}
value={useTokensFlag()}
featureFlag={FeatureFlag.tokens}
label="Tokens"
/>
<FeatureFlagOption
variant={TokenSafetyVariant}
value={useTokenSafetyFlag()}
featureFlag={FeatureFlag.tokenSafety}
label="Token Safety"
/>
</FeatureFlagGroup>
<FeatureFlagGroup name="Phase 0 Follow-ups">
<FeatureFlagOption
variant={FavoriteTokensVariant}

View File

@@ -1,26 +0,0 @@
import { ReactElement } from 'react'
import styled from 'styled-components/macro'
import SantaHat from '../../assets/images/santa-hat.png'
const SantaHatImage = styled.img`
position: absolute;
top: -4px;
right: -4px;
height: 18px;
`
const Christmas = <SantaHatImage src={SantaHat} alt="Santa hat" />
const DATE_TO_ORNAMENT: { [date: string]: ReactElement } = {
'12-24': Christmas,
'12-25': Christmas,
}
const HolidayOrnament = () => {
// months in javascript are 0 indexed...
const today = `${new Date().getMonth() + 1}-${new Date().getDate()}`
return DATE_TO_ORNAMENT[today] || null
}
export default HolidayOrnament

View File

@@ -1,345 +0,0 @@
import { Trans } from '@lingui/macro'
import { useWeb3React } from '@web3-react/core'
import { getChainInfo } from 'constants/chainInfo'
import { SupportedChainId } from 'constants/chains'
import useSelectChain from 'hooks/useSelectChain'
import useSyncChainQuery from 'hooks/useSyncChainQuery'
import { darken } from 'polished'
import { useRef } from 'react'
import { AlertTriangle, ArrowDownCircle, ChevronDown } from 'react-feather'
import { useCloseModal, useModalIsOpen, useOpenModal, useToggleModal } from 'state/application/hooks'
import { ApplicationModal } from 'state/application/reducer'
import styled from 'styled-components/macro'
import { ExternalLink, MEDIA_WIDTHS } from 'theme'
import { isMobile } from 'utils/userAgent'
const ActiveRowLinkList = styled.div`
display: flex;
flex-direction: column;
padding: 0 8px;
& > a {
align-items: center;
color: ${({ theme }) => theme.deprecated_text2};
display: flex;
flex-direction: row;
font-size: 14px;
font-weight: 500;
justify-content: space-between;
padding: 8px 0 4px;
text-decoration: none;
}
& > a:first-child {
margin: 0;
margin-top: 0px;
padding-top: 10px;
}
`
const ActiveRowWrapper = styled.div`
background-color: ${({ theme }) => theme.deprecated_bg1};
border-radius: 8px;
cursor: pointer;
padding: 8px;
width: 100%;
`
const FlyoutHeader = styled.div`
color: ${({ theme }) => theme.deprecated_text2};
cursor: default;
font-weight: 400;
`
const FlyoutMenu = styled.div`
position: absolute;
top: 54px;
width: 272px;
z-index: 99;
padding-top: 10px;
@media screen and (min-width: ${MEDIA_WIDTHS.deprecated_upToSmall}px) {
top: 40px;
}
`
const FlyoutMenuContents = styled.div`
align-items: flex-start;
background-color: ${({ theme }) => theme.deprecated_bg0};
box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.01), 0px 4px 8px rgba(0, 0, 0, 0.04), 0px 16px 24px rgba(0, 0, 0, 0.04),
0px 24px 32px rgba(0, 0, 0, 0.01);
border-radius: 20px;
display: flex;
flex-direction: column;
font-size: 16px;
overflow: auto;
padding: 16px;
& > *:not(:last-child) {
margin-bottom: 12px;
}
`
const FlyoutRow = styled.div<{ active: boolean }>`
align-items: center;
background-color: ${({ active, theme }) => (active ? theme.deprecated_bg1 : 'transparent')};
border-radius: 8px;
cursor: pointer;
display: flex;
font-weight: 500;
justify-content: space-between;
padding: 6px 8px;
text-align: left;
width: 100%;
`
const FlyoutRowActiveIndicator = styled.div`
background-color: ${({ theme }) => theme.deprecated_green1};
border-radius: 50%;
height: 9px;
width: 9px;
`
const CircleContainer = styled.div`
width: 20px;
display: flex;
justify-content: center;
`
const LinkOutCircle = styled(ArrowDownCircle)`
transform: rotate(230deg);
width: 16px;
height: 16px;
`
const Logo = styled.img`
height: 20px;
width: 20px;
margin-right: 8px;
`
const NetworkLabel = styled.div`
flex: 1 1 auto;
`
const SelectorLabel = styled(NetworkLabel)`
display: none;
@media screen and (min-width: ${MEDIA_WIDTHS.deprecated_upToSmall}px) {
display: block;
margin-right: 8px;
}
`
const NetworkAlertLabel = styled(NetworkLabel)`
display: none;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin: 0 0.5rem 0 0.4rem;
font-size: 1rem;
width: fit-content;
font-weight: 500;
@media screen and (min-width: ${MEDIA_WIDTHS.deprecated_upToSmall}px) {
display: block;
}
`
const SelectorControls = styled.div<{ supportedChain: boolean }>`
align-items: center;
background-color: ${({ theme }) => theme.deprecated_bg0};
border: 2px solid ${({ theme }) => theme.deprecated_bg0};
border-radius: 16px;
color: ${({ theme }) => theme.deprecated_text1};
display: flex;
font-weight: 500;
justify-content: space-between;
padding: 6px 8px;
${({ supportedChain, theme }) =>
!supportedChain &&
`
color: ${theme.deprecated_white};
background-color: ${theme.deprecated_red1};
border: 2px solid ${theme.deprecated_red1};
`}
cursor: default;
:focus {
background-color: ${({ theme }) => darken(0.1, theme.deprecated_red1)};
}
`
const SelectorLogo = styled(Logo)`
@media screen and (min-width: ${MEDIA_WIDTHS.deprecated_upToSmall}px) {
margin-right: 8px;
}
`
const SelectorWrapper = styled.div`
@media screen and (min-width: ${MEDIA_WIDTHS.deprecated_upToSmall}px) {
position: relative;
}
`
const StyledChevronDown = styled(ChevronDown)`
width: 16px;
`
const NetworkIcon = styled(AlertTriangle)`
margin-left: 0.25rem;
margin-right: 0.25rem;
width: 16px;
height: 16px;
`
const BridgeLabel = ({ chainId }: { chainId: SupportedChainId }) => {
switch (chainId) {
case SupportedChainId.ARBITRUM_ONE:
case SupportedChainId.ARBITRUM_RINKEBY:
return <Trans>Arbitrum Bridge</Trans>
case SupportedChainId.OPTIMISM:
case SupportedChainId.OPTIMISM_GOERLI:
return <Trans>Optimism Bridge</Trans>
case SupportedChainId.POLYGON:
case SupportedChainId.POLYGON_MUMBAI:
return <Trans>Polygon Bridge</Trans>
case SupportedChainId.CELO:
case SupportedChainId.CELO_ALFAJORES:
return <Trans>Portal Bridge</Trans>
default:
return <Trans>Bridge</Trans>
}
}
const ExplorerLabel = ({ chainId }: { chainId: SupportedChainId }) => {
switch (chainId) {
case SupportedChainId.ARBITRUM_ONE:
case SupportedChainId.ARBITRUM_RINKEBY:
return <Trans>Arbiscan</Trans>
case SupportedChainId.OPTIMISM:
case SupportedChainId.OPTIMISM_GOERLI:
return <Trans>Optimistic Etherscan</Trans>
case SupportedChainId.POLYGON:
case SupportedChainId.POLYGON_MUMBAI:
return <Trans>Polygonscan</Trans>
case SupportedChainId.CELO:
case SupportedChainId.CELO_ALFAJORES:
return <Trans>Blockscout</Trans>
default:
return <Trans>Etherscan</Trans>
}
}
function Row({
targetChain,
onSelectChain,
}: {
targetChain: SupportedChainId
onSelectChain: (targetChain: number) => void
}) {
const { provider, chainId } = useWeb3React()
if (!provider || !chainId) {
return null
}
const active = chainId === targetChain
const { helpCenterUrl, explorer, bridge, label, logoUrl } = getChainInfo(targetChain)
const rowContent = (
<FlyoutRow onClick={() => onSelectChain(targetChain)} active={active}>
<Logo src={logoUrl} />
<NetworkLabel>{label}</NetworkLabel>
{chainId === targetChain && (
<CircleContainer>
<FlyoutRowActiveIndicator />
</CircleContainer>
)}
</FlyoutRow>
)
if (active) {
return (
<ActiveRowWrapper>
{rowContent}
<ActiveRowLinkList>
{bridge && (
<ExternalLink href={bridge}>
<BridgeLabel chainId={chainId} />
<CircleContainer>
<LinkOutCircle />
</CircleContainer>
</ExternalLink>
)}
{explorer && (
<ExternalLink href={explorer}>
<ExplorerLabel chainId={chainId} />
<CircleContainer>
<LinkOutCircle />
</CircleContainer>
</ExternalLink>
)}
{helpCenterUrl && (
<ExternalLink href={helpCenterUrl}>
<Trans>Help Center</Trans>
<CircleContainer>
<LinkOutCircle />
</CircleContainer>
</ExternalLink>
)}
</ActiveRowLinkList>
</ActiveRowWrapper>
)
}
return rowContent
}
const NETWORK_SELECTOR_CHAINS = [
SupportedChainId.MAINNET,
SupportedChainId.POLYGON,
SupportedChainId.OPTIMISM,
SupportedChainId.ARBITRUM_ONE,
SupportedChainId.CELO,
]
export default function NetworkSelector() {
const { chainId, provider } = useWeb3React()
const node = useRef<HTMLDivElement>(null)
const isOpen = useModalIsOpen(ApplicationModal.NETWORK_SELECTOR)
const openModal = useOpenModal(ApplicationModal.NETWORK_SELECTOR)
const closeModal = useCloseModal(ApplicationModal.NETWORK_SELECTOR)
const toggleModal = useToggleModal(ApplicationModal.NETWORK_SELECTOR)
const info = getChainInfo(chainId)
const selectChain = useSelectChain()
useSyncChainQuery()
if (!chainId || !provider) {
return null
}
const onSupportedChain = info !== undefined
return (
<SelectorWrapper
ref={node}
onMouseEnter={openModal}
onMouseLeave={closeModal}
onClick={isMobile ? toggleModal : undefined}
>
<SelectorControls supportedChain={onSupportedChain}>
{onSupportedChain ? (
<>
<SelectorLogo src={info.logoUrl} />
<SelectorLabel>{info.label}</SelectorLabel>
<StyledChevronDown />
</>
) : (
<>
<NetworkIcon />
<NetworkAlertLabel>Switch Network</NetworkAlertLabel>
<StyledChevronDown />
</>
)}
</SelectorControls>
{isOpen && (
<FlyoutMenu>
<FlyoutMenuContents>
<FlyoutHeader>
<Trans>Select a {!onSupportedChain ? ' supported ' : ''}network</Trans>
</FlyoutHeader>
{NETWORK_SELECTOR_CHAINS.map((chainId: SupportedChainId) => (
<Row
onSelectChain={async (targetChainId: SupportedChainId) => {
await selectChain(targetChainId)
closeModal()
}}
targetChain={chainId}
key={chainId}
/>
))}
</FlyoutMenuContents>
</FlyoutMenu>
)}
</SelectorWrapper>
)
}

View File

@@ -1,356 +0,0 @@
import { Trans } from '@lingui/macro'
import useScrollPosition from '@react-hook/window-scroll'
import { useWeb3React } from '@web3-react/core'
import { getChainInfoOrDefault } from 'constants/chainInfo'
import { SupportedChainId } from 'constants/chains'
import { TokensVariant, useTokensFlag } from 'featureFlags/flags/tokens'
import { darken } from 'polished'
import { NavLink, useLocation } from 'react-router-dom'
import { Text } from 'rebass'
import { useShowClaimPopup, useToggleSelfClaimModal } from 'state/application/hooks'
import { useUserHasAvailableClaim } from 'state/claim/hooks'
import { useNativeCurrencyBalances } from 'state/connection/hooks'
import { useUserHasSubmittedClaim } from 'state/transactions/hooks'
import { useDarkModeManager } from 'state/user/hooks'
import styled, { useTheme } from 'styled-components/macro'
import { ReactComponent as Logo } from '../../assets/svg/logo.svg'
import { ExternalLink, ThemedText } from '../../theme'
import ClaimModal from '../claim/ClaimModal'
import { CardNoise } from '../earn/styled'
import Menu from '../Menu'
import Row from '../Row'
import { Dots } from '../swap/styleds'
import Web3Status from '../Web3Status'
import HolidayOrnament from './HolidayOrnament'
import NetworkSelector from './NetworkSelector'
const HeaderFrame = styled.div<{ showBackground: boolean }>`
display: grid;
grid-template-columns: 120px 1fr 120px;
align-items: center;
justify-content: space-between;
align-items: center;
flex-direction: row;
width: 100%;
top: 0;
position: relative;
padding: 1rem;
z-index: 21;
position: relative;
/* Background slide effect on scroll. */
background-image: ${({ theme }) => `linear-gradient(to bottom, transparent 50%, ${theme.deprecated_bg0} 50% )}}`};
background-position: ${({ showBackground }) => (showBackground ? '0 -100%' : '0 0')};
background-size: 100% 200%;
box-shadow: 0px 0px 0px 1px ${({ theme, showBackground }) => (showBackground ? theme.deprecated_bg2 : 'transparent;')};
transition: background-position 0.1s, box-shadow 0.1s;
background-blend-mode: hard-light;
${({ theme }) => theme.deprecated_mediaWidth.deprecated_upToLarge`
grid-template-columns: 48px 1fr 1fr;
`};
${({ theme }) => theme.deprecated_mediaWidth.deprecated_upToMedium`
padding: 1rem;
grid-template-columns: 1fr 1fr;
`};
${({ theme }) => theme.deprecated_mediaWidth.deprecated_upToSmall`
padding: 1rem;
grid-template-columns: 36px 1fr;
`};
`
const HeaderControls = styled.div`
display: flex;
flex-direction: row;
align-items: center;
justify-self: flex-end;
`
const HeaderElement = styled.div`
display: flex;
align-items: center;
&:not(:first-child) {
margin-left: 0.5em;
}
/* addresses safaris lack of support for "gap" */
& > *:not(:first-child) {
margin-left: 8px;
}
${({ theme }) => theme.deprecated_mediaWidth.deprecated_upToMedium`
align-items: center;
`};
`
const HeaderLinks = styled(Row)`
justify-self: center;
background-color: ${({ theme }) => theme.deprecated_bg0};
width: max-content;
padding: 2px;
border-radius: 16px;
display: grid;
grid-auto-flow: column;
grid-gap: 10px;
overflow: auto;
align-items: center;
${({ theme }) => theme.deprecated_mediaWidth.deprecated_upToLarge`
justify-self: start;
`};
${({ theme }) => theme.deprecated_mediaWidth.deprecated_upToMedium`
justify-self: center;
`};
${({ theme }) => theme.deprecated_mediaWidth.deprecated_upToMedium`
flex-direction: row;
justify-content: space-between;
justify-self: center;
z-index: 99;
position: fixed;
bottom: 0; right: 50%;
transform: translate(50%,-50%);
margin: 0 auto;
background-color: ${({ theme }) => theme.deprecated_bg0};
border: 1px solid ${({ theme }) => theme.deprecated_bg2};
box-shadow: 0px 6px 10px rgb(0 0 0 / 2%);
`};
`
const AccountElement = styled.div<{ active: boolean }>`
display: flex;
flex-direction: row;
align-items: center;
background-color: ${({ theme, active }) => (!active ? theme.deprecated_bg0 : theme.deprecated_bg0)};
border-radius: 16px;
white-space: nowrap;
width: 100%;
height: 40px;
:focus {
border: 1px solid blue;
}
`
const UNIAmount = styled(AccountElement)`
color: white;
padding: 4px 8px;
height: 36px;
font-weight: 500;
background-color: ${({ theme }) => theme.deprecated_bg3};
background: radial-gradient(174.47% 188.91% at 1.84% 0%, #ff007a 0%, #2172e5 100%), #edeef2;
`
const UNIWrapper = styled.span`
width: fit-content;
position: relative;
cursor: pointer;
:hover {
opacity: 0.8;
}
:active {
opacity: 0.9;
}
`
const BalanceText = styled(Text)`
${({ theme }) => theme.deprecated_mediaWidth.deprecated_upToExtraSmall`
display: none;
`};
`
const Title = styled.a`
display: flex;
align-items: center;
pointer-events: auto;
justify-self: flex-start;
margin-right: 12px;
${({ theme }) => theme.deprecated_mediaWidth.deprecated_upToSmall`
justify-self: center;
`};
:hover {
cursor: pointer;
}
`
const UniIcon = styled.div`
transition: transform 0.3s ease;
:hover {
transform: rotate(-5deg);
}
position: relative;
`
// can't be customized under react-router-dom v6
// so we have to persist to the default one, i.e., .active
const activeClassName = 'active'
const StyledNavLink = styled(NavLink)`
${({ theme }) => theme.flexRowNoWrap}
align-items: left;
border-radius: 3rem;
outline: none;
cursor: pointer;
text-decoration: none;
color: ${({ theme }) => theme.deprecated_text2};
font-size: 1rem;
font-weight: 500;
padding: 8px 12px;
word-break: break-word;
overflow: hidden;
white-space: nowrap;
&.${activeClassName} {
border-radius: 14px;
font-weight: 600;
justify-content: center;
color: ${({ theme }) => theme.deprecated_text1};
background-color: ${({ theme }) => theme.deprecated_bg1};
}
:hover,
:focus {
color: ${({ theme }) => darken(0.1, theme.deprecated_text1)};
}
`
const StyledExternalLink = styled(ExternalLink)`
${({ theme }) => theme.flexRowNoWrap}
align-items: left;
border-radius: 3rem;
outline: none;
cursor: pointer;
text-decoration: none;
color: ${({ theme }) => theme.deprecated_text2};
font-size: 1rem;
width: fit-content;
margin: 0 12px;
font-weight: 500;
&.${activeClassName} {
border-radius: 14px;
font-weight: 600;
color: ${({ theme }) => theme.deprecated_text1};
}
:hover,
:focus {
color: ${({ theme }) => darken(0.1, theme.deprecated_text1)};
text-decoration: none;
}
`
export default function Header() {
const tokensFlag = useTokensFlag()
const { account, chainId } = useWeb3React()
const userEthBalance = useNativeCurrencyBalances(account ? [account] : [])?.[account ?? '']
const [darkMode] = useDarkModeManager()
const { deprecated_white, deprecated_black } = useTheme()
const toggleClaimModal = useToggleSelfClaimModal()
const availableClaim: boolean = useUserHasAvailableClaim(account)
const { claimTxn } = useUserHasSubmittedClaim(account ?? undefined)
const showClaimPopup = useShowClaimPopup()
const scrollY = useScrollPosition()
const { pathname } = useLocation()
const {
infoLink,
nativeCurrency: { symbol: nativeCurrencySymbol },
} = getChainInfoOrDefault(chainId)
// work around https://github.com/remix-run/react-router/issues/8161
// as we can't pass function `({isActive}) => ''` to className with styled-components
const isPoolActive =
pathname.startsWith('/pool') ||
pathname.startsWith('/add') ||
pathname.startsWith('/remove') ||
pathname.startsWith('/increase') ||
pathname.startsWith('/find')
return (
<HeaderFrame showBackground={scrollY > 45}>
<ClaimModal />
<Title href=".">
<UniIcon>
<Logo fill={darkMode ? deprecated_white : deprecated_black} width="24px" height="100%" title="logo" />
<HolidayOrnament />
</UniIcon>
</Title>
<HeaderLinks>
<StyledNavLink id={`swap-nav-link`} to={'/swap'}>
<Trans>Swap</Trans>
</StyledNavLink>
{tokensFlag === TokensVariant.Enabled && (
<StyledNavLink id={`tokens-nav-link`} to={'/tokens'}>
<Trans>Tokens</Trans>
</StyledNavLink>
)}
<StyledNavLink
data-cy="pool-nav-link"
id={`pool-nav-link`}
to={'/pool'}
className={isPoolActive ? activeClassName : undefined}
>
<Trans>Pool</Trans>
</StyledNavLink>
{(!chainId || chainId === SupportedChainId.MAINNET) && (
<StyledNavLink id={`vote-nav-link`} to={'/vote'}>
<Trans>Vote</Trans>
</StyledNavLink>
)}
<StyledExternalLink id={`charts-nav-link`} href={infoLink}>
<Trans>Charts</Trans>
<sup></sup>
</StyledExternalLink>
</HeaderLinks>
<HeaderControls>
<HeaderElement>
<NetworkSelector />
</HeaderElement>
<HeaderElement>
{availableClaim && !showClaimPopup && (
<UNIWrapper onClick={toggleClaimModal}>
<UNIAmount active={!!account && !availableClaim} style={{ pointerEvents: 'auto' }}>
<ThemedText.DeprecatedWhite padding="0 2px">
{claimTxn && !claimTxn?.receipt ? (
<Dots>
<Trans>Claiming UNI</Trans>
</Dots>
) : (
<Trans>Claim UNI</Trans>
)}
</ThemedText.DeprecatedWhite>
</UNIAmount>
<CardNoise />
</UNIWrapper>
)}
<AccountElement active={!!account}>
{account && userEthBalance ? (
<BalanceText style={{ flexShrink: 0, userSelect: 'none' }} pl="0.75rem" pr=".4rem" fontWeight={500}>
<Trans>
{userEthBalance?.toSignificant(3)} {nativeCurrencySymbol}
</Trans>
</BalanceText>
) : null}
<Web3Status />
</AccountElement>
</HeaderElement>
<HeaderElement>
<Menu />
</HeaderElement>
</HeaderControls>
</HeaderFrame>
)
}

View File

@@ -1,6 +1,5 @@
import { useWeb3React } from '@web3-react/core'
import { ConnectionType } from 'connection'
import { NavBarVariant, useNavBarFlag } from 'featureFlags/flags/navBar'
import useENSAvatar from 'hooks/useENSAvatar'
import styled from 'styled-components/macro'
@@ -53,9 +52,8 @@ const Socks = () => {
const useIcon = (connectionType: ConnectionType) => {
const { account } = useWeb3React()
const { avatar } = useENSAvatar(account ?? undefined)
const isNavbarEnabled = useNavBarFlag() === NavBarVariant.Enabled
if ((isNavbarEnabled && avatar) || connectionType === ConnectionType.INJECTED) {
if (avatar || connectionType === ConnectionType.INJECTED) {
return <Identicon />
} else if (connectionType === ConnectionType.WALLET_CONNECT) {
return <img src={WalletConnectIcon} alt="WalletConnect" />
@@ -68,12 +66,11 @@ const useIcon = (connectionType: ConnectionType) => {
export default function StatusIcon({ connectionType, size }: { connectionType: ConnectionType; size?: number }) {
const hasSocks = useHasSocks()
const isNavbarEnabled = useNavBarFlag() === NavBarVariant.Enabled
const icon = useIcon(connectionType)
return (
<IconWrapper size={size ?? 16}>
{isNavbarEnabled && hasSocks && <Socks />}
{hasSocks && <Socks />}
{icon}
</IconWrapper>
)

View File

@@ -1,6 +1,5 @@
import jazzicon from '@metamask/jazzicon'
import { useWeb3React } from '@web3-react/core'
import { NavBarVariant, useNavBarFlag } from 'featureFlags/flags/navBar'
import useENSAvatar from 'hooks/useENSAvatar'
import { useLayoutEffect, useMemo, useRef, useState } from 'react'
import styled from 'styled-components/macro'
@@ -23,8 +22,7 @@ export default function Identicon({ size }: { size?: number }) {
const { account } = useWeb3React()
const { avatar } = useENSAvatar(account ?? undefined)
const [fetchable, setFetchable] = useState(true)
const isNavbarEnabled = useNavBarFlag() === NavBarVariant.Enabled
const iconSize = size ? size : isNavbarEnabled ? 24 : 16
const iconSize = size ?? 24
const icon = useMemo(() => account && jazzicon(iconSize, parseInt(account.slice(2, 10), 16)), [account, iconSize])
const iconRef = useRef<HTMLDivElement>(null)

View File

@@ -143,7 +143,7 @@ export const MenuDropdown = () => {
<BarChartIcon width={24} height={24} />
</Icon>
<PrimaryMenuRow.Text>
<Trans>View token analytics</Trans>
<Trans>View more analytics</Trans>
</PrimaryMenuRow.Text>
</PrimaryMenuRow>
</Column>

View File

@@ -106,7 +106,7 @@ interface SearchBarDropdownProps {
export const SearchBarDropdown = ({ toggleOpen, tokens, collections, hasInput, isLoading }: SearchBarDropdownProps) => {
const [hoveredIndex, setHoveredIndex] = useState<number | undefined>(0)
const searchHistory = useSearchHistory((state: { history: (FungibleToken | GenieCollection)[] }) => state.history)
const { history: searchHistory, updateItem: updateSearchHistory } = useSearchHistory()
const shortenedHistory = useMemo(() => searchHistory.slice(0, 2), [searchHistory])
const { pathname } = useLocation()
const isNFTPage = pathname.includes('/nfts')
@@ -146,9 +146,11 @@ export const SearchBarDropdown = ({ toggleOpen, tokens, collections, hasInput, i
refetchOnReconnect: false,
}
)
useEffect(() => {
trendingTokenResults?.forEach(updateSearchHistory)
}, [trendingTokenResults, updateSearchHistory])
const trendingTokensLength = phase1Flag === NftVariant.Enabled ? (isTokenPage ? 3 : 2) : 4
const trendingTokens = useMemo(
() =>
trendingTokenResults

View File

@@ -1,4 +1,8 @@
import { useWeb3React } from '@web3-react/core'
import clsx from 'clsx'
import { L2NetworkLogo, LogoContainer } from 'components/Tokens/TokenTable/TokenRow'
import { VerifiedIcon } from 'components/TokenSafety/TokenSafetyIcon'
import { getChainInfo } from 'constants/chainInfo'
import { getTokenDetailsURL } from 'graphql/data/util'
import uriToHttp from 'lib/utils/uriToHttp'
import { Box } from 'nft/components/Box'
@@ -10,8 +14,8 @@ import { ethNumberStandardFormatter } from 'nft/utils/currency'
import { putCommas } from 'nft/utils/putCommas'
import { useCallback, useEffect, useState } from 'react'
import { Link, useNavigate } from 'react-router-dom'
import { formatDollar } from 'utils/formatNumbers'
import { VerifiedIcon } from '../../nft/components/icons'
import * as styles from './SearchBar.css'
interface CollectionRowProps {
@@ -100,6 +104,15 @@ export const CollectionRow = ({
)
}
function useBridgedAddress(token: FungibleToken): [string | undefined, number | undefined, string | undefined] {
const { chainId: connectedChainId } = useWeb3React()
const bridgedAddress = connectedChainId ? token.extensions?.bridgeInfo?.[connectedChainId]?.tokenAddress : undefined
if (bridgedAddress && connectedChainId) {
return [bridgedAddress, connectedChainId, getChainInfo(connectedChainId)?.circleLogoUrl]
}
return [undefined, undefined, undefined]
}
interface TokenRowProps {
token: FungibleToken
isHovered: boolean
@@ -123,7 +136,8 @@ export const TokenRow = ({ token, isHovered, setHoveredIndex, toggleOpen, traceE
traceEvent()
}, [addToSearchHistory, toggleOpen, token, traceEvent])
const tokenDetailsPath = getTokenDetailsURL(token.address, undefined, token.chainId)
const [bridgedAddress, bridgedChain, L2Icon] = useBridgedAddress(token)
const tokenDetailsPath = getTokenDetailsURL(bridgedAddress ?? token.address, undefined, bridgedChain ?? token.chainId)
// Close the modal on escape
useEffect(() => {
const keyDownHandler = (event: KeyboardEvent) => {
@@ -150,14 +164,17 @@ export const TokenRow = ({ token, isHovered, setHoveredIndex, toggleOpen, traceE
>
<Row style={{ width: '65%' }}>
{!brokenImage && token.logoURI ? (
<Box
as="img"
src={token.logoURI.includes('ipfs://') ? uriToHttp(token.logoURI)[0] : token.logoURI}
alt={token.name}
className={clsx(loaded ? styles.suggestionImage : styles.imageHolder)}
onError={() => setBrokenImage(true)}
onLoad={() => setLoaded(true)}
/>
<LogoContainer>
<Box
as="img"
src={token.logoURI.includes('ipfs://') ? uriToHttp(token.logoURI)[0] : token.logoURI}
alt={token.name}
className={clsx(loaded ? styles.suggestionImage : styles.imageHolder)}
onError={() => setBrokenImage(true)}
onLoad={() => setLoaded(true)}
/>
<L2NetworkLogo networkUrl={L2Icon} size="16px" />
</LogoContainer>
) : (
<Box className={styles.imageHolder} />
)}
@@ -173,7 +190,7 @@ export const TokenRow = ({ token, isHovered, setHoveredIndex, toggleOpen, traceE
<Column className={styles.suggestionSecondaryContainer}>
{token.priceUsd && (
<Row gap="4">
<Box className={styles.primaryText}>{ethNumberStandardFormatter(token.priceUsd, true)}</Box>
<Box className={styles.primaryText}>{formatDollar({ num: token.priceUsd, isPrice: true })}</Box>
</Row>
)}
{token.price24hChange && (

View File

@@ -1,7 +1,8 @@
import { Trans } from '@lingui/macro'
import { useWeb3React } from '@web3-react/core'
import Web3Status from 'components/Web3Status'
import { NftVariant, useNftFlag } from 'featureFlags/flags/nft'
import { useGlobalChainName } from 'graphql/data/util'
import { chainIdToBackendName } from 'graphql/data/util'
import { Box } from 'nft/components/Box'
import { Row } from 'nft/components/Flex'
import { UniIcon } from 'nft/components/icons'
@@ -37,7 +38,8 @@ const MenuItem = ({ href, id, isActive, children }: MenuItemProps) => {
const PageTabs = () => {
const { pathname } = useLocation()
const nftFlag = useNftFlag()
const chainName = useGlobalChainName()
const { chainId: connectedChainId } = useWeb3React()
const chainName = chainIdToBackendName(connectedChainId)
const isPoolActive =
pathname.startsWith('/pool') ||

View File

@@ -36,7 +36,7 @@ const StyledInput = styled.input<{ error?: boolean; fontSize?: string; align?: s
}
::placeholder {
color: ${({ theme, redesignFlag }) => (redesignFlag ? theme.textSecondary : theme.deprecated_text4)};
color: ${({ theme, redesignFlag }) => (redesignFlag ? theme.textTertiary : theme.deprecated_text4)};
}
`

View File

@@ -1,4 +1,3 @@
import { NavBarVariant, useNavBarFlag } from 'featureFlags/flags/navBar'
import { useCallback, useEffect } from 'react'
import { X } from 'react-feather'
import { animated } from 'react-spring'
@@ -8,7 +7,6 @@ import styled, { useTheme } from 'styled-components/macro'
import { useRemovePopup } from '../../state/application/hooks'
import { PopupContent } from '../../state/application/reducer'
import FailedNetworkSwitchPopup from './FailedNetworkSwitchPopup'
import TransactionPopup from './TransactionPopup'
const StyledClose = styled(X)`
position: absolute;
@@ -58,7 +56,6 @@ export default function PopupItem({
popKey: string
}) {
const removePopup = useRemovePopup()
const navbarFlag = useNavBarFlag()
const removeThisPopup = useCallback(() => removePopup(popKey), [popKey, removePopup])
useEffect(() => {
if (removeAfterMs === null) return undefined
@@ -80,14 +77,7 @@ export default function PopupItem({
})
let popupContent
if ('txn' in content) {
const {
txn: { hash },
} = content
if (navbarFlag === NavBarVariant.Enabled) return null
popupContent = <TransactionPopup hash={hash} />
} else if ('failedSwitchNetwork' in content) {
if ('failedSwitchNetwork' in content) {
popupContent = <FailedNetworkSwitchPopup chainId={content.failedSwitchNetwork} />
}

View File

@@ -7,7 +7,7 @@ exports[`renders multi route 1`] = `
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
background-color: #EDEEF2;
background-color: #E8ECFB;
border: unset;
border-radius: 0.5rem;
color: #000;
@@ -110,11 +110,11 @@ exports[`renders multi route 1`] = `
}
.c6 path {
stroke: #888D9B;
stroke: #99A1BD;
}
.c8 {
background-color: #EDEEF2;
background-color: #E8ECFB;
border-radius: 8px;
display: grid;
font-size: 12px;
@@ -129,9 +129,9 @@ exports[`renders multi route 1`] = `
}
.c9 {
background-color: #CED0D9;
background-color: #C9D0E7;
border-radius: 4px;
color: #565A69;
color: #5E6887;
font-size: 10px;
padding: 2px 4px;
z-index: 1021;
@@ -245,7 +245,7 @@ exports[`renders single route 1`] = `
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
background-color: #EDEEF2;
background-color: #E8ECFB;
border: unset;
border-radius: 0.5rem;
color: #000;
@@ -348,11 +348,11 @@ exports[`renders single route 1`] = `
}
.c6 path {
stroke: #888D9B;
stroke: #99A1BD;
}
.c8 {
background-color: #EDEEF2;
background-color: #E8ECFB;
border-radius: 8px;
display: grid;
font-size: 12px;
@@ -367,9 +367,9 @@ exports[`renders single route 1`] = `
}
.c9 {
background-color: #CED0D9;
background-color: #C9D0E7;
border-radius: 4px;
color: #565A69;
color: #5E6887;
font-size: 10px;
padding: 2px 4px;
z-index: 1021;

View File

@@ -3,7 +3,7 @@
exports[`renders currency rows correctly when currencies list is non-empty 1`] = `
<DocumentFragment>
.c7 {
color: #6E727D;
color: #99A1BD;
}
.c4 {
@@ -72,7 +72,7 @@ exports[`renders currency rows correctly when currencies list is non-empty 1`] =
}
.c3:hover {
background-color: #EDEEF2;
background-color: #C9D0E714;
}
.c6 {
@@ -212,12 +212,74 @@ exports[`renders currency rows correctly when currencies list is non-empty 1`] =
exports[`renders loading rows when isLoading is true 1`] = `
<DocumentFragment>
<div
.c0 {
display: grid;
}
.c0 > div {
-webkit-animation: fAQEyV 1.5s infinite;
animation: fAQEyV 1.5s infinite;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
background: linear-gradient( to left,#F5F6FC 25%,#E8ECFB 50%,#F5F6FC 75% );
background-size: 400%;
border-radius: 12px;
height: 2.4em;
will-change: background-position;
}
.c1 {
grid-column-gap: 0.5em;
grid-template-columns: repeat(12,1fr);
max-width: 960px;
padding: 12px 20px;
}
.c1 > div:nth-child(4n + 1) {
grid-column: 1 / 8;
height: 1em;
margin-bottom: 0.25em;
}
.c1 > div:nth-child(4n + 2) {
grid-column: 12;
height: 1em;
margin-top: 0.25em;
}
.c1 > div:nth-child(4n + 3) {
grid-column: 1 / 4;
height: 0.75em;
}
<div
style="position: relative; height: 10px; width: 100%; overflow: auto; will-change: transform; direction: ltr;"
>
<div
style="height: 0px; width: 100%;"
/>
style="height: 560px; width: 100%;"
>
<div
class="c0 c1"
>
<div />
<div />
<div />
</div>
<div
class="c0 c1"
>
<div />
<div />
<div />
</div>
<div
class="c0 c1"
>
<div />
<div />
<div />
</div>
</div>
</div>
</DocumentFragment>
`;

View File

@@ -6,7 +6,6 @@ import { TraceEvent } from 'analytics/TraceEvent'
import TokenSafetyIcon from 'components/TokenSafety/TokenSafetyIcon'
import { checkWarning } from 'constants/tokenSafety'
import { RedesignVariant, useRedesignFlag } from 'featureFlags/flags/redesign'
import { TokenSafetyVariant, useTokenSafetyFlag } from 'featureFlags/flags/tokenSafety'
import { CSSProperties, MutableRefObject, useCallback, useMemo } from 'react'
import { XOctagon } from 'react-feather'
import { Check } from 'react-feather'
@@ -135,7 +134,6 @@ export function CurrencyRow({
const balance = useCurrencyBalance(account ?? undefined, currency)
const warning = currency.isNative ? null : checkWarning(currency.address)
const redesignFlagEnabled = useRedesignFlag() === RedesignVariant.Enabled
const tokenSafetyFlagEnabled = useTokenSafetyFlag() === TokenSafetyVariant.Enabled
const isBlockedToken = !!warning && !warning.canProceed
const blockedTokenOpacity = '0.6'
@@ -168,7 +166,7 @@ export function CurrencyRow({
<AutoColumn style={{ opacity: isBlockedToken ? blockedTokenOpacity : '1' }}>
<Row>
<CurrencyName title={currency.name}>{currency.name}</CurrencyName>
{tokenSafetyFlagEnabled && <TokenSafetyIcon warning={warning} />}
<TokenSafetyIcon warning={warning} />
{isBlockedToken && <BlockedTokenIcon />}
</Row>
<ThemedText.DeprecatedDarkGray ml="0px" fontSize={'12px'} fontWeight={300}>
@@ -227,6 +225,14 @@ export const formatAnalyticsEventProperties = (
: { search_token_address_input: isAddressSearch }),
})
const LoadingRow = () => (
<LoadingRows>
<div />
<div />
<div />
</LoadingRows>
)
export default function CurrencyList({
height,
currencies,
@@ -272,13 +278,7 @@ export default function CurrencyList({
const token = currency?.wrapped
if (isLoading) {
return (
<LoadingRows>
<div />
<div />
<div />
</LoadingRows>
)
return LoadingRow()
} else if (currency) {
return (
<CurrencyRow
@@ -303,7 +303,11 @@ export default function CurrencyList({
return currencyKey(currency)
}, [])
return (
return isLoading ? (
<FixedSizeList height={height} ref={fixedListRef as any} width="100%" itemData={[]} itemCount={10} itemSize={56}>
{LoadingRow}
</FixedSizeList>
) : (
<FixedSizeList
height={height}
ref={fixedListRef as any}

View File

@@ -13,7 +13,6 @@ import useNativeCurrency from 'lib/hooks/useNativeCurrency'
import { getTokenFilter } from 'lib/hooks/useTokenList/filtering'
import { tokenComparator, useSortTokensByQuery } from 'lib/hooks/useTokenList/sorting'
import { ChangeEvent, KeyboardEvent, RefObject, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { Edit } from 'react-feather'
import AutoSizer from 'react-virtualized-auto-sizer'
import { FixedSizeList } from 'react-window'
import { Text } from 'rebass'
@@ -21,10 +20,10 @@ import { useAllTokenBalances } from 'state/connection/hooks'
import styled, { useTheme } from 'styled-components/macro'
import { useAllTokens, useIsUserAddedToken, useSearchInactiveTokenLists, useToken } from '../../hooks/Tokens'
import { ButtonText, CloseIcon, IconWrapper, ThemedText } from '../../theme'
import { CloseIcon, ThemedText } from '../../theme'
import { isAddress } from '../../utils'
import Column from '../Column'
import Row, { RowBetween, RowFixed } from '../Row'
import Row, { RowBetween } from '../Row'
import CommonBases from './CommonBases'
import { CurrencyRow, formatAnalyticsEventProperties } from './CurrencyList'
import CurrencyList from './CurrencyList'
@@ -37,16 +36,6 @@ const ContentWrapper = styled(Column)<{ redesignFlag?: boolean }>`
position: relative;
`
const Footer = styled.div`
width: 100%;
border-radius: 20px;
padding: 20px;
border-top-left-radius: 0;
border-top-right-radius: 0;
background-color: ${({ theme }) => theme.deprecated_bg1};
border-top: 1px solid ${({ theme }) => theme.deprecated_bg2};
`
interface CurrencySearchProps {
isOpen: boolean
onDismiss: () => void
@@ -56,7 +45,6 @@ interface CurrencySearchProps {
showCommonBases?: boolean
showCurrencyAmount?: boolean
disableNonToken?: boolean
showManageView: () => void
}
export function CurrencySearch({
@@ -68,7 +56,6 @@ export function CurrencySearch({
disableNonToken,
onDismiss,
isOpen,
showManageView,
}: CurrencySearchProps) {
const redesignFlag = useRedesignFlag()
const redesignFlagEnabled = redesignFlag === RedesignVariant.Enabled
@@ -107,11 +94,12 @@ export function CurrencySearch({
return Object.values(allTokens).filter(getTokenFilter(debouncedQuery))
}, [allTokens, debouncedQuery])
const [balances, balancesIsLoading] = useAllTokenBalances()
const [balances, balancesAreLoading] = useAllTokenBalances()
const sortedTokens: Token[] = useMemo(
() => (!balancesIsLoading ? [...filteredTokens].sort(tokenComparator.bind(null, balances)) : []),
[balances, filteredTokens, balancesIsLoading]
() => (!balancesAreLoading ? [...filteredTokens].sort(tokenComparator.bind(null, balances)) : []),
[balances, filteredTokens, balancesAreLoading]
)
const isLoading = Boolean(balancesAreLoading && !tokenLoaderTimerElapsed)
const filteredSortedTokens = useSortTokensByQuery(debouncedQuery, sortedTokens)
@@ -241,7 +229,7 @@ export function CurrencySearch({
)}
/>
</Column>
) : filteredSortedTokens?.length > 0 || filteredInactiveTokens?.length > 0 ? (
) : filteredSortedTokens?.length > 0 || filteredInactiveTokens?.length > 0 || isLoading ? (
<div style={{ flex: '1' }}>
<AutoSizer disableWidth>
{({ height }) => (
@@ -254,7 +242,7 @@ export function CurrencySearch({
selectedCurrency={selectedCurrency}
fixedListRef={fixedList}
showCurrencyAmount={showCurrencyAmount}
isLoading={balancesIsLoading && !tokenLoaderTimerElapsed}
isLoading={isLoading}
searchQuery={searchQuery}
isAddressSearch={isAddressSearch}
/>
@@ -268,26 +256,6 @@ export function CurrencySearch({
</ThemedText.DeprecatedMain>
</Column>
)}
{!redesignFlagEnabled && (
<Footer>
<Row justify="center">
<ButtonText
onClick={showManageView}
color={theme.deprecated_primary1}
className="list-token-manage-button"
>
<RowFixed>
<IconWrapper size="16px" marginRight="6px" stroke={theme.deprecated_primaryText1}>
<Edit />
</IconWrapper>
<ThemedText.DeprecatedMain color={theme.deprecated_primaryText1}>
<Trans>Manage Token Lists</Trans>
</ThemedText.DeprecatedMain>
</RowFixed>
</ButtonText>
</Row>
</Footer>
)}
</Trace>
</ContentWrapper>
)

View File

@@ -1,7 +1,6 @@
import { Currency, Token } from '@uniswap/sdk-core'
import { TokenList } from '@uniswap/token-lists'
import TokenSafety from 'components/TokenSafety'
import { TokenSafetyVariant, useTokenSafetyFlag } from 'featureFlags/flags/tokenSafety'
import usePrevious from 'hooks/usePrevious'
import { memo, useCallback, useEffect, useState } from 'react'
import { WrappedTokenInfo } from 'state/lists/wrappedTokenInfo'
@@ -44,7 +43,7 @@ export default memo(function CurrencySearchModal({
showCurrencyAmount = true,
disableNonToken = false,
}: CurrencySearchModalProps) {
const [modalView, setModalView] = useState<CurrencyModalView>(CurrencyModalView.manage)
const [modalView, setModalView] = useState<CurrencyModalView>(CurrencyModalView.search)
const lastOpen = useLast(isOpen)
const userAddedTokens = useUserAddedTokens()
@@ -59,23 +58,16 @@ export default memo(function CurrencySearchModal({
setModalView(CurrencyModalView.tokenSafety)
}
const tokenSafetyFlag = useTokenSafetyFlag()
const handleCurrencySelect = useCallback(
(currency: Currency, hasWarning?: boolean) => {
if (
tokenSafetyFlag === TokenSafetyVariant.Enabled &&
hasWarning &&
currency.isToken &&
!userAddedTokens.find((token) => token.equals(currency))
) {
if (hasWarning && currency.isToken && !userAddedTokens.find((token) => token.equals(currency))) {
showTokenSafetySpeedbump(currency)
} else {
onCurrencySelect(currency)
onDismiss()
}
},
[onDismiss, onCurrencySelect, tokenSafetyFlag, userAddedTokens]
[onDismiss, onCurrencySelect, userAddedTokens]
)
// for token import view
@@ -91,7 +83,6 @@ export default memo(function CurrencySearchModal({
// used for token safety
const [warningToken, setWarningToken] = useState<Token | undefined>()
const showManageView = useCallback(() => setModalView(CurrencyModalView.manage), [setModalView])
const handleBackImport = useCallback(
() => setModalView(prevView && prevView !== CurrencyModalView.importToken ? prevView : CurrencyModalView.search),
[setModalView, prevView]
@@ -117,13 +108,12 @@ export default memo(function CurrencySearchModal({
showCommonBases={showCommonBases}
showCurrencyAmount={showCurrencyAmount}
disableNonToken={disableNonToken}
showManageView={showManageView}
/>
)
break
case CurrencyModalView.tokenSafety:
modalHeight = undefined
if (tokenSafetyFlag === TokenSafetyVariant.Enabled && warningToken) {
if (warningToken) {
content = (
<TokenSafety
tokenAddress={warningToken.address}
@@ -137,9 +127,7 @@ export default memo(function CurrencySearchModal({
case CurrencyModalView.importToken:
if (importToken) {
modalHeight = undefined
if (tokenSafetyFlag === TokenSafetyVariant.Enabled) {
showTokenSafetySpeedbump(importToken)
}
showTokenSafetySpeedbump(importToken)
content = (
<ImportToken
tokens={[importToken]}

View File

@@ -11,10 +11,10 @@ exports[`ResizableTextArea renders correctly 1`] = `
flex: 1 1 auto;
width: 0;
resize: none;
background-color: #F7F8FA;
background-color: #F5F6FC;
-webkit-transition: color 300ms step-start;
transition: color 300ms step-start;
color: #000000;
color: #0E111A;
overflow: hidden;
text-overflow: ellipsis;
font-weight: 500;
@@ -34,19 +34,19 @@ exports[`ResizableTextArea renders correctly 1`] = `
}
.c0::-webkit-input-placeholder {
color: #C3C5CB;
color: #99A1BD;
}
.c0::-moz-placeholder {
color: #C3C5CB;
color: #99A1BD;
}
.c0:-ms-input-placeholder {
color: #C3C5CB;
color: #99A1BD;
}
.c0::placeholder {
color: #C3C5CB;
color: #99A1BD;
}
<textarea
@@ -74,10 +74,10 @@ exports[`TextInput renders correctly 1`] = `
-ms-flex: 1 1 auto;
flex: 1 1 auto;
width: 0;
background-color: #F7F8FA;
background-color: #F5F6FC;
-webkit-transition: color 300ms step-start;
transition: color 300ms step-start;
color: #000000;
color: #0E111A;
overflow: hidden;
text-overflow: ellipsis;
font-weight: 500;
@@ -96,19 +96,19 @@ exports[`TextInput renders correctly 1`] = `
}
.c0::-webkit-input-placeholder {
color: #C3C5CB;
color: #99A1BD;
}
.c0::-moz-placeholder {
color: #C3C5CB;
color: #99A1BD;
}
.c0:-ms-input-placeholder {
color: #C3C5CB;
color: #99A1BD;
}
.c0::placeholder {
color: #C3C5CB;
color: #99A1BD;
}
<div

View File

@@ -11,6 +11,7 @@ const VerifiedContainer = styled.div`
export const VerifiedIcon = styled(Verified)<{ size?: string }>`
width: ${({ size }) => size ?? '1em'};
height: ${({ size }) => size ?? '1em'};
color: ${({ theme }) => theme.accentAction};
`
export default function TokenSafetyIcon({ warning }: { warning: Warning | null }) {

View File

@@ -2,6 +2,7 @@ import { Trans } from '@lingui/macro'
import { darken } from 'polished'
import { useState } from 'react'
import styled from 'styled-components/macro'
import { ThemedText } from 'theme'
import { textFadeIn } from 'theme/animations'
import Resource from './Resource'
@@ -24,8 +25,8 @@ const TokenDescriptionContainer = styled.div`
const TruncateDescriptionButton = styled.div`
color: ${({ theme }) => theme.textSecondary};
font-weight: 400;
font-size: 14px;
padding-top: 14px;
font-size: 0.85em;
padding-top: 0.5em;
&:hover,
&:focus {
@@ -52,9 +53,8 @@ export const AboutContainer = styled.div`
padding: 24px 0px;
${textFadeIn}
`
export const AboutHeader = styled.span`
font-size: 28px;
line-height: 36px;
export const AboutHeader = styled(ThemedText.MediumHeader)`
font-size: 28px !important;
`
export const ResourcesContainer = styled.div`
@@ -90,13 +90,17 @@ export function AboutSection({ address, description, homepageUrl, twitterName }:
{tokenDescription}
{shouldTruncate && (
<TruncateDescriptionButton onClick={() => setIsDescriptionTruncated(!isDescriptionTruncated)}>
{isDescriptionTruncated ? <Trans>Read more</Trans> : <Trans>Hide</Trans>}
{isDescriptionTruncated ? <Trans>Show more</Trans> : <Trans>Hide</Trans>}
</TruncateDescriptionButton>
)}
</TokenDescriptionContainer>
<br />
<ThemedText.SubHeaderSmall>
<Trans>Links</Trans>
</ThemedText.SubHeaderSmall>
<ResourcesContainer>
<Resource name={'Etherscan'} link={`https://etherscan.io/address/${address}`} />
<Resource name={'Protocol info'} link={`https://info.uniswap.org/#/tokens/${address}`} />
<Resource name={'More analytics'} link={`https://info.uniswap.org/#/tokens/${address}`} />
{homepageUrl && <Resource name={'Website'} link={homepageUrl} />}
{twitterName && <Resource name={'Twitter'} link={`https://twitter.com/${twitterName}`} />}
</ResourcesContainer>

View File

@@ -1,15 +1,14 @@
import { Trans } from '@lingui/macro'
import styled from 'styled-components/macro'
import { CopyContractAddress } from 'theme'
import { CopyContractAddress, ThemedText } from 'theme'
export const ContractAddressSection = styled.div`
display: flex;
flex-direction: column;
color: ${({ theme }) => theme.textSecondary};
font-weight: 600;
font-size: 14px;
font-size: 0.9em;
gap: 4px;
padding: 36px 0px;
padding: 4px 0px;
`
const ContractAddress = styled.button`
@@ -21,13 +20,14 @@ const ContractAddress = styled.button`
border: none;
min-height: 38px;
padding: 0px;
cursor: pointer;
`
export default function AddressSection({ address }: { address: string }) {
return (
<ContractAddressSection>
<Trans>Contract address</Trans>
<ThemedText.SubHeaderSmall>
<Trans>Contract address</Trans>
</ThemedText.SubHeaderSmall>
<ContractAddress>
<CopyContractAddress address={address} />
</ContractAddress>

View File

@@ -1,83 +1,140 @@
import { Trans } from '@lingui/macro'
import { useToken } from 'hooks/Tokens'
import { useNetworkTokenBalances } from 'hooks/useNetworkTokenBalances'
import { AlertTriangle } from 'react-feather'
import { Currency, CurrencyAmount, Token } from '@uniswap/sdk-core'
import { formatToDecimal } from 'analytics/utils'
import CurrencyLogo from 'components/CurrencyLogo'
import { validateUrlChainParam } from 'graphql/data/util'
import { useStablecoinValue } from 'hooks/useStablecoinPrice'
import { useParams } from 'react-router-dom'
import styled from 'styled-components/macro'
import { StyledInternalLink } from 'theme'
import { currencyAmountToPreciseFloat, formatDollar } from 'utils/formatNumbers'
const BalancesCard = styled.div`
width: 100%;
height: fit-content;
color: ${({ theme }) => theme.textPrimary};
font-size: 12px;
line-height: 16px;
padding: 20px;
box-shadow: ${({ theme }) => theme.shallowShadow};
background-color: ${({ theme }) => theme.backgroundSurface};
border: ${({ theme }) => `1px solid ${theme.backgroundOutline}`};
border-radius: 16px;
`
const ErrorState = styled.div`
display: flex;
align-items: center;
gap: 12px;
color: ${({ theme }) => theme.textSecondary};
font-weight: 500;
font-size: 14px;
line-height: 20px;
`
const ErrorText = styled.span`
display: flex;
flex-wrap: wrap;
`
color: ${({ theme }) => theme.textPrimary};
display: none;
font-size: 12px;
height: fit-content;
line-height: 16px;
padding: 20px;
width: 100%;
// 768 hardcoded to match NFT-redesign navbar breakpoints
// src/nft/css/sprinkles.css.ts
// change to match theme breakpoints when this navbar is updated
@media screen and (min-width: 768px) {
display: flex;
}
`
const TotalBalanceSection = styled.div`
height: fit-content;
width: 100%;
`
const TotalBalance = styled.div`
align-items: center;
display: flex;
justify-content: space-between;
flex-direction: row;
font-size: 20px;
justify-content: space-between;
line-height: 28px;
margin-top: 12px;
align-items: center;
`
const TotalBalanceItem = styled.div`
display: flex;
`
export default function BalanceSummary({
address,
balance,
balanceUsd,
}: {
address: string
balance?: number
balanceUsd?: number
}) {
const token = useToken(address)
const { loading, error } = useNetworkTokenBalances({ address })
const BalanceRowLink = styled(StyledInternalLink)`
color: unset;
`
function BalanceRow({ currency, formattedBalance, usdValue, href }: BalanceRowData) {
const content = (
<TotalBalance key={currency.wrapped.address}>
<TotalBalanceItem>
<CurrencyLogo currency={currency} />
&nbsp;{formattedBalance} {currency?.symbol}
</TotalBalanceItem>
<TotalBalanceItem>{formatDollar({ num: usdValue === 0 ? undefined : usdValue, isPrice: true })}</TotalBalanceItem>
</TotalBalance>
)
if (href) {
return <BalanceRowLink to={href}>{content}</BalanceRowLink>
}
return content
}
interface BalanceRowData {
currency: Currency
formattedBalance: number
usdValue: number | undefined
href?: string
}
export interface BalanceSummaryProps {
tokenAmount: CurrencyAmount<Token> | undefined
nativeCurrencyAmount: CurrencyAmount<Currency> | undefined
isNative: boolean
}
export default function BalanceSummary({ tokenAmount, nativeCurrencyAmount, isNative }: BalanceSummaryProps) {
const balanceUsdValue = useStablecoinValue(tokenAmount)
const nativeBalanceUsdValue = useStablecoinValue(nativeCurrencyAmount)
const { chainName } = useParams<{ chainName?: string }>()
const pageChainName = validateUrlChainParam(chainName).toLowerCase()
const tokenIsWrappedNative =
tokenAmount &&
nativeCurrencyAmount &&
tokenAmount.currency.address.toLowerCase() === nativeCurrencyAmount.currency.wrapped.address.toLowerCase()
if (
(!tokenAmount && !nativeCurrencyAmount) ||
(!tokenAmount && !tokenIsWrappedNative && !isNative) ||
(!isNative && !tokenIsWrappedNative && tokenAmount?.equalTo(0)) ||
(isNative && tokenAmount?.equalTo(0) && nativeCurrencyAmount?.equalTo(0))
) {
return null
}
const showNative = tokenIsWrappedNative || isNative
const currencies = []
if (tokenAmount) {
const tokenData: BalanceRowData = {
currency: tokenAmount.currency,
formattedBalance: formatToDecimal(tokenAmount, Math.min(tokenAmount.currency.decimals, 2)),
usdValue: balanceUsdValue ? currencyAmountToPreciseFloat(balanceUsdValue) : undefined,
}
if (isNative) {
tokenData.href = `/tokens/${pageChainName}/${tokenAmount.currency.address}`
}
currencies.push(tokenData)
}
if (showNative && nativeCurrencyAmount) {
const nativeData: BalanceRowData = {
currency: nativeCurrencyAmount.currency,
formattedBalance: formatToDecimal(nativeCurrencyAmount, Math.min(nativeCurrencyAmount.currency.decimals, 2)),
usdValue: nativeBalanceUsdValue ? currencyAmountToPreciseFloat(nativeBalanceUsdValue) : undefined,
}
if (isNative) {
currencies.unshift(nativeData)
} else {
nativeData.href = `/tokens/${pageChainName}/NATIVE`
currencies.push(nativeData)
}
}
if (loading || (!error && !balance && !balanceUsd)) return null
return (
<BalancesCard>
{error ? (
<ErrorState>
<AlertTriangle size={24} />
<ErrorText>
<Trans>There was an error loading your {token?.symbol} balance</Trans>
</ErrorText>
</ErrorState>
) : (
<>
<TotalBalanceSection>
Your balance
<TotalBalance>
<TotalBalanceItem>{`${balance} ${token?.symbol}`}</TotalBalanceItem>
<TotalBalanceItem>{`$${balanceUsd}`}</TotalBalanceItem>
</TotalBalance>
</TotalBalanceSection>
</>
)}
<TotalBalanceSection>
<Trans>Your balance</Trans>
{currencies.map((props, i) => (
<BalanceRow {...props} key={props.currency.wrapped.address + i} />
))}
</TotalBalanceSection>
</BalancesCard>
)
}

View File

@@ -1,20 +1,21 @@
import { Trans } from '@lingui/macro'
import { NativeCurrency, Token } from '@uniswap/sdk-core'
import { Currency, NativeCurrency, Token } from '@uniswap/sdk-core'
import { ParentSize } from '@visx/responsive'
import CurrencyLogo from 'components/CurrencyLogo'
import { VerifiedIcon } from 'components/TokenSafety/TokenSafetyIcon'
import { getChainInfo } from 'constants/chainInfo'
import { checkWarning } from 'constants/tokenSafety'
import { FavoriteTokensVariant, useFavoriteTokensFlag } from 'featureFlags/flags/favoriteTokens'
import { SingleTokenData, useTokenPricesCached } from 'graphql/data/Token'
import { PriceDurations, PricePoint, SingleTokenData } from 'graphql/data/Token'
import { TopToken } from 'graphql/data/TopTokens'
import { CHAIN_NAME_TO_CHAIN_ID } from 'graphql/data/util'
import useCurrencyLogoURIs, { getTokenLogoURI } from 'lib/hooks/useCurrencyLogoURIs'
import { CHAIN_NAME_TO_CHAIN_ID, TimePeriod } from 'graphql/data/util'
import { useAtomValue } from 'jotai/utils'
import useCurrencyLogoURIs from 'lib/hooks/useCurrencyLogoURIs'
import { useMemo } from 'react'
import styled from 'styled-components/macro'
import { textFadeIn } from 'theme/animations'
import { isAddress } from 'utils'
import { useIsFavorited, useToggleFavorite } from '../state'
import { filterTimeAtom, useIsFavorited, useToggleFavorite } from '../state'
import { ClickFavorited, FavoriteIcon, L2NetworkLogo, LogoContainer } from '../TokenTable/TokenRow'
import PriceChart from './PriceChart'
import ShareButton from './ShareButton'
@@ -59,48 +60,73 @@ export function useTokenLogoURI(
token: NonNullable<SingleTokenData> | NonNullable<TopToken>,
nativeCurrency?: Token | NativeCurrency
) {
const checksummedAddress = isAddress(token.address)
const chainId = CHAIN_NAME_TO_CHAIN_ID[token.chain]
return (
useCurrencyLogoURIs(nativeCurrency)[0] ??
(checksummedAddress && getTokenLogoURI(checksummedAddress, chainId)) ??
token.project?.logoUrl
)
return [
...useCurrencyLogoURIs(nativeCurrency),
...useCurrencyLogoURIs({ ...token, chainId }),
token.project?.logoUrl,
][0]
}
export default function ChartSection({
token,
currency,
nativeCurrency,
prices,
}: {
token: NonNullable<SingleTokenData>
currency?: Currency | null
nativeCurrency?: Token | NativeCurrency
prices: PriceDurations
}) {
const isFavorited = useIsFavorited(token.address)
const toggleFavorite = useToggleFavorite(token.address)
const chainId = CHAIN_NAME_TO_CHAIN_ID[token.chain]
const L2Icon = getChainInfo(chainId).circleLogoUrl
const L2Icon = getChainInfo(chainId)?.circleLogoUrl
const warning = checkWarning(token.address ?? '')
const { prices } = useTokenPricesCached(token)
const timePeriod = useAtomValue(filterTimeAtom)
const logoSrc = useTokenLogoURI(token, nativeCurrency)
// Backend doesn't always return latest price point for every duration.
// Thus we need to manually determine latest price point available, and
// append it to the prices list for every duration.
useMemo(() => {
let latestPricePoint: PricePoint = { value: 0, timestamp: 0 }
let latestPricePointTimePeriod: TimePeriod
Object.keys(prices).forEach((key) => {
const latestPricePointForTimePeriod = prices[key as unknown as TimePeriod]?.slice(-1)[0]
if (latestPricePointForTimePeriod && latestPricePointForTimePeriod.timestamp > latestPricePoint.timestamp) {
latestPricePoint = latestPricePointForTimePeriod
latestPricePointTimePeriod = key as unknown as TimePeriod
}
})
Object.keys(prices).forEach((key) => {
if ((key as unknown as TimePeriod) !== latestPricePointTimePeriod) {
prices[key as unknown as TimePeriod]?.push(latestPricePoint)
}
})
}, [prices])
return (
<ChartHeader>
<TokenInfoContainer>
<TokenNameCell>
<LogoContainer>
<CurrencyLogo src={logoSrc} size={'32px'} symbol={nativeCurrency?.symbol ?? token.symbol} />
<CurrencyLogo
src={logoSrc}
size={'32px'}
symbol={nativeCurrency?.symbol ?? token.symbol}
currency={nativeCurrency ? undefined : currency}
/>
<L2NetworkLogo networkUrl={L2Icon} size={'16px'} />
</LogoContainer>
{nativeCurrency?.name ?? token.name ?? <Trans>Name not found</Trans>}
<TokenSymbol>{nativeCurrency?.symbol ?? token.symbol ?? <Trans>Symbol not found</Trans>}</TokenSymbol>
{!warning && <VerifiedIcon size="20px" />}
{!warning && <VerifiedIcon size="16px" />}
</TokenNameCell>
<TokenActions>
{token.name && token.symbol && token.address && (
<ShareButton tokenName={token.name} tokenSymbol={token.symbol} tokenAddress={token.address} />
)}
{token.name && token.symbol && token.address && <ShareButton token={token} isNative={!!nativeCurrency} />}
{useFavoriteTokensFlag() === FavoriteTokensVariant.Enabled && (
<ClickFavorited onClick={toggleFavorite}>
<FavoriteIcon isFavorited={isFavorited} />
@@ -110,7 +136,7 @@ export default function ChartSection({
</TokenInfoContainer>
<ChartContainer>
<ParentSize>
{({ width, height }) => prices && <PriceChart prices={prices} width={width} height={height} />}
{({ width, height }) => prices && <PriceChart prices={prices[timePeriod]} width={width} height={height} />}
</ParentSize>
</ChartContainer>
</ChartHeader>

View File

@@ -1,199 +0,0 @@
import { Trans } from '@lingui/macro'
import { useToken } from 'hooks/Tokens'
import { useNetworkTokenBalances } from 'hooks/useNetworkTokenBalances'
import { useState } from 'react'
import { AlertTriangle } from 'react-feather'
import { Link } from 'react-router-dom'
import styled from 'styled-components/macro'
import { SMALLEST_MOBILE_MEDIA_BREAKPOINT } from '../constants'
import { LoadingBubble } from '../loading'
const PLACEHOLDER_NAV_FOOTER_HEIGHT = '56px'
const BalanceFooter = styled.div`
height: fit-content;
border: 1px solid ${({ theme }) => theme.backgroundOutline};
background-color: ${({ theme }) => theme.backgroundSurface};
border-radius: 20px 20px 0px 0px;
padding: 12px 16px;
font-weight: 500;
font-size: 14px;
line-height: 20px;
width: 100%;
color: ${({ theme }) => theme.textSecondary};
position: fixed;
left: 0;
bottom: ${PLACEHOLDER_NAV_FOOTER_HEIGHT};
display: flex;
flex-direction: column;
align-content: center;
`
const BalanceValue = styled.div`
font-size: 20px;
line-height: 28px;
display: flex;
gap: 8px;
`
const BalanceTotal = styled.div`
display: flex;
flex-wrap: wrap;
gap: 8px;
color: ${({ theme }) => theme.textPrimary};
`
const BalanceInfo = styled.div`
display: flex;
justify-content: flex-start;
flex-direction: column;
`
const FakeFooterNavBar = styled.div`
position: fixed;
bottom: 0px;
left: 0px;
background-color: ${({ theme }) => theme.backgroundBackdrop};
height: ${PLACEHOLDER_NAV_FOOTER_HEIGHT};
width: 100%;
align-items: flex-end;
padding: 20px 8px;
font-size: 10px;
`
const FiatValue = styled.span`
display: flex;
align-self: flex-end;
font-size: 12px;
line-height: 24px;
@media only screen and (max-width: ${SMALLEST_MOBILE_MEDIA_BREAKPOINT}) {
line-height: 16px;
}
`
const NetworkBalancesSection = styled.div`
height: fit-content;
border-top: 1px solid ${({ theme }) => theme.backgroundOutline};
display: flex;
flex-direction: column;
padding: 16px 0px 8px 0px;
margin-top: 16px;
color: ${({ theme }) => theme.textPrimary};
`
const NetworkBalancesLabel = styled.span`
color: ${({ theme }) => theme.textSecondary};
`
const SwapButton = styled.button`
background-color: ${({ theme }) => theme.accentAction};
border-radius: 12px;
display: flex;
align-items: center;
border: none;
color: ${({ theme }) => theme.accentTextLightPrimary};
padding: 12px 16px;
width: 120px;
height: 44px;
font-size: 16px;
font-weight: 600;
justify-content: center;
`
const TotalBalancesSection = styled.div`
display: flex;
color: ${({ theme }) => theme.textSecondary};
justify-content: space-between;
align-items: center;
`
const ViewAll = styled.span`
display: flex;
color: ${({ theme }) => theme.accentAction};
font-size: 14px;
line-height: 20px;
cursor: pointer;
`
const ErrorState = styled.div`
display: flex;
align-items: center;
gap: 8px;
padding-right: 8px;
`
const LoadingState = styled.div`
display: flex;
flex-direction: column;
gap: 12px;
`
const TopBalanceLoadBubble = styled(LoadingBubble)`
height: 12px;
width: 172px;
`
const BottomBalanceLoadBubble = styled(LoadingBubble)`
height: 16px;
width: 188px;
`
const ErrorText = styled.span`
display: flex;
flex-wrap: wrap;
`
export default function FooterBalanceSummary({
address,
networkBalances,
balance,
balanceUsd,
}: {
address: string
networkBalances: (JSX.Element | null)[] | null
balance?: number
balanceUsd?: number
}) {
const tokenSymbol = useToken(address)?.symbol
const [showMultipleBalances, setShowMultipleBalances] = useState(false)
const multipleBalances = false // for testing purposes
const networkNameIfOneBalance = 'Ethereum' // for testing purposes
const { loading, error } = useNetworkTokenBalances({ address })
return (
<BalanceFooter>
<TotalBalancesSection>
{loading ? (
<LoadingState>
<TopBalanceLoadBubble></TopBalanceLoadBubble>
<BottomBalanceLoadBubble></BottomBalanceLoadBubble>
</LoadingState>
) : error ? (
<ErrorState>
<AlertTriangle size={17} />
<ErrorText>
<Trans>There was an error fetching your balance</Trans>
</ErrorText>
</ErrorState>
) : (
!!balance &&
!!balanceUsd && (
<BalanceInfo>
{multipleBalances ? 'Balance on all networks' : `Your balance on ${networkNameIfOneBalance}`}
<BalanceTotal>
<BalanceValue>
{balance} {tokenSymbol}
</BalanceValue>
<FiatValue>{`$${balanceUsd}`}</FiatValue>
</BalanceTotal>
{multipleBalances && (
<ViewAll onClick={() => setShowMultipleBalances(!showMultipleBalances)}>
<Trans>{showMultipleBalances ? 'Hide' : 'View'} all balances</Trans>
</ViewAll>
)}
</BalanceInfo>
)
)}
<Link to={`/swap?outputCurrency=${address}`}>
<SwapButton>
<Trans>Swap</Trans>
</SwapButton>
</Link>
</TotalBalancesSection>
{showMultipleBalances && (
<NetworkBalancesSection>
<NetworkBalancesLabel>
<Trans>Your balances by network</Trans>
</NetworkBalancesLabel>
{networkBalances}
</NetworkBalancesSection>
)}
<FakeFooterNavBar>**leaving space for updated nav footer**</FakeFooterNavBar>
</BalanceFooter>
)
}

View File

@@ -0,0 +1,40 @@
import Tooltip from 'components/Tooltip'
import { ReactNode, useCallback, useState } from 'react'
import { Info } from 'react-feather'
import styled from 'styled-components/macro'
const InfoTipContainer = styled.div`
display: flex;
position: relative;
align-items: center;
cursor: help;
`
const InfoTipBody = styled.div`
color: ${({ theme }) => theme.textPrimary};
font-weight: 400;
font-size: 12px;
line-height: 16px;
`
const InfoTipWrapper = styled.div`
margin-left: 4px;
display: flex;
align-items: center;
`
export default function InfoTip({ text }: { text: ReactNode; size?: number }) {
const [show, setShow] = useState<boolean>(false)
const open = useCallback(() => setShow(true), [setShow])
const close = useCallback(() => setShow(false), [setShow])
return (
<InfoTipWrapper>
<Tooltip text={<InfoTipBody>{text}</InfoTipBody>} show={show} placement="right">
<InfoTipContainer onClick={open} onMouseEnter={open} onMouseLeave={close}>
<Info size={14} />
</InfoTipContainer>
</Tooltip>
</InfoTipWrapper>
)
}

View File

@@ -1,4 +1,5 @@
import { Footer, LeftPanel, RightPanel, TokenDetailsLayout } from 'pages/TokenDetails'
import { WidgetSkeleton } from 'components/Widget'
import { LeftPanel, RightPanel, TokenDetailsLayout } from 'pages/TokenDetails'
import styled, { useTheme } from 'styled-components/macro'
import { LoadingBubble } from '../loading'
@@ -154,8 +155,9 @@ export function LoadingTokenDetails() {
return (
<TokenDetailsLayout>
<LoadingTokenDetail />
<RightPanel />
<Footer />
<RightPanel>
<WidgetSkeleton />
</RightPanel>
</TokenDetailsLayout>
)
}

View File

@@ -0,0 +1,130 @@
import { Trans } from '@lingui/macro'
import { formatToDecimal } from 'analytics/utils'
import { useStablecoinValue } from 'hooks/useStablecoinPrice'
import styled from 'styled-components/macro'
import { StyledInternalLink } from 'theme'
import { currencyAmountToPreciseFloat, formatDollar } from 'utils/formatNumbers'
import { BalanceSummaryProps } from './BalanceSummary'
const Wrapper = styled.div`
align-content: center;
align-items: center;
border: 1px solid ${({ theme }) => theme.backgroundOutline};
background-color: ${({ theme }) => theme.backgroundSurface};
border-radius: 20px 20px 0px 0px;
bottom: 56px;
color: ${({ theme }) => theme.textSecondary};
display: flex;
flex-direction: row;
font-weight: 500;
font-size: 14px;
height: fit-content;
justify-content: space-between;
left: 0;
line-height: 20px;
padding: 12px 16px;
position: fixed;
width: 100%;
@media screen and (min-width: ${({ theme }) => theme.breakpoint.md}px) {
bottom: 0px;
}
@media screen and (min-width: ${({ theme }) => theme.breakpoint.lg}px) {
display: none;
}
`
const BalanceValue = styled.div`
color: ${({ theme }) => theme.textPrimary};
font-size: 20px;
line-height: 28px;
display: flex;
gap: 8px;
`
const BalanceTotal = styled.div`
align-items: center;
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 8px;
`
const BalanceInfo = styled.div`
display: flex;
flex: 10 1 auto;
flex-direction: column;
justify-content: flex-start;
`
const FiatValue = styled.span`
font-size: 12px;
line-height: 16px;
@media screen and (min-width: ${({ theme }) => theme.breakpoint.sm}px) {
line-height: 24px;
}
`
const SwapButton = styled(StyledInternalLink)`
background-color: ${({ theme }) => theme.accentAction};
border: none;
border-radius: 12px;
color: ${({ theme }) => theme.accentTextLightPrimary};
display: flex;
flex: 1 1 auto;
padding: 12px 16px;
font-size: 1em;
font-weight: 600;
height: 44px;
justify-content: center;
margin: auto;
max-width: 100vw;
`
export default function MobileBalanceSummaryFooter({
tokenAmount,
nativeCurrencyAmount,
isNative,
tokenAddress,
}: BalanceSummaryProps & { tokenAddress: string }) {
const balanceUsdValue = useStablecoinValue(tokenAmount)
const nativeBalanceUsdValue = useStablecoinValue(nativeCurrencyAmount)
const formattedBalance = tokenAmount
? formatToDecimal(tokenAmount, Math.min(tokenAmount.currency.decimals, 2))
: undefined
const balanceUsd = balanceUsdValue ? currencyAmountToPreciseFloat(balanceUsdValue) : undefined
const formattedNativeBalance = nativeCurrencyAmount
? formatToDecimal(nativeCurrencyAmount, Math.min(nativeCurrencyAmount.currency.decimals, 2))
: undefined
const nativeBalanceUsd = nativeBalanceUsdValue ? currencyAmountToPreciseFloat(nativeBalanceUsdValue) : undefined
return (
<Wrapper>
{Boolean(formattedBalance !== undefined && !isNative && tokenAmount?.greaterThan(0)) && (
<BalanceInfo>
<Trans>Your {tokenAmount?.currency?.symbol} balance</Trans>
<BalanceTotal>
<BalanceValue>
{formattedBalance} {tokenAmount?.currency?.symbol}
</BalanceValue>
<FiatValue>{formatDollar({ num: balanceUsd, isPrice: true })}</FiatValue>
</BalanceTotal>
</BalanceInfo>
)}
{Boolean(isNative && nativeCurrencyAmount?.greaterThan(0)) && (
<BalanceInfo>
<Trans>Your {nativeCurrencyAmount?.currency?.symbol} balance</Trans>
<BalanceTotal>
<BalanceValue>
{formattedNativeBalance} {nativeCurrencyAmount?.currency?.symbol}
</BalanceValue>
<FiatValue>{formatDollar({ num: nativeBalanceUsd, isPrice: true })}</FiatValue>
</BalanceTotal>
</BalanceInfo>
)}
<SwapButton to={`/swap?outputCurrency=${tokenAddress}`}>
<Trans>Swap</Trans>
</SwapButton>
</Wrapper>
)
}

View File

@@ -1,64 +0,0 @@
import styled, { useTheme } from 'styled-components/macro'
const Balance = styled.div`
width: 100%;
display: flex;
flex-direction: column;
font-size: 16px;
line-height: 20px;
`
const BalanceItem = styled.div`
display: flex;
`
const BalanceRow = styled.div`
display: flex;
justify-content: space-between;
`
const Logo = styled.img`
height: 32px;
width: 32px;
margin-right: 8px;
`
const Network = styled.span<{ color: string }>`
font-size: 12px;
line-height: 16px;
font-weight: 500;
color: ${({ color }) => color};
`
const NetworkBalanceContainer = styled.div`
display: flex;
padding-top: 16px;
align-items: center;
`
export default function NetworkBalance({
logoUrl,
balance,
tokenSymbol,
fiatValue,
label,
networkColor,
}: {
logoUrl: string
balance: string
tokenSymbol: string
fiatValue: string | number
label: string
networkColor: string | undefined
}) {
const theme = useTheme()
return (
<NetworkBalanceContainer>
<Logo src={logoUrl} />
<Balance>
<BalanceRow>
<BalanceItem>
{balance}&nbsp;{tokenSymbol}
</BalanceItem>
<BalanceItem>${fiatValue}</BalanceItem>
</BalanceRow>
<Network color={networkColor ?? theme.textPrimary}>{label}</Network>
</Balance>
</NetworkBalanceContainer>
)
}

View File

@@ -1,3 +1,4 @@
import { Trans } from '@lingui/macro'
import { AxisBottom, TickFormatter } from '@visx/axis'
import { localPoint } from '@visx/event'
import { EventType } from '@visx/event/lib/types'
@@ -10,8 +11,8 @@ import { PricePoint } from 'graphql/data/Token'
import { TimePeriod } from 'graphql/data/util'
import { useActiveLocale } from 'hooks/useActiveLocale'
import { useAtom } from 'jotai'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { ArrowDownRight, ArrowUpRight } from 'react-feather'
import { ReactNode, useCallback, useEffect, useMemo, useState } from 'react'
import { ArrowDownRight, ArrowUpRight, TrendingUp } from 'react-feather'
import styled, { useTheme } from 'styled-components/macro'
import {
dayHourFormatter,
@@ -21,6 +22,7 @@ import {
monthYearDayFormatter,
weekFormatter,
} from 'utils/formatChartTimes'
import { formatDollar } from 'utils/formatNumbers'
import { MEDIUM_MEDIA_BREAKPOINT } from '../constants'
import { DISPLAYS, ORDERED_TIMES } from '../TokenTable/TimeSelector'
@@ -109,6 +111,7 @@ const TimeButton = styled.button<{ active: boolean }>`
flex: 1;
display: flex;
align-items: center;
justify-content: center;
background-color: ${({ theme, active }) => (active ? theme.backgroundInteractive : 'transparent')};
font-weight: 600;
font-size: 16px;
@@ -247,17 +250,13 @@ export function PriceChart({ width, height, prices }: PriceChartProps) {
setDisplayPrice(endingPrice)
}, [setCrosshair, setDisplayPrice, endingPrice])
// TODO: Display no data available error
if (!prices) {
return null
}
const [tickFormatter, crosshairDateFormatter, ticks] = tickFormat(timePeriod, locale)
const delta = calculateDelta(startingPrice.value, displayPrice.value)
const formattedDelta = formatDelta(delta)
const arrow = getDeltaArrow(delta)
const crosshairEdgeMax = width * 0.85
const crosshairAtEdge = !!crosshair && crosshair > crosshairEdgeMax
const hasData = prices && prices.length > 0
/*
* Default curve doesn't look good for the HOUR chart.
@@ -266,85 +265,95 @@ export function PriceChart({ width, height, prices }: PriceChartProps) {
*/
const curveTension = timePeriod === TimePeriod.HOUR ? 1 : 0.9
const getX = useMemo(() => (p: PricePoint) => timeScale(p.timestamp), [timeScale])
const getY = useMemo(() => (p: PricePoint) => rdScale(p.value), [rdScale])
const curve = useMemo(() => curveCardinal.tension(curveTension), [curveTension])
return (
<>
<ChartHeader>
<TokenPrice>${displayPrice.value < 0.000001 ? '<0.000001' : displayPrice.value.toFixed(6)}</TokenPrice>
<TokenPrice>{formatDollar({ num: displayPrice.value, isPrice: true })}</TokenPrice>
<DeltaContainer>
{formattedDelta}
<ArrowCell>{arrow}</ArrowCell>
</DeltaContainer>
</ChartHeader>
<AnimatedInLineChart
data={prices}
getX={(p: PricePoint) => timeScale(p.timestamp)}
getY={(p: PricePoint) => rdScale(p.value)}
marginTop={margin.top}
curve={curveCardinal.tension(curveTension)}
strokeWidth={2}
width={width}
height={graphHeight}
>
{crosshair !== null ? (
<g>
<AxisBottom
scale={timeScale}
stroke={theme.backgroundOutline}
tickFormat={tickFormatter}
tickStroke={theme.backgroundOutline}
tickLength={4}
hideTicks={true}
tickTransform={'translate(0 -5)'}
tickValues={ticks}
top={graphHeight - 1}
tickLabelProps={() => ({
fill: theme.textSecondary,
fontSize: 12,
textAnchor: 'middle',
transform: 'translate(0 -24)',
})}
/>
<text
x={crosshair + (crosshairAtEdge ? -4 : 4)}
y={margin.crosshair + 10}
textAnchor={crosshairAtEdge ? 'end' : 'start'}
fontSize={12}
fill={theme.textSecondary}
>
{crosshairDateFormatter(displayPrice.timestamp)}
</text>
<Line
from={{ x: crosshair, y: margin.crosshair }}
to={{ x: crosshair, y: graphHeight }}
stroke={theme.backgroundOutline}
strokeWidth={1}
pointerEvents="none"
strokeDasharray="4,4"
/>
<GlyphCircle
left={crosshair}
top={rdScale(displayPrice.value) + margin.top}
size={50}
fill={theme.accentActive}
stroke={theme.backgroundOutline}
strokeWidth={2}
/>
</g>
) : (
<AxisBottom scale={timeScale} stroke={theme.backgroundOutline} top={graphHeight - 1} hideTicks />
)}
<rect
x={0}
y={0}
{!hasData ? (
<MissingPriceChart
width={width}
height={graphHeight}
fill={'transparent'}
onTouchStart={handleHover}
onTouchMove={handleHover}
onMouseMove={handleHover}
onMouseLeave={resetDisplay}
message={prices && prices.length === 0 ? <NoV3DataMessage /> : <MissingDataMessage />}
/>
</AnimatedInLineChart>
) : (
<svg width={width} height={graphHeight}>
<AnimatedInLineChart
data={prices}
getX={getX}
getY={getY}
marginTop={margin.top}
curve={curve}
strokeWidth={2}
/>
{crosshair !== null ? (
<g>
<AxisBottom
scale={timeScale}
stroke={theme.backgroundOutline}
tickFormat={tickFormatter}
tickStroke={theme.backgroundOutline}
tickLength={4}
hideTicks={true}
tickTransform={'translate(0 -5)'}
tickValues={ticks}
top={graphHeight - 1}
tickLabelProps={() => ({
fill: theme.textSecondary,
fontSize: 12,
textAnchor: 'middle',
transform: 'translate(0 -24)',
})}
/>
<text
x={crosshair + (crosshairAtEdge ? -4 : 4)}
y={margin.crosshair + 10}
textAnchor={crosshairAtEdge ? 'end' : 'start'}
fontSize={12}
fill={theme.textSecondary}
>
{crosshairDateFormatter(displayPrice.timestamp)}
</text>
<Line
from={{ x: crosshair, y: margin.crosshair }}
to={{ x: crosshair, y: graphHeight }}
stroke={theme.backgroundOutline}
strokeWidth={1}
pointerEvents="none"
strokeDasharray="4,4"
/>
<GlyphCircle
left={crosshair}
top={rdScale(displayPrice.value) + margin.top}
size={50}
fill={theme.accentAction}
stroke={theme.backgroundOutline}
strokeWidth={0.5}
/>
</g>
) : (
<AxisBottom scale={timeScale} stroke={theme.backgroundOutline} top={graphHeight - 1} hideTicks />
)}
<rect
x={0}
y={0}
width={width}
height={graphHeight}
fill={'transparent'}
onTouchStart={handleHover}
onTouchMove={handleHover}
onMouseMove={handleHover}
onMouseLeave={resetDisplay}
/>
</svg>
)}
<TimeOptionsWrapper>
<TimeOptionsContainer>
{ORDERED_TIMES.map((time) => (
@@ -364,4 +373,44 @@ export function PriceChart({ width, height, prices }: PriceChartProps) {
)
}
const StyledMissingChart = styled.svg`
text {
font-size: 12px;
font-weight: 400;
}
`
const chartBottomPadding = 15
const NoV3DataMessage = () => (
<Trans>This token doesn&apos;t have chart data because it hasn&apos;t been traded on Uniswap v3</Trans>
)
const MissingDataMessage = () => <Trans>Missing chart data</Trans>
function MissingPriceChart({ width, height, message }: { width: number; height: number; message: ReactNode }) {
const theme = useTheme()
const midPoint = height / 2 + 45
return (
<StyledMissingChart width={width} height={height}>
<path
d={`M 0 ${midPoint} Q 104 ${midPoint - 70}, 208 ${midPoint} T 416 ${midPoint}
M 416 ${midPoint} Q 520 ${midPoint - 70}, 624 ${midPoint} T 832 ${midPoint}`}
stroke={theme.backgroundOutline}
fill="transparent"
strokeWidth="2"
/>
<TrendingUp stroke={theme.textTertiary} x={0} size={12} y={height - chartBottomPadding - 10} />
<text y={height - chartBottomPadding} x="20" fill={theme.textTertiary}>
{message || <Trans>Missing chart data</Trans>}
</text>
<path
d={`M 0 ${height - 1}, ${width} ${height - 1}`}
stroke={theme.backgroundOutline}
fill="transparent"
strokeWidth="1"
/>
</StyledMissingChart>
)
}
export default PriceChart

View File

@@ -1,4 +1,6 @@
import { Trans } from '@lingui/macro'
import { NATIVE_CHAIN_ID } from 'constants/tokens'
import { SingleTokenData } from 'graphql/data/Token'
import { useOnClickOutside } from 'hooks/useOnClickOutside'
import { useRef } from 'react'
import { Twitter } from 'react-feather'
@@ -62,9 +64,8 @@ const ShareAction = styled.div`
`
interface TokenInfo {
tokenName: string
tokenSymbol: string
tokenAddress: string
token: NonNullable<SingleTokenData>
isNative: boolean
}
export default function ShareButton(tokenInfo: TokenInfo) {
@@ -75,11 +76,12 @@ export default function ShareButton(tokenInfo: TokenInfo) {
useOnClickOutside(node, open ? toggleShare : undefined)
const positionX = (window.screen.width - TWITTER_WIDTH) / 2
const positionY = (window.screen.height - TWITTER_HEIGHT) / 2
const tokenAddress = tokenInfo.isNative ? NATIVE_CHAIN_ID : tokenInfo.token.address
const shareTweet = () => {
toggleShare()
window.open(
`https://twitter.com/intent/tweet?text=Check%20out%20${tokenInfo.tokenName}%20(${tokenInfo.tokenSymbol})%20https://app.uniswap.org/%23/tokens/${tokenInfo.tokenAddress}%20via%20@uniswap`,
`https://twitter.com/intent/tweet?text=Check%20out%20${tokenInfo.token.name}%20(${tokenInfo.token.symbol})%20https://app.uniswap.org/%23/tokens/${tokenInfo.token.chain}/${tokenAddress}%20via%20@uniswap`,
'newwindow',
`left=${positionX}, top=${positionY}, width=${TWITTER_WIDTH}, height=${TWITTER_HEIGHT}`
)

View File

@@ -1,8 +1,13 @@
import { Trans } from '@lingui/macro'
import { ReactNode } from 'react'
import styled from 'styled-components/macro'
import { ThemedText } from 'theme'
import { textFadeIn } from 'theme/animations'
import { formatDollarAmount } from 'utils/formatDollarAmt'
import { formatDollar } from 'utils/formatNumbers'
import { TokenSortMethod } from '../state'
import { HEADER_DESCRIPTIONS } from '../TokenTable/TokenRow'
import InfoTip from './InfoTip'
export const StatWrapper = styled.div`
display: flex;
@@ -17,13 +22,21 @@ export const StatWrapper = styled.div`
export const TokenStatsSection = styled.div`
display: flex;
flex-wrap: wrap;
${textFadeIn}
`
export const StatPair = styled.div`
display: flex;
flex: 1;
flex-wrap: wrap;
`
const Header = styled(ThemedText.MediumHeader)`
font-size: 28px !important;
`
const StatTitle = styled.div`
display: flex;
flex-direction: row;
gap: 4px;
`
const StatPrice = styled.span`
font-size: 28px;
color: ${({ theme }) => theme.textPrimary};
@@ -31,14 +44,32 @@ const StatPrice = styled.span`
const NoData = styled.div`
color: ${({ theme }) => theme.textTertiary};
`
const Wrapper = styled.div`
gap: 16px;
${textFadeIn}
`
type NumericStat = number | undefined | null
function Stat({ value, title }: { value: NumericStat; title: ReactNode }) {
function Stat({
value,
title,
description,
isPrice = false,
}: {
value: NumericStat
title: ReactNode
description?: ReactNode
isPrice?: boolean
}) {
return (
<StatWrapper>
{title}
<StatPrice>{value ? formatDollarAmount(value) : '-'}</StatPrice>
<StatTitle>
{title}
{description && <InfoTip text={description}></InfoTip>}
</StatTitle>
<StatPrice>{formatDollar({ num: value, isPrice })}</StatPrice>
</StatWrapper>
)
}
@@ -53,16 +84,33 @@ export default function StatsSection(props: StatsSectionProps) {
const { priceLow52W, priceHigh52W, TVL, volume24H } = props
if (TVL || volume24H || priceLow52W || priceHigh52W) {
return (
<TokenStatsSection>
<StatPair>
<Stat value={TVL} title={<Trans>Total Value Locked</Trans>} />
<Stat value={volume24H} title={<Trans>24H volume</Trans>} />
</StatPair>
<StatPair>
<Stat value={priceLow52W} title={<Trans>52W low</Trans>} />
<Stat value={priceHigh52W} title={<Trans>52W high</Trans>} />
</StatPair>
</TokenStatsSection>
<Wrapper>
<Header>
<Trans>Stats</Trans>
</Header>
<TokenStatsSection>
<StatPair>
<Stat
value={TVL}
description={HEADER_DESCRIPTIONS[TokenSortMethod.TOTAL_VALUE_LOCKED]}
title={<Trans>TVL</Trans>}
/>
<Stat
value={volume24H}
description={
<Trans>
24H volume is the amount of the asset that has been traded on Uniswap v3 during the past 24 hours.
</Trans>
}
title={<Trans>24H volume</Trans>}
/>
</StatPair>
<StatPair>
<Stat value={priceLow52W} title={<Trans>52W low</Trans>} isPrice={true} />
<Stat value={priceHigh52W} title={<Trans>52W high</Trans>} isPrice={true} />
</StatPair>
</TokenStatsSection>
</Wrapper>
)
} else {
return <NoData>No stats available</NoData>

View File

@@ -106,7 +106,7 @@ export default function NetworkFilter() {
<NetworkFilterOption onClick={toggleMenu} aria-label={`networkFilter`} active={open}>
<StyledMenuContent>
<NetworkLabel>
<Logo src={circleLogoUrl ?? logoUrl} /> {label}
<Logo src={logoUrl ?? circleLogoUrl} /> {label}
</NetworkLabel>
<Chevron open={open}>
{open ? (
@@ -130,7 +130,7 @@ export default function NetworkFilter() {
}}
>
<NetworkLabel>
<Logo src={chainInfo.circleLogoUrl ?? chainInfo.logoUrl} />
<Logo src={chainInfo.logoUrl ?? chainInfo.circleLogoUrl} />
{chainInfo.label}
</NetworkLabel>
{network === currentChainName && (

View File

@@ -6,16 +6,17 @@ import SparklineChart from 'components/Charts/SparklineChart'
import CurrencyLogo from 'components/CurrencyLogo'
import { getChainInfo } from 'constants/chainInfo'
import { FavoriteTokensVariant, useFavoriteTokensFlag } from 'featureFlags/flags/favoriteTokens'
import { TokenSortMethod, TopToken } from 'graphql/data/TopTokens'
import { SparklineMap, TopToken } from 'graphql/data/TopTokens'
import { CHAIN_NAME_TO_CHAIN_ID, getTokenDetailsURL } from 'graphql/data/util'
import { useAtomValue } from 'jotai/utils'
import { ForwardedRef, forwardRef } from 'react'
import { CSSProperties, ReactNode } from 'react'
import { ArrowDown, ArrowUp, Heart } from 'react-feather'
import { Link, useParams } from 'react-router-dom'
import { Text } from 'rebass'
import styled, { css, useTheme } from 'styled-components/macro'
import { ClickableStyle } from 'theme'
import { formatDollarAmount } from 'utils/formatDollarAmt'
import { formatDollar } from 'utils/formatNumbers'
import {
LARGE_MEDIA_BREAKPOINT,
@@ -29,11 +30,13 @@ import {
filterTimeAtom,
sortAscendingAtom,
sortMethodAtom,
TokenSortMethod,
useIsFavorited,
useSetSortMethod,
useToggleFavorite,
} from '../state'
import { useTokenLogoURI } from '../TokenDetails/ChartSection'
import InfoTip from '../TokenDetails/InfoTip'
import { formatDelta, getDeltaArrow } from '../TokenDetails/PriceChart'
const Cell = styled.div`
@@ -171,7 +174,6 @@ const ListNumberCell = styled(Cell)<{ header: boolean }>`
color: ${({ theme }) => theme.textSecondary};
min-width: 32px;
font-size: 14px;
height: ${({ header }) => (header ? '48px' : '60px')};
@media only screen and (max-width: ${SMALL_MEDIA_BREAKPOINT}) {
display: none;
@@ -188,7 +190,7 @@ const DataCell = styled(Cell)<{ sortable: boolean }>`
},
}) => css`background-color ${duration.medium} ${timing.ease}`};
`
const MarketCapCell = styled(DataCell)`
const TvlCell = styled(DataCell)`
padding-right: 8px;
@media only screen and (max-width: ${MEDIUM_MEDIA_BREAKPOINT}) {
display: none;
@@ -197,7 +199,7 @@ const MarketCapCell = styled(DataCell)`
const NameCell = styled(Cell)`
justify-content: flex-start;
padding: 0px 8px;
min-width: 200px;
min-width: 240px;
gap: 8px;
`
const PriceCell = styled(DataCell)`
@@ -229,18 +231,18 @@ const PriceInfoCell = styled(Cell)`
align-items: flex-end;
}
`
const SortArrowCell = styled(Cell)`
padding-right: 2px;
`
const HeaderCellWrapper = styled.span<{ onClick?: () => void }>`
align-items: center;
${ClickableStyle}
cursor: ${({ onClick }) => (onClick ? 'pointer' : 'unset')};
display: flex;
gap: 4px;
height: 100%;
justify-content: flex-end;
width: 100%;
`
const HeaderCellText = styled(Text)`
${ClickableStyle}
`
const SparkLineCell = styled(Cell)`
padding: 0px 24px;
min-width: 120px;
@@ -309,7 +311,7 @@ const IconLoadingBubble = styled(LoadingBubble)`
border-radius: 50%;
width: 24px;
`
const SparkLineLoadingBubble = styled(LongLoadingBubble)`
export const SparkLineLoadingBubble = styled(LongLoadingBubble)`
height: 4px;
`
@@ -318,7 +320,7 @@ export const L2NetworkLogo = styled.div<{ networkUrl?: string; size?: string }>`
width: ${({ size }) => size ?? '12px'};
position: absolute;
left: 50%;
top: 50%;
bottom: 0;
background: url(${({ networkUrl }) => networkUrl});
background-repeat: no-repeat;
background-size: ${({ size }) => (size ? `${size} ${size}` : '12px 12px')};
@@ -330,6 +332,17 @@ export const LogoContainer = styled.div`
display: flex;
`
export const HEADER_DESCRIPTIONS: Record<TokenSortMethod, ReactNode | undefined> = {
[TokenSortMethod.PRICE]: undefined,
[TokenSortMethod.PERCENT_CHANGE]: undefined,
[TokenSortMethod.TOTAL_VALUE_LOCKED]: (
<Trans>Total value locked (TVL) is the amount of the asset thats currently in a Uniswap v3 liquidity pool.</Trans>
),
[TokenSortMethod.VOLUME]: (
<Trans>Volume is the amount of the asset that has been traded on Uniswap v3 during the selected time frame.</Trans>
),
}
/* Get singular header cell for header row */
function HeaderCell({
category,
@@ -343,31 +356,23 @@ function HeaderCell({
const handleSortCategory = useSetSortMethod(category)
const sortMethod = useAtomValue(sortMethodAtom)
if (sortMethod === category) {
return (
<HeaderCellWrapper onClick={handleSortCategory}>
<SortArrowCell>
const description = HEADER_DESCRIPTIONS[category]
return (
<HeaderCellWrapper onClick={handleSortCategory}>
{sortMethod === category && (
<>
{sortAscending ? (
<ArrowUp size={20} strokeWidth={1.8} color={theme.accentActive} />
) : (
<ArrowDown size={20} strokeWidth={1.8} color={theme.accentActive} />
)}
</SortArrowCell>
{category}
</HeaderCellWrapper>
)
}
if (sortable) {
return (
<HeaderCellWrapper onClick={handleSortCategory}>
<SortArrowCell>
<ArrowUp size={14} visibility="hidden" />
</SortArrowCell>
{category}
</HeaderCellWrapper>
)
}
return <HeaderCellWrapper>{category}</HeaderCellWrapper>
</>
)}
<HeaderCellText>{category}</HeaderCellText>
{description && <InfoTip text={description}></InfoTip>}
</HeaderCellWrapper>
)
}
/* Token Row: skeleton row component */
@@ -378,7 +383,7 @@ export function TokenRow({
tokenInfo,
price,
percentChange,
marketCap,
tvl,
volume,
sparkLine,
...rest
@@ -388,10 +393,10 @@ export function TokenRow({
header: boolean
listNumber: ReactNode
loading?: boolean
marketCap: ReactNode
tvl: ReactNode
price: ReactNode
percentChange: ReactNode
sparkLine: ReactNode
sparkLine?: ReactNode
tokenInfo: ReactNode
volume: ReactNode
last?: boolean
@@ -404,7 +409,7 @@ export function TokenRow({
<NameCell>{tokenInfo}</NameCell>
<PriceCell sortable={header}>{price}</PriceCell>
<PercentChangeCell sortable={header}>{percentChange}</PercentChangeCell>
<MarketCapCell sortable={header}>{marketCap}</MarketCapCell>
<TvlCell sortable={header}>{tvl}</TvlCell>
<VolumeCell sortable={header}>{volume}</VolumeCell>
<SparkLineCell>{sparkLine}</SparkLineCell>
{favoriteTokensEnabled && <FavoriteCell>{favorited}</FavoriteCell>}
@@ -425,10 +430,10 @@ export function HeaderRow() {
header={true}
favorited={null}
listNumber="#"
tokenInfo={<Trans>Token Name</Trans>}
tokenInfo={<Trans>Token name</Trans>}
price={<HeaderCell category={TokenSortMethod.PRICE} sortable />}
percentChange={<HeaderCell category={TokenSortMethod.PERCENT_CHANGE} sortable />}
marketCap={<HeaderCell category={TokenSortMethod.TOTAL_VALUE_LOCKED} sortable />}
tvl={<HeaderCell category={TokenSortMethod.TOTAL_VALUE_LOCKED} sortable />}
volume={<HeaderCell category={TokenSortMethod.VOLUME} sortable />}
sparkLine={null}
/>
@@ -451,7 +456,7 @@ export function LoadingRow() {
}
price={<MediumLoadingBubble />}
percentChange={<LoadingBubble />}
marketCap={<LoadingBubble />}
tvl={<LoadingBubble />}
volume={<LoadingBubble />}
sparkLine={<SparkLineLoadingBubble />}
/>
@@ -462,6 +467,7 @@ interface LoadedRowProps {
tokenListIndex: number
tokenListLength: number
token: NonNullable<TopToken>
sparklineMap: SparklineMap
}
/* Loaded State: row component with token information */
@@ -473,21 +479,23 @@ export const LoadedRow = forwardRef((props: LoadedRowProps, ref: ForwardedRef<HT
const isFavorited = useIsFavorited(tokenAddress)
const toggleFavorite = useToggleFavorite(tokenAddress)
const filterString = useAtomValue(filterStringAtom)
const sortAscending = useAtomValue(sortAscendingAtom)
const lowercaseChainName = useParams<{ chainName?: string }>().chainName?.toUpperCase() ?? 'ethereum'
const filterNetwork = lowercaseChainName.toUpperCase()
const L2Icon = getChainInfo(CHAIN_NAME_TO_CHAIN_ID[filterNetwork]).circleLogoUrl
const L2Icon = getChainInfo(CHAIN_NAME_TO_CHAIN_ID[filterNetwork])?.circleLogoUrl
const timePeriod = useAtomValue(filterTimeAtom)
const delta = token.market?.pricePercentChange?.value
const arrow = getDeltaArrow(delta)
const formattedDelta = formatDelta(delta)
const sortAscending = useAtomValue(sortAscendingAtom)
const rank = sortAscending ? tokenListLength - tokenListIndex : tokenListIndex + 1
const exploreTokenSelectedEventProperties = {
chain_id: filterNetwork,
token_address: tokenAddress,
token_symbol: tokenSymbol,
token_list_index: tokenListIndex,
token_list_rank: rank,
token_list_length: tokenListLength,
time_frame: timePeriod,
search_token_address_input: filterString,
@@ -512,7 +520,7 @@ export const LoadedRow = forwardRef((props: LoadedRowProps, ref: ForwardedRef<HT
<FavoriteIcon isFavorited={isFavorited} />
</ClickFavorited>
}
listNumber={sortAscending ? tokenListLength - tokenListIndex : tokenListIndex + 1}
listNumber={rank}
tokenInfo={
<ClickableName>
<LogoContainer>
@@ -528,7 +536,7 @@ export const LoadedRow = forwardRef((props: LoadedRowProps, ref: ForwardedRef<HT
price={
<ClickableContent>
<PriceInfoCell>
{token.market?.price?.value ? formatDollarAmount(token.market.price.value) : '-'}
{formatDollar({ num: token.market?.price?.value, isPrice: true, lessPreciseStablecoinValues: true })}
<PercentChangeInfoCell>
{formattedDelta}
{arrow}
@@ -542,28 +550,23 @@ export const LoadedRow = forwardRef((props: LoadedRowProps, ref: ForwardedRef<HT
{arrow}
</ClickableContent>
}
marketCap={
<ClickableContent>
{token.market?.totalValueLocked?.value ? formatDollarAmount(token.market.totalValueLocked.value) : '-'}
</ClickableContent>
}
volume={
<ClickableContent>
{token.market?.volume?.value ? formatDollarAmount(token.market.volume.value) : '-'}
</ClickableContent>
}
tvl={<ClickableContent>{formatDollar({ num: token.market?.totalValueLocked?.value })}</ClickableContent>}
volume={<ClickableContent>{formatDollar({ num: token.market?.volume?.value })}</ClickableContent>}
sparkLine={
<SparkLine>
<ParentSize>
{({ width, height }) => (
<SparklineChart
width={width}
height={height}
tokenData={token}
pricePercentChange={token.market?.pricePercentChange?.value}
timePeriod={timePeriod}
/>
)}
{({ width, height }) =>
props.sparklineMap && (
<SparklineChart
width={width}
height={height}
tokenData={token}
pricePercentChange={token.market?.pricePercentChange?.value}
timePeriod={timePeriod}
sparklineMap={props.sparklineMap}
/>
)
}
</ParentSize>
</SparkLine>
}

View File

@@ -3,7 +3,7 @@ import { showFavoritesAtom } from 'components/Tokens/state'
import { PAGE_SIZE, useTopTokens } from 'graphql/data/TopTokens'
import { validateUrlChainParam } from 'graphql/data/util'
import { useAtomValue } from 'jotai/utils'
import { ReactNode, useCallback, useRef } from 'react'
import { ReactNode } from 'react'
import { AlertTriangle } from 'react-feather'
import { useParams } from 'react-router-dom'
import styled from 'styled-components/macro'
@@ -11,8 +11,6 @@ import styled from 'styled-components/macro'
import { MAX_WIDTH_MEDIA_BREAKPOINT } from '../constants'
import { HeaderRow, LoadedRow, LoadingRow } from './TokenRow'
const LOADING_ROWS_COUNT = 3
const GridContainer = styled.div`
display: flex;
flex-direction: column;
@@ -58,8 +56,19 @@ function NoTokensState({ message }: { message: ReactNode }) {
)
}
const LoadingMoreRows = Array(LOADING_ROWS_COUNT).fill(<LoadingRow />)
const LoadingRows = (rowCount?: number) => Array(rowCount ?? PAGE_SIZE).fill(<LoadingRow />)
const LoadingRowsWrapper = styled.div`
margin-top: 8px;
`
const LoadingRows = (rowCount?: number) => (
<LoadingRowsWrapper>
{Array(rowCount ?? PAGE_SIZE)
.fill(null)
.map((_, index) => {
return <LoadingRow key={index} />
})}
</LoadingRowsWrapper>
)
export function LoadingTokenTable({ rowCount }: { rowCount?: number }) {
return (
@@ -70,73 +79,51 @@ export function LoadingTokenTable({ rowCount }: { rowCount?: number }) {
)
}
export default function TokenTable() {
export default function TokenTable({ setRowCount }: { setRowCount: (c: number) => void }) {
const showFavorites = useAtomValue<boolean>(showFavoritesAtom)
// TODO: consider moving prefetched call into app.tsx and passing it here, use a preloaded call & updated on interval every 60s
const chainName = validateUrlChainParam(useParams<{ chainName?: string }>().chainName)
const { error, loading, tokens, hasMore, loadMoreTokens, loadingRowCount } = useTopTokens(chainName)
const showMoreLoadingRows = Boolean(loading && hasMore)
const observer = useRef<IntersectionObserver>()
const lastTokenRef = useCallback(
(node: HTMLDivElement) => {
if (loading) return
if (observer.current) observer.current.disconnect()
observer.current = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting && hasMore) {
loadMoreTokens()
}
})
if (node) observer.current.observe(node)
},
[loading, hasMore, loadMoreTokens]
)
const { tokens, sparklines } = useTopTokens(chainName)
setRowCount(tokens?.length ?? PAGE_SIZE)
/* loading and error state */
if (loading && (!tokens || tokens?.length === 0)) {
return <LoadingTokenTable rowCount={loadingRowCount} />
if (!tokens) {
return (
<NoTokensState
message={
<>
<AlertTriangle size={16} />
<Trans>An error occurred loading tokens. Please try again.</Trans>
</>
}
/>
)
} else if (tokens?.length === 0) {
return showFavorites ? (
<NoTokensState message={<Trans>You have no favorited tokens</Trans>} />
) : (
<NoTokensState message={<Trans>No tokens found</Trans>} />
)
} else {
if (error || !tokens) {
return (
<NoTokensState
message={
<>
<AlertTriangle size={16} />
<Trans>An error occured loading tokens. Please try again.</Trans>
</>
}
/>
)
} else if (tokens?.length === 0) {
return showFavorites ? (
<NoTokensState message={<Trans>You have no favorited tokens</Trans>} />
) : (
<NoTokensState message={<Trans>No tokens found</Trans>} />
)
} else {
return (
<>
<GridContainer>
<HeaderRow />
<TokenDataContainer>
{tokens.map(
(token, index) =>
token && (
<LoadedRow
key={token?.address}
tokenListIndex={index}
tokenListLength={tokens.length}
token={token}
ref={index + 1 === tokens.length ? lastTokenRef : undefined}
/>
)
)}
{showMoreLoadingRows && LoadingMoreRows}
</TokenDataContainer>
</GridContainer>
</>
)
}
return (
<GridContainer>
<HeaderRow />
<TokenDataContainer>
{tokens.map(
(token, index) =>
token && (
<LoadedRow
key={token?.address}
tokenListIndex={index}
tokenListLength={tokens.length}
token={token}
sparklineMap={sparklines}
/>
)
)}
</TokenDataContainer>
</GridContainer>
)
}
}

View File

@@ -1,3 +1,8 @@
import { Trans } from '@lingui/macro'
import { useWeb3React } from '@web3-react/core'
import { ElementName, Event, EventName } from 'analytics/constants'
import { TraceEvent } from 'analytics/TraceEvent'
import { chainIdToBackendName } from 'graphql/data/util'
import { X } from 'react-feather'
import { Link } from 'react-router-dom'
import { useShowTokensPromoBanner } from 'state/user/hooks'
@@ -8,26 +13,32 @@ import { Z_INDEX } from 'theme/zIndex'
import tokensPromoDark from '../../assets/images/tokensPromoDark.png'
import tokensPromoLight from '../../assets/images/tokensPromoLight.png'
const PopupContainer = styled.div<{ show: boolean }>`
position: fixed;
display: ${({ show }) => (show ? 'flex' : 'none')};
flex-direction: column;
padding: 12px 16px 12px 20px;
gap: 8px;
bottom: 48px;
right: 16px;
width: 320px;
height: 88px;
z-index: ${Z_INDEX.sticky};
background-color: ${({ theme }) => (theme.darkMode ? theme.backgroundScrim : opacify(60, '#FDF0F8'))};
color: ${({ theme }) => theme.textPrimary};
const BackgroundColor = styled(Link)<{ show: boolean }>`
background-color: ${({ theme }) => (theme.darkMode ? theme.backgroundScrim : '#FDF0F8')};
border: 1px solid ${({ theme }) => theme.backgroundOutline};
border-radius: 12px;
bottom: 48px;
box-shadow: ${({ theme }) => theme.deepShadow};
display: ${({ show }) => (show ? 'block' : 'none')};
height: 88px;
position: fixed;
right: clamp(0px, 1vw, 16px);
text-decoration: none;
width: 320px;
z-index: ${Z_INDEX.sticky};
`
const PopupContainer = styled.div`
background-color: ${({ theme }) => (theme.darkMode ? theme.backgroundScrim : opacify(60, '#FDF0F8'))};
background-image: url(${({ theme }) => (theme.darkMode ? `${tokensPromoDark}` : `${tokensPromoLight}`)});
background-size: cover;
background-blend-mode: overlay;
border-radius: 12px;
color: ${({ theme }) => theme.textPrimary};
display: flex;
flex-direction: column;
gap: 8px;
height: 100%;
padding: 12px 16px 12px 20px;
transition: ${({
theme: {
@@ -36,46 +47,54 @@ const PopupContainer = styled.div<{ show: boolean }>`
}) => `${duration.slow} opacity ${timing.in}`};
`
const Header = styled.div`
display: flex;
align-items: center;
display: flex;
justify-content: space-between;
`
const HeaderText = styled(Link)`
const HeaderText = styled.span`
font-weight: 600;
font-size: 14px;
line-height: 20px;
text-decoration: none;
color: ${({ theme }) => theme.textPrimary};
`
const Description = styled(Link)`
const Description = styled.span`
font-weight: 400;
font-size: 12px;
line-height: 16px;
width: 75%;
text-decoration: none;
color: ${({ theme }) => theme.textPrimary};
width: max(212px, calc(100% - 36px));
`
export default function TokensBanner() {
const theme = useTheme()
const [showTokensPromoBanner, setShowTokensPromoBanner] = useShowTokensPromoBanner()
const closeBanner = () => {
setShowTokensPromoBanner(false)
}
const { chainId: connectedChainId } = useWeb3React()
const chainName = chainIdToBackendName(connectedChainId).toLowerCase()
return (
<PopupContainer show={showTokensPromoBanner}>
<Header>
<HeaderText to={'/tokens'} onClick={closeBanner}>
Explore Top Tokens
</HeaderText>
<X size={20} color={theme.textSecondary} onClick={closeBanner} style={{ cursor: 'pointer' }} />
</Header>
<BackgroundColor show={showTokensPromoBanner} to={`/tokens/${chainName}`}>
<TraceEvent events={[Event.onClick]} name={EventName.EXPLORE_BANNER_CLICKED} element={ElementName.EXPLORE_BANNER}>
<PopupContainer>
<Header>
<HeaderText>
<Trans>Explore Top Tokens on Uniswap</Trans>
</HeaderText>
<X
size={20}
color={theme.textSecondary}
onClick={(e) => {
e.preventDefault()
e.stopPropagation()
setShowTokensPromoBanner(false)
}}
style={{ cursor: 'pointer' }}
/>
</Header>
<Description to={'/tokens'} onClick={closeBanner}>
Check out the new explore tab to discover and learn more
</Description>
</PopupContainer>
<Description>
<Trans>Sort and filter assets across networks on the new Tokens page.</Trans>
</Description>
</PopupContainer>
</TraceEvent>
</BackgroundColor>
)
}

View File

@@ -1,9 +1,15 @@
import { TokenSortMethod } from 'graphql/data/TopTokens'
import { TimePeriod } from 'graphql/data/util'
import { atom, useAtom } from 'jotai'
import { atomWithReset, atomWithStorage, useAtomValue } from 'jotai/utils'
import { useCallback, useMemo } from 'react'
export enum TokenSortMethod {
PRICE = 'Price',
PERCENT_CHANGE = 'Change',
TOTAL_VALUE_LOCKED = 'TVL',
VOLUME = 'Volume',
}
export const favoritesAtom = atomWithStorage<string[]>('favorites', [])
export const showFavoritesAtom = atomWithStorage<boolean>('showFavorites', false)
export const filterStringAtom = atomWithReset<string>('')

View File

@@ -3,14 +3,12 @@ import AddressClaimModal from 'components/claim/AddressClaimModal'
import ConnectedAccountBlocked from 'components/ConnectedAccountBlocked'
import TokensBanner from 'components/Tokens/TokensBanner'
import { NftVariant, useNftFlag } from 'featureFlags/flags/nft'
import { TokensVariant, useTokensFlag } from 'featureFlags/flags/tokens'
import useAccountRiskCheck from 'hooks/useAccountRiskCheck'
import { lazy } from 'react'
import { useLocation } from 'react-router-dom'
import { useModalIsOpen, useToggleModal } from 'state/application/hooks'
import { ApplicationModal } from 'state/application/reducer'
const Cart = lazy(() => import('nft/components/profile/modal/ListingTag'))
const Bag = lazy(() => import('nft/components/bag/Bag'))
const TransactionCompleteModal = lazy(() => import('nft/components/collection/TransactionCompleteModal'))
@@ -28,9 +26,7 @@ export default function TopLevelModals() {
<>
<AddressClaimModal isOpen={addressClaimOpen} onDismiss={addressClaimToggle} />
<ConnectedAccountBlocked account={account} isOpen={open} />
{useTokensFlag() === TokensVariant.Enabled &&
(location.pathname.includes('/pool') || location.pathname.includes('/swap')) && <TokensBanner />}
<Cart />
{(location.pathname.includes('/pool') || location.pathname.includes('/swap')) && <TokensBanner />}
<Bag />
{useNftFlag() === NftVariant.Enabled && <TransactionCompleteModal />}
</>

View File

@@ -7,6 +7,7 @@ import { sendEvent } from 'components/analytics'
import { AutoColumn } from 'components/Column'
import { AutoRow } from 'components/Row'
import { getConnection, getConnectionName, getIsCoinbaseWallet, getIsInjected, getIsMetaMask } from 'connection/utils'
import { NftVariant, useNftFlag } from 'featureFlags/flags/nft'
import { RedesignVariant, useRedesignFlag } from 'featureFlags/flags/redesign'
import usePrevious from 'hooks/usePrevious'
import { useCallback, useEffect, useState } from 'react'
@@ -156,6 +157,7 @@ export default function WalletModal({
const redesignFlag = useRedesignFlag()
const redesignFlagEnabled = redesignFlag === RedesignVariant.Enabled
const nftFlagEnabled = useNftFlag() === NftVariant.Enabled
const [walletView, setWalletView] = useState(WALLET_VIEWS.ACCOUNT)
const [lastActiveWalletAddress, setLastActiveWalletAddress] = useState<string | undefined>(account)
@@ -307,9 +309,9 @@ export default function WalletModal({
)
}
function getTermsOfService(redesignFlagEnabled: boolean, walletView: string) {
if (redesignFlagEnabled && walletView === WALLET_VIEWS.PENDING) return null
return redesignFlagEnabled ? (
function getTermsOfService(nftFlagEnabled: boolean, walletView: string) {
if (nftFlagEnabled && walletView === WALLET_VIEWS.PENDING) return null
return nftFlagEnabled ? (
<AutoRow style={{ flexWrap: 'nowrap', padding: '4px 16px' }}>
<ThemedText.BodySecondary fontSize={16} lineHeight={'24px'}>
<Trans>
@@ -357,7 +359,7 @@ export default function WalletModal({
/>
)}
{walletView !== WALLET_VIEWS.PENDING && <OptionGrid data-testid="option-grid">{getOptions()}</OptionGrid>}
{!pendingError && getTermsOfService(redesignFlagEnabled, walletView)}
{!pendingError && getTermsOfService(nftFlagEnabled, walletView)}
</AutoColumn>
</ContentWrapper>
</UpperSection>

View File

@@ -1,11 +1,9 @@
// eslint-disable-next-line no-restricted-imports
import { t, Trans } from '@lingui/macro'
import { Trans } from '@lingui/macro'
import { useWeb3React } from '@web3-react/core'
import { ElementName, Event, EventName } from 'analytics/constants'
import { TraceEvent } from 'analytics/TraceEvent'
import WalletDropdown from 'components/WalletDropdown'
import { getConnection } from 'connection/utils'
import { NavBarVariant, useNavBarFlag } from 'featureFlags/flags/navBar'
import { Portal } from 'nft/components/common/Portal'
import { getIsValidSwapQuote } from 'pages/Swap'
import { darken } from 'polished'
@@ -13,10 +11,9 @@ import { useMemo, useRef } from 'react'
import { AlertTriangle, ChevronDown, ChevronUp } from 'react-feather'
import { useAppSelector } from 'state/hooks'
import { useDerivedSwapInfo } from 'state/swap/hooks'
import styled, { css, useTheme } from 'styled-components/macro'
import styled, { useTheme } from 'styled-components/macro'
import { useOnClickOutside } from '../../hooks/useOnClickOutside'
import { useHasSocks } from '../../hooks/useSocksBalance'
import {
useCloseModal,
useModalIsOpen,
@@ -36,6 +33,23 @@ import WalletModal from '../WalletModal'
// https://stackoverflow.com/a/31617326
const FULL_BORDER_RADIUS = 9999
const ChevronWrapper = styled.button`
background-color: transparent;
border: none;
cursor: pointer;
display: flex;
padding: 10px 16px 10px 4px;
:hover {
color: ${({ theme }) => theme.accentActionSoft};
}
:hover,
:active,
:focus {
border: none;
}
`
const Web3StatusGeneric = styled(ButtonSecondary)`
${({ theme }) => theme.flexRowNoWrap}
width: 100%;
@@ -62,14 +76,13 @@ const Web3StatusError = styled(Web3StatusGeneric)`
}
`
const Web3StatusConnectButton = styled.button<{ faded?: boolean }>`
const Web3StatusConnectWrapper = styled.div<{ faded?: boolean }>`
${({ theme }) => theme.flexRowNoWrap}
align-items: center;
background-color: ${({ theme }) => theme.accentActionSoft};
border-radius: ${FULL_BORDER_RADIUS}px;
border: none;
cursor: pointer;
padding: 0 12px;
padding: 0;
height: 40px;
:hover,
@@ -79,33 +92,6 @@ const Web3StatusConnectButton = styled.button<{ faded?: boolean }>`
}
`
const Web3StatusConnect = styled(Web3StatusGeneric)<{ faded?: boolean }>`
background-color: ${({ theme }) => theme.deprecated_primary4};
border: none;
color: ${({ theme }) => theme.deprecated_primaryText1};
font-weight: 500;
:hover,
:focus {
border: 1px solid ${({ theme }) => darken(0.05, theme.deprecated_primary4)};
color: ${({ theme }) => theme.deprecated_primaryText1};
}
${({ faded }) =>
faded &&
css`
background-color: ${({ theme }) => theme.deprecated_primary5};
border: 1px solid ${({ theme }) => theme.deprecated_primary5};
color: ${({ theme }) => theme.deprecated_primaryText1};
:hover,
:focus {
border: 1px solid ${({ theme }) => darken(0.05, theme.deprecated_primary4)};
color: ${({ theme }) => darken(0.05, theme.deprecated_primaryText1)};
}
`}
`
const Web3StatusConnected = styled(Web3StatusGeneric)<{ pending?: boolean }>`
background-color: ${({ pending, theme }) => (pending ? theme.deprecated_primary1 : theme.deprecated_bg1)};
border: 1px solid ${({ pending, theme }) => (pending ? theme.deprecated_primary1 : theme.deprecated_bg1)};
@@ -146,34 +132,37 @@ function newTransactionsFirst(a: TransactionDetails, b: TransactionDetails) {
return b.addedTime - a.addedTime
}
function Sock() {
return (
<span role="img" aria-label={t`has socks emoji`} style={{ marginTop: -4, marginBottom: -4 }}>
🧦
</span>
)
}
const VerticalDivider = styled.div`
height: 20px;
margin: 0px 4px;
margin: 0px;
width: 1px;
background-color: ${({ theme }) => theme.accentAction};
`
const StyledConnect = styled.div`
const StyledConnectButton = styled.button`
background-color: transparent;
border: none;
border-top-left-radius: ${FULL_BORDER_RADIUS}px;
border-bottom-left-radius: ${FULL_BORDER_RADIUS}px;
color: ${({ theme }) => theme.accentAction};
cursor: pointer;
font-weight: 600;
font-size: 16px;
margin-right: 8px;
padding: 10px 8px 10px 12px;
&:hover {
transition: ${({
theme: {
transition: { duration, timing },
},
}) => `${duration.fast} color ${timing.in}`};
:hover,
:active,
:focus {
border: none;
}
:hover {
color: ${({ theme }) => theme.accentActionSoft};
transition: ${({
theme: {
transition: { duration, timing },
},
}) => `${duration.fast} color ${timing.in}`};
}
`
@@ -190,11 +179,10 @@ function Web3StatusInner() {
inputError: swapInputError,
} = useDerivedSwapInfo()
const validSwapQuote = getIsValidSwapQuote(trade, tradeState, swapInputError)
const navbarFlagEnabled = useNavBarFlag() === NavBarVariant.Enabled
const theme = useTheme()
const toggleWalletDropdown = useToggleWalletDropdown()
const toggleWalletModal = useToggleWalletModal()
const walletIsOpen = useIsOpen()
const walletIsOpen = useModalIsOpen(ApplicationModal.WALLET_DROPDOWN)
const error = useAppSelector((state) => state.connection.errorByConnectionType[getConnection(connector).type])
@@ -208,8 +196,7 @@ function Web3StatusInner() {
const pending = sortedRecentTransactions.filter((tx) => !tx.receipt).map((tx) => tx.hash)
const hasPendingTransactions = !!pending.length
const hasSocks = useHasSocks()
const toggleWallet = navbarFlagEnabled ? toggleWalletDropdown : toggleWalletModal
const toggleWallet = toggleWalletDropdown
if (!chainId) {
return null
@@ -229,7 +216,7 @@ function Web3StatusInner() {
}
return (
<Web3StatusConnected data-testid="web3-status-connected" onClick={toggleWallet} pending={hasPendingTransactions}>
{navbarFlagEnabled && !hasPendingTransactions && <StatusIcon size={24} connectionType={connectionType} />}
{!hasPendingTransactions && <StatusIcon size={24} connectionType={connectionType} />}
{hasPendingTransactions ? (
<RowBetween>
<Text>
@@ -239,18 +226,10 @@ function Web3StatusInner() {
</RowBetween>
) : (
<>
{hasSocks && !navbarFlagEnabled ? <Sock /> : null}
<Text>{ENSName || shortenAddress(account)}</Text>
{navbarFlagEnabled ? (
walletIsOpen ? (
<ChevronUp {...chevronProps} />
) : (
<ChevronDown {...chevronProps} />
)
) : null}
{walletIsOpen ? <ChevronUp {...chevronProps} /> : <ChevronDown {...chevronProps} />}
</>
)}
{!navbarFlagEnabled && !hasPendingTransactions && <StatusIcon connectionType={connectionType} />}
</Web3StatusConnected>
)
} else {
@@ -258,7 +237,6 @@ function Web3StatusInner() {
...CHEVRON_PROPS,
color: theme.accentAction,
'data-testid': 'navbar-wallet-dropdown',
onClick: toggleWalletDropdown,
}
return (
<TraceEvent
@@ -267,33 +245,20 @@ function Web3StatusInner() {
properties={{ received_swap_quote: validSwapQuote }}
element={ElementName.CONNECT_WALLET_BUTTON}
>
{navbarFlagEnabled ? (
<Web3StatusConnectButton faded={!account}>
<StyledConnect data-testid="navbar-connect-wallet" onClick={toggleWalletModal}>
<Trans>Connect</Trans>
</StyledConnect>
<VerticalDivider />
<Web3StatusConnectWrapper faded={!account}>
<StyledConnectButton data-testid="navbar-connect-wallet" onClick={toggleWalletModal}>
<Trans>Connect</Trans>
</StyledConnectButton>
<VerticalDivider />
<ChevronWrapper onClick={toggleWalletDropdown}>
{walletIsOpen ? <ChevronUp {...chevronProps} /> : <ChevronDown {...chevronProps} />}
</Web3StatusConnectButton>
) : (
<Web3StatusConnect onClick={toggleWallet} faded={!account}>
<Text>
<Trans>Connect Wallet</Trans>
</Text>
</Web3StatusConnect>
)}
</ChevronWrapper>
</Web3StatusConnectWrapper>
</TraceEvent>
)
}
}
const useIsOpen = () => {
const walletDropdownOpen = useModalIsOpen(ApplicationModal.WALLET_DROPDOWN)
const navbarFlag = useNavBarFlag()
return useMemo(() => navbarFlag === NavBarVariant.Enabled && walletDropdownOpen, [navbarFlag, walletDropdownOpen])
}
export default function Web3Status() {
const { ENSName } = useWeb3React()
@@ -301,7 +266,7 @@ export default function Web3Status() {
const ref = useRef<HTMLDivElement>(null)
const walletRef = useRef<HTMLDivElement>(null)
const closeModal = useCloseModal(ApplicationModal.WALLET_DROPDOWN)
const isOpen = useIsOpen()
const isOpen = useModalIsOpen(ApplicationModal.WALLET_DROPDOWN)
useOnClickOutside(ref, isOpen ? closeModal : undefined, [walletRef])

View File

@@ -1,9 +1,33 @@
import { Currency, OnReviewSwapClick, SwapWidget } from '@uniswap/widgets'
// Import fonts.css for the side-effect of loading fonts for @uniswap/widgets.
// eslint-disable-next-line no-restricted-imports
import '@uniswap/widgets/dist/fonts.css'
import { Trade } from '@uniswap/router-sdk'
import { Currency, TradeType } from '@uniswap/sdk-core'
import {
AddEthereumChainParameter,
EMPTY_TOKEN_LIST,
OnReviewSwapClick,
SwapWidget,
SwapWidgetSkeleton,
} from '@uniswap/widgets'
import { useWeb3React } from '@web3-react/core'
import { sendAnalyticsEvent } from 'analytics'
import { EventName, SectionName } from 'analytics/constants'
import { SWAP_PRICE_UPDATE_USER_RESPONSE } from 'analytics/constants'
import { useTrace } from 'analytics/Trace'
import {
formatPercentInBasisPointsNumber,
formatToDecimal,
getPriceUpdateBasisPoints,
getTokenAddress,
} from 'analytics/utils'
import { useActiveLocale } from 'hooks/useActiveLocale'
import { useMemo } from 'react'
import { useCallback } from 'react'
import { useIsDarkMode } from 'state/user/hooks'
import { DARK_THEME, LIGHT_THEME } from 'theme/widget'
import { computeRealizedPriceImpact } from 'utils/prices'
import { switchChain } from 'utils/switchChain'
import { useSyncWidgetInputs } from './inputs'
import { useSyncWidgetSettings } from './settings'
@@ -20,32 +44,115 @@ export interface WidgetProps {
export default function Widget({ defaultToken, onReviewSwapClick }: WidgetProps) {
const locale = useActiveLocale()
const darkMode = useIsDarkMode()
const theme = useMemo(() => (darkMode ? DARK_THEME : LIGHT_THEME), [darkMode])
const { provider } = useWeb3React()
const theme = useIsDarkMode() ? DARK_THEME : LIGHT_THEME
const { connector, provider } = useWeb3React()
const { inputs, tokenSelector } = useSyncWidgetInputs(defaultToken)
const { settings } = useSyncWidgetSettings()
const { transactions } = useSyncWidgetTransactions()
const trace = useTrace({ section: SectionName.WIDGET })
// TODO(lynnshaoyu): add back onInitialSwapQuote logging once widget side logic is fixed
// in onInitialSwapQuote handler.
const onApproveToken = useCallback(() => {
const input = inputs.value.INPUT
if (!input) return
const eventProperties = {
chain_id: input.chainId,
token_symbol: input.symbol,
token_address: getTokenAddress(input),
...trace,
}
sendAnalyticsEvent(EventName.APPROVE_TOKEN_TXN_SUBMITTED, eventProperties)
}, [inputs.value.INPUT, trace])
const onExpandSwapDetails = useCallback(() => {
sendAnalyticsEvent(EventName.SWAP_DETAILS_EXPANDED, { ...trace })
}, [trace])
const onSwapPriceUpdateAck = useCallback(
(stale: Trade<Currency, Currency, TradeType>, update: Trade<Currency, Currency, TradeType>) => {
const eventProperties = {
chain_id: update.inputAmount.currency.chainId,
response: SWAP_PRICE_UPDATE_USER_RESPONSE.ACCEPTED,
token_in_symbol: update.inputAmount.currency.symbol,
token_out_symbol: update.outputAmount.currency.symbol,
price_update_basis_points: getPriceUpdateBasisPoints(stale.executionPrice, update.executionPrice),
...trace,
}
sendAnalyticsEvent(EventName.SWAP_PRICE_UPDATE_ACKNOWLEDGED, eventProperties)
},
[trace]
)
const onSubmitSwapClick = useCallback(
(trade: Trade<Currency, Currency, TradeType>) => {
const eventProperties = {
// TODO(1416): Include undefined values.
estimated_network_fee_usd: undefined,
transaction_deadline_seconds: undefined,
token_in_address: getTokenAddress(trade.inputAmount.currency),
token_out_address: getTokenAddress(trade.outputAmount.currency),
token_in_symbol: trade.inputAmount.currency.symbol,
token_out_symbol: trade.outputAmount.currency.symbol,
token_in_amount: formatToDecimal(trade.inputAmount, trade.inputAmount.currency.decimals),
token_out_amount: formatToDecimal(trade.outputAmount, trade.outputAmount.currency.decimals),
token_in_amount_usd: undefined,
token_out_amount_usd: undefined,
price_impact_basis_points: formatPercentInBasisPointsNumber(computeRealizedPriceImpact(trade)),
allowed_slippage_basis_points: undefined,
is_auto_router_api: undefined,
is_auto_slippage: undefined,
chain_id: trade.inputAmount.currency.chainId,
// duration should be getDurationFromDateMilliseconds(initialQuoteDate) once initialQuoteDate
// is made available from TODO above for onInitialSwapQuote logging.
duration_from_first_quote_to_swap_submission_milliseconds: undefined,
swap_quote_block_number: undefined,
...trace,
}
sendAnalyticsEvent(EventName.SWAP_SUBMITTED_BUTTON_CLICKED, eventProperties)
},
[trace]
)
const onSwitchChain = useCallback(
// TODO: Widget should not break if this rejects - upstream the catch to ignore it.
({ chainId }: AddEthereumChainParameter) => switchChain(connector, Number(chainId)).catch(() => undefined),
[connector]
)
if (!inputs.value.INPUT && !inputs.value.OUTPUT) {
return <WidgetSkeleton />
}
return (
<>
<SwapWidget
disableBranding
hideConnectionUI
// jsonRpcUrlMap is excluded - network providers are always passed directly
routerUrl={WIDGET_ROUTER_URL}
width={WIDGET_WIDTH}
locale={locale}
theme={theme}
onReviewSwapClick={onReviewSwapClick}
// defaultChainId is excluded - it is always inferred from the passed provider
provider={provider}
onSwitchChain={onSwitchChain}
tokenList={EMPTY_TOKEN_LIST} // prevents loading the default token list, as we use our own token selector UI
{...inputs}
{...settings}
{...transactions}
onExpandSwapDetails={onExpandSwapDetails}
onReviewSwapClick={onReviewSwapClick}
onSubmitSwapClick={onSubmitSwapClick}
onSwapApprove={onApproveToken}
onSwapPriceUpdateAck={onSwapPriceUpdateAck}
/>
{tokenSelector}
</>
)
}
export function WidgetSkeleton() {
return <SwapWidgetSkeleton theme={useIsDarkMode() ? DARK_THEME : LIGHT_THEME} width={WIDGET_WIDTH} />
}

View File

@@ -1,4 +1,7 @@
import { Currency, Field, SwapController, SwapEventHandlers, TradeType } from '@uniswap/widgets'
import { sendAnalyticsEvent } from 'analytics'
import { EventName, SectionName } from 'analytics/constants'
import { useTrace } from 'analytics/Trace'
import CurrencySearchModal from 'components/SearchModal/CurrencySearchModal'
import { useCallback, useEffect, useMemo, useState } from 'react'
@@ -9,18 +12,28 @@ const EMPTY_AMOUNT = ''
* Treats the Widget as a controlled component, using the app's own token selector for selection.
*/
export function useSyncWidgetInputs(defaultToken?: Currency) {
const trace = useTrace({ section: SectionName.WIDGET })
const [type, setType] = useState(TradeType.EXACT_INPUT)
const [amount, setAmount] = useState(EMPTY_AMOUNT)
const onAmountChange = useCallback((field: Field, amount: string) => {
setType(toTradeType(field))
setAmount(amount)
}, [])
const onAmountChange = useCallback(
(field: Field, amount: string, origin?: 'max') => {
if (origin === 'max') {
sendAnalyticsEvent(EventName.SWAP_MAX_TOKEN_AMOUNT_SELECTED, { ...trace })
}
setType(toTradeType(field))
setAmount(amount)
},
[trace]
)
const [tokens, setTokens] = useState<{ [Field.INPUT]?: Currency; [Field.OUTPUT]?: Currency }>({
[Field.OUTPUT]: defaultToken,
})
useEffect(() => {
// Avoid overwriting tokens if none are specified, so that a loading token does not cause layout flashing.
if (!defaultToken) return
setTokens({
[Field.OUTPUT]: defaultToken,
})
@@ -28,12 +41,13 @@ export function useSyncWidgetInputs(defaultToken?: Currency) {
}, [defaultToken])
const onSwitchTokens = useCallback(() => {
sendAnalyticsEvent(EventName.SWAP_TOKENS_REVERSED, { ...trace })
setType((type) => invertTradeType(type))
setTokens((tokens) => ({
[Field.INPUT]: tokens[Field.OUTPUT],
[Field.OUTPUT]: tokens[Field.INPUT],
}))
}, [])
}, [trace])
const [selectingField, setSelectingField] = useState<Field>()
const otherField = useMemo(() => (selectingField === Field.INPUT ? Field.OUTPUT : Field.INPUT), [selectingField])
@@ -51,7 +65,7 @@ export function useSyncWidgetInputs(defaultToken?: Currency) {
setType(TradeType.EXACT_INPUT)
setTokens(() => {
return {
[otherField]: token === otherToken ? selectingToken : otherToken,
[otherField]: otherToken?.equals(token) ? selectingToken : otherToken,
[selectingField]: token,
}
})
@@ -68,7 +82,7 @@ export function useSyncWidgetInputs(defaultToken?: Currency) {
/>
)
const value: SwapController = useMemo(() => ({ type, amount, ...tokens }), [amount, tokens, type])
const value: SwapController['value'] = useMemo(() => ({ type, amount, ...tokens }), [amount, tokens, type])
const valueHandlers: SwapEventHandlers = useMemo(
() => ({ onAmountChange, onSwitchTokens, onTokenSelectorClick }),
[onAmountChange, onSwitchTokens, onTokenSelectorClick]

View File

@@ -1,5 +1,5 @@
import { Percent } from '@uniswap/sdk-core'
import { Slippage, SwapEventHandlers, SwapSettingsController } from '@uniswap/widgets'
import { Slippage, SwapController, SwapEventHandlers } from '@uniswap/widgets'
import { DEFAULT_DEADLINE_FROM_NOW } from 'constants/misc'
import { useCallback, useMemo, useState } from 'react'
import { useUserSlippageTolerance, useUserTransactionTTL } from 'state/user/hooks'
@@ -44,7 +44,7 @@ export function useSyncWidgetSettings() {
setAppSlippage('auto')
}, [setAppSlippage, setAppTtl])
const settings: SwapSettingsController = useMemo(() => {
const settings: SwapController['settings'] = useMemo(() => {
const auto = appSlippage === 'auto'
return { slippage: { auto, max: widgetSlippage }, transactionTtl: widgetTtl }
}, [widgetSlippage, widgetTtl, appSlippage])

View File

@@ -6,6 +6,12 @@ import {
TransactionType as WidgetTransactionType,
} from '@uniswap/widgets'
import { useWeb3React } from '@web3-react/core'
import { sendAnalyticsEvent } from 'analytics'
import { EventName, SectionName } from 'analytics/constants'
import { useTrace } from 'analytics/Trace'
import { formatToDecimal, getTokenAddress } from 'analytics/utils'
import { formatSwapSignedAnalyticsEventProperties } from 'analytics/utils'
import { WrapType } from 'hooks/useWrapCallback'
import { useCallback, useMemo } from 'react'
import { useTransactionAdder } from 'state/transactions/hooks'
import {
@@ -18,6 +24,8 @@ import { currencyId } from 'utils/currencyId'
/** Integrates the Widget's transactions, showing the widget's transactions in the app. */
export function useSyncWidgetTransactions() {
const trace = useTrace({ section: SectionName.WIDGET })
const { chainId } = useWeb3React()
const addTransaction = useTransactionAdder()
@@ -28,8 +36,23 @@ export function useSyncWidgetTransactions() {
if (!type || !response) {
return
} else if (type === WidgetTransactionType.WRAP || type === WidgetTransactionType.UNWRAP) {
const { amount } = transaction.info
const { type, amount: transactionAmount } = transaction.info
const eventProperties = {
// get this info from widget handlers
token_in_address: getTokenAddress(transactionAmount.currency),
token_out_address: getTokenAddress(transactionAmount.currency.wrapped),
token_in_symbol: transactionAmount.currency.symbol,
token_out_symbol: transactionAmount.currency.wrapped.symbol,
chain_id: transactionAmount.currency.chainId,
amount: transactionAmount
? formatToDecimal(transactionAmount, transactionAmount?.currency.decimals)
: undefined,
type: type === WidgetTransactionType.WRAP ? WrapType.WRAP : WrapType.UNWRAP,
...trace,
}
sendAnalyticsEvent(EventName.WRAP_TOKEN_TXN_SUBMITTED, eventProperties)
const { amount } = transaction.info
addTransaction(response, {
type: AppTransactionType.WRAP,
unwrapped: type === WidgetTransactionType.UNWRAP,
@@ -38,6 +61,15 @@ export function useSyncWidgetTransactions() {
} as WrapTransactionInfo)
} else if (type === WidgetTransactionType.SWAP) {
const { slippageTolerance, trade, tradeType } = transaction.info
const eventProperties = {
...formatSwapSignedAnalyticsEventProperties({
trade,
txHash: transaction.receipt?.transactionHash ?? '',
}),
...trace,
}
sendAnalyticsEvent(EventName.SWAP_SIGNED, eventProperties)
const baseTxInfo = {
type: AppTransactionType.SWAP,
tradeType,
@@ -61,7 +93,7 @@ export function useSyncWidgetTransactions() {
}
}
},
[addTransaction, chainId]
[addTransaction, chainId, trace]
)
const txHandlers: TransactionEventHandlers = useMemo(() => ({ onTxSubmit }), [onTxSubmit])

View File

@@ -5,10 +5,9 @@ import { sendAnalyticsEvent } from 'analytics'
import { ModalName } from 'analytics/constants'
import { EventName } from 'analytics/constants'
import { Trace } from 'analytics/Trace'
import { formatPercentInBasisPointsNumber, formatToDecimal, getTokenAddress } from 'analytics/utils'
import { formatSwapSignedAnalyticsEventProperties } from 'analytics/utils'
import { ReactNode, useCallback, useEffect, useMemo, useState } from 'react'
import { InterfaceTrade } from 'state/routing/types'
import { computeRealizedPriceImpact } from 'utils/prices'
import { tradeMeaningfullyDiffers } from 'utils/tradeMeaningFullyDiffer'
import TransactionConfirmationModal, {
@@ -18,27 +17,6 @@ import TransactionConfirmationModal, {
import SwapModalFooter from './SwapModalFooter'
import SwapModalHeader from './SwapModalHeader'
const formatAnalyticsEventProperties = ({
trade,
txHash,
}: {
trade: InterfaceTrade<Currency, Currency, TradeType>
txHash: string
}) => ({
transaction_hash: txHash,
token_in_address: getTokenAddress(trade.inputAmount.currency),
token_out_address: getTokenAddress(trade.outputAmount.currency),
token_in_symbol: trade.inputAmount.currency.symbol,
token_out_symbol: trade.outputAmount.currency.symbol,
token_in_amount: formatToDecimal(trade.inputAmount, trade.inputAmount.currency.decimals),
token_out_amount: formatToDecimal(trade.outputAmount, trade.outputAmount.currency.decimals),
price_impact_basis_points: formatPercentInBasisPointsNumber(computeRealizedPriceImpact(trade)),
chain_id:
trade.inputAmount.currency.chainId === trade.outputAmount.currency.chainId
? trade.inputAmount.currency.chainId
: undefined,
})
export default function ConfirmSwapModal({
trade,
originalTrade,
@@ -149,7 +127,7 @@ export default function ConfirmSwapModal({
useEffect(() => {
if (!attemptingTxn && isOpen && txHash && trade && txHash !== lastTxnHashLogged) {
sendAnalyticsEvent(EventName.SWAP_SIGNED, formatAnalyticsEventProperties({ trade, txHash }))
sendAnalyticsEvent(EventName.SWAP_SIGNED, formatSwapSignedAnalyticsEventProperties({ trade, txHash }))
setLastTxnHashLogged(txHash)
}
}, [attemptingTxn, isOpen, txHash, trade, lastTxnHashLogged])

View File

@@ -1,9 +1,8 @@
import { Trans } from '@lingui/macro'
import { Currency, Percent, TradeType } from '@uniswap/sdk-core'
import { Price } from '@uniswap/sdk-core'
import { sendAnalyticsEvent } from 'analytics'
import { EventName, SWAP_PRICE_UPDATE_USER_RESPONSE } from 'analytics/constants'
import { formatPercentInBasisPointsNumber } from 'analytics/utils'
import { getPriceUpdateBasisPoints } from 'analytics/utils'
import { RedesignVariant, useRedesignFlag } from 'featureFlags/flags/redesign'
import { useEffect, useState } from 'react'
import { AlertTriangle, ArrowDown } from 'react-feather'
@@ -58,15 +57,6 @@ const formatAnalyticsEventProperties = (
price_update_basis_points: priceUpdate,
})
const getPriceUpdateBasisPoints = (
prevPrice: Price<Currency, Currency>,
newPrice: Price<Currency, Currency>
): number => {
const changeFraction = newPrice.subtract(prevPrice).divide(prevPrice)
const changePercentage = new Percent(changeFraction.numerator, changeFraction.denominator)
return formatPercentInBasisPointsNumber(changePercentage)
}
export default function SwapModalHeader({
trade,
shouldLogModalCloseEvent,

View File

@@ -5,6 +5,7 @@ import { useCallback } from 'react'
import { Text } from 'rebass'
import styled, { useTheme } from 'styled-components/macro'
import { ThemedText } from 'theme'
import { formatDollar, formatTransactionAmount, priceToPreciseFloat } from 'utils/formatNumbers'
interface TradePriceProps {
price: Price<Currency, Currency>
@@ -33,15 +34,12 @@ export default function TradePrice({ price, showInverted, setShowInverted }: Tra
const theme = useTheme()
const usdcPrice = useStablecoinPrice(showInverted ? price.baseCurrency : price.quoteCurrency)
/*
* calculate needed amount of decimal prices, for prices between 0.95-1.05 use 4 decimal places
*/
const p = Number(usdcPrice?.toFixed())
const visibleDecimalPlaces = p < 1.05 ? 4 : 2
let formattedPrice: string
try {
formattedPrice = showInverted ? price.toSignificant(4) : price.invert()?.toSignificant(4)
formattedPrice = showInverted
? formatTransactionAmount(priceToPreciseFloat(price))
: formatTransactionAmount(priceToPreciseFloat(price.invert()))
} catch (error) {
formattedPrice = '0'
}
@@ -65,7 +63,7 @@ export default function TradePrice({ price, showInverted, setShowInverted }: Tra
</Text>{' '}
{usdcPrice && (
<ThemedText.DeprecatedDarkGray>
<Trans>(${usdcPrice.toFixed(visibleDecimalPlaces, { groupSeparator: ',' })})</Trans>
<Trans>({formatDollar({ num: priceToPreciseFloat(usdcPrice) })})</Trans>
</ThemedText.DeprecatedDarkGray>
)}
</StyledPriceContainer>

View File

@@ -8,17 +8,17 @@ import { Z_INDEX } from 'theme/zIndex'
import { AutoColumn } from '../Column'
export const PageWrapper = styled.div<{ redesignFlag: boolean; navBarFlag: boolean }>`
padding: ${({ navBarFlag }) => (navBarFlag ? '68px 8px 0px' : '0px 8px')};
export const PageWrapper = styled.div<{ redesignFlag: boolean }>`
padding: 68px 8px 0px;
max-width: 480px;
width: 100%;
@media only screen and (max-width: ${({ theme }) => `${theme.breakpoint.md}px`}) {
padding-top: ${({ navBarFlag }) => (navBarFlag ? '48px' : '0px')};
padding-top: 48px;
}
@media only screen and (max-width: ${({ theme }) => `${theme.breakpoint.sm}px`}) {
padding-top: ${({ navBarFlag }) => (navBarFlag ? '20px' : '0px')};
padding-top: 20px;
}
`

View File

@@ -3,6 +3,7 @@ import { TokenInfo } from '@uniswap/token-lists'
import store from '../state'
import { UNI_EXTENDED_LIST, UNI_LIST, UNSUPPORTED_LIST_URLS } from './lists'
import brokenTokenList from './tokenLists/broken.tokenlist.json'
import { NATIVE_CHAIN_ID } from './tokens'
export enum TOKEN_LIST_TYPES {
UNI_DEFAULT = 1,
@@ -47,6 +48,9 @@ class TokenSafetyLookupTable {
if (!this.dict) {
this.dict = this.createMap()
}
if (address === NATIVE_CHAIN_ID.toLowerCase()) {
return TOKEN_LIST_TYPES.UNI_DEFAULT
}
return this.dict[address] ?? TOKEN_LIST_TYPES.UNKNOWN
}
}

View File

@@ -1,6 +1,5 @@
import celoCircleLogoUrl from 'assets/images/celoCircle.png'
import ethereumLogoUrl from 'assets/images/ethereum-logo.png'
import optimismCircleLogoUrl from 'assets/images/optimismCircle.png'
import polygonCircleLogoUrl from 'assets/images/polygonCircle.png'
import { default as arbitrumCircleLogoUrl, default as arbitrumLogoUrl } from 'assets/svg/arbitrum_logo.svg'
import celoLogo from 'assets/svg/celo_logo.svg'
@@ -114,7 +113,8 @@ const CHAIN_INFO: ChainInfoMap = {
infoLink: 'https://info.uniswap.org/#/optimism/',
label: 'Optimism',
logoUrl: optimismLogoUrl,
circleLogoUrl: optimismCircleLogoUrl,
// Optimism perfers same icon for both
circleLogoUrl: optimismLogoUrl,
statusPage: 'https://optimism.io/status',
helpCenterUrl: 'https://help.uniswap.org/en/collections/3137778-uniswap-on-optimistic-ethereum-oξ',
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },

View File

@@ -4,6 +4,8 @@ import invariant from 'tiny-invariant'
import { UNI_ADDRESS } from './addresses'
import { SupportedChainId } from './chains'
export const NATIVE_CHAIN_ID = 'NATIVE'
export const USDC_MAINNET = new Token(
SupportedChainId.MAINNET,
'0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',

View File

@@ -1,9 +1,6 @@
export enum FeatureFlag {
favoriteTokens = 'favoriteTokens',
navBar = 'navBar',
nft = 'nfts',
redesign = 'redesign',
tokens = 'tokens',
tokenSafety = 'tokenSafety',
traceJsonRpc = 'traceJsonRpc',
multiNetworkBalances = 'multiNetworkBalances',
}

View File

@@ -1,7 +0,0 @@
import { BaseVariant, FeatureFlag, useBaseFlag } from '../index'
export function useNavBarFlag(): BaseVariant {
return useBaseFlag(FeatureFlag.navBar)
}
export { BaseVariant as NavBarVariant }

View File

@@ -1,7 +1,7 @@
import { BaseVariant, FeatureFlag, useBaseFlag } from '../index'
import { BaseVariant } from '../index'
export function useRedesignFlag(): BaseVariant {
return useBaseFlag(FeatureFlag.redesign)
return BaseVariant.Enabled
}
export { BaseVariant as RedesignVariant }

View File

@@ -1,7 +0,0 @@
import { BaseVariant, FeatureFlag, useBaseFlag } from '../index'
export function useTokenSafetyFlag(): BaseVariant {
return useBaseFlag(FeatureFlag.tokenSafety)
}
export { BaseVariant as TokenSafetyVariant }

View File

@@ -1,7 +0,0 @@
import { BaseVariant, FeatureFlag, useBaseFlag } from '../index'
export function useTokensFlag(): BaseVariant {
return useBaseFlag(FeatureFlag.tokens)
}
export { BaseVariant as TokensVariant }

View File

@@ -1,32 +1,12 @@
import graphql from 'babel-plugin-relay/macro'
import { filterTimeAtom } from 'components/Tokens/state'
import { useAtomValue } from 'jotai/utils'
import { useCallback, useEffect, useState } from 'react'
import { fetchQuery, useFragment, useLazyLoadQuery, useRelayEnvironment } from 'react-relay'
import { useMemo, useState } from 'react'
import { fetchQuery, useLazyLoadQuery } from 'react-relay'
import { Chain, TokenPriceQuery } from './__generated__/TokenPriceQuery.graphql'
import { TokenPrices$data, TokenPrices$key } from './__generated__/TokenPrices.graphql'
import { TokenQuery, TokenQuery$data } from './__generated__/TokenQuery.graphql'
import { ContractInput, HistoryDuration, TokenQuery, TokenQuery$data } from './__generated__/TokenQuery.graphql'
import environment from './RelayEnvironment'
import { TimePeriod, toHistoryDuration } from './util'
export type PricePoint = { value: number; timestamp: number }
export const projectMetaDataFragment = graphql`
fragment Token_TokenProject_Metadata on TokenProject {
description
homepageUrl
twitterName
name
}
`
const tokenPricesFragment = graphql`
fragment TokenPrices on TokenProjectMarket {
priceHistory(duration: $duration) {
timestamp
value
}
}
`
/*
The difference between Token and TokenProject:
Token: an on-chain entity referring to a contract (e.g. uni token on ethereum 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984)
@@ -60,6 +40,12 @@ const tokenQuery = graphql`
value
currency
}
priceHigh52W: priceHighLow(duration: YEAR, highLow: HIGH) {
value
}
priceLow52W: priceHighLow(duration: YEAR, highLow: LOW) {
value
}
}
project {
description
@@ -75,13 +61,79 @@ const tokenQuery = graphql`
}
`
export function useTokenQuery(address: string, chain: Chain, timePeriod: TimePeriod) {
const data = useLazyLoadQuery<TokenQuery>(tokenQuery, {
contract: { address: address.toLowerCase(), chain },
duration: toHistoryDuration(timePeriod),
export type PricePoint = { value: number; timestamp: number }
export function filterPrices(prices: NonNullable<NonNullable<SingleTokenData>['market']>['priceHistory'] | undefined) {
return prices?.filter((p): p is PricePoint => Boolean(p && p.value))
}
export type PriceDurations = Record<TimePeriod, PricePoint[] | undefined>
function fetchAllPriceDurations(contract: ContractInput, originalDuration: HistoryDuration) {
return fetchQuery<TokenPriceQuery>(environment, tokenPriceQuery, {
contract,
skip1H: originalDuration === 'HOUR',
skip1D: originalDuration === 'DAY',
skip1W: originalDuration === 'WEEK',
skip1M: originalDuration === 'MONTH',
skip1Y: originalDuration === 'YEAR',
})
}
export type SingleTokenData = NonNullable<TokenQuery$data['tokens']>[number]
export function useTokenQuery(
address: string,
chain: Chain,
timePeriod: TimePeriod
): [SingleTokenData | undefined, PriceDurations] {
const [prices, setPrices] = useState<PriceDurations>({
[TimePeriod.HOUR]: undefined,
[TimePeriod.DAY]: undefined,
[TimePeriod.WEEK]: undefined,
[TimePeriod.MONTH]: undefined,
[TimePeriod.YEAR]: undefined,
})
return data
const contract = useMemo(() => {
return { address: address.toLowerCase(), chain }
}, [address, chain])
// eslint-disable-next-line react-hooks/exhaustive-deps
const originalTimePeriod = useMemo(() => timePeriod, [contract])
const updatePrices = (response: TokenPriceQuery['response']) => {
const priceData = response.tokens?.[0]?.market
if (priceData) {
setPrices((current) => {
return {
[TimePeriod.HOUR]: filterPrices(priceData.priceHistory1H) ?? current[TimePeriod.HOUR],
[TimePeriod.DAY]: filterPrices(priceData.priceHistory1D) ?? current[TimePeriod.DAY],
[TimePeriod.WEEK]: filterPrices(priceData.priceHistory1W) ?? current[TimePeriod.WEEK],
[TimePeriod.MONTH]: filterPrices(priceData.priceHistory1M) ?? current[TimePeriod.MONTH],
[TimePeriod.YEAR]: filterPrices(priceData.priceHistory1Y) ?? current[TimePeriod.YEAR],
}
})
}
}
// Fetch prices & token info in tandem so we can render faster
useMemo(
() => fetchAllPriceDurations(contract, toHistoryDuration(originalTimePeriod)).subscribe({ next: updatePrices }),
[contract, originalTimePeriod]
)
const token = useLazyLoadQuery<TokenQuery>(tokenQuery, {
contract,
duration: toHistoryDuration(originalTimePeriod),
}).tokens?.[0]
useMemo(
() =>
setPrices((current) => {
current[originalTimePeriod] = filterPrices(token?.market?.priceHistory)
return current
}),
[token, originalTimePeriod]
)
return [token, prices]
}
const tokenPriceQuery = graphql`
@@ -119,60 +171,3 @@ const tokenPriceQuery = graphql`
}
}
`
export function filterPrices(prices: TokenPrices$data['priceHistory'] | undefined) {
return prices?.filter((p): p is PricePoint => Boolean(p && p.value))
}
export function useTokenPricesFromFragment(key: TokenPrices$key | null | undefined) {
const fetchedTokenPrices = useFragment(tokenPricesFragment, key ?? null)?.priceHistory
return filterPrices(fetchedTokenPrices)
}
export function useTokenPricesCached(token: SingleTokenData) {
// Attempt to use token prices already provided by TokenDetails / TopToken queries
const environment = useRelayEnvironment()
const timePeriod = useAtomValue(filterTimeAtom)
const [priceMap, setPriceMap] = useState<Map<TimePeriod, PricePoint[] | undefined>>(new Map())
const updatePrices = useCallback(
(key: TimePeriod, data?: PricePoint[]) => {
setPriceMap(new Map(priceMap.set(key, data)))
},
[priceMap]
)
// Fetch the other timePeriods after first render
useEffect(() => {
const fetchedTokenPrices = token?.market?.priceHistory
updatePrices(timePeriod, filterPrices(fetchedTokenPrices))
// Fetch all time periods except the one already populated
if (token?.chain && token?.address) {
fetchQuery<TokenPriceQuery>(environment, tokenPriceQuery, {
contract: { address: token.address, chain: token.chain },
skip1H: timePeriod === TimePeriod.HOUR && !!fetchedTokenPrices,
skip1D: timePeriod === TimePeriod.DAY && !!fetchedTokenPrices,
skip1W: timePeriod === TimePeriod.WEEK && !!fetchedTokenPrices,
skip1M: timePeriod === TimePeriod.MONTH && !!fetchedTokenPrices,
skip1Y: timePeriod === TimePeriod.YEAR && !!fetchedTokenPrices,
}).subscribe({
next: (data) => {
const market = data.tokens?.[0]?.market
if (market) {
market.priceHistory1H && updatePrices(TimePeriod.HOUR, filterPrices(market.priceHistory1H))
market.priceHistory1D && updatePrices(TimePeriod.DAY, filterPrices(market.priceHistory1D))
market.priceHistory1W && updatePrices(TimePeriod.WEEK, filterPrices(market.priceHistory1W))
market.priceHistory1M && updatePrices(TimePeriod.MONTH, filterPrices(market.priceHistory1M))
market.priceHistory1Y && updatePrices(TimePeriod.YEAR, filterPrices(market.priceHistory1Y))
}
},
})
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [token?.chain, token?.address])
return { prices: priceMap.get(timePeriod) }
}
export type SingleTokenData = NonNullable<TokenQuery$data['tokens']>[number]

View File

@@ -6,19 +6,16 @@ import {
showFavoritesAtom,
sortAscendingAtom,
sortMethodAtom,
TokenSortMethod,
} from 'components/Tokens/state'
import { useAtomValue } from 'jotai/utils'
import { useCallback, useEffect, useLayoutEffect, useMemo, useState } from 'react'
import { fetchQuery, useRelayEnvironment } from 'react-relay'
import { useEffect, useMemo, useState } from 'react'
import { fetchQuery, useLazyLoadQuery, useRelayEnvironment } from 'react-relay'
import {
Chain,
ContractInput,
HistoryDuration,
TopTokens_TokensQuery,
} from './__generated__/TopTokens_TokensQuery.graphql'
import type { TopTokens100Query } from './__generated__/TopTokens100Query.graphql'
import { toHistoryDuration } from './util'
import type { Chain, TopTokens100Query } from './__generated__/TopTokens100Query.graphql'
import { TopTokensSparklineQuery } from './__generated__/TopTokensSparklineQuery.graphql'
import { filterPrices, PricePoint } from './Token'
import { CHAIN_NAME_TO_CHAIN_ID, toHistoryDuration, unwrapToken } from './util'
const topTokens100Query = graphql`
query TopTokens100Query($duration: HistoryDuration!, $chain: Chain!) {
@@ -46,26 +43,34 @@ const topTokens100Query = graphql`
currency
}
}
project {
logoUrl
}
}
}
`
export enum TokenSortMethod {
PRICE = 'Price',
PERCENT_CHANGE = 'Change',
TOTAL_VALUE_LOCKED = 'TVL',
VOLUME = 'Volume',
}
const tokenSparklineQuery = graphql`
query TopTokensSparklineQuery($duration: HistoryDuration!, $chain: Chain!) {
topTokens(pageSize: 100, page: 1, chain: $chain) {
address
market(currency: USD) {
priceHistory(duration: $duration) {
timestamp
value
}
}
}
}
`
export type PrefetchedTopToken = NonNullable<TopTokens100Query['response']['topTokens']>[number]
function useSortedTokens(tokens: TopTokens100Query['response']['topTokens'] | undefined) {
function useSortedTokens(tokens: NonNullable<TopTokens100Query['response']['topTokens']>) {
const sortMethod = useAtomValue(sortMethodAtom)
const sortAscending = useAtomValue(sortAscendingAtom)
return useMemo(() => {
if (!tokens) return []
let tokenArray = Array.from(tokens)
switch (sortMethod) {
case TokenSortMethod.PRICE:
@@ -90,7 +95,7 @@ function useSortedTokens(tokens: TopTokens100Query['response']['topTokens'] | un
}, [tokens, sortMethod, sortAscending])
}
function useFilteredTokens(tokens: PrefetchedTopToken[]) {
function useFilteredTokens(tokens: NonNullable<TopTokens100Query['response']['topTokens']>) {
const filterString = useAtomValue(filterStringAtom)
const favorites = useAtomValue(favoritesAtom)
const showFavorites = useAtomValue(showFavoritesAtom)
@@ -98,10 +103,6 @@ function useFilteredTokens(tokens: PrefetchedTopToken[]) {
const lowercaseFilterString = useMemo(() => filterString.toLowerCase(), [filterString])
return useMemo(() => {
if (!tokens) {
return []
}
let returnTokens = tokens
if (showFavorites) {
returnTokens = returnTokens?.filter((token) => token?.address && favorites.includes(token.address))
@@ -121,205 +122,43 @@ function useFilteredTokens(tokens: PrefetchedTopToken[]) {
// Number of items to render in each fetch in infinite scroll.
export const PAGE_SIZE = 20
function toContractInput(token: PrefetchedTopToken) {
return {
address: token?.address ?? '',
chain: token?.chain ?? 'ETHEREUM',
}
}
// Map of key: ${HistoryDuration} and value: another Map, of key:${chain} + ${address} and value: TopToken object.
// Acts as a local cache.
const tokensWithPriceHistoryCache: Record<HistoryDuration, Record<string, TopToken>> = {
DAY: {},
HOUR: {},
MAX: {},
MONTH: {},
WEEK: {},
YEAR: {},
'%future added value': {},
}
const checkIfAllTokensCached = (duration: HistoryDuration, tokens: PrefetchedTopToken[]) => {
let everyTokenInCache = true
const cachedTokens: TopToken[] = []
const checkCache = (token: PrefetchedTopToken) => {
const tokenCacheKey = !!token ? `${token.chain}${token.address}` : ''
if (tokenCacheKey in tokensWithPriceHistoryCache[duration]) {
cachedTokens.push(tokensWithPriceHistoryCache[duration][tokenCacheKey])
return true
} else {
everyTokenInCache = false
cachedTokens.length = 0
return false
}
}
tokens.every((token) => checkCache(token))
return { everyTokenInCache, cachedTokens }
}
export type TopToken = NonNullable<TopTokens_TokensQuery['response']['tokens']>[number]
export type TopToken = NonNullable<NonNullable<TopTokens100Query['response']>['topTokens']>[number]
export type SparklineMap = { [key: string]: PricePoint[] | undefined }
interface UseTopTokensReturnValue {
error: Error | undefined
loading: boolean
tokens: TopToken[] | undefined
hasMore: boolean
loadMoreTokens: () => void
loadingRowCount: number
sparklines: SparklineMap
}
export function useTopTokens(chain: Chain): UseTopTokensReturnValue {
const chainId = CHAIN_NAME_TO_CHAIN_ID[chain]
const duration = toHistoryDuration(useAtomValue(filterTimeAtom))
const [loadingTokensWithoutPriceHistory, setLoadingTokensWithoutPriceHistory] = useState(true)
const [loadingTokensWithPriceHistory, setLoadingTokensWithPriceHistory] = useState(true)
const [tokens, setTokens] = useState<TopToken[]>()
const [page, setPage] = useState(0)
const [error, setError] = useState<Error | undefined>()
const [prefetchedData, setPrefetchedData] = useState<PrefetchedTopToken[]>()
const prefetchedSelectedTokensWithoutPriceHistory = useFilteredTokens(useSortedTokens(prefetchedData))
const loading = Boolean(loadingTokensWithPriceHistory || loadingTokensWithoutPriceHistory)
// loadingRowCount defaults to PAGE_SIZE when no prefetchedData is available yet because the initial load
// count will always be PAGE_SIZE.
const loadingRowCount = useMemo(
() => (prefetchedData ? Math.min(prefetchedSelectedTokensWithoutPriceHistory.length, PAGE_SIZE) : PAGE_SIZE),
[prefetchedSelectedTokensWithoutPriceHistory, prefetchedData]
)
const hasMore = !tokens || tokens.length < prefetchedSelectedTokensWithoutPriceHistory.length
const environment = useRelayEnvironment()
const loadTokensWithoutPriceHistory = useCallback(
({ duration, chain }: { duration: HistoryDuration; chain: Chain }) => {
fetchQuery<TopTokens100Query>(
environment,
topTokens100Query,
{ duration, chain },
{ fetchPolicy: 'store-or-network' }
).subscribe({
next: (data) => {
if (data?.topTokens) setPrefetchedData([...data?.topTokens])
},
error: setError,
complete: () => setLoadingTokensWithoutPriceHistory(false),
})
},
[environment]
)
// TopTokens should ideally be fetched with usePaginationFragment. The backend does not current support graphql cursors;
// in the meantime, fetchQuery is used, as other relay hooks do not allow the refreshing and lazy loading we need
const loadTokensWithPriceHistory = useCallback(
({
contracts,
appendingTokens,
page,
tokens,
}: {
contracts: ContractInput[]
appendingTokens: boolean
page: number
tokens?: TopToken[]
}) => {
fetchQuery<TopTokens_TokensQuery>(
environment,
tokensQuery,
{ contracts, duration },
{ fetchPolicy: 'store-or-network' }
).subscribe({
next: (data) => {
if (data?.tokens) {
const priceHistoryCacheForCurrentDuration = tokensWithPriceHistoryCache[duration]
data.tokens.map((token) =>
!!token ? (priceHistoryCacheForCurrentDuration[`${token.chain}${token.address}`] = token) : null
)
appendingTokens ? setTokens([...(tokens ?? []), ...data.tokens]) : setTokens([...data.tokens])
setLoadingTokensWithPriceHistory(false)
setPage(page + 1)
}
},
error: setError,
complete: () => setLoadingTokensWithPriceHistory(false),
})
},
[duration, environment]
)
const loadMoreTokens = useCallback(() => {
setLoadingTokensWithPriceHistory(true)
const contracts = prefetchedSelectedTokensWithoutPriceHistory
.slice(page * PAGE_SIZE, (page + 1) * PAGE_SIZE)
.map(toContractInput)
loadTokensWithPriceHistory({ contracts, appendingTokens: true, page, tokens })
}, [prefetchedSelectedTokensWithoutPriceHistory, page, loadTokensWithPriceHistory, tokens])
// Reset count when filters are changed
useLayoutEffect(() => {
const { everyTokenInCache, cachedTokens } = checkIfAllTokensCached(
duration,
prefetchedSelectedTokensWithoutPriceHistory
)
if (everyTokenInCache) {
setTokens(cachedTokens)
setLoadingTokensWithPriceHistory(false)
} else {
setLoadingTokensWithPriceHistory(true)
setTokens([])
const contracts = prefetchedSelectedTokensWithoutPriceHistory.slice(0, PAGE_SIZE).map(toContractInput)
loadTokensWithPriceHistory({ contracts, appendingTokens: false, page: 0 })
}
}, [loadTokensWithPriceHistory, prefetchedSelectedTokensWithoutPriceHistory, duration])
// Trigger fetching top 100 tokens without price history on first load, and on
// each change of chain or duration.
const [sparklines, setSparklines] = useState<SparklineMap>({})
useEffect(() => {
setLoadingTokensWithoutPriceHistory(true)
loadTokensWithoutPriceHistory({ duration, chain })
}, [chain, duration, loadTokensWithoutPriceHistory])
const subscription = fetchQuery<TopTokensSparklineQuery>(environment, tokenSparklineQuery, { duration, chain })
.map((data) => ({
topTokens: data.topTokens?.map((token) => unwrapToken(chainId, token)),
}))
.subscribe({
next(data) {
const map: SparklineMap = {}
data.topTokens?.forEach(
(current) => current?.address && (map[current.address] = filterPrices(current?.market?.priceHistory))
)
setSparklines(map)
},
})
return () => subscription.unsubscribe()
}, [chain, chainId, duration, environment])
return {
error,
loading,
tokens,
hasMore,
loadMoreTokens,
loadingRowCount,
}
useEffect(() => {
setSparklines({})
}, [duration])
const { topTokens } = useLazyLoadQuery<TopTokens100Query>(topTokens100Query, { duration, chain })
const mappedTokens = useMemo(() => topTokens?.map((token) => unwrapToken(chainId, token)) ?? [], [chainId, topTokens])
const filteredTokens = useFilteredTokens(mappedTokens)
const sortedTokens = useSortedTokens(filteredTokens)
return useMemo(() => ({ tokens: sortedTokens, sparklines }), [sortedTokens, sparklines])
}
export const tokensQuery = graphql`
query TopTokens_TokensQuery($contracts: [ContractInput!]!, $duration: HistoryDuration!) {
tokens(contracts: $contracts) {
id @required(action: LOG)
name
chain @required(action: LOG)
address @required(action: LOG)
symbol
market(currency: USD) {
totalValueLocked {
value
currency
}
priceHistory(duration: $duration) {
timestamp
value
}
price {
value
currency
}
volume(duration: $duration) {
value
currency
}
pricePercentChange(duration: $duration) {
currency
value
}
}
project {
logoUrl
}
}
}
`

View File

@@ -16,7 +16,12 @@ const fetchQuery = (params: RequestParameters, variables: Variables): Promise<Gr
variables,
})
return fetch(URL, { method: 'POST', body, headers }).then((res) => res.json())
return fetch(URL, { method: 'POST', body, headers })
.then((res) => res.json())
.catch((e) => {
console.error(e)
return { data: [] }
})
}
export default fetchQuery

View File

@@ -1,5 +1,6 @@
import { SupportedChainId } from 'constants/chains'
import { useAppSelector } from 'state/hooks'
import { ZERO_ADDRESS } from 'constants/misc'
import { NATIVE_CHAIN_ID, nativeOnChain, WRAPPED_NATIVE_CURRENCY } from 'constants/tokens'
import { Chain, HistoryDuration } from './__generated__/TokenQuery.graphql'
@@ -39,9 +40,10 @@ export const CHAIN_ID_TO_BACKEND_NAME: { [key: number]: Chain } = {
[SupportedChainId.OPTIMISM_GOERLI]: 'OPTIMISM',
}
export function useGlobalChainName() {
const chainId = useAppSelector((state) => state.application.chainId)
return chainId && CHAIN_ID_TO_BACKEND_NAME[chainId] ? CHAIN_ID_TO_BACKEND_NAME[chainId] : 'ETHEREUM'
export function chainIdToBackendName(chainId: number | undefined) {
return chainId && CHAIN_ID_TO_BACKEND_NAME[chainId]
? CHAIN_ID_TO_BACKEND_NAME[chainId]
: CHAIN_ID_TO_BACKEND_NAME[SupportedChainId.MAINNET]
}
export const URL_CHAIN_PARAM_TO_BACKEND: { [key: string]: Chain } = {
@@ -64,7 +66,7 @@ export const CHAIN_NAME_TO_CHAIN_ID: { [key: string]: SupportedChainId } = {
OPTIMISM: SupportedChainId.OPTIMISM,
}
export const BACKEND_CHAIN_NAMES: Chain[] = ['ARBITRUM', 'CELO', 'ETHEREUM', 'OPTIMISM', 'POLYGON']
export const BACKEND_CHAIN_NAMES: Chain[] = ['ETHEREUM', 'POLYGON', 'OPTIMISM', 'ARBITRUM', 'CELO']
export function isValidBackendChainName(chainName: string | undefined): chainName is Chain {
if (!chainName) return false
@@ -75,7 +77,9 @@ export function isValidBackendChainName(chainName: string | undefined): chainNam
}
export function getTokenDetailsURL(address: string, chainName?: Chain, chainId?: number) {
if (chainName) {
if (address === ZERO_ADDRESS && chainId && chainId === SupportedChainId.MAINNET) {
return `/tokens/${CHAIN_ID_TO_BACKEND_NAME[chainId].toLowerCase()}/${NATIVE_CHAIN_ID}`
} else if (chainName) {
return `/tokens/${chainName.toLowerCase()}/${address}`
} else if (chainId) {
const chainName = CHAIN_ID_TO_BACKEND_NAME[chainId]
@@ -84,3 +88,19 @@ export function getTokenDetailsURL(address: string, chainName?: Chain, chainId?:
return ''
}
}
export function unwrapToken<T extends { address: string | null } | null>(chainId: number, token: T): T {
if (!token?.address) return token
const address = token.address.toLowerCase()
const nativeAddress = WRAPPED_NATIVE_CURRENCY[chainId]?.address.toLowerCase()
if (address !== nativeAddress) return token
const nativeToken = nativeOnChain(chainId)
return {
...token,
...nativeToken,
address: NATIVE_CHAIN_ID,
extensions: undefined, // prevents marking cross-chain wrapped tokens as native
}
}

View File

@@ -1,9 +1,11 @@
import { useWeb3React } from '@web3-react/core'
import { Chain } from 'graphql/data/__generated__/TokenQuery.graphql'
import { useGlobalChainName } from 'graphql/data/util'
import { chainIdToBackendName } from 'graphql/data/util'
import { useEffect, useRef } from 'react'
export const useOnGlobalChainSwitch = (callback: (chain: Chain) => void) => {
const globalChainName = useGlobalChainName()
const { chainId: connectedChainId } = useWeb3React()
const globalChainName = chainIdToBackendName(connectedChainId)
const prevGlobalChainRef = useRef(globalChainName)
useEffect(() => {
if (prevGlobalChainRef.current !== globalChainName) {

View File

@@ -0,0 +1,123 @@
import { Currency, CurrencyAmount, NativeCurrency, Token } from '@uniswap/sdk-core'
import { useWeb3React } from '@web3-react/core'
import { Weth } from 'abis/types'
import WETH_ABI from 'abis/weth.json'
import { ALL_SUPPORTED_CHAIN_IDS, isSupportedChain, SupportedChainId, TESTNET_CHAIN_IDS } from 'constants/chains'
import { RPC_PROVIDERS } from 'constants/providers'
import { NATIVE_CHAIN_ID, nativeOnChain, WRAPPED_NATIVE_CURRENCY } from 'constants/tokens'
import { BaseVariant, FeatureFlag, useBaseFlag } from 'featureFlags'
import { useCallback, useEffect, useState } from 'react'
import { getContract } from 'utils'
interface useMultiNetworkAddressBalancesArgs {
ownerAddress: string | undefined
tokenAddress: 'NATIVE' | string | undefined
}
type AddressNetworkBalanceData = Partial<
Record<
SupportedChainId,
Record<string | 'NATIVE', CurrencyAmount<Token> | CurrencyAmount<NativeCurrency> | undefined>
>
>
interface handleBalanceArg {
amount: CurrencyAmount<Currency>
chainId: SupportedChainId
tokenAddress: string | 'NATIVE'
}
const testnetSet = new Set(TESTNET_CHAIN_IDS) as Set<SupportedChainId>
export function useMultiNetworkAddressBalances({ ownerAddress, tokenAddress }: useMultiNetworkAddressBalancesArgs) {
const [data, setData] = useState<AddressNetworkBalanceData>({})
const [error] = useState<string | null>(null)
const [loading, setLoading] = useState(false)
const { chainId: connectedChainId } = useWeb3React()
const feature_flag_multi_network_balances = useBaseFlag(FeatureFlag.multiNetworkBalances)
const handleBalance = useCallback(({ amount, chainId, tokenAddress }: handleBalanceArg) => {
if (!amount.greaterThan(0) || !tokenAddress) {
return
}
setData((data) => ({
...data,
[chainId]: {
...(data[chainId] ?? {}),
[tokenAddress]: amount,
},
}))
}, [])
useEffect(() => {
if (!ownerAddress || !tokenAddress) {
return
}
const isConnecteToTestnet = connectedChainId ? TESTNET_CHAIN_IDS.includes(connectedChainId) : false
setLoading(true)
const isNative = tokenAddress === NATIVE_CHAIN_ID
const promises: Promise<any>[] = []
const isWrappedNative = ALL_SUPPORTED_CHAIN_IDS.some(
(chainId) => WRAPPED_NATIVE_CURRENCY[chainId]?.address.toLowerCase() === tokenAddress.toLowerCase()
)
const chainsToCheck: SupportedChainId[] =
feature_flag_multi_network_balances === BaseVariant.Enabled
? ALL_SUPPORTED_CHAIN_IDS
: isSupportedChain(connectedChainId)
? [SupportedChainId.MAINNET, connectedChainId]
: [SupportedChainId.MAINNET]
chainsToCheck.forEach((chainId) => {
const isTestnet = testnetSet.has(chainId)
if ((isConnecteToTestnet && isTestnet) || !isTestnet) {
const provider = RPC_PROVIDERS[chainId]
if (isWrappedNative || isNative) {
const wrappedNative = WRAPPED_NATIVE_CURRENCY[chainId]
if (wrappedNative) {
promises.push(
new Promise(async (resolve) => {
try {
const wrappedNativeContract = getContract(wrappedNative.address, WETH_ABI, provider) as Weth
const balance = await wrappedNativeContract.balanceOf(ownerAddress, { blockTag: 'latest' })
const amount = CurrencyAmount.fromRawAmount(wrappedNative, balance.toString())
resolve(handleBalance({ amount, chainId, tokenAddress: wrappedNative.address.toLowerCase() }))
} catch (e) {}
})
)
}
promises.push(
new Promise(async (resolve) => {
try {
const balance = await provider.getBalance(ownerAddress, 'latest')
const nativeCurrency = nativeOnChain(chainId)
const amount = CurrencyAmount.fromRawAmount(nativeCurrency, balance.toString())
resolve(handleBalance({ amount, chainId, tokenAddress: 'NATIVE' }))
} catch (e) {}
})
)
// todo (jordan): support multi-network ERC20 balances
// } else {
// promises.push(
// new Promise(async (resolve) => {
// try {
// const ERC20Contract = getContract(tokenAddress, ERC20_ABI, provider) as Erc20
// const balance = await ERC20Contract.balanceOf(ownerAddress, { blockTag: 'latest' })
// const amount = //
// resolve(handleBalance({ amount, chainId, tokenAddress }))
// } catch (e) {}
// })
// )
}
}
})
Promise.all(promises)
.catch(() => ({}))
.finally(() => setLoading(false))
}, [connectedChainId, feature_flag_multi_network_balances, handleBalance, ownerAddress, tokenAddress])
return { data, error, loading }
}

View File

@@ -1,77 +0,0 @@
import { CurrencyAmount, Token } from '@uniswap/sdk-core'
import { SupportedChainId } from 'constants/chains'
import { gql } from 'graphql-request'
import { useEffect, useState } from 'react'
type NetworkTokenBalancesMap = Partial<Record<SupportedChainId, CurrencyAmount<Token>>>
interface useNetworkTokenBalancesResult {
data: NetworkTokenBalancesMap | null
error: null | string
loading: boolean
}
interface useNetworkTokenBalancesArgs {
address: string | undefined
}
export function useNetworkTokenBalances({ address }: useNetworkTokenBalancesArgs): useNetworkTokenBalancesResult {
const [data, setData] = useState<NetworkTokenBalancesMap | null>(null)
const [error, setError] = useState<string | null>(null)
const [loading, setLoading] = useState(false)
const query = gql``
useEffect(() => {
if (address) {
const FAKE_TOKEN_NETWORK_BALANCES = {
[SupportedChainId.ARBITRUM_ONE]: CurrencyAmount.fromRawAmount(
new Token(SupportedChainId.ARBITRUM_ONE, address, 18),
10e18
),
[SupportedChainId.MAINNET]: CurrencyAmount.fromRawAmount(
new Token(SupportedChainId.MAINNET, address, 18),
1e18
),
[SupportedChainId.RINKEBY]: CurrencyAmount.fromRawAmount(
new Token(SupportedChainId.RINKEBY, address, 9),
10e18
),
}
const fetchNetworkTokenBalances = async (address: string): Promise<NetworkTokenBalancesMap | void> => {
const waitRandom = (min: number, max: number): Promise<void> =>
new Promise((resolve) => setTimeout(resolve, min + Math.round(Math.random() * Math.max(0, max - min))))
try {
setLoading(true)
setError(null)
await waitRandom(250, 2000)
if (Math.random() < 0.05) {
throw new Error('fake error')
}
return FAKE_TOKEN_NETWORK_BALANCES
} catch (e) {
setError('something went wrong')
} finally {
setLoading(false)
}
}
setLoading(true)
setError(null)
fetchNetworkTokenBalances(address)
.then((data) => {
if (data) setData(data)
})
.catch((e) => setError(e))
.finally(() => setLoading(false))
} else {
setData(null)
}
}, [address, query])
return {
data,
error,
loading,
}
}

View File

@@ -2,16 +2,90 @@ import { arrayify } from '@ethersproject/bytes'
import { parseBytes32String } from '@ethersproject/strings'
import { Currency, Token } from '@uniswap/sdk-core'
import { useWeb3React } from '@web3-react/core'
import { isSupportedChain } from 'constants/chains'
import ERC20_ABI from 'abis/erc20.json'
import { Erc20 } from 'abis/types'
import { isSupportedChain, SupportedChainId } from 'constants/chains'
import { RPC_PROVIDERS } from 'constants/providers'
import { useBytes32TokenContract, useTokenContract } from 'hooks/useContract'
import { NEVER_RELOAD, useSingleCallResult } from 'lib/hooks/multicall'
import useNativeCurrency from 'lib/hooks/useNativeCurrency'
import { useMemo } from 'react'
import { useEffect, useMemo, useState } from 'react'
import { WrappedTokenInfo } from 'state/lists/wrappedTokenInfo'
import { TOKEN_SHORTHANDS } from '../../constants/tokens'
import { isAddress } from '../../utils'
import { getContract, isAddress } from '../../utils'
import { supportedChainId } from '../../utils/supportedChainId'
/**
* Returns a Token from query data.
* Data should already include all fields except decimals, or it will be considered invalid.
* Returns null if the token is loading or null was passed.
* Returns undefined if invalid or the token does not exist.
*/
export function useTokenFromQuery({
address: tokenAddress,
chainId,
symbol,
name,
project,
}: {
address?: string
chainId?: SupportedChainId
symbol?: string | null
name?: string | null
project?: { logoUrl?: string | null } | null
} = {}): Token | null | undefined {
const { chainId: activeChainId } = useWeb3React()
const address = isAddress(tokenAddress)
const [decimals, setDecimals] = useState<number | null | undefined>(null)
const tokenContract = useTokenContract(chainId === activeChainId ? (address ? address : undefined) : undefined, false)
const { loading, result: [decimalsResult] = [] } = useSingleCallResult(
tokenContract,
'decimals',
undefined,
NEVER_RELOAD
)
useEffect(() => {
if (loading) {
setDecimals(null)
} else if (decimalsResult) {
setDecimals(decimalsResult)
} else if (!address || !chainId || chainId === activeChainId) {
setDecimals(undefined)
} else {
setDecimals(null)
// Load decimals from a cross-chain RPC provider.
const provider = RPC_PROVIDERS[chainId]
const contract = getContract(address, ERC20_ABI, provider) as Erc20
contract
.decimals()
.then((value) => {
if (!stale) setDecimals(value)
})
.catch(() => undefined)
}
let stale = false
return () => {
stale = true
}
}, [activeChainId, address, chainId, decimalsResult, loading])
return useMemo(() => {
if (!chainId || !address) return undefined
if (decimals === null || decimals === undefined) return decimals
if (!symbol || !name) {
return new Token(chainId, address, decimals, symbol ?? undefined, name ?? undefined)
} else {
const logoURI = project?.logoUrl ?? undefined
return new WrappedTokenInfo({ chainId, address, decimals, symbol, name, logoURI })
}
}, [address, chainId, decimals, name, project?.logoUrl, symbol])
}
// parse a name or symbol from a token response
const BYTES32_REGEX = /^0x[a-fA-F0-9]{64}$/
@@ -29,48 +103,43 @@ function parseStringOrBytes32(str: string | undefined, bytes32: string | undefin
* Returns null if token is loading or null was passed.
* Returns undefined if tokenAddress is invalid or token does not exist.
*/
export function useTokenFromNetwork(tokenAddress: string | null | undefined): Token | null | undefined {
export function useTokenFromActiveNetwork(tokenAddress: string | undefined): Token | null | undefined {
const { chainId } = useWeb3React()
const supportedChain = isSupportedChain(chainId)
const formattedAddress = isAddress(tokenAddress)
const tokenContract = useTokenContract(formattedAddress ? formattedAddress : undefined, false)
const tokenContractBytes32 = useBytes32TokenContract(formattedAddress ? formattedAddress : undefined, false)
// TODO: Fix redux-multicall so that these values do not reload.
const tokenName = useSingleCallResult(tokenContract, 'name', undefined, NEVER_RELOAD)
const tokenNameBytes32 = useSingleCallResult(tokenContractBytes32, 'name', undefined, NEVER_RELOAD)
const symbol = useSingleCallResult(tokenContract, 'symbol', undefined, NEVER_RELOAD)
const symbolBytes32 = useSingleCallResult(tokenContractBytes32, 'symbol', undefined, NEVER_RELOAD)
const decimals = useSingleCallResult(tokenContract, 'decimals', undefined, NEVER_RELOAD)
const isLoading = useMemo(
() => decimals.loading || symbol.loading || tokenName.loading,
[decimals.loading, symbol.loading, tokenName.loading]
)
const parsedDecimals = useMemo(() => decimals.result?.[0], [decimals.result])
const parsedSymbol = useMemo(
() => parseStringOrBytes32(symbol.result?.[0], symbolBytes32.result?.[0], 'UNKNOWN'),
[symbol.result, symbolBytes32.result]
)
const parsedName = useMemo(
() => parseStringOrBytes32(tokenName.result?.[0], tokenNameBytes32.result?.[0], 'Unknown Token'),
[tokenName.result, tokenNameBytes32.result]
)
return useMemo(() => {
if (typeof tokenAddress !== 'string' || !supportedChain || !formattedAddress) return undefined
if (decimals.loading || symbol.loading || tokenName.loading) return null
if (decimals.result) {
return new Token(
chainId,
formattedAddress,
decimals.result[0],
parseStringOrBytes32(symbol.result?.[0], symbolBytes32.result?.[0], 'UNKNOWN'),
parseStringOrBytes32(tokenName.result?.[0], tokenNameBytes32.result?.[0], 'Unknown Token')
)
}
return undefined
}, [
formattedAddress,
chainId,
supportedChain,
decimals.loading,
decimals.result,
symbol.loading,
symbol.result,
symbolBytes32.result,
tokenAddress,
tokenName.loading,
tokenName.result,
tokenNameBytes32.result,
])
// If the token is on another chain, we cannot fetch it on-chain, and it is invalid.
if (typeof tokenAddress !== 'string' || !isSupportedChain(chainId) || !formattedAddress) return undefined
if (isLoading || !chainId) return null
if (!parsedDecimals) return undefined
return new Token(chainId, formattedAddress, parsedDecimals, parsedSymbol, parsedName)
}, [chainId, tokenAddress, formattedAddress, isLoading, parsedDecimals, parsedSymbol, parsedName])
}
type TokenMap = { [address: string]: Token }
@@ -84,7 +153,7 @@ export function useTokenFromMapOrNetwork(tokens: TokenMap, tokenAddress?: string
const address = isAddress(tokenAddress)
const token: Token | undefined = address ? tokens[address] : undefined
const tokenFromNetwork = useTokenFromNetwork(token ? undefined : address ? address : undefined)
const tokenFromNetwork = useTokenFromActiveNetwork(token ? undefined : address ? address : undefined)
return tokenFromNetwork ?? token
}
@@ -105,8 +174,7 @@ export function useCurrencyFromMap(tokens: TokenMap, currencyId?: string | null)
const token = useTokenFromMapOrNetwork(tokens, isNative ? undefined : shorthandMatchAddress ?? currencyId)
const supportedChain = isSupportedChain(chainId)
if (currencyId === null || currencyId === undefined || !supportedChain) return null
if (currencyId === null || currencyId === undefined || !isSupportedChain(chainId)) return null
// this case so we use our builtin wrapped token instead of wrapped tokens on token lists
const wrappedNative = nativeCurrency?.wrapped

View File

@@ -56,9 +56,10 @@ export function useTokenBalancesWithLoadingIndicator(
address?: string,
tokens?: (Token | undefined)[]
): [{ [tokenAddress: string]: CurrencyAmount<Token> | undefined }, boolean] {
const { chainId } = useWeb3React() // we cannot fetch balances cross-chain
const validatedTokens: Token[] = useMemo(
() => tokens?.filter((t?: Token): t is Token => isAddress(t?.address) !== false) ?? [],
[tokens]
() => tokens?.filter((t?: Token): t is Token => isAddress(t?.address) !== false && t?.chainId === chainId) ?? [],
[chainId, tokens]
)
const validatedTokenAddresses = useMemo(() => validatedTokens.map((vt) => vt.address), [validatedTokens])

View File

@@ -1,13 +1,12 @@
import { Currency } from '@uniswap/sdk-core'
import { SupportedChainId } from 'constants/chains'
import useHttpLocations from 'hooks/useHttpLocations'
import { useMemo } from 'react'
import { WrappedTokenInfo } from 'state/lists/wrappedTokenInfo'
import { isAddress } from 'utils'
import EthereumLogo from '../../assets/images/ethereum-logo.png'
import CeloLogo from '../../assets/svg/celo_logo.svg'
import MaticLogo from '../../assets/svg/matic-token-icon.svg'
import { isCelo, nativeOnChain } from '../../constants/tokens'
import { isCelo, NATIVE_CHAIN_ID, nativeOnChain } from '../../constants/tokens'
type Network = 'ethereum' | 'arbitrum' | 'optimism' | 'polygon'
@@ -54,15 +53,27 @@ export function getTokenLogoURI(address: string, chainId: SupportedChainId = Sup
}
}
export default function useCurrencyLogoURIs(currency?: Currency | null): string[] {
const locations = useHttpLocations(currency instanceof WrappedTokenInfo ? currency.logoURI : undefined)
export default function useCurrencyLogoURIs(
currency:
| {
isNative?: boolean
isToken?: boolean
address?: string
chainId: number
logoURI?: string
}
| null
| undefined
): string[] {
const locations = useHttpLocations(currency?.logoURI)
return useMemo(() => {
const logoURIs = [...locations]
if (currency) {
if (currency.isNative) {
if (currency.isNative || currency.address === NATIVE_CHAIN_ID) {
logoURIs.push(getNativeLogoURI(currency.chainId))
} else if (currency.isToken) {
const logoURI = getTokenLogoURI(currency.address, currency.chainId)
} else if (currency.isToken || currency.address) {
const checksummedAddress = isAddress(currency.address)
const logoURI = checksummedAddress && getTokenLogoURI(checksummedAddress, currency.chainId)
if (logoURI) {
logoURIs.push(logoURI)
}

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: uniswap-interface\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2022-09-21 21:05\n"
"PO-Revision-Date: 2022-10-11 02:57\n"
"Last-Translator: \n"
"Language: af_ZA\n"
"Language-Team: Afrikaans\n"
@@ -21,10 +21,6 @@ msgstr ""
msgid "$-"
msgstr "$ -"
#: src/components/CurrencyInputPanel/FiatValue.tsx
msgid "$<0/>"
msgstr "$<0/>"
#: src/components/earn/PoolCard.tsx
#: src/components/swap/GasEstimateBadge.tsx
#: src/pages/Pool/PositionPage.tsx
@@ -63,6 +59,10 @@ msgstr "0 UNI / week"
msgid "24H volume"
msgstr "24H volume"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "24H volume is the amount of the asset that has been traded on Uniswap v3 during the past 24 hours."
msgstr "24H-volume is die bedrag van die bate wat gedurende die afgelope 24 uur op Uniswap v3 verhandel is."
#: src/pages/RemoveLiquidity/V3.tsx
msgid "25%"
msgstr "25%"
@@ -240,7 +240,7 @@ msgid "Amount"
msgstr "Bedrag"
#: src/components/Tokens/TokenTable/TokenTable.tsx
msgid "An error occured loading tokens. Please try again."
msgid "An error occurred loading tokens. Please try again."
msgstr "Kon nie tokens laai nie. Probeer asseblief weer."
#: src/utils/swapErrorToUserReadableMessage.tsx
@@ -373,11 +373,14 @@ msgstr "Deur likiditeit by te voeg, verdien u 0,3% van alle transaksies op hierd
msgid "By adding this list you are implicitly trusting that the data is correct. Anyone can create a list, including creating fake versions of existing lists and lists that claim to represent projects that do not have one."
msgstr "Deur hierdie lys by te voeg, vertrou u implisiet dat die data korrek is. Almal kan 'n lys opstel, insluitend die skep van vals weergawes van bestaande lyste en lyste wat beweer dat hulle projekte verteenwoordig wat nie een het nie."
#: src/components/WalletModal/index.tsx
#: src/components/WalletModal/index.tsx
msgid "By connecting a wallet, you agree to Uniswap Labs <0>Terms of Service</0> and acknowledge that you have read and understand the Uniswap <1>Protocol Disclaimer</1>."
msgstr "Deur 'n beursie te koppel, stem jy in tot Uniswap Labs se <0>Diensbepalings</0> en erken dat jy die Uniswap <1>Protokol Disclaimer</1>gelees en verstaan het."
#: src/components/WalletModal/index.tsx
msgid "By connecting a wallet, you agree to Uniswap Labs <0>Terms of Service</0> and consent to its <1>Privacy Policy</1>."
msgstr "Deur 'n beursie te koppel, stem jy in tot Uniswap Labs se <0>Diensbepalings</0> en stem in tot sy <1>Privaatheidsbeleid</1>."
#: src/pages/Vote/styled.tsx
msgid "Canceled"
msgstr "Gekanselleer"
@@ -605,11 +608,13 @@ msgid "Contract address"
msgstr "Kontrak adres"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
#: src/nft/components/profile/view/ProfileAccountDetails.tsx
#: src/theme/components.tsx
msgid "Copied!"
msgstr "Gekopieer!"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
#: src/nft/components/profile/view/ProfileAccountDetails.tsx
msgid "Copy"
msgstr "Kopieer"
@@ -889,10 +894,6 @@ msgstr "Die uitvoering van hierdie voorstel sal die oproepdata in die ketting in
msgid "Execution Submitted"
msgstr "Uitvoering ingedien"
#: src/components/SearchModal/CurrencyList/index.tsx
msgid "Expanded results from inactive Token Lists"
msgstr "Uitgebreide resultate van onaktiewe tekenlyste"
#: src/components/swap/AdvancedSwapDetails.tsx
msgid "Expected Output"
msgstr "Verwagte uitset"
@@ -913,10 +914,9 @@ msgstr "Verstreke"
msgid "Explore"
msgstr "Verken"
#: src/pages/Tokens/index.tsx
#: src/pages/Tokens/index.tsx
msgid "Explore Tokens"
msgstr "Verken Tokens"
#: src/components/Tokens/TokensBanner.tsx
msgid "Explore Top Tokens on Uniswap"
msgstr "Verken Top Tokens op Uniswap"
#: src/pages/Pool/CTACards.tsx
msgid "Explore Uniswap Analytics."
@@ -1130,6 +1130,10 @@ msgstr "Ligte tema"
msgid "Light theme"
msgstr "Ligte tema"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Links"
msgstr "Skakels"
#: src/components/claim/ClaimModal.tsx
#: src/pages/Pool/PositionPage.tsx
msgid "Liquidity"
@@ -1262,6 +1266,11 @@ msgstr "Min:"
msgid "Minimum received"
msgstr "Minimum ontvang"
#: src/components/Tokens/TokenDetails/PriceChart.tsx
#: src/components/Tokens/TokenDetails/PriceChart.tsx
msgid "Missing chart data"
msgstr "Grafiekdata ontbreek"
#: src/lib/hooks/swap/useSwapCallback.tsx
msgid "Missing dependencies"
msgstr "Ontbrekings ontbreek"
@@ -1270,7 +1279,7 @@ msgstr "Ontbrekings ontbreek"
msgid "More"
msgstr "Meer"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "NFT Collections"
msgstr "NFT-versamelings"
@@ -1298,6 +1307,10 @@ msgstr "Netwerkfooie oorskry 50% van die ruilbedrag!"
msgid "New Position"
msgstr "Nuwe posisie"
#: src/nft/components/profile/view/EmptyWalletContent.tsx
msgid "No NFTs in"
msgstr "Geen NFT's in nie"
#: src/pages/MigrateV2/index.tsx
msgid "No V2 Liquidity found."
msgstr "Geen V2-likiditeit gevind nie."
@@ -1339,7 +1352,7 @@ msgstr "Geen tekeninligting beskikbaar nie"
msgid "No tokens found"
msgstr "Geen tokens gevind nie"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "No tokens found."
msgstr "Geen tokens gevind nie."
@@ -1468,11 +1481,11 @@ msgstr "Gepoel {0}:"
msgid "Pools"
msgstr "Swembaddens"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Popular NFT collections"
msgstr "Gewilde NFT-versamelings"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Popular tokens"
msgstr "Gewilde tekens"
@@ -1577,10 +1590,6 @@ msgstr "Toustaan"
msgid "Rates"
msgstr "Tariewe"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Read more"
msgstr "Lees meer"
#: src/pages/Earn/index.tsx
msgid "Read more about UNI"
msgstr "Lees meer oor UNI"
@@ -1601,7 +1610,7 @@ msgstr "Lees meer oor onondersteunde bates"
msgid "Recent Transactions"
msgstr "Onlangse transaksies"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Recent searches"
msgstr "Onlangse soektogte"
@@ -1719,10 +1728,6 @@ msgstr "Self"
msgid "Self Delegate"
msgstr "Self Afgevaardigde"
#: src/components/NavBar/MenuDropdown.tsx
msgid "Sell NFTs"
msgstr "Verkoop NFT's"
#: src/pages/AddLiquidity/index.tsx
#: src/pages/AddLiquidity/index.tsx
#: src/pages/MigrateV2/MigrateV2Pair.tsx
@@ -1755,6 +1760,10 @@ msgstr "Vertoning is gekanselleer"
msgid "Show closed positions"
msgstr "Toon geslote posisies"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Show more"
msgstr "Wys meer"
#: src/pages/RemoveLiquidity/index.tsx
msgid "Simple"
msgstr "Eenvoudig"
@@ -1771,6 +1780,14 @@ msgstr "Sommige bates is nie beskikbaar via hierdie koppelvlak nie, omdat dit mo
msgid "Something went wrong"
msgstr "Iets het verkeerd geloop"
#: src/components/Tokens/TokensBanner.tsx
msgid "Sort and filter assets across networks on the new Tokens page."
msgstr "Sorteer en filtreer bates oor netwerke op die nuwe Tokens-bladsy."
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "Stats"
msgstr "Statistieke"
#: src/pages/Earn/Manage.tsx
msgid "Step 1. Get UNI-V2 Liquidity tokens"
msgstr "Stap 1. Kry UNI-V2 likiditeitstekens"
@@ -1806,7 +1823,7 @@ msgstr "Verskaf {0} {1} en {2} {3}"
#: src/components/AccountDetailsV2/TransactionBody.tsx
#: src/components/Header/index.tsx
#: src/components/NavBar/index.tsx
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
#: src/components/swap/SwapHeader.tsx
#: src/pages/Swap/index.tsx
#: src/pages/Swap/index.tsx
@@ -1848,6 +1865,10 @@ msgstr "Ruil {0} {1} vir {2} {3}"
msgid "Symbol not found"
msgstr "Simbool nie gevind nie"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "TVL"
msgstr "TVL"
#: src/components/Popups/SurveyPopup.tsx
msgid "Take a 10 minute survey to help us improve your experience in the Uniswap app."
msgstr "Neem 'n 10 minute opname om ons te help om jou ervaring in die Uniswap-toepassing te verbeter."
@@ -1962,14 +1983,6 @@ msgstr "Die transaksie kon nie gestuur word nie omdat die sperdatum verstryk het
msgid "There is no liquidity data."
msgstr "Daar is geen likiditeitsdata nie."
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "There was an error fetching your balance"
msgstr "Kon nie jou saldo haal nie"
#: src/components/Tokens/TokenDetails/BalanceSummary.tsx
msgid "There was an error loading your {0} balance"
msgstr "Kon nie jou {0} -saldo laai nie"
#: src/components/ConnectedAccountBlocked/index.tsx
msgid "This address is blocked on the Uniswap Labs interface because it is associated with one or more"
msgstr "Hierdie adres is geblokkeer op die Uniswap Labs-koppelvlak omdat dit met een of meer geassosieer word"
@@ -1994,6 +2007,10 @@ msgstr "Hierdie roete optimaliseer jou totale uitset deur gesplete roetes, veelv
msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade."
msgstr "Hierdie teken verskyn nie op die aktiewe tekenlys(te) nie. Maak seker dat dit die teken is wat u wil verhandel."
#: src/components/Tokens/TokenDetails/PriceChart.tsx
msgid "This token doesn't have chart data because it hasn't been traded on Uniswap v3"
msgstr "Hierdie teken het nie grafiekdata nie omdat dit nie op Uniswap v3 verhandel is nie"
#: src/components/SearchModal/BlockedToken.tsx
msgid "This token is not supported in the Uniswap Labs app"
msgstr "Hierdie teken word nie in die Uniswap Labs-toepassing ondersteun nie"
@@ -2033,23 +2050,20 @@ msgid "Token not supported"
msgstr "Token word nie ondersteun nie"
#: src/components/Header/index.tsx
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
#: src/components/NavBar/index.tsx
#: src/components/SearchModal/Manage.tsx
msgid "Tokens"
msgstr "Tekens"
#: src/components/SearchModal/CurrencyList/index.tsx
msgid "Tokens from inactive lists. Import specific tokens below or click Manage to activate more lists."
msgstr "Tekens uit onaktiewe lyste. Voer spesifieke tekens hieronder in of klik op Bestuur om meer lyste te aktiveer."
#: src/pages/Pool/CTACards.tsx
msgid "Top pools"
msgstr "Top poele"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "Total Value Locked"
msgstr "Totale waarde gesluit"
#: src/pages/Tokens/index.tsx
#: src/pages/Tokens/index.tsx
msgid "Top tokens on Uniswap"
msgstr "Top tokens op Uniswap"
#: src/components/earn/PoolCard.tsx
msgid "Total deposited"
@@ -2059,6 +2073,10 @@ msgstr "Totale deposito"
msgid "Total deposits"
msgstr "Totale deposito's"
#: src/components/Tokens/TokenTable/TokenRow.tsx
msgid "Total value locked (TVL) is the amount of the asset thats currently in a Uniswap v3 liquidity pool."
msgstr "Totale waarde gesluit (TVL) is die bedrag van die bate wat tans in 'n Uniswap v3-likiditeitspoel is."
#: src/components/swap/RouterLabel.tsx
msgid "Trade Route"
msgstr "Handelsroete"
@@ -2263,10 +2281,18 @@ msgstr "V3 {0} prys:"
msgid "View accrued fees and analytics<0>↗</0>"
msgstr "Kyk na opgelope fooie en analise <0> ↗</0>"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
msgid "View and sell NFTs"
msgstr "Bekyk en verkoop NFT's"
#: src/components/SearchModal/ManageLists.tsx
msgid "View list"
msgstr "Kyk na lys"
#: src/components/NavBar/MenuDropdown.tsx
msgid "View more analytics"
msgstr "Bekyk meer ontledings"
#: src/components/TransactionConfirmationModal/index.tsx
#: src/pages/CreateProposal/ProposalSubmissionModal.tsx
msgid "View on Etherscan"
@@ -2278,10 +2304,6 @@ msgstr "Uitsig op Etherscan"
msgid "View on Explorer"
msgstr "Bekyk op Explorer"
#: src/components/NavBar/MenuDropdown.tsx
msgid "View token analytics"
msgstr "Bekyk token-analise"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
@@ -2291,6 +2313,10 @@ msgstr "Bekyk token-analise"
msgid "View transaction on Explorer"
msgstr "Bekyk transaksie op Explorer"
#: src/components/Tokens/TokenTable/TokenRow.tsx
msgid "Volume is the amount of the asset that has been traded on Uniswap v3 during the selected time frame."
msgstr "Volume is die bedrag van die bate wat gedurende die geselekteerde tydraamwerk op Uniswap v3 verhandel is."
#: src/components/Header/index.tsx
msgid "Vote"
msgstr "Stem"
@@ -2472,10 +2498,6 @@ msgstr "U het nog nie likiditeit in hierdie poel nie."
msgid "You have no favorited tokens"
msgstr "Jy het geen gunsteling-tokens nie"
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "You may have lost your network connection, or {label} might be down right now."
msgstr "Miskien het u u netwerkverbinding verloor, of {label} is tans af."
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "You may have lost your network connection."
msgstr "U het moontlik u netwerkverbinding verloor."
@@ -2517,9 +2539,9 @@ msgstr "U V2-likiditeit"
msgid "Your active V3 liquidity positions will appear here."
msgstr "Jou aktiewe V3-likiditeitsposisies sal hier verskyn."
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "Your balances by network"
msgstr "Jou saldo's per netwerk"
#: src/components/Tokens/TokenDetails/BalanceSummary.tsx
msgid "Your balance"
msgstr "Jou balans"
#: src/pages/Pool/index.tsx
msgid "Your connected network is unsupported."
@@ -2608,6 +2630,11 @@ msgstr "U transaksies sal hier verskyn ..."
msgid "Your unclaimed UNI"
msgstr "U onopgeëiste UNI"
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
msgid "Your {0} balance"
msgstr "Jou {0} -saldo"
#: src/components/swap/AdvancedSwapDetails.tsx
msgid "after slippage"
msgstr "na gly"
@@ -2684,8 +2711,8 @@ msgid "{0, plural, =1 {Import token} other {Import tokens}}"
msgstr "{0, plural, =1 {Voer teken in} other {Voer tekens in}}"
#: src/constants/tokenSafety.tsx
msgid "{0, plural, =1 {This token isn't verified} other {These tokens aren't verified}}"
msgstr "{0, plural, =1 {Hierdie teken is nie geverifieer nie} other {Hierdie tekens is nie geverifieer nie}}"
msgid "{0, plural, =1 {This token isn't verified.} other {These tokens aren't verified.}}"
msgstr "{0, plural, =1 {Hierdie teken is nie geverifieer nie.} other {Hierdie tekens is nie geverifieer nie.}}"
#: src/constants/tokenSafety.tsx
msgid "{0, plural, =1 {You can't trade this token using the Uniswap App.} other {You can't trade these tokens using the Uniswap App.}}"
@@ -2758,10 +2785,6 @@ msgstr "{0} UNI-V2 LP tekens beskikbaar"
msgid "{0} Votes"
msgstr "{0} Stemme"
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "{0} all balances"
msgstr "{0} alle saldo's"
#: src/components/PositionPreview/index.tsx
#: src/components/PositionPreview/index.tsx
#: src/components/PositionPreview/index.tsx
@@ -2839,6 +2862,10 @@ msgstr "{USER_AMOUNT} UNI"
msgid "{activeTokensOnThisChain} tokens"
msgstr "{activeTokensOnThisChain} tokens"
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "{label} might be down right now, or you may have lost your network connection."
msgstr "{label} is dalk op die oomblik af, of jy het dalk jou netwerkverbinding verloor."
#: src/components/NetworkAlert/NetworkAlert.tsx
msgid "{label} token bridge"
msgstr "{label} teken brug"

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: uniswap-interface\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2022-09-21 21:05\n"
"PO-Revision-Date: 2022-10-11 02:57\n"
"Last-Translator: \n"
"Language: ar_SA\n"
"Language-Team: Arabic\n"
@@ -21,10 +21,6 @@ msgstr ""
msgid "$-"
msgstr "$-"
#: src/components/CurrencyInputPanel/FiatValue.tsx
msgid "$<0/>"
msgstr "<0/>دولار"
#: src/components/earn/PoolCard.tsx
#: src/components/swap/GasEstimateBadge.tsx
#: src/pages/Pool/PositionPage.tsx
@@ -63,6 +59,10 @@ msgstr "0 UNI / أسبوع"
msgid "24H volume"
msgstr "حجم 24H"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "24H volume is the amount of the asset that has been traded on Uniswap v3 during the past 24 hours."
msgstr "حجم 24 ساعة هو مقدار الأصل الذي تم تداوله على Uniswap v3 خلال الـ 24 ساعة الماضية."
#: src/pages/RemoveLiquidity/V3.tsx
msgid "25%"
msgstr "25%"
@@ -240,8 +240,8 @@ msgid "Amount"
msgstr "المبلغ"
#: src/components/Tokens/TokenTable/TokenTable.tsx
msgid "An error occured loading tokens. Please try again."
msgstr "حدث خطأ أثناء تحميل الرموز. حاول مرة اخرى."
msgid "An error occurred loading tokens. Please try again."
msgstr "حدث خطأ أثناء تحميل الرموز المميزة. حاول مرة اخرى."
#: src/utils/swapErrorToUserReadableMessage.tsx
msgid "An error occurred when trying to execute this swap. You may need to increase your slippage tolerance. If that does not work, there may be an incompatibility with the token you are trading. Note: fee on transfer and rebase tokens are incompatible with Uniswap V3."
@@ -373,11 +373,14 @@ msgstr "من خلال إضافة السيولة ستكسب 0.3٪ من جميع
msgid "By adding this list you are implicitly trusting that the data is correct. Anyone can create a list, including creating fake versions of existing lists and lists that claim to represent projects that do not have one."
msgstr "بإضافة هذه القائمة فإنك تثق ضمنًا بأن البيانات صحيحة. ويمكن لأي شخص أن ينشئ قائمة، بما في ذلك إنشاء صيغ مزيفة من القوائم القائمة والقوائم التي تزعم أنها تمثل مشاريع لا تملك قائمة."
#: src/components/WalletModal/index.tsx
#: src/components/WalletModal/index.tsx
msgid "By connecting a wallet, you agree to Uniswap Labs <0>Terms of Service</0> and acknowledge that you have read and understand the Uniswap <1>Protocol Disclaimer</1>."
msgstr "من خلال ربط المحفظة ، فإنك توافق على شروط الخدمة</0> <0>وتقر بأنك قد قرأت وفهمت إخلاء مسؤولية بروتوكول <1></1>."
#: src/components/WalletModal/index.tsx
msgid "By connecting a wallet, you agree to Uniswap Labs <0>Terms of Service</0> and consent to its <1>Privacy Policy</1>."
msgstr "من خلال ربط المحفظة ، فإنك توافق على شروط الخدمة <0>الخاصة بـ</1>Labs وتوافق على</0> سياسة الخصوصية <1>."
#: src/pages/Vote/styled.tsx
msgid "Canceled"
msgstr "ألغيت"
@@ -605,11 +608,13 @@ msgid "Contract address"
msgstr "عنوان العقد"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
#: src/nft/components/profile/view/ProfileAccountDetails.tsx
#: src/theme/components.tsx
msgid "Copied!"
msgstr "نسخ!"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
#: src/nft/components/profile/view/ProfileAccountDetails.tsx
msgid "Copy"
msgstr "ينسخ"
@@ -889,10 +894,6 @@ msgstr "سيؤدي تنفيذ هذا الاقتراح إلى تفعيل Calldata
msgid "Execution Submitted"
msgstr "تم تقديم التنفيذ"
#: src/components/SearchModal/CurrencyList/index.tsx
msgid "Expanded results from inactive Token Lists"
msgstr "النتائج الموسعة من قوائم الرموز غير النشطة"
#: src/components/swap/AdvancedSwapDetails.tsx
msgid "Expected Output"
msgstr "الناتج المتوقع"
@@ -913,10 +914,9 @@ msgstr "منتهي الصلاحية"
msgid "Explore"
msgstr "يكتشف"
#: src/pages/Tokens/index.tsx
#: src/pages/Tokens/index.tsx
msgid "Explore Tokens"
msgstr "اكتشف الرموز"
#: src/components/Tokens/TokensBanner.tsx
msgid "Explore Top Tokens on Uniswap"
msgstr "استكشف أفضل الرموز على Uniswap"
#: src/pages/Pool/CTACards.tsx
msgid "Explore Uniswap Analytics."
@@ -1130,6 +1130,10 @@ msgstr "مظهر خفيف"
msgid "Light theme"
msgstr "مظهر خفيف"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Links"
msgstr "الروابط"
#: src/components/claim/ClaimModal.tsx
#: src/pages/Pool/PositionPage.tsx
msgid "Liquidity"
@@ -1262,6 +1266,11 @@ msgstr "دقيقة:"
msgid "Minimum received"
msgstr "تلقى الحد الأدنى"
#: src/components/Tokens/TokenDetails/PriceChart.tsx
#: src/components/Tokens/TokenDetails/PriceChart.tsx
msgid "Missing chart data"
msgstr "بيانات الرسم البياني مفقودة"
#: src/lib/hooks/swap/useSwapCallback.tsx
msgid "Missing dependencies"
msgstr "التبعيات المفقودة"
@@ -1270,7 +1279,7 @@ msgstr "التبعيات المفقودة"
msgid "More"
msgstr "المزيد"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "NFT Collections"
msgstr "مجموعات NFT"
@@ -1298,6 +1307,10 @@ msgstr "رسوم الشبكة تتجاوز 50٪ من مبلغ المبادلة!"
msgid "New Position"
msgstr "موضع جديد"
#: src/nft/components/profile/view/EmptyWalletContent.tsx
msgid "No NFTs in"
msgstr "لا توجد NFTs في"
#: src/pages/MigrateV2/index.tsx
msgid "No V2 Liquidity found."
msgstr "لم يتم العثور على سيولة V2."
@@ -1339,7 +1352,7 @@ msgstr "لا توجد معلومات رمزية متاحة"
msgid "No tokens found"
msgstr "لم يتم العثور على الرموز المميزة"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "No tokens found."
msgstr "لم يتم العثور على الرموز المميزة."
@@ -1468,11 +1481,11 @@ msgstr "مجمّع {0}:"
msgid "Pools"
msgstr "حمامات السباحة"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Popular NFT collections"
msgstr "مجموعات NFT الشعبية"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Popular tokens"
msgstr "الرموز الشعبية"
@@ -1577,10 +1590,6 @@ msgstr "قائمة الانتظار"
msgid "Rates"
msgstr "الأسعار"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Read more"
msgstr "اقرأ أكثر"
#: src/pages/Earn/index.tsx
msgid "Read more about UNI"
msgstr "اقرأ المزيد عن UNI"
@@ -1601,7 +1610,7 @@ msgstr "اقرأ المزيد عن الأصول غير المدعومة"
msgid "Recent Transactions"
msgstr "المعاملات الأخيرة"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Recent searches"
msgstr "عمليات البحث الأخيرة"
@@ -1719,10 +1728,6 @@ msgstr "نفسه"
msgid "Self Delegate"
msgstr "تفويض ذاتي"
#: src/components/NavBar/MenuDropdown.tsx
msgid "Sell NFTs"
msgstr "بيع NFTs"
#: src/pages/AddLiquidity/index.tsx
#: src/pages/AddLiquidity/index.tsx
#: src/pages/MigrateV2/MigrateV2Pair.tsx
@@ -1755,6 +1760,10 @@ msgstr "إظهار الملغاة"
msgid "Show closed positions"
msgstr "إظهار المراكز المغلقة"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Show more"
msgstr "أظهر المزيد"
#: src/pages/RemoveLiquidity/index.tsx
msgid "Simple"
msgstr "بسيط"
@@ -1771,6 +1780,14 @@ msgstr "بعض الأصول غير متوفرة من خلال هذه الواج
msgid "Something went wrong"
msgstr "حدث خطأ ما"
#: src/components/Tokens/TokensBanner.tsx
msgid "Sort and filter assets across networks on the new Tokens page."
msgstr "قم بفرز الأصول وتصفيتها عبر الشبكات في صفحة الرموز الجديدة."
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "Stats"
msgstr "احصائيات"
#: src/pages/Earn/Manage.tsx
msgid "Step 1. Get UNI-V2 Liquidity tokens"
msgstr "الخطوة 1. احصل على رمز سيولة UNI-V2"
@@ -1806,7 +1823,7 @@ msgstr "إمداد {0} {1} و {2} {3}"
#: src/components/AccountDetailsV2/TransactionBody.tsx
#: src/components/Header/index.tsx
#: src/components/NavBar/index.tsx
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
#: src/components/swap/SwapHeader.tsx
#: src/pages/Swap/index.tsx
#: src/pages/Swap/index.tsx
@@ -1848,6 +1865,10 @@ msgstr "مبادلة {0} {1} مقابل {2} {3}"
msgid "Symbol not found"
msgstr "لم يتم العثور على الرمز"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "TVL"
msgstr "TVL"
#: src/components/Popups/SurveyPopup.tsx
msgid "Take a 10 minute survey to help us improve your experience in the Uniswap app."
msgstr "شارك في استبيان مدته 10 دقائق لمساعدتنا على تحسين تجربتك في تطبيق Uniswap."
@@ -1962,14 +1983,6 @@ msgstr "تعذر إرسال المعاملة لانتهاء الموعد الم
msgid "There is no liquidity data."
msgstr "لا توجد بيانات سيولة."
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "There was an error fetching your balance"
msgstr "حدث خطأ في جلب رصيدك"
#: src/components/Tokens/TokenDetails/BalanceSummary.tsx
msgid "There was an error loading your {0} balance"
msgstr "حدث خطأ أثناء تحميل رصيدك {0}"
#: src/components/ConnectedAccountBlocked/index.tsx
msgid "This address is blocked on the Uniswap Labs interface because it is associated with one or more"
msgstr "هذا العنوان محظور في واجهة Uniswap Labs لأنه مرتبط بواحد أو أكثر"
@@ -1994,6 +2007,10 @@ msgstr "يعمل هذا المسار على تحسين إنتاجك الإجما
msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade."
msgstr "لا يظهر هذا الرمز في قائمة (قوائم) الرموز النشطة. تأكد من أن هذا هو الرمز الذي تريد تداوله."
#: src/components/Tokens/TokenDetails/PriceChart.tsx
msgid "This token doesn't have chart data because it hasn't been traded on Uniswap v3"
msgstr "لا يحتوي هذا الرمز المميز على بيانات مخطط لأنه لم يتم تداوله على Uniswap v3"
#: src/components/SearchModal/BlockedToken.tsx
msgid "This token is not supported in the Uniswap Labs app"
msgstr "هذا الرمز المميز غير مدعوم في تطبيق Uniswap Labs"
@@ -2033,23 +2050,20 @@ msgid "Token not supported"
msgstr "رمز غير مدعوم"
#: src/components/Header/index.tsx
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
#: src/components/NavBar/index.tsx
#: src/components/SearchModal/Manage.tsx
msgid "Tokens"
msgstr "الرموز"
#: src/components/SearchModal/CurrencyList/index.tsx
msgid "Tokens from inactive lists. Import specific tokens below or click Manage to activate more lists."
msgstr "الرموز من القوائم غير النشطة. قم باستيراد الرموز المميزة المحددة أدناه أو انقر فوق \"إدارة\" لتنشيط المزيد من القوائم."
#: src/pages/Pool/CTACards.tsx
msgid "Top pools"
msgstr "أفضل المجموعات"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "Total Value Locked"
msgstr "إجمالي القيمة مؤمن"
#: src/pages/Tokens/index.tsx
#: src/pages/Tokens/index.tsx
msgid "Top tokens on Uniswap"
msgstr "أعلى الرموز على Uniswap"
#: src/components/earn/PoolCard.tsx
msgid "Total deposited"
@@ -2059,6 +2073,10 @@ msgstr "الإجمالي المودَع"
msgid "Total deposits"
msgstr "مجموع الودائع"
#: src/components/Tokens/TokenTable/TokenRow.tsx
msgid "Total value locked (TVL) is the amount of the asset thats currently in a Uniswap v3 liquidity pool."
msgstr "إجمالي القيمة المقفلة (TVL) هو مقدار الأصل الموجود حاليًا في تجمع سيولة Uniswap v3."
#: src/components/swap/RouterLabel.tsx
msgid "Trade Route"
msgstr "طريق التجارة"
@@ -2263,10 +2281,18 @@ msgstr "سعر V3 {0}:"
msgid "View accrued fees and analytics<0>↗</0>"
msgstr "عرض الرسوم المتراكمة والتحليلات <0>↗</0>"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
msgid "View and sell NFTs"
msgstr "عرض وبيع NFTs"
#: src/components/SearchModal/ManageLists.tsx
msgid "View list"
msgstr "عرض القائمة"
#: src/components/NavBar/MenuDropdown.tsx
msgid "View more analytics"
msgstr "عرض المزيد من التحليلات"
#: src/components/TransactionConfirmationModal/index.tsx
#: src/pages/CreateProposal/ProposalSubmissionModal.tsx
msgid "View on Etherscan"
@@ -2278,10 +2304,6 @@ msgstr "عرض على Etherscan"
msgid "View on Explorer"
msgstr "عرض على Explorer"
#: src/components/NavBar/MenuDropdown.tsx
msgid "View token analytics"
msgstr "عرض تحليلات الرمز المميز"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
@@ -2291,6 +2313,10 @@ msgstr "عرض تحليلات الرمز المميز"
msgid "View transaction on Explorer"
msgstr "عرض المعاملة على Explorer"
#: src/components/Tokens/TokenTable/TokenRow.tsx
msgid "Volume is the amount of the asset that has been traded on Uniswap v3 during the selected time frame."
msgstr "الحجم هو مقدار الأصل الذي تم تداوله على Uniswap v3 خلال الإطار الزمني المحدد."
#: src/components/Header/index.tsx
msgid "Vote"
msgstr "التصويت"
@@ -2472,10 +2498,6 @@ msgstr "ليس لديك سيولة في هذه المجموعة حتى الآن.
msgid "You have no favorited tokens"
msgstr "ليس لديك رموز مفضلة"
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "You may have lost your network connection, or {label} might be down right now."
msgstr "ربما تكون قد فقدت اتصالك بالشبكة ، أو ربما يكون الرقم {label}"
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "You may have lost your network connection."
msgstr "ربما تكون قد فقدت اتصالك بالشبكة."
@@ -2517,9 +2539,9 @@ msgstr "سيولة V2 الخاصة بك"
msgid "Your active V3 liquidity positions will appear here."
msgstr "ستظهر مراكز سيولة V3 النشطة الخاصة بك هنا."
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "Your balances by network"
msgstr "الأرصدة الخاصة بك عن طريق الشبكة"
#: src/components/Tokens/TokenDetails/BalanceSummary.tsx
msgid "Your balance"
msgstr "رصيدك"
#: src/pages/Pool/index.tsx
msgid "Your connected network is unsupported."
@@ -2608,6 +2630,11 @@ msgstr "المعاملات الخاصة بك ستظهر هنا..."
msgid "Your unclaimed UNI"
msgstr "UNI الخاص بك بدون مطالبة"
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
msgid "Your {0} balance"
msgstr "رصيدك {0}"
#: src/components/swap/AdvancedSwapDetails.tsx
msgid "after slippage"
msgstr "بعد الانزلاق السعري"
@@ -2684,8 +2711,8 @@ msgid "{0, plural, =1 {Import token} other {Import tokens}}"
msgstr "{0, plural, =1 {رمز الاستيراد} other {استيراد الرموز}}"
#: src/constants/tokenSafety.tsx
msgid "{0, plural, =1 {This token isn't verified} other {These tokens aren't verified}}"
msgstr "{0, plural, =1 {لم يتم التحقق من هذا الرمز} other {لم يتم التحقق من هذه الرموز}}"
msgid "{0, plural, =1 {This token isn't verified.} other {These tokens aren't verified.}}"
msgstr "{0, plural, =1 {لم يتم التحقق من هذا الرمز المميز.} other {لم يتم التحقق من هذه الرموز المميزة.}}"
#: src/constants/tokenSafety.tsx
msgid "{0, plural, =1 {You can't trade this token using the Uniswap App.} other {You can't trade these tokens using the Uniswap App.}}"
@@ -2758,10 +2785,6 @@ msgstr "{0} رموز UNI-V2 LP متاحة"
msgid "{0} Votes"
msgstr "{0} أصوات"
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "{0} all balances"
msgstr "{0} جميع الأرصدة"
#: src/components/PositionPreview/index.tsx
#: src/components/PositionPreview/index.tsx
#: src/components/PositionPreview/index.tsx
@@ -2839,6 +2862,10 @@ msgstr "{USER_AMOUNT} UNI"
msgid "{activeTokensOnThisChain} tokens"
msgstr "{activeTokensOnThisChain} توكينز"
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "{label} might be down right now, or you may have lost your network connection."
msgstr "قد يكون الرقم {label} معطلاً الآن ، أو ربما فقدت اتصالك بالشبكة."
#: src/components/NetworkAlert/NetworkAlert.tsx
msgid "{label} token bridge"
msgstr "{label} جسر رمزي"

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: uniswap-interface\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2022-09-21 21:05\n"
"PO-Revision-Date: 2022-10-11 02:57\n"
"Last-Translator: \n"
"Language: ca_ES\n"
"Language-Team: Catalan\n"
@@ -21,10 +21,6 @@ msgstr ""
msgid "$-"
msgstr "$-"
#: src/components/CurrencyInputPanel/FiatValue.tsx
msgid "$<0/>"
msgstr "<0/> $"
#: src/components/earn/PoolCard.tsx
#: src/components/swap/GasEstimateBadge.tsx
#: src/pages/Pool/PositionPage.tsx
@@ -63,6 +59,10 @@ msgstr "0 UNI / setmana"
msgid "24H volume"
msgstr "Volum 24 h"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "24H volume is the amount of the asset that has been traded on Uniswap v3 during the past 24 hours."
msgstr "El volum de 24 hores és la quantitat de l'actiu que s'ha negociat a Uniswap v3 durant les últimes 24 hores."
#: src/pages/RemoveLiquidity/V3.tsx
msgid "25%"
msgstr "25%"
@@ -240,7 +240,7 @@ msgid "Amount"
msgstr "Import"
#: src/components/Tokens/TokenTable/TokenTable.tsx
msgid "An error occured loading tokens. Please try again."
msgid "An error occurred loading tokens. Please try again."
msgstr "S'ha produït un error en carregar fitxes. Siusplau torna-ho a provar."
#: src/utils/swapErrorToUserReadableMessage.tsx
@@ -373,11 +373,14 @@ msgstr "Si afegiu liquiditat, guanyareu el 0,3% de totes les operacions daque
msgid "By adding this list you are implicitly trusting that the data is correct. Anyone can create a list, including creating fake versions of existing lists and lists that claim to represent projects that do not have one."
msgstr "En afegir aquesta llista, confieu implícitament que les dades són correctes. Qualsevol persona pot crear una llista, inclosa la creació de versions falses de llistes existents i llistes que afirmen representar projectes que no en tenen cap."
#: src/components/WalletModal/index.tsx
#: src/components/WalletModal/index.tsx
msgid "By connecting a wallet, you agree to Uniswap Labs <0>Terms of Service</0> and acknowledge that you have read and understand the Uniswap <1>Protocol Disclaimer</1>."
msgstr "En connectar una cartera, acceptes les Condicions del servei <0></0> i reconeixes que has llegit i entén l'exempció <1>responsabilitat del protocol d'</1>."
#: src/components/WalletModal/index.tsx
msgid "By connecting a wallet, you agree to Uniswap Labs <0>Terms of Service</0> and consent to its <1>Privacy Policy</1>."
msgstr "En connectar una cartera, accepteu les <0>Condicions del servei</0> d'Uniswap Labs i accepteu la seva <1>Política de privadesa</1>."
#: src/pages/Vote/styled.tsx
msgid "Canceled"
msgstr "Cancel·lat"
@@ -605,11 +608,13 @@ msgid "Contract address"
msgstr "Adreça del contracte"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
#: src/nft/components/profile/view/ProfileAccountDetails.tsx
#: src/theme/components.tsx
msgid "Copied!"
msgstr "Copiat!"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
#: src/nft/components/profile/view/ProfileAccountDetails.tsx
msgid "Copy"
msgstr "Còpia"
@@ -889,10 +894,6 @@ msgstr "L'execució d'aquesta proposta promulgarà les dades de la convocatòria
msgid "Execution Submitted"
msgstr "Execució presentada"
#: src/components/SearchModal/CurrencyList/index.tsx
msgid "Expanded results from inactive Token Lists"
msgstr "Resultats ampliats de llistes de fitxes inactives"
#: src/components/swap/AdvancedSwapDetails.tsx
msgid "Expected Output"
msgstr "Sortida esperada"
@@ -913,10 +914,9 @@ msgstr "Caducat"
msgid "Explore"
msgstr "Explora"
#: src/pages/Tokens/index.tsx
#: src/pages/Tokens/index.tsx
msgid "Explore Tokens"
msgstr "Exploreu fitxes"
#: src/components/Tokens/TokensBanner.tsx
msgid "Explore Top Tokens on Uniswap"
msgstr "Exploreu les fitxes principals a Uniswap"
#: src/pages/Pool/CTACards.tsx
msgid "Explore Uniswap Analytics."
@@ -1130,6 +1130,10 @@ msgstr "Tema de la llum"
msgid "Light theme"
msgstr "Tema lleuger"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Links"
msgstr "Enllaços"
#: src/components/claim/ClaimModal.tsx
#: src/pages/Pool/PositionPage.tsx
msgid "Liquidity"
@@ -1262,6 +1266,11 @@ msgstr "Min:"
msgid "Minimum received"
msgstr "Mínim rebut"
#: src/components/Tokens/TokenDetails/PriceChart.tsx
#: src/components/Tokens/TokenDetails/PriceChart.tsx
msgid "Missing chart data"
msgstr "Falten dades del gràfic"
#: src/lib/hooks/swap/useSwapCallback.tsx
msgid "Missing dependencies"
msgstr "Falten dependències"
@@ -1270,7 +1279,7 @@ msgstr "Falten dependències"
msgid "More"
msgstr "Més"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "NFT Collections"
msgstr "Col·leccions NFT"
@@ -1298,6 +1307,10 @@ msgstr "Les tarifes de la xarxa superen el 50% de l'import de l'intercanvi!"
msgid "New Position"
msgstr "Nova posició"
#: src/nft/components/profile/view/EmptyWalletContent.tsx
msgid "No NFTs in"
msgstr "No hi ha NFT"
#: src/pages/MigrateV2/index.tsx
msgid "No V2 Liquidity found."
msgstr "No s'ha trobat cap liquiditat V2."
@@ -1339,7 +1352,7 @@ msgstr "No hi ha informació de testimoni disponible"
msgid "No tokens found"
msgstr "No s'han trobat fitxes"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "No tokens found."
msgstr "No s'han trobat fitxes."
@@ -1468,11 +1481,11 @@ msgstr "Agrupat {0}:"
msgid "Pools"
msgstr "Piscines"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Popular NFT collections"
msgstr "Col·leccions populars de NFT"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Popular tokens"
msgstr "Fitxes populars"
@@ -1577,10 +1590,6 @@ msgstr "Fent cua"
msgid "Rates"
msgstr "Tarifes"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Read more"
msgstr "Llegeix més"
#: src/pages/Earn/index.tsx
msgid "Read more about UNI"
msgstr "Llegiu més sobre UNI"
@@ -1601,7 +1610,7 @@ msgstr "Obteniu més informació sobre els recursos no compatibles"
msgid "Recent Transactions"
msgstr "Transaccions recents"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Recent searches"
msgstr "Recerques recents"
@@ -1719,10 +1728,6 @@ msgstr "Auto"
msgid "Self Delegate"
msgstr "Autodelegat"
#: src/components/NavBar/MenuDropdown.tsx
msgid "Sell NFTs"
msgstr "Vendre NFT"
#: src/pages/AddLiquidity/index.tsx
#: src/pages/AddLiquidity/index.tsx
#: src/pages/MigrateV2/MigrateV2Pair.tsx
@@ -1755,6 +1760,10 @@ msgstr "Mostra cancel·lada"
msgid "Show closed positions"
msgstr "Mostra posicions tancades"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Show more"
msgstr "Mostra més"
#: src/pages/RemoveLiquidity/index.tsx
msgid "Simple"
msgstr "Senzill"
@@ -1771,6 +1780,14 @@ msgstr "Alguns recursos no estan disponibles a través daquesta interfície p
msgid "Something went wrong"
msgstr "Alguna cosa ha anat malament"
#: src/components/Tokens/TokensBanner.tsx
msgid "Sort and filter assets across networks on the new Tokens page."
msgstr "Ordena i filtra els actius a través de les xarxes a la nova pàgina de fitxes."
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "Stats"
msgstr "Estadístiques"
#: src/pages/Earn/Manage.tsx
msgid "Step 1. Get UNI-V2 Liquidity tokens"
msgstr "Pas 1. Obteniu fitxes de liquiditat UNI-V2"
@@ -1806,7 +1823,7 @@ msgstr "Subministrant {0} {1} i {2} {3}"
#: src/components/AccountDetailsV2/TransactionBody.tsx
#: src/components/Header/index.tsx
#: src/components/NavBar/index.tsx
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
#: src/components/swap/SwapHeader.tsx
#: src/pages/Swap/index.tsx
#: src/pages/Swap/index.tsx
@@ -1848,6 +1865,10 @@ msgstr "Intercanvi de {0} {1} per {2} {3}"
msgid "Symbol not found"
msgstr "No s'ha trobat el símbol"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "TVL"
msgstr "TVL"
#: src/components/Popups/SurveyPopup.tsx
msgid "Take a 10 minute survey to help us improve your experience in the Uniswap app."
msgstr "Fes una enquesta de 10 minuts per ajudar-nos a millorar la teva experiència a l'aplicació Uniswap."
@@ -1962,14 +1983,6 @@ msgstr "No s'ha pogut enviar la transacció perquè s'ha acabat el termini. Comp
msgid "There is no liquidity data."
msgstr "No hi ha dades de liquiditat."
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "There was an error fetching your balance"
msgstr "S'ha produït un error en recuperar el vostre saldo"
#: src/components/Tokens/TokenDetails/BalanceSummary.tsx
msgid "There was an error loading your {0} balance"
msgstr "S'ha produït un error en carregar el vostre saldo {0}"
#: src/components/ConnectedAccountBlocked/index.tsx
msgid "This address is blocked on the Uniswap Labs interface because it is associated with one or more"
msgstr "Aquesta adreça està bloquejada a la interfície d'Uniswap Labs perquè està associada amb una o més"
@@ -1994,6 +2007,10 @@ msgstr "Aquesta ruta optimitza la producció total tenint en compte les rutes di
msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade."
msgstr "Aquest testimoni no apareix a la llista de fitxes actives. Assegureu-vos que aquest sigui el testimoni que voleu canviar."
#: src/components/Tokens/TokenDetails/PriceChart.tsx
msgid "This token doesn't have chart data because it hasn't been traded on Uniswap v3"
msgstr "Aquest testimoni no té dades de gràfics perquè no s'ha negociat a Uniswap v3"
#: src/components/SearchModal/BlockedToken.tsx
msgid "This token is not supported in the Uniswap Labs app"
msgstr "Aquest testimoni no és compatible amb l'aplicació Uniswap Labs"
@@ -2033,23 +2050,20 @@ msgid "Token not supported"
msgstr "El testimoni no és compatible"
#: src/components/Header/index.tsx
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
#: src/components/NavBar/index.tsx
#: src/components/SearchModal/Manage.tsx
msgid "Tokens"
msgstr "Fitxes"
#: src/components/SearchModal/CurrencyList/index.tsx
msgid "Tokens from inactive lists. Import specific tokens below or click Manage to activate more lists."
msgstr "Fitxes de llistes inactives. Importeu fitxes específiques a continuació o feu clic a Gestiona per activar més llistes."
#: src/pages/Pool/CTACards.tsx
msgid "Top pools"
msgstr "Grups principals"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "Total Value Locked"
msgstr "Valor total bloquejat"
#: src/pages/Tokens/index.tsx
#: src/pages/Tokens/index.tsx
msgid "Top tokens on Uniswap"
msgstr "Les fitxes principals d'Uniswap"
#: src/components/earn/PoolCard.tsx
msgid "Total deposited"
@@ -2059,6 +2073,10 @@ msgstr "Total dipositat"
msgid "Total deposits"
msgstr "Dipòsits totals"
#: src/components/Tokens/TokenTable/TokenRow.tsx
msgid "Total value locked (TVL) is the amount of the asset thats currently in a Uniswap v3 liquidity pool."
msgstr "El valor total bloquejat (TVL) és la quantitat de l'actiu que es troba actualment en un conjunt de liquiditat Uniswap v3."
#: src/components/swap/RouterLabel.tsx
msgid "Trade Route"
msgstr "Ruta del comerç"
@@ -2263,10 +2281,18 @@ msgstr "V3 {0} Preu:"
msgid "View accrued fees and analytics<0>↗</0>"
msgstr "Consulteu els honoraris i les taxes acumulades <0> ↗</0>"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
msgid "View and sell NFTs"
msgstr "Veure i vendre NFT"
#: src/components/SearchModal/ManageLists.tsx
msgid "View list"
msgstr "Veure llista"
#: src/components/NavBar/MenuDropdown.tsx
msgid "View more analytics"
msgstr "Veure més analítiques"
#: src/components/TransactionConfirmationModal/index.tsx
#: src/pages/CreateProposal/ProposalSubmissionModal.tsx
msgid "View on Etherscan"
@@ -2278,10 +2304,6 @@ msgstr "Veure a Etherscan"
msgid "View on Explorer"
msgstr "Veure a Explorer"
#: src/components/NavBar/MenuDropdown.tsx
msgid "View token analytics"
msgstr "Veure l'anàlisi de testimonis"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
@@ -2291,6 +2313,10 @@ msgstr "Veure l'anàlisi de testimonis"
msgid "View transaction on Explorer"
msgstr "Veure la transacció a Explorer"
#: src/components/Tokens/TokenTable/TokenRow.tsx
msgid "Volume is the amount of the asset that has been traded on Uniswap v3 during the selected time frame."
msgstr "El volum és la quantitat de l'actiu que s'ha negociat a Uniswap v3 durant el període de temps seleccionat."
#: src/components/Header/index.tsx
msgid "Vote"
msgstr "Vota"
@@ -2472,10 +2498,6 @@ msgstr "Encara no teniu liquiditat en aquest grup."
msgid "You have no favorited tokens"
msgstr "No tens fitxes preferides"
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "You may have lost your network connection, or {label} might be down right now."
msgstr "És possible que hàgiu perdut la connexió de xarxa o que {label} estigui inactiu en aquest moment."
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "You may have lost your network connection."
msgstr "És possible que hàgiu perdut la connexió de xarxa."
@@ -2517,9 +2539,9 @@ msgstr "La vostra liquiditat V2"
msgid "Your active V3 liquidity positions will appear here."
msgstr "Les vostres posicions de liquiditat V3 actives apareixeran aquí."
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "Your balances by network"
msgstr "Els teus saldos per xarxa"
#: src/components/Tokens/TokenDetails/BalanceSummary.tsx
msgid "Your balance"
msgstr "El teu saldo"
#: src/pages/Pool/index.tsx
msgid "Your connected network is unsupported."
@@ -2608,6 +2630,11 @@ msgstr "Les vostres transaccions apareixeran aquí..."
msgid "Your unclaimed UNI"
msgstr "La vostra UNI no reclamada"
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
msgid "Your {0} balance"
msgstr "El teu saldo {0}"
#: src/components/swap/AdvancedSwapDetails.tsx
msgid "after slippage"
msgstr "després del lliscament"
@@ -2684,8 +2711,8 @@ msgid "{0, plural, =1 {Import token} other {Import tokens}}"
msgstr "{0, plural, =1 {Fitxa d'importació} other {Importa fitxes}}"
#: src/constants/tokenSafety.tsx
msgid "{0, plural, =1 {This token isn't verified} other {These tokens aren't verified}}"
msgstr "{0, plural, =1 {Aquest testimoni no està verificat} other {Aquestes fitxes no estan verificades}}"
msgid "{0, plural, =1 {This token isn't verified.} other {These tokens aren't verified.}}"
msgstr "{0, plural, =1 {Aquest testimoni no està verificat.} other {Aquestes fitxes no estan verificades.}}"
#: src/constants/tokenSafety.tsx
msgid "{0, plural, =1 {You can't trade this token using the Uniswap App.} other {You can't trade these tokens using the Uniswap App.}}"
@@ -2758,10 +2785,6 @@ msgstr "{0} fitxes UNI-V2 LP disponibles"
msgid "{0} Votes"
msgstr "{0} vVots"
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "{0} all balances"
msgstr "{0} tots els saldos"
#: src/components/PositionPreview/index.tsx
#: src/components/PositionPreview/index.tsx
#: src/components/PositionPreview/index.tsx
@@ -2839,6 +2862,10 @@ msgstr "{USER_AMOUNT} UNI"
msgid "{activeTokensOnThisChain} tokens"
msgstr "{activeTokensOnThisChain} fitxes"
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "{label} might be down right now, or you may have lost your network connection."
msgstr "És possible que {label} estigui inactiva en aquest moment o que hagis perdut la connexió a la xarxa."
#: src/components/NetworkAlert/NetworkAlert.tsx
msgid "{label} token bridge"
msgstr "{label} pont de fitxes"

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: uniswap-interface\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2022-09-21 21:05\n"
"PO-Revision-Date: 2022-10-11 02:57\n"
"Last-Translator: \n"
"Language: cs_CZ\n"
"Language-Team: Czech\n"
@@ -21,10 +21,6 @@ msgstr ""
msgid "$-"
msgstr "$-"
#: src/components/CurrencyInputPanel/FiatValue.tsx
msgid "$<0/>"
msgstr "<0/>$"
#: src/components/earn/PoolCard.tsx
#: src/components/swap/GasEstimateBadge.tsx
#: src/pages/Pool/PositionPage.tsx
@@ -63,6 +59,10 @@ msgstr "0 UNI / týden"
msgid "24H volume"
msgstr "Hlasitost 24h"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "24H volume is the amount of the asset that has been traded on Uniswap v3 during the past 24 hours."
msgstr "Objem za 24 hodin je množství aktiv, které bylo zobchodováno na Uniswap v3 během posledních 24 hodin."
#: src/pages/RemoveLiquidity/V3.tsx
msgid "25%"
msgstr "25 %"
@@ -240,7 +240,7 @@ msgid "Amount"
msgstr "Částka"
#: src/components/Tokens/TokenTable/TokenTable.tsx
msgid "An error occured loading tokens. Please try again."
msgid "An error occurred loading tokens. Please try again."
msgstr "Při načítání tokenů došlo k chybě. Prosím zkuste to znovu."
#: src/utils/swapErrorToUserReadableMessage.tsx
@@ -373,11 +373,14 @@ msgstr "Přidáním likvidity získáte 0,3 % všech obchodů na tomto páru úm
msgid "By adding this list you are implicitly trusting that the data is correct. Anyone can create a list, including creating fake versions of existing lists and lists that claim to represent projects that do not have one."
msgstr "Přidáním tohoto seznamu implicitně vyjadřujete důvěru v to, že data jsou správná. Seznam může vytvořit kdokoli, včetně vytváření falešných verzí existujících seznamů a seznamů, které prohlašují, že reprezentují projekty, které žádný seznam nemají."
#: src/components/WalletModal/index.tsx
#: src/components/WalletModal/index.tsx
msgid "By connecting a wallet, you agree to Uniswap Labs <0>Terms of Service</0> and acknowledge that you have read and understand the Uniswap <1>Protocol Disclaimer</1>."
msgstr "Připojením peněženky souhlasíte s <0>podmínkami služby</0> a potvrzujete, že jste si přečetli a rozumíte prohlášení o vyloučení odpovědnosti za protokol <1></1>."
#: src/components/WalletModal/index.tsx
msgid "By connecting a wallet, you agree to Uniswap Labs <0>Terms of Service</0> and consent to its <1>Privacy Policy</1>."
msgstr "Připojením peněženky souhlasíte s <0>Smluvními podmínkami</0> společnosti Uniswap Labs a souhlasíte s jejími <1>Zásadami ochrany osobních údajů</1>."
#: src/pages/Vote/styled.tsx
msgid "Canceled"
msgstr "Zrušeno"
@@ -605,11 +608,13 @@ msgid "Contract address"
msgstr "Adresa smlouvy"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
#: src/nft/components/profile/view/ProfileAccountDetails.tsx
#: src/theme/components.tsx
msgid "Copied!"
msgstr "Zkopírováno!"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
#: src/nft/components/profile/view/ProfileAccountDetails.tsx
msgid "Copy"
msgstr "kopírovat"
@@ -889,10 +894,6 @@ msgstr "Provedení tohoto návrhu uzákoní data volání v řetězci."
msgid "Execution Submitted"
msgstr "Provedení předloženo"
#: src/components/SearchModal/CurrencyList/index.tsx
msgid "Expanded results from inactive Token Lists"
msgstr "Rozšířené výsledky z neaktivních seznamů žetonů"
#: src/components/swap/AdvancedSwapDetails.tsx
msgid "Expected Output"
msgstr "Očekávaný výstup"
@@ -913,10 +914,9 @@ msgstr "Vypršela"
msgid "Explore"
msgstr "Prozkoumat"
#: src/pages/Tokens/index.tsx
#: src/pages/Tokens/index.tsx
msgid "Explore Tokens"
msgstr "Prozkoumejte tokeny"
#: src/components/Tokens/TokensBanner.tsx
msgid "Explore Top Tokens on Uniswap"
msgstr "Prozkoumejte nejlepší tokeny na Uniswapu"
#: src/pages/Pool/CTACards.tsx
msgid "Explore Uniswap Analytics."
@@ -1130,6 +1130,10 @@ msgstr "Lehké téma"
msgid "Light theme"
msgstr "Světlé téma"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Links"
msgstr "Odkazy"
#: src/components/claim/ClaimModal.tsx
#: src/pages/Pool/PositionPage.tsx
msgid "Liquidity"
@@ -1262,6 +1266,11 @@ msgstr "Minimum:"
msgid "Minimum received"
msgstr "Minimum přijato"
#: src/components/Tokens/TokenDetails/PriceChart.tsx
#: src/components/Tokens/TokenDetails/PriceChart.tsx
msgid "Missing chart data"
msgstr "Chybí data grafu"
#: src/lib/hooks/swap/useSwapCallback.tsx
msgid "Missing dependencies"
msgstr "Chybějící závislosti"
@@ -1270,7 +1279,7 @@ msgstr "Chybějící závislosti"
msgid "More"
msgstr "Více"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "NFT Collections"
msgstr "Sbírky NFT"
@@ -1298,6 +1307,10 @@ msgstr "Síťové poplatky přesahují 50 % swapové částky!"
msgid "New Position"
msgstr "Nová pozice"
#: src/nft/components/profile/view/EmptyWalletContent.tsx
msgid "No NFTs in"
msgstr "Žádné NFT"
#: src/pages/MigrateV2/index.tsx
msgid "No V2 Liquidity found."
msgstr "Nebyla nalezena likvidita V2."
@@ -1339,7 +1352,7 @@ msgstr "Nejsou k dispozici žádné informace o tokenu"
msgid "No tokens found"
msgstr "Nebyly nalezeny žádné tokeny"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "No tokens found."
msgstr "Nebyly nalezeny žádné tokeny."
@@ -1468,11 +1481,11 @@ msgstr "Sestaveno do fondu {0}:"
msgid "Pools"
msgstr "Bazény"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Popular NFT collections"
msgstr "Populární kolekce NFT"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Popular tokens"
msgstr "Populární tokeny"
@@ -1577,10 +1590,6 @@ msgstr "Zařazení do fronty"
msgid "Rates"
msgstr "Sazby"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Read more"
msgstr "Přečtěte si více"
#: src/pages/Earn/index.tsx
msgid "Read more about UNI"
msgstr "Přečtěte si více o UNI"
@@ -1601,7 +1610,7 @@ msgstr "Přečtěte si více o nepodporovaných aktivech"
msgid "Recent Transactions"
msgstr "Nedávné transakce"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Recent searches"
msgstr "Nedávná vyhledávání"
@@ -1719,10 +1728,6 @@ msgstr "Sám"
msgid "Self Delegate"
msgstr "Sobě delegovat"
#: src/components/NavBar/MenuDropdown.tsx
msgid "Sell NFTs"
msgstr "Prodám NFT"
#: src/pages/AddLiquidity/index.tsx
#: src/pages/AddLiquidity/index.tsx
#: src/pages/MigrateV2/MigrateV2Pair.tsx
@@ -1755,6 +1760,10 @@ msgstr "Zobrazit zrušeno"
msgid "Show closed positions"
msgstr "Zobrazit uzavřené pozice"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Show more"
msgstr "Zobrazit více"
#: src/pages/RemoveLiquidity/index.tsx
msgid "Simple"
msgstr "Jednoduché"
@@ -1771,6 +1780,14 @@ msgstr "Některá aktiva nejsou přes toto rozhraní dostupná, protože nemusí
msgid "Something went wrong"
msgstr "Něco je špatně"
#: src/components/Tokens/TokensBanner.tsx
msgid "Sort and filter assets across networks on the new Tokens page."
msgstr "Seřaďte a filtrujte aktiva napříč sítěmi na nové stránce Tokeny."
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "Stats"
msgstr "Statistiky"
#: src/pages/Earn/Manage.tsx
msgid "Step 1. Get UNI-V2 Liquidity tokens"
msgstr "Krok 1. Získejte žetony likvidity UNI-V2"
@@ -1806,7 +1823,7 @@ msgstr "Dodávání {0} {1} a {2} {3}"
#: src/components/AccountDetailsV2/TransactionBody.tsx
#: src/components/Header/index.tsx
#: src/components/NavBar/index.tsx
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
#: src/components/swap/SwapHeader.tsx
#: src/pages/Swap/index.tsx
#: src/pages/Swap/index.tsx
@@ -1848,6 +1865,10 @@ msgstr "Výměna {0} {1} za {2} {3}"
msgid "Symbol not found"
msgstr "Symbol nenalezen"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "TVL"
msgstr "TVL"
#: src/components/Popups/SurveyPopup.tsx
msgid "Take a 10 minute survey to help us improve your experience in the Uniswap app."
msgstr "Udělejte si 10minutový průzkum, který nám pomůže zlepšit vaši zkušenost s aplikací Uniswap."
@@ -1962,14 +1983,6 @@ msgstr "Transakci nebylo možno odeslat, protože uplynula lhůta. Zkontrolujte,
msgid "There is no liquidity data."
msgstr "Neexistují žádné údaje o likviditě."
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "There was an error fetching your balance"
msgstr "Při načítání vašeho zůstatku došlo k chybě"
#: src/components/Tokens/TokenDetails/BalanceSummary.tsx
msgid "There was an error loading your {0} balance"
msgstr "Při načítání vašeho zůstatku {0} došlo k chybě"
#: src/components/ConnectedAccountBlocked/index.tsx
msgid "This address is blocked on the Uniswap Labs interface because it is associated with one or more"
msgstr "Tato adresa je v rozhraní Uniswap Labs blokována, protože je přidružena k jedné nebo více"
@@ -1994,6 +2007,10 @@ msgstr "Tato trasa optimalizuje váš celkový výkon zohledněním rozdělenýc
msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade."
msgstr "Tento žeton není na seznamech aktivních žetonů. Ujistěte se, že toto je ten žeton, který chcete obchodovat."
#: src/components/Tokens/TokenDetails/PriceChart.tsx
msgid "This token doesn't have chart data because it hasn't been traded on Uniswap v3"
msgstr "Tento token nemá data grafu, protože nebyl obchodován na Uniswap v3"
#: src/components/SearchModal/BlockedToken.tsx
msgid "This token is not supported in the Uniswap Labs app"
msgstr "Tento token není podporován v aplikaci Uniswap Labs"
@@ -2033,23 +2050,20 @@ msgid "Token not supported"
msgstr "Token není podporován"
#: src/components/Header/index.tsx
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
#: src/components/NavBar/index.tsx
#: src/components/SearchModal/Manage.tsx
msgid "Tokens"
msgstr "Žetony"
#: src/components/SearchModal/CurrencyList/index.tsx
msgid "Tokens from inactive lists. Import specific tokens below or click Manage to activate more lists."
msgstr "Žetony z neaktivních seznamů. Buď importujte konkrétní žetony níže nebo kliknutím na Správa aktivujte další seznamy."
#: src/pages/Pool/CTACards.tsx
msgid "Top pools"
msgstr "Nejvýše umístěné fondy"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "Total Value Locked"
msgstr "Celková hodnota uzamčena"
#: src/pages/Tokens/index.tsx
#: src/pages/Tokens/index.tsx
msgid "Top tokens on Uniswap"
msgstr "Nejlepší tokeny na Uniswapu"
#: src/components/earn/PoolCard.tsx
msgid "Total deposited"
@@ -2059,6 +2073,10 @@ msgstr "Celkem uloženo"
msgid "Total deposits"
msgstr "Vklady celkem"
#: src/components/Tokens/TokenTable/TokenRow.tsx
msgid "Total value locked (TVL) is the amount of the asset thats currently in a Uniswap v3 liquidity pool."
msgstr "Uzamčená celková hodnota (TVL) je množství aktiva, které je aktuálně v fondu likvidity Uniswap v3."
#: src/components/swap/RouterLabel.tsx
msgid "Trade Route"
msgstr "Obchodní cesta"
@@ -2263,10 +2281,18 @@ msgstr "V3 {0} cena:"
msgid "View accrued fees and analytics<0>↗</0>"
msgstr "Zobrazit naběhlé poplatky a analýzy<0>↗</0>"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
msgid "View and sell NFTs"
msgstr "Prohlížejte a prodávejte NFT"
#: src/components/SearchModal/ManageLists.tsx
msgid "View list"
msgstr "Zobrazit seznam"
#: src/components/NavBar/MenuDropdown.tsx
msgid "View more analytics"
msgstr "Zobrazit další analýzy"
#: src/components/TransactionConfirmationModal/index.tsx
#: src/pages/CreateProposal/ProposalSubmissionModal.tsx
msgid "View on Etherscan"
@@ -2278,10 +2304,6 @@ msgstr "Pohled na Etherscan"
msgid "View on Explorer"
msgstr "Zobrazit v Průzkumníku"
#: src/components/NavBar/MenuDropdown.tsx
msgid "View token analytics"
msgstr "Zobrazit analýzu tokenů"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
@@ -2291,6 +2313,10 @@ msgstr "Zobrazit analýzu tokenů"
msgid "View transaction on Explorer"
msgstr "Zobrazit transakci v Průzkumníku"
#: src/components/Tokens/TokenTable/TokenRow.tsx
msgid "Volume is the amount of the asset that has been traded on Uniswap v3 during the selected time frame."
msgstr "Objem je množství aktiva, které bylo obchodováno na Uniswap v3 během zvoleného časového rámce."
#: src/components/Header/index.tsx
msgid "Vote"
msgstr "Hlasovat"
@@ -2472,10 +2498,6 @@ msgstr "V tomto fondu zatím nemáte likviditu."
msgid "You have no favorited tokens"
msgstr "Nemáte žádné oblíbené žetony"
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "You may have lost your network connection, or {label} might be down right now."
msgstr "Možná jste ztratili připojení k síti nebo {label} může být právě mimo provoz."
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "You may have lost your network connection."
msgstr "Možná jste ztratili připojení k síti."
@@ -2517,9 +2539,9 @@ msgstr "Vaše likvidita V2"
msgid "Your active V3 liquidity positions will appear here."
msgstr "Zde se zobrazí vaše aktivní pozice likvidity V3."
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "Your balances by network"
msgstr "Vaše zůstatky podle sítě"
#: src/components/Tokens/TokenDetails/BalanceSummary.tsx
msgid "Your balance"
msgstr "Tvůj zůstatek"
#: src/pages/Pool/index.tsx
msgid "Your connected network is unsupported."
@@ -2608,6 +2630,11 @@ msgstr "Tady se budou zobrazovat vaše transakce..."
msgid "Your unclaimed UNI"
msgstr "Vaše nenárokované UNI"
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
msgid "Your {0} balance"
msgstr "Váš zůstatek {0}"
#: src/components/swap/AdvancedSwapDetails.tsx
msgid "after slippage"
msgstr "po uklouznutí"
@@ -2684,7 +2711,7 @@ msgid "{0, plural, =1 {Import token} other {Import tokens}}"
msgstr ""
#: src/constants/tokenSafety.tsx
msgid "{0, plural, =1 {This token isn't verified} other {These tokens aren't verified}}"
msgid "{0, plural, =1 {This token isn't verified.} other {These tokens aren't verified.}}"
msgstr ""
#: src/constants/tokenSafety.tsx
@@ -2758,10 +2785,6 @@ msgstr "{0} dostupných žetonů UNI-V2 LP"
msgid "{0} Votes"
msgstr "{0} hlasů"
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "{0} all balances"
msgstr "{0} všechny zůstatky"
#: src/components/PositionPreview/index.tsx
#: src/components/PositionPreview/index.tsx
#: src/components/PositionPreview/index.tsx
@@ -2839,6 +2862,10 @@ msgstr "{USER_AMOUNT} UNI"
msgid "{activeTokensOnThisChain} tokens"
msgstr "{activeTokensOnThisChain} žetonů"
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "{label} might be down right now, or you may have lost your network connection."
msgstr "{label} může být právě teď mimo provoz, nebo jste možná ztratili připojení k síti."
#: src/components/NetworkAlert/NetworkAlert.tsx
msgid "{label} token bridge"
msgstr "{label} token bridge"

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: uniswap-interface\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2022-09-21 21:05\n"
"PO-Revision-Date: 2022-10-11 02:57\n"
"Last-Translator: \n"
"Language: da_DK\n"
"Language-Team: Danish\n"
@@ -21,10 +21,6 @@ msgstr ""
msgid "$-"
msgstr "$-"
#: src/components/CurrencyInputPanel/FiatValue.tsx
msgid "$<0/>"
msgstr "$<0/>"
#: src/components/earn/PoolCard.tsx
#: src/components/swap/GasEstimateBadge.tsx
#: src/pages/Pool/PositionPage.tsx
@@ -63,6 +59,10 @@ msgstr "0 UNI / uge"
msgid "24H volume"
msgstr "24H volumen"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "24H volume is the amount of the asset that has been traded on Uniswap v3 during the past 24 hours."
msgstr "24H volumen er mængden af aktivet, der er blevet handlet på Uniswap v3 i løbet af de seneste 24 timer."
#: src/pages/RemoveLiquidity/V3.tsx
msgid "25%"
msgstr "25%"
@@ -240,7 +240,7 @@ msgid "Amount"
msgstr "Beløb"
#: src/components/Tokens/TokenTable/TokenTable.tsx
msgid "An error occured loading tokens. Please try again."
msgid "An error occurred loading tokens. Please try again."
msgstr "Der opstod en fejl under indlæsning af tokens. Prøv igen."
#: src/utils/swapErrorToUserReadableMessage.tsx
@@ -373,11 +373,14 @@ msgstr "Ved at tilføje likviditet optjener du 0,3 % af alle handler på dette p
msgid "By adding this list you are implicitly trusting that the data is correct. Anyone can create a list, including creating fake versions of existing lists and lists that claim to represent projects that do not have one."
msgstr "Ved at tilføje denne liste har du implicit tillid til, at dataene er korrekte. Alle kan oprette en liste, herunder skabe falske versioner af eksisterende lister og lister, der hævder at repræsentere projekter, der ikke har en."
#: src/components/WalletModal/index.tsx
#: src/components/WalletModal/index.tsx
msgid "By connecting a wallet, you agree to Uniswap Labs <0>Terms of Service</0> and acknowledge that you have read and understand the Uniswap <1>Protocol Disclaimer</1>."
msgstr "Ved at tilslutte en tegnebog accepterer du Uniswap Labs' <0>Servicevilkår</0> og anerkender, at du har læst og forstået Uniswap <1>Protocol Disclaimer</1>."
#: src/components/WalletModal/index.tsx
msgid "By connecting a wallet, you agree to Uniswap Labs <0>Terms of Service</0> and consent to its <1>Privacy Policy</1>."
msgstr "Ved at tilslutte en tegnebog accepterer du Uniswap Labs' <0>Servicevilkår</0> og samtykker til dens <1>Privatlivspolitik</1>."
#: src/pages/Vote/styled.tsx
msgid "Canceled"
msgstr "Annulleret"
@@ -605,11 +608,13 @@ msgid "Contract address"
msgstr "Kontrakt adresse"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
#: src/nft/components/profile/view/ProfileAccountDetails.tsx
#: src/theme/components.tsx
msgid "Copied!"
msgstr "Kopieret!"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
#: src/nft/components/profile/view/ProfileAccountDetails.tsx
msgid "Copy"
msgstr "Kopi"
@@ -889,10 +894,6 @@ msgstr "Eksekvering af dette forslag vil indføre opkaldsdata på kæden."
msgid "Execution Submitted"
msgstr "Udførelse indsendt"
#: src/components/SearchModal/CurrencyList/index.tsx
msgid "Expanded results from inactive Token Lists"
msgstr "Ekspanderede resultater fra inaktive token-lister"
#: src/components/swap/AdvancedSwapDetails.tsx
msgid "Expected Output"
msgstr "Forventet output"
@@ -913,10 +914,9 @@ msgstr "Udløbet"
msgid "Explore"
msgstr "Udforske"
#: src/pages/Tokens/index.tsx
#: src/pages/Tokens/index.tsx
msgid "Explore Tokens"
msgstr "Udforsk Tokens"
#: src/components/Tokens/TokensBanner.tsx
msgid "Explore Top Tokens on Uniswap"
msgstr "Udforsk Top Tokens på Uniswap"
#: src/pages/Pool/CTACards.tsx
msgid "Explore Uniswap Analytics."
@@ -1130,6 +1130,10 @@ msgstr "Let tema"
msgid "Light theme"
msgstr "Lys tema"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Links"
msgstr "Links"
#: src/components/claim/ClaimModal.tsx
#: src/pages/Pool/PositionPage.tsx
msgid "Liquidity"
@@ -1262,6 +1266,11 @@ msgstr "Min:"
msgid "Minimum received"
msgstr "Minimum modtaget"
#: src/components/Tokens/TokenDetails/PriceChart.tsx
#: src/components/Tokens/TokenDetails/PriceChart.tsx
msgid "Missing chart data"
msgstr "Manglende diagramdata"
#: src/lib/hooks/swap/useSwapCallback.tsx
msgid "Missing dependencies"
msgstr "Manglende afhængigheder"
@@ -1270,7 +1279,7 @@ msgstr "Manglende afhængigheder"
msgid "More"
msgstr "Mere"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "NFT Collections"
msgstr "NFT samlinger"
@@ -1298,6 +1307,10 @@ msgstr "Netværksgebyrer overstiger 50 % af byttebeløbet!"
msgid "New Position"
msgstr "Ny position"
#: src/nft/components/profile/view/EmptyWalletContent.tsx
msgid "No NFTs in"
msgstr "Ingen NFT'er i"
#: src/pages/MigrateV2/index.tsx
msgid "No V2 Liquidity found."
msgstr "Ingen V2-likviditet fundet."
@@ -1339,7 +1352,7 @@ msgstr "Ingen token-information tilgængelig"
msgid "No tokens found"
msgstr "Ingen tokens fundet"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "No tokens found."
msgstr "Ingen tokens fundet."
@@ -1468,11 +1481,11 @@ msgstr "Pulje {0}:"
msgid "Pools"
msgstr "Pools"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Popular NFT collections"
msgstr "Populære NFT-samlinger"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Popular tokens"
msgstr "Populære tokens"
@@ -1577,10 +1590,6 @@ msgstr "Stå i kø"
msgid "Rates"
msgstr "Satser"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Read more"
msgstr "Læs mere"
#: src/pages/Earn/index.tsx
msgid "Read more about UNI"
msgstr "Læs mere om UNI"
@@ -1601,7 +1610,7 @@ msgstr "Læs mere om ikke-understøttede aktiver"
msgid "Recent Transactions"
msgstr "Seneste transaktioner"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Recent searches"
msgstr "Seneste søgninger"
@@ -1719,10 +1728,6 @@ msgstr "Selv"
msgid "Self Delegate"
msgstr "Selvuddelegering"
#: src/components/NavBar/MenuDropdown.tsx
msgid "Sell NFTs"
msgstr "Sælg NFT'er"
#: src/pages/AddLiquidity/index.tsx
#: src/pages/AddLiquidity/index.tsx
#: src/pages/MigrateV2/MigrateV2Pair.tsx
@@ -1755,6 +1760,10 @@ msgstr "Show annulleret"
msgid "Show closed positions"
msgstr "Vis lukkede positioner"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Show more"
msgstr "Vis mere"
#: src/pages/RemoveLiquidity/index.tsx
msgid "Simple"
msgstr "Simpel"
@@ -1771,6 +1780,14 @@ msgstr "Nogle aktiver er ikke tilgængelige via denne grænseflade, fordi de må
msgid "Something went wrong"
msgstr "Noget gik galt"
#: src/components/Tokens/TokensBanner.tsx
msgid "Sort and filter assets across networks on the new Tokens page."
msgstr "Sorter og filtrer aktiver på tværs af netværk på den nye Tokens-side."
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "Stats"
msgstr "Statistik"
#: src/pages/Earn/Manage.tsx
msgid "Step 1. Get UNI-V2 Liquidity tokens"
msgstr "Trin 1. Få UNI-V2 Likviditetstokens"
@@ -1806,7 +1823,7 @@ msgstr "Forsyning {0} {1} og {2} {3}"
#: src/components/AccountDetailsV2/TransactionBody.tsx
#: src/components/Header/index.tsx
#: src/components/NavBar/index.tsx
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
#: src/components/swap/SwapHeader.tsx
#: src/pages/Swap/index.tsx
#: src/pages/Swap/index.tsx
@@ -1848,6 +1865,10 @@ msgstr "Byt {0} {1} til {2} {3}"
msgid "Symbol not found"
msgstr "Symbol ikke fundet"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "TVL"
msgstr "TVL"
#: src/components/Popups/SurveyPopup.tsx
msgid "Take a 10 minute survey to help us improve your experience in the Uniswap app."
msgstr "Tag en 10 minutters undersøgelse for at hjælpe os med at forbedre din oplevelse i Uniswap-appen."
@@ -1962,14 +1983,6 @@ msgstr "Transaktionen kunne ikke sendes, fordi fristen er udløbet. Kontroller,
msgid "There is no liquidity data."
msgstr "Der er ingen likviditetsdata."
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "There was an error fetching your balance"
msgstr "Der opstod en fejl under hentning af din saldo"
#: src/components/Tokens/TokenDetails/BalanceSummary.tsx
msgid "There was an error loading your {0} balance"
msgstr "Der opstod en fejl under indlæsning af din {0} -saldo"
#: src/components/ConnectedAccountBlocked/index.tsx
msgid "This address is blocked on the Uniswap Labs interface because it is associated with one or more"
msgstr "Denne adresse er blokeret på Uniswap Labs-grænsefladen, fordi den er knyttet til en eller flere"
@@ -1994,6 +2007,10 @@ msgstr "Denne rute optimerer dit samlede output ved at overveje opdelte ruter, f
msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade."
msgstr "Dette token vises ikke på den/de aktive tokenlister. Sørg for, at dette er det token, du vil handle."
#: src/components/Tokens/TokenDetails/PriceChart.tsx
msgid "This token doesn't have chart data because it hasn't been traded on Uniswap v3"
msgstr "Dette token har ikke diagramdata, fordi det ikke er blevet handlet på Uniswap v3"
#: src/components/SearchModal/BlockedToken.tsx
msgid "This token is not supported in the Uniswap Labs app"
msgstr "Dette token understøttes ikke i Uniswap Labs-appen"
@@ -2033,23 +2050,20 @@ msgid "Token not supported"
msgstr "Token understøttes ikke"
#: src/components/Header/index.tsx
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
#: src/components/NavBar/index.tsx
#: src/components/SearchModal/Manage.tsx
msgid "Tokens"
msgstr "Tokens"
#: src/components/SearchModal/CurrencyList/index.tsx
msgid "Tokens from inactive lists. Import specific tokens below or click Manage to activate more lists."
msgstr "Tokens fra inaktive lister. Importer specifikke tokens nedenfor, eller klik på Administrer for at aktivere flere lister."
#: src/pages/Pool/CTACards.tsx
msgid "Top pools"
msgstr "Toppuljer"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "Total Value Locked"
msgstr "Samlet værdi låst"
#: src/pages/Tokens/index.tsx
#: src/pages/Tokens/index.tsx
msgid "Top tokens on Uniswap"
msgstr "Top tokens på Uniswap"
#: src/components/earn/PoolCard.tsx
msgid "Total deposited"
@@ -2059,6 +2073,10 @@ msgstr "I alt deponeret"
msgid "Total deposits"
msgstr "Indlån i alt"
#: src/components/Tokens/TokenTable/TokenRow.tsx
msgid "Total value locked (TVL) is the amount of the asset thats currently in a Uniswap v3 liquidity pool."
msgstr "Total værdi låst (TVL) er mængden af aktivet, der i øjeblikket er i en Uniswap v3-likviditetspulje."
#: src/components/swap/RouterLabel.tsx
msgid "Trade Route"
msgstr "Handelsrute"
@@ -2263,10 +2281,18 @@ msgstr "V3 {0}-pris:"
msgid "View accrued fees and analytics<0>↗</0>"
msgstr "Se påløbne gebyrer og analyser<0>↗</0>"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
msgid "View and sell NFTs"
msgstr "Se og sælg NFT'er"
#: src/components/SearchModal/ManageLists.tsx
msgid "View list"
msgstr "Vis liste"
#: src/components/NavBar/MenuDropdown.tsx
msgid "View more analytics"
msgstr "Se flere analyser"
#: src/components/TransactionConfirmationModal/index.tsx
#: src/pages/CreateProposal/ProposalSubmissionModal.tsx
msgid "View on Etherscan"
@@ -2278,10 +2304,6 @@ msgstr "Se på Etherscan"
msgid "View on Explorer"
msgstr "Vis i Explorer"
#: src/components/NavBar/MenuDropdown.tsx
msgid "View token analytics"
msgstr "Se token-analyse"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
@@ -2291,6 +2313,10 @@ msgstr "Se token-analyse"
msgid "View transaction on Explorer"
msgstr "Se transaktion i Explorer"
#: src/components/Tokens/TokenTable/TokenRow.tsx
msgid "Volume is the amount of the asset that has been traded on Uniswap v3 during the selected time frame."
msgstr "Volumen er mængden af aktivet, der er blevet handlet på Uniswap v3 i den valgte tidsramme."
#: src/components/Header/index.tsx
msgid "Vote"
msgstr "Stem"
@@ -2472,10 +2498,6 @@ msgstr "Du har ikke likviditet i denne pulje endnu."
msgid "You have no favorited tokens"
msgstr "Du har ingen foretrukne tokens"
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "You may have lost your network connection, or {label} might be down right now."
msgstr "Du har muligvis mistet din netværksforbindelse, eller {label} muligvis nede lige nu."
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "You may have lost your network connection."
msgstr "Du har muligvis mistet din netværksforbindelse."
@@ -2517,9 +2539,9 @@ msgstr "Din V2-likviditet"
msgid "Your active V3 liquidity positions will appear here."
msgstr "Dine aktive V3-likviditetspositioner vises her."
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "Your balances by network"
msgstr "Dine saldi efter netværk"
#: src/components/Tokens/TokenDetails/BalanceSummary.tsx
msgid "Your balance"
msgstr "Din balance"
#: src/pages/Pool/index.tsx
msgid "Your connected network is unsupported."
@@ -2608,6 +2630,11 @@ msgstr "Dine transaktioner vises her..."
msgid "Your unclaimed UNI"
msgstr "Din ikke-krævede UNI"
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
msgid "Your {0} balance"
msgstr "Din {0} -saldo"
#: src/components/swap/AdvancedSwapDetails.tsx
msgid "after slippage"
msgstr "efter glidning"
@@ -2684,8 +2711,8 @@ msgid "{0, plural, =1 {Import token} other {Import tokens}}"
msgstr "{0, plural, =1 {Importer token} other {Importer tokens}}"
#: src/constants/tokenSafety.tsx
msgid "{0, plural, =1 {This token isn't verified} other {These tokens aren't verified}}"
msgstr "{0, plural, =1 {Dette token er ikke verificeret} other {Disse tokens er ikke verificeret}}"
msgid "{0, plural, =1 {This token isn't verified.} other {These tokens aren't verified.}}"
msgstr "{0, plural, =1 {Dette token er ikke bekræftet.} other {Disse tokens er ikke bekræftet.}}"
#: src/constants/tokenSafety.tsx
msgid "{0, plural, =1 {You can't trade this token using the Uniswap App.} other {You can't trade these tokens using the Uniswap App.}}"
@@ -2758,10 +2785,6 @@ msgstr "{0} UNI-V2 LP-tokens tilgængelige"
msgid "{0} Votes"
msgstr "{0} Stemmer"
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "{0} all balances"
msgstr "{0} alle saldi"
#: src/components/PositionPreview/index.tsx
#: src/components/PositionPreview/index.tsx
#: src/components/PositionPreview/index.tsx
@@ -2839,6 +2862,10 @@ msgstr "{USER_AMOUNT} UNI"
msgid "{activeTokensOnThisChain} tokens"
msgstr "{activeTokensOnThisChain} poletter"
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "{label} might be down right now, or you may have lost your network connection."
msgstr "{label} kan være nede lige nu, eller du kan have mistet din netværksforbindelse."
#: src/components/NetworkAlert/NetworkAlert.tsx
msgid "{label} token bridge"
msgstr "{label} token bridge"

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: uniswap-interface\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2022-09-21 21:05\n"
"PO-Revision-Date: 2022-10-11 02:57\n"
"Last-Translator: \n"
"Language: de_DE\n"
"Language-Team: German\n"
@@ -21,10 +21,6 @@ msgstr ""
msgid "$-"
msgstr "$-"
#: src/components/CurrencyInputPanel/FiatValue.tsx
msgid "$<0/>"
msgstr "$<0/>"
#: src/components/earn/PoolCard.tsx
#: src/components/swap/GasEstimateBadge.tsx
#: src/pages/Pool/PositionPage.tsx
@@ -63,6 +59,10 @@ msgstr "0 UNI / Woche"
msgid "24H volume"
msgstr "24-Stunden-Lautstärke"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "24H volume is the amount of the asset that has been traded on Uniswap v3 during the past 24 hours."
msgstr "Das 24-Stunden-Volumen ist der Betrag des Vermögenswerts, der in den letzten 24 Stunden auf Uniswap v3 gehandelt wurde."
#: src/pages/RemoveLiquidity/V3.tsx
msgid "25%"
msgstr "25%"
@@ -240,7 +240,7 @@ msgid "Amount"
msgstr "Betrag"
#: src/components/Tokens/TokenTable/TokenTable.tsx
msgid "An error occured loading tokens. Please try again."
msgid "An error occurred loading tokens. Please try again."
msgstr "Beim Laden der Token ist ein Fehler aufgetreten. Bitte versuche es erneut."
#: src/utils/swapErrorToUserReadableMessage.tsx
@@ -373,11 +373,14 @@ msgstr "Durch das Hinzufügen von Liquidität verdienen Sie 0,3% aller Transakti
msgid "By adding this list you are implicitly trusting that the data is correct. Anyone can create a list, including creating fake versions of existing lists and lists that claim to represent projects that do not have one."
msgstr "Durch das Hinzufügen dieser Liste vertrauen Sie implizit darauf, dass die Daten korrekt sind. Jeder kann eine Liste erstellen, einschließlich gefälschter Versionen bestehender Listen oder Listen die vorgeben Projekte zu repräsentieren, die keine Liste haben."
#: src/components/WalletModal/index.tsx
#: src/components/WalletModal/index.tsx
msgid "By connecting a wallet, you agree to Uniswap Labs <0>Terms of Service</0> and acknowledge that you have read and understand the Uniswap <1>Protocol Disclaimer</1>."
msgstr "Durch das Verbinden einer Brieftasche stimmen Sie den <0>Nutzungsbedingungen von</0> und bestätigen, dass Sie den Haftungsausschluss für das Protokoll von <1></1>."
#: src/components/WalletModal/index.tsx
msgid "By connecting a wallet, you agree to Uniswap Labs <0>Terms of Service</0> and consent to its <1>Privacy Policy</1>."
msgstr "Indem Sie ein Wallet verbinden, stimmen Sie den <0>Nutzungsbedingungen</0> von Uniswap Labs und der <1>Datenschutzrichtlinie</1>zu."
#: src/pages/Vote/styled.tsx
msgid "Canceled"
msgstr "Abgesagt"
@@ -605,11 +608,13 @@ msgid "Contract address"
msgstr "Vertragsadresse"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
#: src/nft/components/profile/view/ProfileAccountDetails.tsx
#: src/theme/components.tsx
msgid "Copied!"
msgstr "Kopiert!"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
#: src/nft/components/profile/view/ProfileAccountDetails.tsx
msgid "Copy"
msgstr "Kopieren"
@@ -889,10 +894,6 @@ msgstr "Durch die Ausführung dieses Vorschlags werden die Anrufdaten in der Ket
msgid "Execution Submitted"
msgstr "Ausführung eingereicht"
#: src/components/SearchModal/CurrencyList/index.tsx
msgid "Expanded results from inactive Token Lists"
msgstr "Erweiterte Ergebnisse aus inaktiven Token-Listen"
#: src/components/swap/AdvancedSwapDetails.tsx
msgid "Expected Output"
msgstr "Erwartete Ausgabe"
@@ -913,10 +914,9 @@ msgstr "Verfallen"
msgid "Explore"
msgstr "Entdecken"
#: src/pages/Tokens/index.tsx
#: src/pages/Tokens/index.tsx
msgid "Explore Tokens"
msgstr "Entdecken Sie Token"
#: src/components/Tokens/TokensBanner.tsx
msgid "Explore Top Tokens on Uniswap"
msgstr "Entdecken Sie Top-Token auf Uniswap"
#: src/pages/Pool/CTACards.tsx
msgid "Explore Uniswap Analytics."
@@ -1130,6 +1130,10 @@ msgstr "Helles Design"
msgid "Light theme"
msgstr "Lichtthema"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Links"
msgstr "Verknüpfungen"
#: src/components/claim/ClaimModal.tsx
#: src/pages/Pool/PositionPage.tsx
msgid "Liquidity"
@@ -1262,6 +1266,11 @@ msgstr "Min.:"
msgid "Minimum received"
msgstr "Minimum erhalten"
#: src/components/Tokens/TokenDetails/PriceChart.tsx
#: src/components/Tokens/TokenDetails/PriceChart.tsx
msgid "Missing chart data"
msgstr "Fehlende Diagrammdaten"
#: src/lib/hooks/swap/useSwapCallback.tsx
msgid "Missing dependencies"
msgstr "Fehlende Abhängigkeiten"
@@ -1270,7 +1279,7 @@ msgstr "Fehlende Abhängigkeiten"
msgid "More"
msgstr "Mehr"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "NFT Collections"
msgstr "NFT-Sammlungen"
@@ -1298,6 +1307,10 @@ msgstr "Netzwerkgebühren übersteigen 50% des Swap-Betrags!"
msgid "New Position"
msgstr "Neue Position"
#: src/nft/components/profile/view/EmptyWalletContent.tsx
msgid "No NFTs in"
msgstr "Keine NFTs drin"
#: src/pages/MigrateV2/index.tsx
msgid "No V2 Liquidity found."
msgstr "Keine V2-Liquidität gefunden."
@@ -1339,7 +1352,7 @@ msgstr "Keine Token-Informationen verfügbar"
msgid "No tokens found"
msgstr "Keine Token gefunden"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "No tokens found."
msgstr "Keine Token gefunden."
@@ -1468,11 +1481,11 @@ msgstr "{0} gepoolt:"
msgid "Pools"
msgstr "Schwimmbecken"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Popular NFT collections"
msgstr "Beliebte NFT-Sammlungen"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Popular tokens"
msgstr "Beliebte Token"
@@ -1577,10 +1590,6 @@ msgstr "Warteschlange"
msgid "Rates"
msgstr "Preise"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Read more"
msgstr "Weiterlesen"
#: src/pages/Earn/index.tsx
msgid "Read more about UNI"
msgstr "Erfahre mehr über UNI"
@@ -1601,7 +1610,7 @@ msgstr "Erfahre mehr über nicht unterstützte Token"
msgid "Recent Transactions"
msgstr "Letzte Transaktionen"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Recent searches"
msgstr "Letzte Suchen"
@@ -1719,10 +1728,6 @@ msgstr "Selbst"
msgid "Self Delegate"
msgstr "Selbstdelegierung"
#: src/components/NavBar/MenuDropdown.tsx
msgid "Sell NFTs"
msgstr "NFT verkaufen"
#: src/pages/AddLiquidity/index.tsx
#: src/pages/AddLiquidity/index.tsx
#: src/pages/MigrateV2/MigrateV2Pair.tsx
@@ -1755,6 +1760,10 @@ msgstr "Show abgesagt"
msgid "Show closed positions"
msgstr "Geschlossene Positionen anzeigen"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Show more"
msgstr "Zeig mehr"
#: src/pages/RemoveLiquidity/index.tsx
msgid "Simple"
msgstr "Einfach"
@@ -1771,6 +1780,14 @@ msgstr "Einige Assets sind über diese Benutzeroberfläche nicht verfügbar, da
msgid "Something went wrong"
msgstr "Etwas ist schief gelaufen"
#: src/components/Tokens/TokensBanner.tsx
msgid "Sort and filter assets across networks on the new Tokens page."
msgstr "Sortieren und filtern Sie Assets netzwerkübergreifend auf der neuen Token-Seite."
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "Stats"
msgstr "Statistiken"
#: src/pages/Earn/Manage.tsx
msgid "Step 1. Get UNI-V2 Liquidity tokens"
msgstr "Schritt 1. Holen Sie sich UNI-V2-Liquiditätstoken"
@@ -1806,7 +1823,7 @@ msgstr "Biete {0} {1} und {2} {3} an"
#: src/components/AccountDetailsV2/TransactionBody.tsx
#: src/components/Header/index.tsx
#: src/components/NavBar/index.tsx
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
#: src/components/swap/SwapHeader.tsx
#: src/pages/Swap/index.tsx
#: src/pages/Swap/index.tsx
@@ -1848,6 +1865,10 @@ msgstr "Tausche {0} {1} gegen {2} {3}"
msgid "Symbol not found"
msgstr "Symbol nicht gefunden"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "TVL"
msgstr "TVL"
#: src/components/Popups/SurveyPopup.tsx
msgid "Take a 10 minute survey to help us improve your experience in the Uniswap app."
msgstr "Nehmen Sie an einer 10-minütigen Umfrage teil, um uns dabei zu helfen, Ihre Erfahrung in der Uniswap-App zu verbessern."
@@ -1962,14 +1983,6 @@ msgstr "Die Transaktion konnte nicht gesendet werden, da die Frist abgelaufen is
msgid "There is no liquidity data."
msgstr "Keine Liquiditätsdaten vorhanden."
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "There was an error fetching your balance"
msgstr "Beim Abrufen Ihres Guthabens ist ein Fehler aufgetreten"
#: src/components/Tokens/TokenDetails/BalanceSummary.tsx
msgid "There was an error loading your {0} balance"
msgstr "Beim Laden Ihres {0} -Guthabens ist ein Fehler aufgetreten"
#: src/components/ConnectedAccountBlocked/index.tsx
msgid "This address is blocked on the Uniswap Labs interface because it is associated with one or more"
msgstr "Diese Adresse ist auf der Uniswap Labs-Schnittstelle blockiert, da sie mit einer oder mehreren verknüpft ist"
@@ -1994,6 +2007,10 @@ msgstr "Diese Route optimiert Ihre Gesamtleistung, indem sie Split-Routen, mehre
msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade."
msgstr "Dieser Token erscheint nicht in der/den aktiven Token-Liste(n). Stellen Sie sicher, dass dies der Token ist, den Sie handeln möchten."
#: src/components/Tokens/TokenDetails/PriceChart.tsx
msgid "This token doesn't have chart data because it hasn't been traded on Uniswap v3"
msgstr "Dieser Token hat keine Chartdaten, da er nicht auf Uniswap v3 gehandelt wurde"
#: src/components/SearchModal/BlockedToken.tsx
msgid "This token is not supported in the Uniswap Labs app"
msgstr "Dieses Token wird in der Uniswap Labs-App nicht unterstützt"
@@ -2033,23 +2050,20 @@ msgid "Token not supported"
msgstr "Token nicht unterstützt"
#: src/components/Header/index.tsx
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
#: src/components/NavBar/index.tsx
#: src/components/SearchModal/Manage.tsx
msgid "Tokens"
msgstr "Token"
#: src/components/SearchModal/CurrencyList/index.tsx
msgid "Tokens from inactive lists. Import specific tokens below or click Manage to activate more lists."
msgstr "Token aus inaktiven Listen. Importieren Sie unten bestimmte Token oder klicken Sie auf Verwalten, um weitere Listen zu aktivieren."
#: src/pages/Pool/CTACards.tsx
msgid "Top pools"
msgstr "Top Pools"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "Total Value Locked"
msgstr "Gesamtwert gesperrt"
#: src/pages/Tokens/index.tsx
#: src/pages/Tokens/index.tsx
msgid "Top tokens on Uniswap"
msgstr "Top-Token auf Uniswap"
#: src/components/earn/PoolCard.tsx
msgid "Total deposited"
@@ -2059,6 +2073,10 @@ msgstr "Gesamt deponiert"
msgid "Total deposits"
msgstr "Gesamteinlagen"
#: src/components/Tokens/TokenTable/TokenRow.tsx
msgid "Total value locked (TVL) is the amount of the asset thats currently in a Uniswap v3 liquidity pool."
msgstr "Der gesperrte Gesamtwert (TVL) ist der Betrag des Vermögenswerts, der sich derzeit in einem Liquiditätspool von Uniswap v3 befindet."
#: src/components/swap/RouterLabel.tsx
msgid "Trade Route"
msgstr "Handelsroute"
@@ -2263,10 +2281,18 @@ msgstr "V3 {0} Preis:"
msgid "View accrued fees and analytics<0>↗</0>"
msgstr "Eingenommene Gebühren und Analysen anzeigen<0>↗</0>"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
msgid "View and sell NFTs"
msgstr "Anzeigen und Verkaufen von NFTs"
#: src/components/SearchModal/ManageLists.tsx
msgid "View list"
msgstr "Liste anzeigen"
#: src/components/NavBar/MenuDropdown.tsx
msgid "View more analytics"
msgstr "Weitere Analysen anzeigen"
#: src/components/TransactionConfirmationModal/index.tsx
#: src/pages/CreateProposal/ProposalSubmissionModal.tsx
msgid "View on Etherscan"
@@ -2278,10 +2304,6 @@ msgstr "Auf Etherscan ansehen"
msgid "View on Explorer"
msgstr "Im Explorer anzeigen"
#: src/components/NavBar/MenuDropdown.tsx
msgid "View token analytics"
msgstr "Anzeigen von Token-Analysen"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
@@ -2291,6 +2313,10 @@ msgstr "Anzeigen von Token-Analysen"
msgid "View transaction on Explorer"
msgstr "Transaktion im Explorer anzeigen"
#: src/components/Tokens/TokenTable/TokenRow.tsx
msgid "Volume is the amount of the asset that has been traded on Uniswap v3 during the selected time frame."
msgstr "Das Volumen ist der Betrag des Vermögenswerts, der während des ausgewählten Zeitrahmens auf Uniswap v3 gehandelt wurde."
#: src/components/Header/index.tsx
msgid "Vote"
msgstr "Abstimmung"
@@ -2472,10 +2498,6 @@ msgstr "Sie haben noch keine Liquidität in diesem Pool."
msgid "You have no favorited tokens"
msgstr "Sie haben keine bevorzugten Token"
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "You may have lost your network connection, or {label} might be down right now."
msgstr "Möglicherweise haben Sie Ihre Netzwerkverbindung verloren oder {label} möglicherweise gerade nicht verfügbar."
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "You may have lost your network connection."
msgstr "Möglicherweise haben Sie Ihre Netzwerkverbindung verloren."
@@ -2517,9 +2539,9 @@ msgstr "Ihre V2-Liquidität"
msgid "Your active V3 liquidity positions will appear here."
msgstr "Hier werden Ihre aktiven V3-Liquiditätspositionen angezeigt."
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "Your balances by network"
msgstr "Ihre Salden nach Netzwerk"
#: src/components/Tokens/TokenDetails/BalanceSummary.tsx
msgid "Your balance"
msgstr "Dein Kontostand"
#: src/pages/Pool/index.tsx
msgid "Your connected network is unsupported."
@@ -2608,6 +2630,11 @@ msgstr "Ihre Transaktionen werden hier erscheinen..."
msgid "Your unclaimed UNI"
msgstr "Deine noch nicht bezogenen UNI"
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
msgid "Your {0} balance"
msgstr "Ihr {0} -Guthaben"
#: src/components/swap/AdvancedSwapDetails.tsx
msgid "after slippage"
msgstr "nach dem rutschen"
@@ -2684,8 +2711,8 @@ msgid "{0, plural, =1 {Import token} other {Import tokens}}"
msgstr "{0, plural, =1 {Token importieren} other {Token importieren}}"
#: src/constants/tokenSafety.tsx
msgid "{0, plural, =1 {This token isn't verified} other {These tokens aren't verified}}"
msgstr "{0, plural, =1 {Dieses Token ist nicht verifiziert} other {Diese Token sind nicht verifiziert}}"
msgid "{0, plural, =1 {This token isn't verified.} other {These tokens aren't verified.}}"
msgstr "{0, plural, =1 {Dieses Token ist nicht verifiziert.} other {Diese Token werden nicht verifiziert.}}"
#: src/constants/tokenSafety.tsx
msgid "{0, plural, =1 {You can't trade this token using the Uniswap App.} other {You can't trade these tokens using the Uniswap App.}}"
@@ -2758,10 +2785,6 @@ msgstr "{0} UNI-V2 LP Token verfügbar"
msgid "{0} Votes"
msgstr "{0} Stimmen"
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "{0} all balances"
msgstr "{0} alle Salden"
#: src/components/PositionPreview/index.tsx
#: src/components/PositionPreview/index.tsx
#: src/components/PositionPreview/index.tsx
@@ -2839,6 +2862,10 @@ msgstr "{USER_AMOUNT} UNI"
msgid "{activeTokensOnThisChain} tokens"
msgstr "{activeTokensOnThisChain} Token"
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "{label} might be down right now, or you may have lost your network connection."
msgstr "{label} ist möglicherweise gerade ausgefallen oder Sie haben Ihre Netzwerkverbindung verloren."
#: src/components/NetworkAlert/NetworkAlert.tsx
msgid "{label} token bridge"
msgstr "{label} Token-Brücke"

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: uniswap-interface\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2022-09-21 21:05\n"
"PO-Revision-Date: 2022-10-11 02:57\n"
"Last-Translator: \n"
"Language: el_GR\n"
"Language-Team: Greek\n"
@@ -21,10 +21,6 @@ msgstr ""
msgid "$-"
msgstr "$-"
#: src/components/CurrencyInputPanel/FiatValue.tsx
msgid "$<0/>"
msgstr "$<0/>"
#: src/components/earn/PoolCard.tsx
#: src/components/swap/GasEstimateBadge.tsx
#: src/pages/Pool/PositionPage.tsx
@@ -63,6 +59,10 @@ msgstr "0 UNI / εβδομάδα"
msgid "24H volume"
msgstr "Ένταση 24 ωρών"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "24H volume is the amount of the asset that has been traded on Uniswap v3 during the past 24 hours."
msgstr "Ο όγκος 24 ωρών είναι το ποσό του περιουσιακού στοιχείου που έχει διαπραγματευτεί στο Uniswap v3 τις τελευταίες 24 ώρες."
#: src/pages/RemoveLiquidity/V3.tsx
msgid "25%"
msgstr "25%"
@@ -240,7 +240,7 @@ msgid "Amount"
msgstr "Ποσό"
#: src/components/Tokens/TokenTable/TokenTable.tsx
msgid "An error occured loading tokens. Please try again."
msgid "An error occurred loading tokens. Please try again."
msgstr "Παρουσιάστηκε σφάλμα κατά τη φόρτωση των διακριτικών. ΠΑΡΑΚΑΛΩ προσπαθησε ξανα."
#: src/utils/swapErrorToUserReadableMessage.tsx
@@ -373,11 +373,14 @@ msgstr "Προσθέτοντας ρευστότητα θα κερδίσετε τ
msgid "By adding this list you are implicitly trusting that the data is correct. Anyone can create a list, including creating fake versions of existing lists and lists that claim to represent projects that do not have one."
msgstr "Προσθέτοντας αυτή τη λίστα, εμπιστεύεστε έμμεσα ότι τα δεδομένα είναι σωστά. Οποιοσδήποτε μπορεί να δημιουργήσει μια λίστα, συμπεριλαμβανομένης της δημιουργίας πλαστών εκδόσεων των υφιστάμενων καταλόγων και καταλόγων που ισχυρίζονται ότι αντιπροσωπεύουν έργα που δεν έχουν ένα."
#: src/components/WalletModal/index.tsx
#: src/components/WalletModal/index.tsx
msgid "By connecting a wallet, you agree to Uniswap Labs <0>Terms of Service</0> and acknowledge that you have read and understand the Uniswap <1>Protocol Disclaimer</1>."
msgstr "Συνδέοντας ένα πορτοφόλι, συμφωνείτε με τους Όρους Παροχής Υπηρεσιών <0></0> και αναγνωρίζετε ότι έχετε διαβάσει και κατανοήσει τη Δήλωση Αποποίησης ευθυνών Πρωτοκόλλου <1></1>."
#: src/components/WalletModal/index.tsx
msgid "By connecting a wallet, you agree to Uniswap Labs <0>Terms of Service</0> and consent to its <1>Privacy Policy</1>."
msgstr "Με τη σύνδεση ενός πορτοφολιού, συμφωνείτε με τους Όρους Παροχής Υπηρεσιών <0>της Uniswap Labs</0> και συναινείτε στην <1>Πολιτική Απορρήτου</1>."
#: src/pages/Vote/styled.tsx
msgid "Canceled"
msgstr "Ακυρώθηκε"
@@ -605,11 +608,13 @@ msgid "Contract address"
msgstr "Διεύθυνση συμβολαίου"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
#: src/nft/components/profile/view/ProfileAccountDetails.tsx
#: src/theme/components.tsx
msgid "Copied!"
msgstr "Αντιγράφηκε!"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
#: src/nft/components/profile/view/ProfileAccountDetails.tsx
msgid "Copy"
msgstr "αντίγραφο"
@@ -889,10 +894,6 @@ msgstr "Η εκτέλεση αυτής της πρότασης θα θεσπίσ
msgid "Execution Submitted"
msgstr "Η εκτέλεση υποβλήθηκε"
#: src/components/SearchModal/CurrencyList/index.tsx
msgid "Expanded results from inactive Token Lists"
msgstr "Εκτεταμένα αποτελέσματα από ανενεργές Λίστες Μάρκας"
#: src/components/swap/AdvancedSwapDetails.tsx
msgid "Expected Output"
msgstr "Αναμενόμενη έξοδος"
@@ -913,10 +914,9 @@ msgstr "έχει λήξει"
msgid "Explore"
msgstr "Εξερευνώ"
#: src/pages/Tokens/index.tsx
#: src/pages/Tokens/index.tsx
msgid "Explore Tokens"
msgstr "Εξερευνήστε τα Tokens"
#: src/components/Tokens/TokensBanner.tsx
msgid "Explore Top Tokens on Uniswap"
msgstr "Εξερευνήστε Κορυφαία Tokens στο Uniswap"
#: src/pages/Pool/CTACards.tsx
msgid "Explore Uniswap Analytics."
@@ -1130,6 +1130,10 @@ msgstr "Ελαφρύ θέμα"
msgid "Light theme"
msgstr "Ελαφρύ θέμα"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Links"
msgstr "Συνδέσεις"
#: src/components/claim/ClaimModal.tsx
#: src/pages/Pool/PositionPage.tsx
msgid "Liquidity"
@@ -1262,6 +1266,11 @@ msgstr "Ελάχιστο:"
msgid "Minimum received"
msgstr "Ελάχιστο λαμβανόμενο"
#: src/components/Tokens/TokenDetails/PriceChart.tsx
#: src/components/Tokens/TokenDetails/PriceChart.tsx
msgid "Missing chart data"
msgstr "Λείπουν δεδομένα γραφήματος"
#: src/lib/hooks/swap/useSwapCallback.tsx
msgid "Missing dependencies"
msgstr "Λείπουν εξαρτήσεις"
@@ -1270,7 +1279,7 @@ msgstr "Λείπουν εξαρτήσεις"
msgid "More"
msgstr "Περισσότερα"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "NFT Collections"
msgstr "Συλλογές NFT"
@@ -1298,6 +1307,10 @@ msgstr "Οι χρεώσεις δικτύου υπερβαίνουν το 50% τ
msgid "New Position"
msgstr "Νέα Θέση"
#: src/nft/components/profile/view/EmptyWalletContent.tsx
msgid "No NFTs in"
msgstr "Δεν υπάρχουν NFT"
#: src/pages/MigrateV2/index.tsx
msgid "No V2 Liquidity found."
msgstr "Δεν βρέθηκε ρευστότητα V2."
@@ -1339,7 +1352,7 @@ msgstr "Δεν υπάρχουν διαθέσιμες πληροφορίες συ
msgid "No tokens found"
msgstr "Δεν βρέθηκαν μάρκες"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "No tokens found."
msgstr "Δεν βρέθηκαν μάρκες."
@@ -1468,11 +1481,11 @@ msgstr "Συγκεντρώθηκε(αν) {0}:"
msgid "Pools"
msgstr "Πισίνες"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Popular NFT collections"
msgstr "Δημοφιλείς συλλογές NFT"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Popular tokens"
msgstr "Δημοφιλή μάρκες"
@@ -1577,10 +1590,6 @@ msgstr "Ουρά"
msgid "Rates"
msgstr "Τιμές"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Read more"
msgstr "Διαβάστε περισσότερα"
#: src/pages/Earn/index.tsx
msgid "Read more about UNI"
msgstr "Διαβάστε περισσότερα για UNI"
@@ -1601,7 +1610,7 @@ msgstr "Διαβάστε περισσότερα για τα μη υποστηρ
msgid "Recent Transactions"
msgstr "Πρόσφατες Συναλλαγές"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Recent searches"
msgstr "Πρόσφατες αναζητήσεις"
@@ -1719,10 +1728,6 @@ msgstr "Αυτοπροσώπως"
msgid "Self Delegate"
msgstr "Ανάθεση στον εαυτό μου"
#: src/components/NavBar/MenuDropdown.tsx
msgid "Sell NFTs"
msgstr "Πουλήστε NFT"
#: src/pages/AddLiquidity/index.tsx
#: src/pages/AddLiquidity/index.tsx
#: src/pages/MigrateV2/MigrateV2Pair.tsx
@@ -1755,6 +1760,10 @@ msgstr "Εμφάνιση ακυρώθηκε"
msgid "Show closed positions"
msgstr "Εμφάνιση κλειστών θέσεων"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Show more"
msgstr "Δείτε περισσότερα"
#: src/pages/RemoveLiquidity/index.tsx
msgid "Simple"
msgstr "Απλό"
@@ -1771,6 +1780,14 @@ msgstr "Ορισμένα περιουσιακά στοιχεία δεν είνα
msgid "Something went wrong"
msgstr "Κάτι πήγε στραβά"
#: src/components/Tokens/TokensBanner.tsx
msgid "Sort and filter assets across networks on the new Tokens page."
msgstr "Ταξινόμηση και φιλτράρισμα στοιχείων στα δίκτυα στη νέα σελίδα Tokens."
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "Stats"
msgstr "Στατιστικά στοιχεία"
#: src/pages/Earn/Manage.tsx
msgid "Step 1. Get UNI-V2 Liquidity tokens"
msgstr "Βήμα 1. Πάρτε τα διακριτικά ρευστότητας UNI-V2"
@@ -1806,7 +1823,7 @@ msgstr "Γίνεται παροχή {0} {1} και {2} {3}"
#: src/components/AccountDetailsV2/TransactionBody.tsx
#: src/components/Header/index.tsx
#: src/components/NavBar/index.tsx
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
#: src/components/swap/SwapHeader.tsx
#: src/pages/Swap/index.tsx
#: src/pages/Swap/index.tsx
@@ -1848,6 +1865,10 @@ msgstr "Ανταλλαγή {0} {1} για {2} {3}"
msgid "Symbol not found"
msgstr "Το σύμβολο δεν βρέθηκε"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "TVL"
msgstr "TVL"
#: src/components/Popups/SurveyPopup.tsx
msgid "Take a 10 minute survey to help us improve your experience in the Uniswap app."
msgstr "Κάντε μια έρευνα 10 λεπτών για να μας βοηθήσετε να βελτιώσουμε την εμπειρία σας στην εφαρμογή Uniswap."
@@ -1962,14 +1983,6 @@ msgstr "Δεν ήταν δυνατή η αποστολή της συναλλαγ
msgid "There is no liquidity data."
msgstr "Δεν υπάρχουν δεδομένα ρευστότητας."
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "There was an error fetching your balance"
msgstr "Παρουσιάστηκε σφάλμα κατά την ανάκτηση του υπολοίπου σας"
#: src/components/Tokens/TokenDetails/BalanceSummary.tsx
msgid "There was an error loading your {0} balance"
msgstr "Παρουσιάστηκε σφάλμα κατά τη φόρτωση του υπολοίπου {0}"
#: src/components/ConnectedAccountBlocked/index.tsx
msgid "This address is blocked on the Uniswap Labs interface because it is associated with one or more"
msgstr "Αυτή η διεύθυνση είναι αποκλεισμένη στη διεπαφή Uniswap Labs επειδή σχετίζεται με μία ή περισσότερες"
@@ -1994,6 +2007,10 @@ msgstr "Αυτή η διαδρομή βελτιστοποιεί τη συνολ
msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade."
msgstr "Αυτή η μάρκα δεν εμφανίζεται στην(ις) ενεργή (ές) λίστα(ες). Βεβαιωθείτε ότι αυτή είναι η μάρκα που θέλετε να διαπραγματευτείτε."
#: src/components/Tokens/TokenDetails/PriceChart.tsx
msgid "This token doesn't have chart data because it hasn't been traded on Uniswap v3"
msgstr "Αυτό το διακριτικό δεν έχει δεδομένα γραφήματος επειδή δεν έχει διαπραγματευτεί στο Uniswap v3"
#: src/components/SearchModal/BlockedToken.tsx
msgid "This token is not supported in the Uniswap Labs app"
msgstr "Αυτό το διακριτικό δεν υποστηρίζεται στην εφαρμογή Uniswap Labs"
@@ -2033,23 +2050,20 @@ msgid "Token not supported"
msgstr "Το διακριτικό δεν υποστηρίζεται"
#: src/components/Header/index.tsx
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
#: src/components/NavBar/index.tsx
#: src/components/SearchModal/Manage.tsx
msgid "Tokens"
msgstr "Μάρκες"
#: src/components/SearchModal/CurrencyList/index.tsx
msgid "Tokens from inactive lists. Import specific tokens below or click Manage to activate more lists."
msgstr "Μάρκες από ανενεργές λίστες. Εισαγάγετε συγκεκριμένες μάρκες παρακάτω ή κάντε κλικ στην επιλογή Διαχείριση για να ενεργοποιήσετε περισσότερες λίστες."
#: src/pages/Pool/CTACards.tsx
msgid "Top pools"
msgstr "Κορυφαίες δεξαμενές"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "Total Value Locked"
msgstr "Κλειδωμένη συνολική αξία"
#: src/pages/Tokens/index.tsx
#: src/pages/Tokens/index.tsx
msgid "Top tokens on Uniswap"
msgstr "Κορυφαία διακριτικά στο Uniswap"
#: src/components/earn/PoolCard.tsx
msgid "Total deposited"
@@ -2059,6 +2073,10 @@ msgstr "Σύνολο που κατατέθηκε"
msgid "Total deposits"
msgstr "Συνολικές καταθέσεις"
#: src/components/Tokens/TokenTable/TokenRow.tsx
msgid "Total value locked (TVL) is the amount of the asset thats currently in a Uniswap v3 liquidity pool."
msgstr "Η συνολική κλειδωμένη αξία (TVL) είναι το ποσό του περιουσιακού στοιχείου που βρίσκεται αυτήν τη στιγμή σε μια ομάδα ρευστότητας Uniswap v3."
#: src/components/swap/RouterLabel.tsx
msgid "Trade Route"
msgstr "Εμπορική οδός"
@@ -2263,10 +2281,18 @@ msgstr "V3 {0} Τιμή:"
msgid "View accrued fees and analytics<0>↗</0>"
msgstr "Προβολή δεδουλευμένων τελών και αναλύσεων<0>↗</0>"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
msgid "View and sell NFTs"
msgstr "Δείτε και πουλήστε NFT"
#: src/components/SearchModal/ManageLists.tsx
msgid "View list"
msgstr "Προβολή λίστας"
#: src/components/NavBar/MenuDropdown.tsx
msgid "View more analytics"
msgstr "Δείτε περισσότερα αναλυτικά στοιχεία"
#: src/components/TransactionConfirmationModal/index.tsx
#: src/pages/CreateProposal/ProposalSubmissionModal.tsx
msgid "View on Etherscan"
@@ -2278,10 +2304,6 @@ msgstr "Θέα στο Ethercan"
msgid "View on Explorer"
msgstr "Προβολή στον Explorer"
#: src/components/NavBar/MenuDropdown.tsx
msgid "View token analytics"
msgstr "Προβολή αναλυτικών στοιχείων διακριτικών"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
@@ -2291,6 +2313,10 @@ msgstr "Προβολή αναλυτικών στοιχείων διακριτι
msgid "View transaction on Explorer"
msgstr "Προβολή συναλλαγής στον Explorer"
#: src/components/Tokens/TokenTable/TokenRow.tsx
msgid "Volume is the amount of the asset that has been traded on Uniswap v3 during the selected time frame."
msgstr "Όγκος είναι το ποσό του περιουσιακού στοιχείου που έχει διαπραγματευτεί στο Uniswap v3 κατά τη διάρκεια του επιλεγμένου χρονικού πλαισίου."
#: src/components/Header/index.tsx
msgid "Vote"
msgstr "Ψηφοφορίες"
@@ -2472,10 +2498,6 @@ msgstr "Δεν έχετε ακόμα ρευστότητα σε αυτή την
msgid "You have no favorited tokens"
msgstr "Δεν έχετε αγαπημένα διακριτικά"
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "You may have lost your network connection, or {label} might be down right now."
msgstr "Μπορεί να έχετε χάσει τη σύνδεσή σας στο δίκτυο ή το {label} να είναι εκτός λειτουργίας αυτήν τη στιγμή."
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "You may have lost your network connection."
msgstr "Ενδέχεται να έχετε χάσει τη σύνδεση δικτύου σας."
@@ -2517,9 +2539,9 @@ msgstr "Η ρευστότητα V2 σας"
msgid "Your active V3 liquidity positions will appear here."
msgstr "Οι ενεργές σας θέσεις ρευστότητας V3 θα εμφανίζονται εδώ."
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "Your balances by network"
msgstr "Τα υπόλοιπά σας ανά δίκτυο"
#: src/components/Tokens/TokenDetails/BalanceSummary.tsx
msgid "Your balance"
msgstr "Η ισορροπία σου"
#: src/pages/Pool/index.tsx
msgid "Your connected network is unsupported."
@@ -2608,6 +2630,11 @@ msgstr "Οι συναλλαγές σας θα εμφανιστούν εδώ..."
msgid "Your unclaimed UNI"
msgstr "Το αζήτητο UNI σας"
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
msgid "Your {0} balance"
msgstr "Το υπόλοιπο {0} σας"
#: src/components/swap/AdvancedSwapDetails.tsx
msgid "after slippage"
msgstr "μετά από ολίσθηση"
@@ -2684,8 +2711,8 @@ msgid "{0, plural, =1 {Import token} other {Import tokens}}"
msgstr "{0, plural, =1 {Εισαγωγή διακριτικού} other {Εισαγάγετε μάρκες}}"
#: src/constants/tokenSafety.tsx
msgid "{0, plural, =1 {This token isn't verified} other {These tokens aren't verified}}"
msgstr "{0, plural, =1 {Αυτό το διακριτικό δεν έχει επαληθευτεί} other {Αυτά τα διακριτικά δεν έχουν επαληθευτεί}}"
msgid "{0, plural, =1 {This token isn't verified.} other {These tokens aren't verified.}}"
msgstr "{0, plural, =1 {Αυτό το διακριτικό δεν έχει επαληθευτεί.} other {Αυτά τα διακριτικά δεν έχουν επαληθευτεί.}}"
#: src/constants/tokenSafety.tsx
msgid "{0, plural, =1 {You can't trade this token using the Uniswap App.} other {You can't trade these tokens using the Uniswap App.}}"
@@ -2758,10 +2785,6 @@ msgstr "{0} διαθέσιμες μάρκες UNI-V2 LP"
msgid "{0} Votes"
msgstr "{0} Ψήφοι"
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "{0} all balances"
msgstr "{0} όλα τα υπόλοιπα"
#: src/components/PositionPreview/index.tsx
#: src/components/PositionPreview/index.tsx
#: src/components/PositionPreview/index.tsx
@@ -2839,6 +2862,10 @@ msgstr "{USER_AMOUNT} UNI"
msgid "{activeTokensOnThisChain} tokens"
msgstr "{activeTokensOnThisChain} μάρκες"
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "{label} might be down right now, or you may have lost your network connection."
msgstr "{label} μπορεί να είναι απενεργοποιημένο αυτήν τη στιγμή ή μπορεί να έχετε χάσει τη σύνδεσή σας στο δίκτυο."
#: src/components/NetworkAlert/NetworkAlert.tsx
msgid "{label} token bridge"
msgstr "{label} συμβολική γέφυρα"

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: uniswap-interface\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2022-09-21 21:05\n"
"PO-Revision-Date: 2022-10-11 02:57\n"
"Last-Translator: \n"
"Language: es_ES\n"
"Language-Team: Spanish\n"
@@ -21,10 +21,6 @@ msgstr ""
msgid "$-"
msgstr "$-"
#: src/components/CurrencyInputPanel/FiatValue.tsx
msgid "$<0/>"
msgstr "$<0/>"
#: src/components/earn/PoolCard.tsx
#: src/components/swap/GasEstimateBadge.tsx
#: src/pages/Pool/PositionPage.tsx
@@ -63,6 +59,10 @@ msgstr "0 UNI / semana"
msgid "24H volume"
msgstr "Volumen 24H"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "24H volume is the amount of the asset that has been traded on Uniswap v3 during the past 24 hours."
msgstr "El volumen de 24 horas es la cantidad del activo que se negoció en Uniswap v3 durante las últimas 24 horas."
#: src/pages/RemoveLiquidity/V3.tsx
msgid "25%"
msgstr "25 %"
@@ -240,7 +240,7 @@ msgid "Amount"
msgstr "Cantidad"
#: src/components/Tokens/TokenTable/TokenTable.tsx
msgid "An error occured loading tokens. Please try again."
msgid "An error occurred loading tokens. Please try again."
msgstr "Ocurrió un error al cargar tokens. Inténtalo de nuevo."
#: src/utils/swapErrorToUserReadableMessage.tsx
@@ -373,11 +373,14 @@ msgstr "Al añadir liquidez, ganará un 0,3 % de todas las operaciones con este
msgid "By adding this list you are implicitly trusting that the data is correct. Anyone can create a list, including creating fake versions of existing lists and lists that claim to represent projects that do not have one."
msgstr "Al añadir esta lista está confiando implícitamente en que los datos son correctos. Cualquiera puede crear una lista; incluso se pueden crear versiones falsas de listas existentes y listas que afirman representar proyectos que no tienen una."
#: src/components/WalletModal/index.tsx
#: src/components/WalletModal/index.tsx
msgid "By connecting a wallet, you agree to Uniswap Labs <0>Terms of Service</0> and acknowledge that you have read and understand the Uniswap <1>Protocol Disclaimer</1>."
msgstr "Al conectar una billetera, acepta los <0>Términos de servicio</0> Uniswap Labs y reconoce que ha leído y comprendido el Descargo <1>responsabilidad del protocolo</1>."
#: src/components/WalletModal/index.tsx
msgid "By connecting a wallet, you agree to Uniswap Labs <0>Terms of Service</0> and consent to its <1>Privacy Policy</1>."
msgstr "Al conectar una billetera, acepta los <0>Términos de servicio</0> de Uniswap Labs y acepta su <1>Política de privacidad</1>."
#: src/pages/Vote/styled.tsx
msgid "Canceled"
msgstr "Cancelado"
@@ -605,11 +608,13 @@ msgid "Contract address"
msgstr "Dirección del contrato"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
#: src/nft/components/profile/view/ProfileAccountDetails.tsx
#: src/theme/components.tsx
msgid "Copied!"
msgstr "¡Copiado!"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
#: src/nft/components/profile/view/ProfileAccountDetails.tsx
msgid "Copy"
msgstr "Copiar"
@@ -889,10 +894,6 @@ msgstr "La ejecución de esta propuesta promulgará los datos de llamada en la c
msgid "Execution Submitted"
msgstr "Ejecución enviada"
#: src/components/SearchModal/CurrencyList/index.tsx
msgid "Expanded results from inactive Token Lists"
msgstr "Resultados ampliados de listas de token inactivas"
#: src/components/swap/AdvancedSwapDetails.tsx
msgid "Expected Output"
msgstr "Rendimiento esperado"
@@ -913,10 +914,9 @@ msgstr "Caducado"
msgid "Explore"
msgstr "Explorar"
#: src/pages/Tokens/index.tsx
#: src/pages/Tokens/index.tsx
msgid "Explore Tokens"
msgstr "Explora fichas"
#: src/components/Tokens/TokensBanner.tsx
msgid "Explore Top Tokens on Uniswap"
msgstr "Explore los mejores tokens en Uniswap"
#: src/pages/Pool/CTACards.tsx
msgid "Explore Uniswap Analytics."
@@ -1130,6 +1130,10 @@ msgstr "Tema de luz"
msgid "Light theme"
msgstr "Tema ligero"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Links"
msgstr "Enlaces"
#: src/components/claim/ClaimModal.tsx
#: src/pages/Pool/PositionPage.tsx
msgid "Liquidity"
@@ -1262,6 +1266,11 @@ msgstr "Mín:"
msgid "Minimum received"
msgstr "Mínimo recibido"
#: src/components/Tokens/TokenDetails/PriceChart.tsx
#: src/components/Tokens/TokenDetails/PriceChart.tsx
msgid "Missing chart data"
msgstr "Faltan datos del gráfico"
#: src/lib/hooks/swap/useSwapCallback.tsx
msgid "Missing dependencies"
msgstr "Dependencias faltantes"
@@ -1270,7 +1279,7 @@ msgstr "Dependencias faltantes"
msgid "More"
msgstr "Más"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "NFT Collections"
msgstr "Colecciones NFT"
@@ -1298,6 +1307,10 @@ msgstr "¡Las tarifas de red superan el 50% del monto del intercambio!"
msgid "New Position"
msgstr "Nueva posición"
#: src/nft/components/profile/view/EmptyWalletContent.tsx
msgid "No NFTs in"
msgstr "No hay NFT en"
#: src/pages/MigrateV2/index.tsx
msgid "No V2 Liquidity found."
msgstr "No se encontró liquidez V2."
@@ -1339,7 +1352,7 @@ msgstr "No hay información de token disponible"
msgid "No tokens found"
msgstr "No se encontraron fichas"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "No tokens found."
msgstr "No se encontraron fichas."
@@ -1468,11 +1481,11 @@ msgstr "Conjunto {0}:"
msgid "Pools"
msgstr "Quinielas"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Popular NFT collections"
msgstr "Colecciones populares de NFT"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Popular tokens"
msgstr "Fichas populares"
@@ -1577,10 +1590,6 @@ msgstr "haciendo cola"
msgid "Rates"
msgstr "Tarifas"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Read more"
msgstr "Lee mas"
#: src/pages/Earn/index.tsx
msgid "Read more about UNI"
msgstr "Leer más sobre UNI"
@@ -1601,7 +1610,7 @@ msgstr "Leer más sobre activos no soportados"
msgid "Recent Transactions"
msgstr "Transacciones recientes"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Recent searches"
msgstr "Búsquedas recientes"
@@ -1719,10 +1728,6 @@ msgstr "Auto"
msgid "Self Delegate"
msgstr "Autodelegado"
#: src/components/NavBar/MenuDropdown.tsx
msgid "Sell NFTs"
msgstr "Vender NFT"
#: src/pages/AddLiquidity/index.tsx
#: src/pages/AddLiquidity/index.tsx
#: src/pages/MigrateV2/MigrateV2Pair.tsx
@@ -1755,6 +1760,10 @@ msgstr "Mostrar cancelado"
msgid "Show closed positions"
msgstr "Mostrar posiciones cerradas"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Show more"
msgstr "Mostrar más"
#: src/pages/RemoveLiquidity/index.tsx
msgid "Simple"
msgstr "Simple"
@@ -1771,6 +1780,14 @@ msgstr "Algunos activos no están disponibles a través de esta interfaz porque
msgid "Something went wrong"
msgstr "Algo salió mal"
#: src/components/Tokens/TokensBanner.tsx
msgid "Sort and filter assets across networks on the new Tokens page."
msgstr "Ordene y filtre activos a través de redes en la nueva página Tokens."
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "Stats"
msgstr "Estadísticas"
#: src/pages/Earn/Manage.tsx
msgid "Step 1. Get UNI-V2 Liquidity tokens"
msgstr "Paso 1. Obtener tokens de liquidez UNI-V2"
@@ -1806,7 +1823,7 @@ msgstr "Suministrando {0} {1} y {2} {3}"
#: src/components/AccountDetailsV2/TransactionBody.tsx
#: src/components/Header/index.tsx
#: src/components/NavBar/index.tsx
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
#: src/components/swap/SwapHeader.tsx
#: src/pages/Swap/index.tsx
#: src/pages/Swap/index.tsx
@@ -1848,6 +1865,10 @@ msgstr "Intercambiando {0} {1} por {2} {3}"
msgid "Symbol not found"
msgstr "Símbolo no encontrado"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "TVL"
msgstr "TVL"
#: src/components/Popups/SurveyPopup.tsx
msgid "Take a 10 minute survey to help us improve your experience in the Uniswap app."
msgstr "Realice una encuesta de 10 minutos para ayudarnos a mejorar su experiencia en la aplicación Uniswap."
@@ -1962,14 +1983,6 @@ msgstr "No se pudo enviar la transacción porque la fecha límite ha pasado. Ver
msgid "There is no liquidity data."
msgstr "No hay datos de liquidez."
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "There was an error fetching your balance"
msgstr "Hubo un error al obtener su saldo"
#: src/components/Tokens/TokenDetails/BalanceSummary.tsx
msgid "There was an error loading your {0} balance"
msgstr "Hubo un error al cargar tu saldo {0}"
#: src/components/ConnectedAccountBlocked/index.tsx
msgid "This address is blocked on the Uniswap Labs interface because it is associated with one or more"
msgstr "Esta dirección está bloqueada en la interfaz de Uniswap Labs porque está asociada con uno o más"
@@ -1994,6 +2007,10 @@ msgstr "Esta ruta optimiza su producción total al considerar rutas divididas, m
msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade."
msgstr "Este token no aparece en las listas de tokens activos. Asegúrese de que este sea el token que desea intercambiar."
#: src/components/Tokens/TokenDetails/PriceChart.tsx
msgid "This token doesn't have chart data because it hasn't been traded on Uniswap v3"
msgstr "Este token no tiene datos de gráficos porque no se ha negociado en Uniswap v3"
#: src/components/SearchModal/BlockedToken.tsx
msgid "This token is not supported in the Uniswap Labs app"
msgstr "Este token no es compatible con la aplicación Uniswap Labs."
@@ -2033,23 +2050,20 @@ msgid "Token not supported"
msgstr "Token no admitido"
#: src/components/Header/index.tsx
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
#: src/components/NavBar/index.tsx
#: src/components/SearchModal/Manage.tsx
msgid "Tokens"
msgstr "Tokens"
#: src/components/SearchModal/CurrencyList/index.tsx
msgid "Tokens from inactive lists. Import specific tokens below or click Manage to activate more lists."
msgstr "Tokens de listas inactivas. Importe tokens específicos a continuación o haga clic en Administrar para activar más listas."
#: src/pages/Pool/CTACards.tsx
msgid "Top pools"
msgstr "Fondos comunes superiores"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "Total Value Locked"
msgstr "Valor total bloqueado"
#: src/pages/Tokens/index.tsx
#: src/pages/Tokens/index.tsx
msgid "Top tokens on Uniswap"
msgstr "Los mejores tokens en Uniswap"
#: src/components/earn/PoolCard.tsx
msgid "Total deposited"
@@ -2059,6 +2073,10 @@ msgstr "Total depositado"
msgid "Total deposits"
msgstr "Total de depósitos"
#: src/components/Tokens/TokenTable/TokenRow.tsx
msgid "Total value locked (TVL) is the amount of the asset thats currently in a Uniswap v3 liquidity pool."
msgstr "El valor total bloqueado (TVL) es la cantidad del activo que se encuentra actualmente en un grupo de liquidez de Uniswap v3."
#: src/components/swap/RouterLabel.tsx
msgid "Trade Route"
msgstr "Ruta comercial"
@@ -2263,10 +2281,18 @@ msgstr "Precio V3 {0}:"
msgid "View accrued fees and analytics<0>↗</0>"
msgstr "Ver comisiones acumuladas y sus estadísticas<0>↗</0>"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
msgid "View and sell NFTs"
msgstr "Ver y vender NFT"
#: src/components/SearchModal/ManageLists.tsx
msgid "View list"
msgstr "Ver lista"
#: src/components/NavBar/MenuDropdown.tsx
msgid "View more analytics"
msgstr "Ver más análisis"
#: src/components/TransactionConfirmationModal/index.tsx
#: src/pages/CreateProposal/ProposalSubmissionModal.tsx
msgid "View on Etherscan"
@@ -2278,10 +2304,6 @@ msgstr "Ver en Etherscan"
msgid "View on Explorer"
msgstr "Ver en el explorador"
#: src/components/NavBar/MenuDropdown.tsx
msgid "View token analytics"
msgstr "Ver análisis de tokens"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
@@ -2291,6 +2313,10 @@ msgstr "Ver análisis de tokens"
msgid "View transaction on Explorer"
msgstr "Mostrar la transacción en el explorador"
#: src/components/Tokens/TokenTable/TokenRow.tsx
msgid "Volume is the amount of the asset that has been traded on Uniswap v3 during the selected time frame."
msgstr "El volumen es la cantidad del activo que se ha negociado en Uniswap v3 durante el período de tiempo seleccionado."
#: src/components/Header/index.tsx
msgid "Vote"
msgstr "Votaciones"
@@ -2472,10 +2498,6 @@ msgstr "Todavía no tiene liquidez en este fondo común."
msgid "You have no favorited tokens"
msgstr "No tienes fichas favoritas"
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "You may have lost your network connection, or {label} might be down right now."
msgstr "Es posible que haya perdido su conexión de red o que {label} esté inactivo en este momento."
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "You may have lost your network connection."
msgstr "Es posible que haya perdido su conexión de red."
@@ -2517,9 +2539,9 @@ msgstr "Su liquidez V2"
msgid "Your active V3 liquidity positions will appear here."
msgstr "Sus posiciones activas de liquidez V3 aparecerán aquí."
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "Your balances by network"
msgstr "Tus saldos por red"
#: src/components/Tokens/TokenDetails/BalanceSummary.tsx
msgid "Your balance"
msgstr "Tu balance"
#: src/pages/Pool/index.tsx
msgid "Your connected network is unsupported."
@@ -2608,6 +2630,11 @@ msgstr "Sus transacciones aparecerán aquí..."
msgid "Your unclaimed UNI"
msgstr "Su UNI no reclamada"
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
msgid "Your {0} balance"
msgstr "Tu saldo {0}"
#: src/components/swap/AdvancedSwapDetails.tsx
msgid "after slippage"
msgstr "después del deslizamiento"
@@ -2684,8 +2711,8 @@ msgid "{0, plural, =1 {Import token} other {Import tokens}}"
msgstr "{0, plural, =1 {Ficha de importación} other {¡Importar fichas}}"
#: src/constants/tokenSafety.tsx
msgid "{0, plural, =1 {This token isn't verified} other {These tokens aren't verified}}"
msgstr "{0, plural, =1 {¡Este token no está verificado} other {¡Estos tokens no están verificados}}"
msgid "{0, plural, =1 {This token isn't verified.} other {These tokens aren't verified.}}"
msgstr "{0, plural, =1 {Este token no está verificado.} other {Estos tokens no están verificados.}}"
#: src/constants/tokenSafety.tsx
msgid "{0, plural, =1 {You can't trade this token using the Uniswap App.} other {You can't trade these tokens using the Uniswap App.}}"
@@ -2758,10 +2785,6 @@ msgstr "{0} tokens LP UNI-V2 disponibles"
msgid "{0} Votes"
msgstr "{0} Votos"
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "{0} all balances"
msgstr "{0} todos los saldos"
#: src/components/PositionPreview/index.tsx
#: src/components/PositionPreview/index.tsx
#: src/components/PositionPreview/index.tsx
@@ -2839,6 +2862,10 @@ msgstr "{USER_AMOUNT} UNI"
msgid "{activeTokensOnThisChain} tokens"
msgstr "{activeTokensOnThisChain} fichas"
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "{label} might be down right now, or you may have lost your network connection."
msgstr "{label} podría estar inactivo en este momento, o es posible que haya perdido su conexión de red."
#: src/components/NetworkAlert/NetworkAlert.tsx
msgid "{label} token bridge"
msgstr "{label} token puente"

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: uniswap-interface\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2022-09-21 21:05\n"
"PO-Revision-Date: 2022-10-11 02:57\n"
"Last-Translator: \n"
"Language: fi_FI\n"
"Language-Team: Finnish\n"
@@ -21,10 +21,6 @@ msgstr ""
msgid "$-"
msgstr "$-"
#: src/components/CurrencyInputPanel/FiatValue.tsx
msgid "$<0/>"
msgstr "<0/>dollaria"
#: src/components/earn/PoolCard.tsx
#: src/components/swap/GasEstimateBadge.tsx
#: src/pages/Pool/PositionPage.tsx
@@ -63,6 +59,10 @@ msgstr "0 UNI / viikko"
msgid "24H volume"
msgstr "24 tunnin tilavuus"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "24H volume is the amount of the asset that has been traded on Uniswap v3 during the past 24 hours."
msgstr "24 tunnin volyymi on omaisuuden määrä, jolla on vaihdettu Uniswap v3:ssa viimeisen 24 tunnin aikana."
#: src/pages/RemoveLiquidity/V3.tsx
msgid "25%"
msgstr "25%"
@@ -240,7 +240,7 @@ msgid "Amount"
msgstr "Määrä"
#: src/components/Tokens/TokenTable/TokenTable.tsx
msgid "An error occured loading tokens. Please try again."
msgid "An error occurred loading tokens. Please try again."
msgstr "Tunnuksia ladattaessa tapahtui virhe. Yritä uudelleen."
#: src/utils/swapErrorToUserReadableMessage.tsx
@@ -373,11 +373,14 @@ msgstr "Lisäämällä likviditeettiä ansaitset 0,3 % kaikista tämän parin ka
msgid "By adding this list you are implicitly trusting that the data is correct. Anyone can create a list, including creating fake versions of existing lists and lists that claim to represent projects that do not have one."
msgstr "Lisäämällä tämän luettelon luotat ehdottomasti siihen, että tiedot ovat oikein. Kuka tahansa voi luoda luettelon ja luoda myös väärennettyjä versioita olemassa olevista luetteloista ja luetteloista, jotka väittävät edustavansa hankkeita, joilla ei sellaista ole."
#: src/components/WalletModal/index.tsx
#: src/components/WalletModal/index.tsx
msgid "By connecting a wallet, you agree to Uniswap Labs <0>Terms of Service</0> and acknowledge that you have read and understand the Uniswap <1>Protocol Disclaimer</1>."
msgstr "Yhdistämällä lompakon hyväksyt Uniswap Labsin <0>-palveluehdot</0> ja vahvistat lukeneesi ja ymmärtäväsi Uniswap <1>-protokollan vastuuvapauslausekkeen</1>."
#: src/components/WalletModal/index.tsx
msgid "By connecting a wallet, you agree to Uniswap Labs <0>Terms of Service</0> and consent to its <1>Privacy Policy</1>."
msgstr "Yhdistämällä lompakon hyväksyt Uniswap Labsin <0>-palveluehdot</0> ja sen <1>tietosuojakäytännön</1>."
#: src/pages/Vote/styled.tsx
msgid "Canceled"
msgstr "Peruutettu"
@@ -605,11 +608,13 @@ msgid "Contract address"
msgstr "Sopimusosoite"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
#: src/nft/components/profile/view/ProfileAccountDetails.tsx
#: src/theme/components.tsx
msgid "Copied!"
msgstr "Kopioitu!"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
#: src/nft/components/profile/view/ProfileAccountDetails.tsx
msgid "Copy"
msgstr "Kopio"
@@ -889,10 +894,6 @@ msgstr "Tämän ehdotuksen toteuttaminen ottaa käyttöön soittotiedot ketjussa
msgid "Execution Submitted"
msgstr "Toteutus lähetetty"
#: src/components/SearchModal/CurrencyList/index.tsx
msgid "Expanded results from inactive Token Lists"
msgstr "Laajennetut tulokset passiivisista rahakeluetteloista"
#: src/components/swap/AdvancedSwapDetails.tsx
msgid "Expected Output"
msgstr "Odotettu tulos"
@@ -913,10 +914,9 @@ msgstr "Vanhentunut"
msgid "Explore"
msgstr "Tutkia"
#: src/pages/Tokens/index.tsx
#: src/pages/Tokens/index.tsx
msgid "Explore Tokens"
msgstr "Tutustu Tokeneihin"
#: src/components/Tokens/TokensBanner.tsx
msgid "Explore Top Tokens on Uniswap"
msgstr "Tutustu suosituimpiin Tokeneihin Uniswapissa"
#: src/pages/Pool/CTACards.tsx
msgid "Explore Uniswap Analytics."
@@ -1130,6 +1130,10 @@ msgstr "Kevyt teema"
msgid "Light theme"
msgstr "Kevyt teema"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Links"
msgstr "Linkit"
#: src/components/claim/ClaimModal.tsx
#: src/pages/Pool/PositionPage.tsx
msgid "Liquidity"
@@ -1262,6 +1266,11 @@ msgstr "Minimi:"
msgid "Minimum received"
msgstr "Minimi vastaanotettu"
#: src/components/Tokens/TokenDetails/PriceChart.tsx
#: src/components/Tokens/TokenDetails/PriceChart.tsx
msgid "Missing chart data"
msgstr "Karttatiedot puuttuvat"
#: src/lib/hooks/swap/useSwapCallback.tsx
msgid "Missing dependencies"
msgstr "Puuttuvat riippuvuudet"
@@ -1270,7 +1279,7 @@ msgstr "Puuttuvat riippuvuudet"
msgid "More"
msgstr "Lisää"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "NFT Collections"
msgstr "NFT-kokoelmat"
@@ -1298,6 +1307,10 @@ msgstr "Verkkomaksut ylittävät 50 % vaihtosummasta!"
msgid "New Position"
msgstr "Uusi positio"
#: src/nft/components/profile/view/EmptyWalletContent.tsx
msgid "No NFTs in"
msgstr "Ei NFT:tä sisään"
#: src/pages/MigrateV2/index.tsx
msgid "No V2 Liquidity found."
msgstr "V2-likviditeettiä ei löytynyt."
@@ -1339,7 +1352,7 @@ msgstr "Tunnustietoja ei ole saatavilla"
msgid "No tokens found"
msgstr "Tunnuksia ei löytynyt"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "No tokens found."
msgstr "Tunnuksia ei löytynyt."
@@ -1468,11 +1481,11 @@ msgstr "Poolattu {0}:"
msgid "Pools"
msgstr "Altaat"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Popular NFT collections"
msgstr "Suositut NFT-kokoelmat"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Popular tokens"
msgstr "Suosittuja tokeneja"
@@ -1577,10 +1590,6 @@ msgstr "Jonotus"
msgid "Rates"
msgstr "Kurssit"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Read more"
msgstr "Lue lisää"
#: src/pages/Earn/index.tsx
msgid "Read more about UNI"
msgstr "Lue lisää UNIsta"
@@ -1601,7 +1610,7 @@ msgstr "Lue lisää ei-tuetuista varoista"
msgid "Recent Transactions"
msgstr "Viimeisimmät tapahtumat"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Recent searches"
msgstr "Viimeaikaiset haut"
@@ -1719,10 +1728,6 @@ msgstr "Itse"
msgid "Self Delegate"
msgstr "Delegoi itse"
#: src/components/NavBar/MenuDropdown.tsx
msgid "Sell NFTs"
msgstr "Myy NFT:t"
#: src/pages/AddLiquidity/index.tsx
#: src/pages/AddLiquidity/index.tsx
#: src/pages/MigrateV2/MigrateV2Pair.tsx
@@ -1755,6 +1760,10 @@ msgstr "Esitys peruutettu"
msgid "Show closed positions"
msgstr "Näytä suljetut sijainnit"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Show more"
msgstr "Näytä lisää"
#: src/pages/RemoveLiquidity/index.tsx
msgid "Simple"
msgstr "Yksinkertainen"
@@ -1771,6 +1780,14 @@ msgstr "Jotkut varat eivät ole käytettävissä tämän käyttöliittymän kaut
msgid "Something went wrong"
msgstr "Jotain meni pieleen"
#: src/components/Tokens/TokensBanner.tsx
msgid "Sort and filter assets across networks on the new Tokens page."
msgstr "Lajittele ja suodata resursseja eri verkostoissa uudella Tokens-sivulla."
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "Stats"
msgstr "Tilastot"
#: src/pages/Earn/Manage.tsx
msgid "Step 1. Get UNI-V2 Liquidity tokens"
msgstr "Vaihe 1. Hanki UNI-V2 likviditeettirahakkeita"
@@ -1806,7 +1823,7 @@ msgstr "Toimitetaan {0} {1} ja {2} {3}"
#: src/components/AccountDetailsV2/TransactionBody.tsx
#: src/components/Header/index.tsx
#: src/components/NavBar/index.tsx
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
#: src/components/swap/SwapHeader.tsx
#: src/pages/Swap/index.tsx
#: src/pages/Swap/index.tsx
@@ -1848,6 +1865,10 @@ msgstr "Vaihdetaan {0} {1} kohteeseen {2} {3}"
msgid "Symbol not found"
msgstr "Symbolia ei löydy"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "TVL"
msgstr "TVL"
#: src/components/Popups/SurveyPopup.tsx
msgid "Take a 10 minute survey to help us improve your experience in the Uniswap app."
msgstr "Vastaa 10 minuutin kyselyyn, jonka avulla voimme parantaa käyttökokemustasi Uniswap-sovelluksessa."
@@ -1962,14 +1983,6 @@ msgstr "Tapahtumaa ei voitu lähettää, koska määräaika on ohi. Tarkista, et
msgid "There is no liquidity data."
msgstr "Likviditeettitietoja ei ole."
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "There was an error fetching your balance"
msgstr "Saldoasi noudettaessa tapahtui virhe"
#: src/components/Tokens/TokenDetails/BalanceSummary.tsx
msgid "There was an error loading your {0} balance"
msgstr "{0} -saldoasi ladattaessa tapahtui virhe"
#: src/components/ConnectedAccountBlocked/index.tsx
msgid "This address is blocked on the Uniswap Labs interface because it is associated with one or more"
msgstr "Tämä osoite on estetty Uniswap Labs -käyttöliittymässä, koska se on liitetty yhteen tai useampaan"
@@ -1994,6 +2007,10 @@ msgstr "Tämä reitti optimoi kokonaistehosi ottamalla huomioon jaetut reitit, u
msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade."
msgstr "Tätä rahaketta ei näy aktiivisissa rahakeluetteloissa. Varmista, että tämä on rahake, jonka haluat vaihtaa."
#: src/components/Tokens/TokenDetails/PriceChart.tsx
msgid "This token doesn't have chart data because it hasn't been traded on Uniswap v3"
msgstr "Tällä tunnuksella ei ole kaaviotietoja, koska sillä ei ole vaihdettu Uniswap v3:ssa"
#: src/components/SearchModal/BlockedToken.tsx
msgid "This token is not supported in the Uniswap Labs app"
msgstr "Uniswap Labs -sovellus ei tue tätä tunnusta"
@@ -2033,23 +2050,20 @@ msgid "Token not supported"
msgstr "Tunnusta ei tueta"
#: src/components/Header/index.tsx
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
#: src/components/NavBar/index.tsx
#: src/components/SearchModal/Manage.tsx
msgid "Tokens"
msgstr "Rahakkeet"
#: src/components/SearchModal/CurrencyList/index.tsx
msgid "Tokens from inactive lists. Import specific tokens below or click Manage to activate more lists."
msgstr "Rahakkeita passiivisista luetteloista. Tuo tietyt rahakkeet alla tai aktivoi lisää luetteloita napsauttamalla \"Hallitse\"."
#: src/pages/Pool/CTACards.tsx
msgid "Top pools"
msgstr "Parhaat poolit"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "Total Value Locked"
msgstr "Kokonaisarvo lukittu"
#: src/pages/Tokens/index.tsx
#: src/pages/Tokens/index.tsx
msgid "Top tokens on Uniswap"
msgstr "Suosituimmat tunnukset Uniswapissa"
#: src/components/earn/PoolCard.tsx
msgid "Total deposited"
@@ -2059,6 +2073,10 @@ msgstr "Talletettu yhteensä"
msgid "Total deposits"
msgstr "Talletuksia yhteensä"
#: src/components/Tokens/TokenTable/TokenRow.tsx
msgid "Total value locked (TVL) is the amount of the asset thats currently in a Uniswap v3 liquidity pool."
msgstr "Lukittu kokonaisarvo (TVL) on Uniswap v3 -likviditeettipoolissa tällä hetkellä olevan omaisuuden määrä."
#: src/components/swap/RouterLabel.tsx
msgid "Trade Route"
msgstr "Kauppareitti"
@@ -2263,10 +2281,18 @@ msgstr "V3 {0} Hinta:"
msgid "View accrued fees and analytics<0>↗</0>"
msgstr "Näytä kertyneet palkkiot ja analytiikka<0>↗</0>"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
msgid "View and sell NFTs"
msgstr "Tarkastele ja myy NFT:itä"
#: src/components/SearchModal/ManageLists.tsx
msgid "View list"
msgstr "Näytä luettelo"
#: src/components/NavBar/MenuDropdown.tsx
msgid "View more analytics"
msgstr "Katso lisää analytiikkaa"
#: src/components/TransactionConfirmationModal/index.tsx
#: src/pages/CreateProposal/ProposalSubmissionModal.tsx
msgid "View on Etherscan"
@@ -2278,10 +2304,6 @@ msgstr "Näkymä Etherscanissa"
msgid "View on Explorer"
msgstr "Näytä Explorerissa"
#: src/components/NavBar/MenuDropdown.tsx
msgid "View token analytics"
msgstr "Näytä token-analytiikka"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
@@ -2291,6 +2313,10 @@ msgstr "Näytä token-analytiikka"
msgid "View transaction on Explorer"
msgstr "Näytä tapahtuma Explorerissa"
#: src/components/Tokens/TokenTable/TokenRow.tsx
msgid "Volume is the amount of the asset that has been traded on Uniswap v3 during the selected time frame."
msgstr "Volyymi on omaisuuden määrä, jolla on vaihdettu Uniswap v3:ssa valitun ajanjakson aikana."
#: src/components/Header/index.tsx
msgid "Vote"
msgstr "Äänestä"
@@ -2472,10 +2498,6 @@ msgstr "Sinulla ei ole vielä likviditeettiä tässä poolissa."
msgid "You have no favorited tokens"
msgstr "Sinulla ei ole suosikkimerkkejä"
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "You may have lost your network connection, or {label} might be down right now."
msgstr "Olet saattanut menettää verkkoyhteytesi tai {label} voi olla katkennut juuri nyt."
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "You may have lost your network connection."
msgstr "Olet ehkä menettänyt verkkoyhteytesi."
@@ -2517,9 +2539,9 @@ msgstr "Sinun V2-likviditeettisi"
msgid "Your active V3 liquidity positions will appear here."
msgstr "Aktiiviset V3-likviditeettipositiosi näkyvät täällä."
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "Your balances by network"
msgstr "Saldosi verkon mukaan"
#: src/components/Tokens/TokenDetails/BalanceSummary.tsx
msgid "Your balance"
msgstr "Tasapainosi"
#: src/pages/Pool/index.tsx
msgid "Your connected network is unsupported."
@@ -2608,6 +2630,11 @@ msgstr "Tapahtumasi näkyvät täällä..."
msgid "Your unclaimed UNI"
msgstr "Lunastamattomat UNIsi"
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
msgid "Your {0} balance"
msgstr "{0} -saldosi"
#: src/components/swap/AdvancedSwapDetails.tsx
msgid "after slippage"
msgstr "liukumisen jälkeen"
@@ -2684,8 +2711,8 @@ msgid "{0, plural, =1 {Import token} other {Import tokens}}"
msgstr "{0, plural, =1 {Tuo tunnus} other {Tuo tunnuksia}}"
#: src/constants/tokenSafety.tsx
msgid "{0, plural, =1 {This token isn't verified} other {These tokens aren't verified}}"
msgstr "{0, plural, =1 {Tätä tunnusta ei ole vahvistettu} other {Näitä tunnuksia ei ole vahvistettu}}"
msgid "{0, plural, =1 {This token isn't verified.} other {These tokens aren't verified.}}"
msgstr "{0, plural, =1 {Tätä tunnusta ei ole vahvistettu.} other {Näitä tunnuksia ei ole vahvistettu.}}"
#: src/constants/tokenSafety.tsx
msgid "{0, plural, =1 {You can't trade this token using the Uniswap App.} other {You can't trade these tokens using the Uniswap App.}}"
@@ -2758,10 +2785,6 @@ msgstr "{0} UNI-V2 LP -rahaketta saatavilla"
msgid "{0} Votes"
msgstr "{0} ääntä"
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "{0} all balances"
msgstr "{0} kaikki saldot"
#: src/components/PositionPreview/index.tsx
#: src/components/PositionPreview/index.tsx
#: src/components/PositionPreview/index.tsx
@@ -2839,6 +2862,10 @@ msgstr "{USER_AMOUNT} UNI"
msgid "{activeTokensOnThisChain} tokens"
msgstr "{activeTokensOnThisChain} rahaketta"
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "{label} might be down right now, or you may have lost your network connection."
msgstr "{label} saattaa olla poissa juuri nyt tai olet ehkä menettänyt verkkoyhteytesi."
#: src/components/NetworkAlert/NetworkAlert.tsx
msgid "{label} token bridge"
msgstr "{label} token silta"

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: uniswap-interface\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2022-09-21 21:05\n"
"PO-Revision-Date: 2022-10-11 02:57\n"
"Last-Translator: \n"
"Language: fr_FR\n"
"Language-Team: French\n"
@@ -21,10 +21,6 @@ msgstr ""
msgid "$-"
msgstr "$-"
#: src/components/CurrencyInputPanel/FiatValue.tsx
msgid "$<0/>"
msgstr "<0/>$"
#: src/components/earn/PoolCard.tsx
#: src/components/swap/GasEstimateBadge.tsx
#: src/pages/Pool/PositionPage.tsx
@@ -63,6 +59,10 @@ msgstr "0 UNI / semaine"
msgid "24H volume"
msgstr "Volume 24h"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "24H volume is the amount of the asset that has been traded on Uniswap v3 during the past 24 hours."
msgstr "Le volume 24H est le montant de l'actif qui a été échangé sur Uniswap v3 au cours des dernières 24 heures."
#: src/pages/RemoveLiquidity/V3.tsx
msgid "25%"
msgstr "25%"
@@ -240,7 +240,7 @@ msgid "Amount"
msgstr "Montant"
#: src/components/Tokens/TokenTable/TokenTable.tsx
msgid "An error occured loading tokens. Please try again."
msgid "An error occurred loading tokens. Please try again."
msgstr "Une erreur s'est produite lors du chargement des jetons. Veuillez réessayer."
#: src/utils/swapErrorToUserReadableMessage.tsx
@@ -373,11 +373,14 @@ msgstr "En ajoutant de la liquidité, vous gagnerez 0,3 % de toutes les transact
msgid "By adding this list you are implicitly trusting that the data is correct. Anyone can create a list, including creating fake versions of existing lists and lists that claim to represent projects that do not have one."
msgstr "En ajoutant cette liste, vous avez implicitement confiance dans le fait que les données sont correctes. N'importe qui peut créer une liste, y compris la création de fausses versions de listes et de listes existantes qui prétendent représenter des projets qui n'en ont pas."
#: src/components/WalletModal/index.tsx
#: src/components/WalletModal/index.tsx
msgid "By connecting a wallet, you agree to Uniswap Labs <0>Terms of Service</0> and acknowledge that you have read and understand the Uniswap <1>Protocol Disclaimer</1>."
msgstr "By connecting a wallet, you agree to Uniswap Labs <0>Terms of Service</0> and acknowledge that you have read and understand the Uniswap <1>Protocol Disclaimer</1>."
#: src/components/WalletModal/index.tsx
msgid "By connecting a wallet, you agree to Uniswap Labs <0>Terms of Service</0> and consent to its <1>Privacy Policy</1>."
msgstr "En connectant un portefeuille, vous acceptez les <0>Conditions d'utilisation</0> d'Uniswap Labs et consentez à sa <1>Politique de confidentialité</1>."
#: src/pages/Vote/styled.tsx
msgid "Canceled"
msgstr "Annulé"
@@ -605,11 +608,13 @@ msgid "Contract address"
msgstr "Adresse du contrat"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
#: src/nft/components/profile/view/ProfileAccountDetails.tsx
#: src/theme/components.tsx
msgid "Copied!"
msgstr "Copié !"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
#: src/nft/components/profile/view/ProfileAccountDetails.tsx
msgid "Copy"
msgstr "Copie"
@@ -889,10 +894,6 @@ msgstr "L'exécution de cette proposition mettra en place les données d'appel e
msgid "Execution Submitted"
msgstr "Exécution soumise"
#: src/components/SearchModal/CurrencyList/index.tsx
msgid "Expanded results from inactive Token Lists"
msgstr "Résultats étendus des listes de jetons inactifs"
#: src/components/swap/AdvancedSwapDetails.tsx
msgid "Expected Output"
msgstr "Production attendue"
@@ -913,10 +914,9 @@ msgstr "Expiré"
msgid "Explore"
msgstr "Explorer"
#: src/pages/Tokens/index.tsx
#: src/pages/Tokens/index.tsx
msgid "Explore Tokens"
msgstr "Explorer les jetons"
#: src/components/Tokens/TokensBanner.tsx
msgid "Explore Top Tokens on Uniswap"
msgstr "Explorez les meilleurs jetons sur Uniswap"
#: src/pages/Pool/CTACards.tsx
msgid "Explore Uniswap Analytics."
@@ -1130,6 +1130,10 @@ msgstr "Thème de la lumière"
msgid "Light theme"
msgstr "Thème lumière"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Links"
msgstr "Liens"
#: src/components/claim/ClaimModal.tsx
#: src/pages/Pool/PositionPage.tsx
msgid "Liquidity"
@@ -1262,6 +1266,11 @@ msgstr "Min :"
msgid "Minimum received"
msgstr "Minimum reçu"
#: src/components/Tokens/TokenDetails/PriceChart.tsx
#: src/components/Tokens/TokenDetails/PriceChart.tsx
msgid "Missing chart data"
msgstr "Données de graphique manquantes"
#: src/lib/hooks/swap/useSwapCallback.tsx
msgid "Missing dependencies"
msgstr "Dépendances manquantes"
@@ -1270,7 +1279,7 @@ msgstr "Dépendances manquantes"
msgid "More"
msgstr "En savoir plus"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "NFT Collections"
msgstr "Collections NFT"
@@ -1298,6 +1307,10 @@ msgstr "Les frais de réseau dépassent 50 % du montant du swap !"
msgid "New Position"
msgstr "Nouvelle position"
#: src/nft/components/profile/view/EmptyWalletContent.tsx
msgid "No NFTs in"
msgstr "Pas de NFT dans"
#: src/pages/MigrateV2/index.tsx
msgid "No V2 Liquidity found."
msgstr "Aucune liquidité V2 trouvée."
@@ -1339,7 +1352,7 @@ msgstr "Aucune information de jeton disponible"
msgid "No tokens found"
msgstr "Aucun jeton trouvé"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "No tokens found."
msgstr "Aucun jeton trouvé."
@@ -1468,11 +1481,11 @@ msgstr "Récupéré {0} :"
msgid "Pools"
msgstr "Piscines"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Popular NFT collections"
msgstr "Collections NFT populaires"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Popular tokens"
msgstr "Jetons populaires"
@@ -1577,10 +1590,6 @@ msgstr "File d'attente"
msgid "Rates"
msgstr "Tarifs"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Read more"
msgstr "Lire la suite"
#: src/pages/Earn/index.tsx
msgid "Read more about UNI"
msgstr "En savoir plus sur UNI"
@@ -1601,7 +1610,7 @@ msgstr "En savoir plus sur les actifs non pris en charge"
msgid "Recent Transactions"
msgstr "Transactions récentes"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Recent searches"
msgstr "Recherches récentes"
@@ -1719,10 +1728,6 @@ msgstr "Soi-même"
msgid "Self Delegate"
msgstr "Auto-délégué"
#: src/components/NavBar/MenuDropdown.tsx
msgid "Sell NFTs"
msgstr "Vendre des NFT"
#: src/pages/AddLiquidity/index.tsx
#: src/pages/AddLiquidity/index.tsx
#: src/pages/MigrateV2/MigrateV2Pair.tsx
@@ -1755,6 +1760,10 @@ msgstr "Afficher annulé"
msgid "Show closed positions"
msgstr "Afficher les positions fermées"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Show more"
msgstr "Montre plus"
#: src/pages/RemoveLiquidity/index.tsx
msgid "Simple"
msgstr "Simple"
@@ -1771,6 +1780,14 @@ msgstr "Certains actifs ne sont pas disponibles via cette interface parce qu'ils
msgid "Something went wrong"
msgstr "Un problème est survenu"
#: src/components/Tokens/TokensBanner.tsx
msgid "Sort and filter assets across networks on the new Tokens page."
msgstr "Triez et filtrez les actifs sur les réseaux sur la nouvelle page Tokens."
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "Stats"
msgstr "Statistiques"
#: src/pages/Earn/Manage.tsx
msgid "Step 1. Get UNI-V2 Liquidity tokens"
msgstr "Étape 1. Obtenir des jetons de liquidité UNI-V2"
@@ -1806,7 +1823,7 @@ msgstr "Approvisionnement {0} {1} et {2} {3}"
#: src/components/AccountDetailsV2/TransactionBody.tsx
#: src/components/Header/index.tsx
#: src/components/NavBar/index.tsx
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
#: src/components/swap/SwapHeader.tsx
#: src/pages/Swap/index.tsx
#: src/pages/Swap/index.tsx
@@ -1848,6 +1865,10 @@ msgstr "Échange de {0} {1} contre {2} {3}"
msgid "Symbol not found"
msgstr "Symbole introuvable"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "TVL"
msgstr "TVL"
#: src/components/Popups/SurveyPopup.tsx
msgid "Take a 10 minute survey to help us improve your experience in the Uniswap app."
msgstr "Répondez à un sondage de 10 minutes pour nous aider à améliorer votre expérience dans l'application Uniswap."
@@ -1962,14 +1983,6 @@ msgstr "La transaction n'a pas pu être envoyée car la date limite est passée.
msgid "There is no liquidity data."
msgstr "Il n'y a pas de données de liquidité."
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "There was an error fetching your balance"
msgstr "Une erreur s'est produite lors de la récupération de votre solde"
#: src/components/Tokens/TokenDetails/BalanceSummary.tsx
msgid "There was an error loading your {0} balance"
msgstr "Une erreur s'est produite lors du chargement de votre solde {0}"
#: src/components/ConnectedAccountBlocked/index.tsx
msgid "This address is blocked on the Uniswap Labs interface because it is associated with one or more"
msgstr "Cette adresse est bloquée sur l'interface Uniswap Labs car elle est associée à un ou plusieurs"
@@ -1994,6 +2007,10 @@ msgstr "Cet itinéraire optimise votre production totale en tenant compte des it
msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade."
msgstr "Ce jeton n'apparaît pas sur la ou les listes de jetons actifs. Assurez-vous qu'il s'agit du jeton que vous souhaitez échanger."
#: src/components/Tokens/TokenDetails/PriceChart.tsx
msgid "This token doesn't have chart data because it hasn't been traded on Uniswap v3"
msgstr "Ce jeton n'a pas de données de graphique car il n'a pas été échangé sur Uniswap v3"
#: src/components/SearchModal/BlockedToken.tsx
msgid "This token is not supported in the Uniswap Labs app"
msgstr "Ce jeton n'est pas pris en charge dans l'application Uniswap Labs"
@@ -2033,23 +2050,20 @@ msgid "Token not supported"
msgstr "Jeton non pris en charge"
#: src/components/Header/index.tsx
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
#: src/components/NavBar/index.tsx
#: src/components/SearchModal/Manage.tsx
msgid "Tokens"
msgstr "Jetons"
#: src/components/SearchModal/CurrencyList/index.tsx
msgid "Tokens from inactive lists. Import specific tokens below or click Manage to activate more lists."
msgstr "Jetons de listes inactives. Importez des jetons spécifiques ci-dessous ou cliquez sur Gérer pour activer plus de listes."
#: src/pages/Pool/CTACards.tsx
msgid "Top pools"
msgstr "Pools du haut"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "Total Value Locked"
msgstr "Valeur totale verrouillée"
#: src/pages/Tokens/index.tsx
#: src/pages/Tokens/index.tsx
msgid "Top tokens on Uniswap"
msgstr "Meilleurs jetons sur Uniswap"
#: src/components/earn/PoolCard.tsx
msgid "Total deposited"
@@ -2059,6 +2073,10 @@ msgstr "Total déposé"
msgid "Total deposits"
msgstr "Total des dépôts"
#: src/components/Tokens/TokenTable/TokenRow.tsx
msgid "Total value locked (TVL) is the amount of the asset thats currently in a Uniswap v3 liquidity pool."
msgstr "La valeur totale verrouillée (TVL) est le montant de l'actif qui se trouve actuellement dans un pool de liquidités Uniswap v3."
#: src/components/swap/RouterLabel.tsx
msgid "Trade Route"
msgstr "Route commerciale"
@@ -2263,10 +2281,18 @@ msgstr "Prix V3 {0} :"
msgid "View accrued fees and analytics<0>↗</0>"
msgstr "Voir les frais et les analyses accumulés<0>↗</0>"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
msgid "View and sell NFTs"
msgstr "Afficher et vendre des NFT"
#: src/components/SearchModal/ManageLists.tsx
msgid "View list"
msgstr "Voir la liste"
#: src/components/NavBar/MenuDropdown.tsx
msgid "View more analytics"
msgstr "Voir plus d'analyses"
#: src/components/TransactionConfirmationModal/index.tsx
#: src/pages/CreateProposal/ProposalSubmissionModal.tsx
msgid "View on Etherscan"
@@ -2278,10 +2304,6 @@ msgstr "Voir sur Etherscan"
msgid "View on Explorer"
msgstr "Voir sur Explorer"
#: src/components/NavBar/MenuDropdown.tsx
msgid "View token analytics"
msgstr "Afficher l'analyse des jetons"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
@@ -2291,6 +2313,10 @@ msgstr "Afficher l'analyse des jetons"
msgid "View transaction on Explorer"
msgstr "Voir la transaction sur Explorer"
#: src/components/Tokens/TokenTable/TokenRow.tsx
msgid "Volume is the amount of the asset that has been traded on Uniswap v3 during the selected time frame."
msgstr "Le volume est le montant de l'actif qui a été échangé sur Uniswap v3 pendant la période sélectionnée."
#: src/components/Header/index.tsx
msgid "Vote"
msgstr "Voter"
@@ -2472,10 +2498,6 @@ msgstr "Vous n'avez pas encore de liquidités dans ce pool."
msgid "You have no favorited tokens"
msgstr "Vous n'avez pas de jetons favoris"
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "You may have lost your network connection, or {label} might be down right now."
msgstr "Vous avez peut-être perdu votre connexion réseau, ou {label} peut-être en panne en ce moment."
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "You may have lost your network connection."
msgstr "Vous avez peut-être perdu votre connexion réseau."
@@ -2517,9 +2539,9 @@ msgstr "Votre liquidité V2"
msgid "Your active V3 liquidity positions will appear here."
msgstr "Vos positions de liquidité V3 actives apparaîtront ici."
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "Your balances by network"
msgstr "Vos soldes par réseau"
#: src/components/Tokens/TokenDetails/BalanceSummary.tsx
msgid "Your balance"
msgstr "Votre solde"
#: src/pages/Pool/index.tsx
msgid "Your connected network is unsupported."
@@ -2608,6 +2630,11 @@ msgstr "Vos transactions apparaîtront ici..."
msgid "Your unclaimed UNI"
msgstr "Votre UNI non réclamé"
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
msgid "Your {0} balance"
msgstr "Votre solde {0}"
#: src/components/swap/AdvancedSwapDetails.tsx
msgid "after slippage"
msgstr "après glissement"
@@ -2684,8 +2711,8 @@ msgid "{0, plural, =1 {Import token} other {Import tokens}}"
msgstr "{0, plural, =1 {Importer le jeton } other {Importez des jetons }}"
#: src/constants/tokenSafety.tsx
msgid "{0, plural, =1 {This token isn't verified} other {These tokens aren't verified}}"
msgstr "{0, plural, =1 {Ce jeton n'est pas vérifié} other {Ces tokens ne sont pas vérifiés}}"
msgid "{0, plural, =1 {This token isn't verified.} other {These tokens aren't verified.}}"
msgstr "{0, plural, =1 {Ce jeton n'est pas vérifié.} other {Ces jetons ne sont pas vérifiés.}}"
#: src/constants/tokenSafety.tsx
msgid "{0, plural, =1 {You can't trade this token using the Uniswap App.} other {You can't trade these tokens using the Uniswap App.}}"
@@ -2758,10 +2785,6 @@ msgstr "{0} jetons UNI-V2 LP disponibles"
msgid "{0} Votes"
msgstr "{0} Votes"
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "{0} all balances"
msgstr "{0} tous les soldes"
#: src/components/PositionPreview/index.tsx
#: src/components/PositionPreview/index.tsx
#: src/components/PositionPreview/index.tsx
@@ -2839,6 +2862,10 @@ msgstr "{USER_AMOUNT} UNI"
msgid "{activeTokensOnThisChain} tokens"
msgstr "{activeTokensOnThisChain} jetons"
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "{label} might be down right now, or you may have lost your network connection."
msgstr "{label} est peut-être en panne en ce moment ou vous avez peut-être perdu votre connexion réseau."
#: src/components/NetworkAlert/NetworkAlert.tsx
msgid "{label} token bridge"
msgstr "{label} jeton pont"

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: uniswap-interface\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2022-09-21 21:05\n"
"PO-Revision-Date: 2022-10-11 02:57\n"
"Last-Translator: \n"
"Language: he_IL\n"
"Language-Team: Hebrew\n"
@@ -21,10 +21,6 @@ msgstr ""
msgid "$-"
msgstr "$-"
#: src/components/CurrencyInputPanel/FiatValue.tsx
msgid "$<0/>"
msgstr "<0/>דולר"
#: src/components/earn/PoolCard.tsx
#: src/components/swap/GasEstimateBadge.tsx
#: src/pages/Pool/PositionPage.tsx
@@ -63,6 +59,10 @@ msgstr "0 UNI לשבוע"
msgid "24H volume"
msgstr "נפח 24 שעות"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "24H volume is the amount of the asset that has been traded on Uniswap v3 during the past 24 hours."
msgstr "נפח 24 שעות הוא סכום הנכס שנסחר ב-Uniswap v3 במהלך 24 השעות האחרונות."
#: src/pages/RemoveLiquidity/V3.tsx
msgid "25%"
msgstr "25%"
@@ -240,7 +240,7 @@ msgid "Amount"
msgstr "כמות"
#: src/components/Tokens/TokenTable/TokenTable.tsx
msgid "An error occured loading tokens. Please try again."
msgid "An error occurred loading tokens. Please try again."
msgstr "אירעה שגיאה בטעינת אסימונים. בבקשה נסה שוב."
#: src/utils/swapErrorToUserReadableMessage.tsx
@@ -373,11 +373,14 @@ msgstr "על ידי הוספת נזילות תרוויח 0.3% מכלל העסק
msgid "By adding this list you are implicitly trusting that the data is correct. Anyone can create a list, including creating fake versions of existing lists and lists that claim to represent projects that do not have one."
msgstr "על ידי הוספת רשימה זו אתה סומך באופן מרומז על כך שהנתונים נכונים. כל אחד יכול ליצור רשימה, כולל יצירת גרסאות מזויפות של רשימות קיימות ורשימות המתיימרות לייצג פרויקטים שאין להם."
#: src/components/WalletModal/index.tsx
#: src/components/WalletModal/index.tsx
msgid "By connecting a wallet, you agree to Uniswap Labs <0>Terms of Service</0> and acknowledge that you have read and understand the Uniswap <1>Protocol Disclaimer</1>."
msgstr "על ידי חיבור ארנק, אתה מסכים לתנאי השירות</0> <0>ומאשר שקראת והבנת את כתב ויתור פרוטוקול <1></1>."
#: src/components/WalletModal/index.tsx
msgid "By connecting a wallet, you agree to Uniswap Labs <0>Terms of Service</0> and consent to its <1>Privacy Policy</1>."
msgstr "על ידי חיבור ארנק, אתה מסכים לתנאי השירות</0> של Uniswap Labs <0>ומסכים למדיניות הפרטיות <1>שלה</1>."
#: src/pages/Vote/styled.tsx
msgid "Canceled"
msgstr "מבוטל"
@@ -605,11 +608,13 @@ msgid "Contract address"
msgstr "כתובת החוזה"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
#: src/nft/components/profile/view/ProfileAccountDetails.tsx
#: src/theme/components.tsx
msgid "Copied!"
msgstr "מוּעֲתָק!"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
#: src/nft/components/profile/view/ProfileAccountDetails.tsx
msgid "Copy"
msgstr "עותק"
@@ -889,10 +894,6 @@ msgstr "ביצוע הצעה זו יחוקק את נתוני השיחות על ה
msgid "Execution Submitted"
msgstr "ביצוע הוגש"
#: src/components/SearchModal/CurrencyList/index.tsx
msgid "Expanded results from inactive Token Lists"
msgstr "תוצאות מורחבות מרשימות אסימון לא פעילות"
#: src/components/swap/AdvancedSwapDetails.tsx
msgid "Expected Output"
msgstr "פלט צפוי"
@@ -913,10 +914,9 @@ msgstr "לא בתוקף"
msgid "Explore"
msgstr "לַחקוֹר"
#: src/pages/Tokens/index.tsx
#: src/pages/Tokens/index.tsx
msgid "Explore Tokens"
msgstr "חקור אסימונים"
#: src/components/Tokens/TokensBanner.tsx
msgid "Explore Top Tokens on Uniswap"
msgstr "חקור את האסימונים המובילים ב-Uniswap"
#: src/pages/Pool/CTACards.tsx
msgid "Explore Uniswap Analytics."
@@ -1130,6 +1130,10 @@ msgstr "נושא קל"
msgid "Light theme"
msgstr "נושא קליל"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Links"
msgstr "קישורים"
#: src/components/claim/ClaimModal.tsx
#: src/pages/Pool/PositionPage.tsx
msgid "Liquidity"
@@ -1262,6 +1266,11 @@ msgstr "דקה:"
msgid "Minimum received"
msgstr "מינימום שהתקבל"
#: src/components/Tokens/TokenDetails/PriceChart.tsx
#: src/components/Tokens/TokenDetails/PriceChart.tsx
msgid "Missing chart data"
msgstr "חסרים נתוני תרשים"
#: src/lib/hooks/swap/useSwapCallback.tsx
msgid "Missing dependencies"
msgstr "חסרות תלות"
@@ -1270,7 +1279,7 @@ msgstr "חסרות תלות"
msgid "More"
msgstr "יותר"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "NFT Collections"
msgstr "אוספי NFT"
@@ -1298,6 +1307,10 @@ msgstr "עמלות הרשת עולות על 50% מסכום ההחלפה!"
msgid "New Position"
msgstr "עמדה חדשה"
#: src/nft/components/profile/view/EmptyWalletContent.tsx
msgid "No NFTs in"
msgstr "אין NFTs בפנים"
#: src/pages/MigrateV2/index.tsx
msgid "No V2 Liquidity found."
msgstr "לא נמצאה נזילות V2."
@@ -1339,7 +1352,7 @@ msgstr "אין מידע אסימון זמין"
msgid "No tokens found"
msgstr "לא נמצאו אסימונים"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "No tokens found."
msgstr "לא נמצאו אסימונים."
@@ -1468,11 +1481,11 @@ msgstr "מאוגד {0}:"
msgid "Pools"
msgstr "בריכות"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Popular NFT collections"
msgstr "אוספי NFT פופולריים"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Popular tokens"
msgstr "אסימונים פופולריים"
@@ -1577,10 +1590,6 @@ msgstr "הִזדַנְבוּת"
msgid "Rates"
msgstr "תעריפים"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Read more"
msgstr "קרא עוד"
#: src/pages/Earn/index.tsx
msgid "Read more about UNI"
msgstr "קרא עוד על UNI"
@@ -1601,7 +1610,7 @@ msgstr "קרא עוד על נכסים שאינם נתמכים"
msgid "Recent Transactions"
msgstr "תנועות אחרונות"
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
msgid "Recent searches"
msgstr "חיפושים אחרונים"
@@ -1719,10 +1728,6 @@ msgstr "עצמי"
msgid "Self Delegate"
msgstr "נציג עצמי"
#: src/components/NavBar/MenuDropdown.tsx
msgid "Sell NFTs"
msgstr "למכור NFTs"
#: src/pages/AddLiquidity/index.tsx
#: src/pages/AddLiquidity/index.tsx
#: src/pages/MigrateV2/MigrateV2Pair.tsx
@@ -1755,6 +1760,10 @@ msgstr "ההצגה בוטלה"
msgid "Show closed positions"
msgstr "הראה עמדות סגורות"
#: src/components/Tokens/TokenDetails/About.tsx
msgid "Show more"
msgstr "להראות יותר"
#: src/pages/RemoveLiquidity/index.tsx
msgid "Simple"
msgstr "פָּשׁוּט"
@@ -1771,6 +1780,14 @@ msgstr "חלק מהנכסים אינם זמינים דרך ממשק זה מכי
msgid "Something went wrong"
msgstr "משהו השתבש"
#: src/components/Tokens/TokensBanner.tsx
msgid "Sort and filter assets across networks on the new Tokens page."
msgstr "מיין וסנן נכסים על פני רשתות בדף האסימונים החדש."
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "Stats"
msgstr "סטטיסטיקות"
#: src/pages/Earn/Manage.tsx
msgid "Step 1. Get UNI-V2 Liquidity tokens"
msgstr "שלב 1. קבל תווי נזילות של UNI-V2"
@@ -1806,7 +1823,7 @@ msgstr "אספקת {0} {1} ו {2} {3}"
#: src/components/AccountDetailsV2/TransactionBody.tsx
#: src/components/Header/index.tsx
#: src/components/NavBar/index.tsx
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
#: src/components/swap/SwapHeader.tsx
#: src/pages/Swap/index.tsx
#: src/pages/Swap/index.tsx
@@ -1848,6 +1865,10 @@ msgstr "החלפת {0} {1} ב- {2} {3}"
msgid "Symbol not found"
msgstr "הסמל לא נמצא"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "TVL"
msgstr "TVL"
#: src/components/Popups/SurveyPopup.tsx
msgid "Take a 10 minute survey to help us improve your experience in the Uniswap app."
msgstr "השתתף בסקר של 10 דקות כדי לעזור לנו לשפר את החוויה שלך באפליקציית Uniswap."
@@ -1962,14 +1983,6 @@ msgstr "לא ניתן היה לשלוח את העסקה מכיוון שהמוע
msgid "There is no liquidity data."
msgstr "אין נתוני נזילות."
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "There was an error fetching your balance"
msgstr "אירעה שגיאה באחזור היתרה שלך"
#: src/components/Tokens/TokenDetails/BalanceSummary.tsx
msgid "There was an error loading your {0} balance"
msgstr "אירעה שגיאה בטעינת יתרת ה {0} שלך"
#: src/components/ConnectedAccountBlocked/index.tsx
msgid "This address is blocked on the Uniswap Labs interface because it is associated with one or more"
msgstr "כתובת זו חסומה בממשק Uniswap Labs מכיוון שהיא משויכת לאחד או יותר"
@@ -1994,6 +2007,10 @@ msgstr "מסלול זה מייעל את התפוקה הכוללת שלך על י
msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade."
msgstr "אסימון זה אינו מופיע ברשימות האסימונים הפעילות. ודא שזה האסימון שאתה רוצה לסחור בו."
#: src/components/Tokens/TokenDetails/PriceChart.tsx
msgid "This token doesn't have chart data because it hasn't been traded on Uniswap v3"
msgstr "לטוקן זה אין נתוני תרשים מכיוון שהוא לא נסחר ב-Uniswap v3"
#: src/components/SearchModal/BlockedToken.tsx
msgid "This token is not supported in the Uniswap Labs app"
msgstr "אסימון זה אינו נתמך באפליקציית Uniswap Labs"
@@ -2033,23 +2050,20 @@ msgid "Token not supported"
msgstr "אסימון אינו נתמך"
#: src/components/Header/index.tsx
#: src/components/NavBar/SearchBar.tsx
#: src/components/NavBar/SearchBarDropdown.tsx
#: src/components/NavBar/index.tsx
#: src/components/SearchModal/Manage.tsx
msgid "Tokens"
msgstr "אסימונים"
#: src/components/SearchModal/CurrencyList/index.tsx
msgid "Tokens from inactive lists. Import specific tokens below or click Manage to activate more lists."
msgstr "אסימונים מרשימות לא פעילות. ייבא אסימונים ספציפיים למטה או לחץ על נהל כדי להפעיל רשימות נוספות."
#: src/pages/Pool/CTACards.tsx
msgid "Top pools"
msgstr "בריכות מובילות"
#: src/components/Tokens/TokenDetails/StatsSection.tsx
msgid "Total Value Locked"
msgstr "ערך כולל נעול"
#: src/pages/Tokens/index.tsx
#: src/pages/Tokens/index.tsx
msgid "Top tokens on Uniswap"
msgstr "אסימונים מובילים ב-Uniswap"
#: src/components/earn/PoolCard.tsx
msgid "Total deposited"
@@ -2059,6 +2073,10 @@ msgstr "סה\"כ מה שהופקד"
msgid "Total deposits"
msgstr "סך ההפקדות"
#: src/components/Tokens/TokenTable/TokenRow.tsx
msgid "Total value locked (TVL) is the amount of the asset thats currently in a Uniswap v3 liquidity pool."
msgstr "ערך כולל נעול (TVL) הוא סכום הנכס שנמצא כעת במאגר נזילות של Uniswap v3."
#: src/components/swap/RouterLabel.tsx
msgid "Trade Route"
msgstr "נתיב מסחר"
@@ -2263,10 +2281,18 @@ msgstr "מחיר V3 {0}"
msgid "View accrued fees and analytics<0>↗</0>"
msgstr "צפו בעמלות וניתוחים צבורים <0> ↗</0>"
#: src/components/WalletDropdown/AuthenticatedHeader.tsx
msgid "View and sell NFTs"
msgstr "הצג ומכור NFTs"
#: src/components/SearchModal/ManageLists.tsx
msgid "View list"
msgstr "רשימת צפייה"
#: src/components/NavBar/MenuDropdown.tsx
msgid "View more analytics"
msgstr "הצג ניתוחים נוספים"
#: src/components/TransactionConfirmationModal/index.tsx
#: src/pages/CreateProposal/ProposalSubmissionModal.tsx
msgid "View on Etherscan"
@@ -2278,10 +2304,6 @@ msgstr "מבט על אתרסקאן"
msgid "View on Explorer"
msgstr "צפה ב- Explorer"
#: src/components/NavBar/MenuDropdown.tsx
msgid "View token analytics"
msgstr "הצג ניתוח אסימון"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
@@ -2291,6 +2313,10 @@ msgstr "הצג ניתוח אסימון"
msgid "View transaction on Explorer"
msgstr "צפה בעסקה ב- Explorer"
#: src/components/Tokens/TokenTable/TokenRow.tsx
msgid "Volume is the amount of the asset that has been traded on Uniswap v3 during the selected time frame."
msgstr "נפח הוא סכום הנכס שנסחר ב-Uniswap v3 במהלך מסגרת הזמן שנבחרה."
#: src/components/Header/index.tsx
msgid "Vote"
msgstr "הַצבָּעָה"
@@ -2472,10 +2498,6 @@ msgstr "עדיין אין לך נזילות במאגר זה."
msgid "You have no favorited tokens"
msgstr "אין לך אסימונים מועדפים"
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "You may have lost your network connection, or {label} might be down right now."
msgstr "ייתכן שאיבדת את חיבור הרשת שלך, או {label} מושבת כרגע."
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "You may have lost your network connection."
msgstr "יכול להיות שאיבדת את חיבור הרשת שלך."
@@ -2517,9 +2539,9 @@ msgstr "נזילות ה- V2 שלך"
msgid "Your active V3 liquidity positions will appear here."
msgstr "עמדות הנזילות הפעילות V3 שלך יופיעו כאן."
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "Your balances by network"
msgstr "היתרות שלך לפי רשת"
#: src/components/Tokens/TokenDetails/BalanceSummary.tsx
msgid "Your balance"
msgstr "האיזון שלך"
#: src/pages/Pool/index.tsx
msgid "Your connected network is unsupported."
@@ -2608,6 +2630,11 @@ msgstr "העסקאות שלך יופיעו כאן ..."
msgid "Your unclaimed UNI"
msgstr "ה-UNI שלך לא נדרש"
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
#: src/components/Tokens/TokenDetails/MobileBalanceSummaryFooter.tsx
msgid "Your {0} balance"
msgstr "יתרת ה {0} שלך"
#: src/components/swap/AdvancedSwapDetails.tsx
msgid "after slippage"
msgstr "לאחר החלקה"
@@ -2684,8 +2711,8 @@ msgid "{0, plural, =1 {Import token} other {Import tokens}}"
msgstr "{0, plural, =1 {ייבוא אסימון} other {ייבוא אסימונים}}"
#: src/constants/tokenSafety.tsx
msgid "{0, plural, =1 {This token isn't verified} other {These tokens aren't verified}}"
msgstr "{0, plural, =1 {אסימון זה אינו מאומת} other {האסימונים האלה אינם מאומתים}}"
msgid "{0, plural, =1 {This token isn't verified.} other {These tokens aren't verified.}}"
msgstr "{0, plural, =1 {האסימון הזה לא מאומת.} other {האסימונים האלה אינם מאומתים.}}"
#: src/constants/tokenSafety.tsx
msgid "{0, plural, =1 {You can't trade this token using the Uniswap App.} other {You can't trade these tokens using the Uniswap App.}}"
@@ -2758,10 +2785,6 @@ msgstr "{0} UNI-V2 LP אסימונים זמינים"
msgid "{0} Votes"
msgstr "{0} הצבעות"
#: src/components/Tokens/TokenDetails/FooterBalanceSummary.tsx
msgid "{0} all balances"
msgstr "{0} כל היתרות"
#: src/components/PositionPreview/index.tsx
#: src/components/PositionPreview/index.tsx
#: src/components/PositionPreview/index.tsx
@@ -2839,6 +2862,10 @@ msgstr "{USER_AMOUNT} UNI"
msgid "{activeTokensOnThisChain} tokens"
msgstr "{activeTokensOnThisChain} אסימונים"
#: src/components/Header/ChainConnectivityWarning.tsx
msgid "{label} might be down right now, or you may have lost your network connection."
msgstr "ייתכן ש {label} מושבת כרגע, או שאיבדת את החיבור לרשת."
#: src/components/NetworkAlert/NetworkAlert.tsx
msgid "{label} token bridge"
msgstr "{label} גשר אסימונים"

Some files were not shown because too many files have changed in this diff Show More