Compare commits

...

87 Commits

Author SHA1 Message Date
Sam Chen
b8829639e9 fix: scroll to top only when pathname changes (#4180) 2022-07-24 14:31:55 -04:00
lynn
62550a4a1f feat: implement swap quote received event (#4165)
* init commit

* add amplitude ts sdk to package.json

* add more comments and documentation

* respond to vm comments

* respond to cmcewen comments

* fix: remove unused constants

* init commit

* adapt to web

* add optional event properties to trace

* correct telemetry to analytics

* init commit

* change telemetry to analytics in doc

* init commit

* fix: respond to cmcewen comments + initialize analytics in app.tsx + add missing return statement

* add element name constant

* init commit

* correct price_impact calculation

* resolve vm comments

* fixes in response to comments

* respond to vm

* use ALL significant digits for token amounts

* init commit

* logged all properties

* create helper function getPriceImpactPercentageNumber

* 4 decimal points for percentages

* price percentage fn

* only log event on FIRST price fetch

* respond to cmcewen comments
2022-07-22 15:50:49 -04:00
lynn
e01f30c0b4 feat: Web 214 implement the main submit swap event (#4061)
* init commit

* add amplitude ts sdk to package.json

* add more comments and documentation

* respond to vm comments

* respond to cmcewen comments

* fix: remove unused constants

* init commit

* adapt to web

* add optional event properties to trace

* correct telemetry to analytics

* init commit

* change telemetry to analytics in doc

* init commit

* fix: respond to cmcewen comments + initialize analytics in app.tsx + add missing return statement

* add element name constant

* init commit

* correct price_impact calculation

* resolve vm comments

* fixes in response to comments

* respond to vm

* use ALL significant digits for token amounts

* create helper function getPriceImpactPercentageNumber

* 4 decimal points for percentages

* change percentage to basis points units
2022-07-21 17:44:34 -04:00
Kaylee George
c60c028dbe feat: add updated theme colors (#4141)
* add colors

* Update settings.json

* Update settings.json

* remove comments

* rename
2022-07-21 12:31:41 -04:00
Vignesh Mohankumar
439fe5e6d4 chore: upgrade cypress (#4161)
* chore: upgrade cypress

* 10.3.1
2022-07-21 12:11:01 -04:00
lynn
e06142e26b feat: implement other swap events part 1 (#4151)
* init commit

* fix prettier errors

* check node env in vercel

* add shouldLogImpression to TraceEvent
2022-07-21 12:09:33 -04:00
github-actions[bot]
1f763a1c7a chore(i18n): new Crowdin translations (#4155)
chore(i18n): synchronize translations from crowdin [skip ci]

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2022-07-21 10:37:05 -04:00
Sam Chen
de6e3747cb refactor: remove unused SwapPoolTabs (#4159)
* chore: clean useless code

* clean unused code
2022-07-21 09:34:18 -04:00
lynn
475af6312f fix: fix swap details expanded not working on local build (#4156)
fix swap details expanded not working
2022-07-20 22:16:27 +00:00
Vignesh Mohankumar
c4c6d7553d build: only test for highest yarn-deduplicate strategy (#4154)
* build: only test for highest yarn-deduplicate strategy

* remove exclusions
2022-07-20 17:33:54 -04:00
cartcrom
0e3c95706e style: updating ui on unsupported network (#4138)
* initial changes

* disabled all swap ui buttons when on unsupported chain

* implementing Cal's requests to change sizing and copy on pools

* updated snapshots

* reverted changed snapshots

* updated unsupported network test

* fixing deprecated colors missing
2022-07-20 17:29:37 -04:00
Daniel James
d5e4e21a79 style: Adds "deprecated_" prefix to all non-theme colors (#4146)
* Add deprecated_ label to white and black

* Add deprecated_ label to text1 through text5

* Add deprecated_ label for bg0 through bg6

* Add deprecated_ prefix to remaining colors

* Add deprecated_ prefix to direct style references

* Add deprecated_ prefix to all remaining colors

* Update link color

* Fix 'deprecated_white' -> theme.deprecated_white

* Update snapshots
2022-07-20 16:18:38 -04:00
Vignesh Mohankumar
4649051843 build: add global jest-styled-components config (#4148)
* add test.config.ts

* don't need per file

* comment

* ts -> js

* rm test.config.js?

* update snapshots

* update jest-styled-components
2022-07-20 15:27:40 -04:00
Jesse
4ba6275b71 fix: add celo gas override (#4147)
fix: add celo gas override to circumvent 'out of gas' error from multicall
2022-07-20 14:48:53 -04:00
Rachel-Eichenberger
17c7a9ee9d fix: increase Polygon gas limit (#3882)
* Update graph link

* Add Gas over ride temp for Polygon

* removal of personal tweaks

* Update index.tsx

* reset to original file

* missing EOL

* Update useClientSideV3Trade.ts

* remove space
2022-07-20 11:59:44 -04:00
Sam Chen
0e36944b23 refactor: clean floating Route (#4144) 2022-07-20 09:47:42 -04:00
Vignesh Mohankumar
5050fe7b06 fix: unused onClickOutside reference (#4140) 2022-07-19 17:54:06 -04:00
Vignesh Mohankumar
80b965f2ca fix: sync chain query parameter (#4019)
* replaceURLChain

* reorder stuff

* don't use usePrevious for previousChainId

* remove the replace param call in promise

* variable names

* comment

* confirm isActive

* wrong place for isActive

* change ret type

* add comments

* check if not previous chain id
2022-07-19 21:42:52 +00:00
Vignesh Mohankumar
417e940c0a test: fix swap test flake (#4135)
* remove all the funky logic

* clear stuff

* uncomment some tests

* remove expert mode tests

* skip these tests again, smh
2022-07-19 16:42:45 -04:00
Sam Chen
c42a5ccf26 chore: access router data with hooks (#4121)
* chore: access router data with hooks

* chore: clean RouteComponentProps

* chore: use children instead of render

* add import
2022-07-19 16:14:16 -04:00
Vignesh Mohankumar
7ba9b1faf6 fix: don't toggle desktop NetworkSelector on click (#4134)
fix: don't NetworkSelector onClick on desktop
2022-07-19 14:35:24 -04:00
Vignesh Mohankumar
5d43d08ff3 build: lock jest-styled-components@7.0.7 (#4132) 2022-07-18 21:42:07 -04:00
lynn
85625d09f0 fix: increase celo blocksPerFetch to 5 to improve interface performance (#4130)
* init commit

* revert yarn.lock changes

* update test snapshots
2022-07-18 18:25:14 -04:00
Vignesh Mohankumar
d85f1f44b9 build: change project name to @uniswap/interface (#4125) 2022-07-18 17:41:32 -04:00
lynn
f41580e43c feat: implement connect wallet category events (#4111)
* init commit

* wallet connected event init commit

* add received_swap_quote event property

* add page context, connect wallet event log

* add received_swap_quote property

* fix typo

* respond to cmcewen comments

* respond to vm comments

* move trace to app.tsx from header

* respond to vm comments
2022-07-18 17:26:29 -04:00
Vignesh Mohankumar
47fe9911fa chore: move prettier, jest-styled-components to devDependencies (#4128)
* change package

* yarn.lock
2022-07-18 16:32:03 -04:00
Noah Zinsmeister
e0f6d82d6c feat: enable 1bp optimism fee tier (#4124)
enable new optimism fee tier
2022-07-18 10:48:28 -04:00
Sam Chen
fb691cf17b fix: catch vibrant failure (#4123)
fix: catch CORS error
2022-07-18 10:05:56 -04:00
Vignesh Mohankumar
f596293b6c build: don't fail cypress on unhandled exception (#4122) 2022-07-18 09:46:31 -04:00
Sam Chen
8012789f69 fix: fixes Popover arrow positioning (#4119)
fix: fix arrow position
2022-07-17 11:22:50 -04:00
Sam Chen
4013743473 chore: upgrades react-router-dom, fixes dev-mode linking (#4115)
* fix: stale route

* fix: add e2e test

* fix: update e2e test
2022-07-17 11:15:04 -04:00
Jesse
e9ef3193ab refactor: remaining changes from the large celo merge (#4088)
* refactor: useUSDCValue -> useStablecoinValue

* refactor: use the isCelo() helper

* refactor: remove unneeded white space
2022-07-15 10:36:19 -04:00
Vignesh Mohankumar
6a1506ade6 build: Revert "build: pause deploy" (#4107)
* Revert "build: pause deploy (#4102)"

This reverts commit 3a1ea3df85.

* prettier
2022-07-14 12:19:23 -04:00
cartcrom
839d4ac8e2 refactor: adding safe getter for ChainInfo (#4110)
* replaced CHAIN_INFO access with a function call
* updated CTACard tests to work with getChainInfo
* updated typechecking, removed console.log
2022-07-14 11:52:37 -04:00
Vignesh Mohankumar
29fdcb80f6 build: upgrade prettier to v2.7.1 (#4109)
* style: prettier based on v2.2

* 2.7.1 instead?

* npx

* ^
2022-07-14 11:28:51 -04:00
lynn
817ea44e8d fix: update styled-components in package.json to latest to remove react invalid hook call warnings (#4103)
* fix warning vig found by updating styled-components

* revert unnecessary yarn.lock changes

* reduce unnecessary changes

* dedup

* manual fix and dedup of yarn.lock

* manually dedup @emotion/is-prop-valid

* update snapshot tests
2022-07-14 10:15:46 -04:00
Vignesh Mohankumar
3a1ea3df85 build: pause deploy (#4102) 2022-07-13 21:24:58 -04:00
Vignesh Mohankumar
2667a897a1 chore(web3-react): fix connectEagerly for MetaMask mobile (#4101)
* chore(web3-react): fix connectEagerly for MetaMask mobile

* fix
2022-07-13 18:20:50 -04:00
lynn
65129604bd chore: upgrade to react 18 (#3992)
* chore: upgrade to react 18

* fix: update tests

* fix: fix lint issues and remove unnecessary react hooks testing library

* fix: add types for stricter typescript checks

* fix: fix additional typescript check issues

* fix: revert to prev commmit

* rebase

* rebase

* fix: fix lint issues and remove unnecessary react hooks testing library

* fix: add types for stricter typescript checks

* fix: fix additional typescript check issues

* rebase

* fix: rebase

* fix

* eslint fix

* fix: package.json changes

* fix: package.json changes

* fix yarn lock

* fix version package.json

* fix: downgrade react-router-dom to original

* fix: undo modification of .github/workflows/release.yaml

* fix: revert cypress testing version update

* rebase

* rebase

* fix: fix lint issues and remove unnecessary react hooks testing library

* fix: add types for stricter typescript checks

* fix: fix additional typescript check issues

* rebase

* chore: upgrade to react 18

* fix: update tests

* fix: fix lint issues and remove unnecessary react hooks testing library

* fix: add types for stricter typescript checks

* fix: fix additional typescript check issues

* fix

* eslint fix

* fix: package.json changes

* fix: package.json changes

* fix yarn lock

* fix version package.json

* fix: downgrade react-router-dom to original

* fix: undo modification of .github/workflows/release.yaml

* fix: revert cypress testing version update

* fix

* fix: error boundary change

* yarn.lock change

* fix: cypress tests finally passing due to zzmp redux multicall fix HOORAY

* undo service worker changes

* build: dedup lockfile

* yarn.lock + lint

* update snapshot tests

* checkpoint

* yarn.lock

* fix: fix type errors during build

* fixes

* fix yarn.lock

* dedup yarn

* fix: import react components explicitly instead of all of react

* dedup

* yarn.lock

* yarn.lock

* dedup

* yarn

* dedup

* dedupe use-sync-external-store

* fix build issues

* dedup use-sync-external-store

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2022-07-13 16:56:09 -04:00
lynn
4e0c9b36a0 feat: implement-page-viewed-event-for-all-main-pages-of-app (#4089)
* init commit: initial constants for pages, implement vote page viewed

* implement swap

* implement pool

* remove charts

* simplify shouldLogImpression
2022-07-13 16:16:42 -04:00
Vignesh Mohankumar
64cb9f3ff2 chore: updates web3-react, adds key for changing connector order (#4085)
* fix connectors changing

* update package

* add connection name

* rename file

* de-dupe

* cb wallet fix

* fix

* yarn change

* log the key

* re-order connections

* memoize the key

* some updates

* rm console

* prevent memory leak

Co-authored-by: Noah Zinsmeister <noahwz@gmail.com>
2022-07-13 15:44:42 -04:00
lynn
cb094a1f4b feat: implement token selector events (#4067)
* init commit

* add amplitude ts sdk to package.json

* add more comments and documentation

* respond to vm comments

* respond to cmcewen comments

* fix: remove unused constants

* init commit

* adapt to web

* add optional event properties to trace

* correct telemetry to analytics

* change telemetry to analytics in doc

* fix: respond to cmcewen comments + initialize analytics in app.tsx + add missing return statement

* init commit

* respond to zzmp comments

* add token selected event

* fixes

* eliminate unnecessary state

* respond to part of zzmp comments

* respond to zzmp comments round 2

* fixes

* respond to zzmp comments

* add imported token event and other fixes

* also log onKeyPress for suggested tokens

* respond to cmcewen comments
2022-07-13 15:43:51 -04:00
Zach Pomerantz
d05fefc231 test: enforce deps deduplication (#4097)
* build: use fewer babel versions

* build: dedup

* test: test deps dedups

* fix: test.yml

* fix: typo

* test: failing

* fix: dedup

* fix: dedup

* test: comment dedup tests

* chore: whitespace
2022-07-13 11:31:19 -04:00
Zach Pomerantz
3e1805a20f build: update caniuse-lite (#4093) 2022-07-13 10:16:21 -04:00
Zach Pomerantz
f58dfe1284 build: upgrade @typescript-eslint (#4095)
build: update @typescript-eslint
2022-07-13 10:14:53 -04:00
github-actions[bot]
f67b7f8b66 chore(i18n): new Crowdin translations (#4090) 2022-07-12 13:09:59 -10:00
Vignesh Mohankumar
869691d43f refactor: wallet specific Option components (#4065)
* refactor: wallet specific Option components

* fix

* fix

* fix coinbase wallet logic

* injected logic

* remove wallet.ts

* install metamask

* move all into InjectedOption

* fix mobile metamask

* wip

* more mocking

* more test fixes

* refactor

* more special casing

* isMetaMask

* simplify components

* fix imports

* fix coinbase wallet

* test fix

* fix connectors changing

* Revert "fix connectors changing"

This reverts commit 2acfe645ca.

* more to typescript logic instead of jsx
2022-07-12 18:33:24 -04:00
lynn
817d808ec5 feat: implement trace framework for analytics (#4060)
* init commit

* add amplitude ts sdk to package.json

* add more comments and documentation

* respond to vm comments

* respond to cmcewen comments

* fix: remove unused constants

* init commit

* adapt to web

* add optional event properties to trace

* correct telemetry to analytics

* change telemetry to analytics in doc

* fix: respond to cmcewen comments + initialize analytics in app.tsx + add missing return statement

* respond to zzmp comments

* fixes

* eliminate unnecessary state

* respond to part of zzmp comments

* respond to zzmp comments round 2

* fixes

* respond to zzmp comments
2022-07-12 16:43:37 -04:00
github-actions[bot]
aee1bce612 chore(i18n): new Crowdin translations (#4084)
chore(i18n): synchronize translations from crowdin [skip ci]

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2022-07-12 13:52:06 -04:00
Bruno Crosier
8b38a9c4e0 fix: add crossplatform prei18n-extract script (#3728)
* fix: 🐛 add crossplatform `prei18n-extract` script

* fix: 🚨 add newline

* Revert "fix: 🐛 add crossplatform `prei18n-extract` script"

This reverts commit 201bd2308a.

* build: 📦 add `shx` as dev dep, use it in `prei18n:extract` script

* fix: 🐛 use platform-specific commands for prei18n-extract
2022-07-12 18:51:24 +02:00
cartcrom
0a115fab17 fix: unsupported chain displays message instead of crash (#4054)
* made initial changes for pools page displaying w/ unsupported chains
* condensed styling
* added chain validation to CTACards and wrote tests for both CTAcards and Pools page
* linted changes
* switched from snapshot to text matching tests
* switched test to use check for text instead of testid
2022-07-12 12:02:02 -04:00
Kaylee George
882147b533 fix: revert "fix button jump on currency panel" (#4083)
fix padding
2022-07-12 11:43:04 -04:00
Jesse
eb06aef199 feat: add support for Celo (#3915)
* feat: Support for Celo

* fix: wrong condition

* combine celo and alfajores lists

* use celo erc20 representation

* fix: refactor infura.ts to networks.ts & add celo to rpc urls

* feature: add celo contract addresses
fix: remove celo from supported gas estimate chains until feature is available

* refactor: useUSDCPrice to useStablecoinPrice
fix: add celo to supported gas estimate chains

* fix: use unique factory address for getting pool address

* fix: darkmode background graident

* fix: removing a comment left behind

* fix: remove bad import

* fix: remove dead link until the Celo is live on info.uniswap.org

* fix: add asset to common bases & minor refactoring

* fix: celo info links point to root info.uniswap.org

* fix: change celo token bridge to portal

* fix: update redux-multicall to latest version

* refactor: for code readability

* fix: celo banner colors & remove unused alternative logo

* fix: change celo token list to hosted version

* fix: update celo banner colors

* fix: move celo to the bottom of the network selector list

* fix: dedup dependencies @uniswap/router-sdk @uniswap/v3-sdk

* fix: refactoring + move Celo above L2s

* fix: update celo contract addresses

* fix: update celo subgraph

* fix: update v3-sdk and smart-order-router versions

* fix: move Celo to the bottom of the network selector list

* fix: downgrade smart-order-router and add casting fix

* fix: downgrade smart-order-router and add casting fix

* fix: resolve Pool dependency

* fix: bridge chain id types

* fix: explorer link test

* fix: use quoter v2 ABI in useClientSideV3Trade fro Celo

* fix: update connection "infura_rpc" to networks

* fix: revert yarn.lock and force install

* fix: dedup router and v3 sdk

* refactor: mv quoter v2 to client side v3 trade

* build: dedup lockfile

* feature: add portal ether to common bases

* fix: add comment for chains that use QuoterV2

* fix: use token as native asset

* fix: supply correct factory address to getPoolAddress call & refactor nativeOnChain method

* feature: adjust celo tokens presetned

* fix: update celo explorer to celoscan

* fix: celo token casting

* fix: celo celo explorer it

* fix: celo chain info should be consistent with block explorer used.

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
2022-07-12 16:48:03 +02:00
Vignesh Mohankumar
1b91e7ce30 fix: Revert "refactor: remove coinbase wallet resetState" (#4081)
Revert "refactor: remove coinbase wallet resetState (#4024)"

This reverts commit e36722ccb4.
2022-07-12 00:37:45 -04:00
Anas Yousef
535e670c63 refactor: remove hideRouteDiagram prop (#3763) 2022-07-11 20:30:16 -04:00
Bruno Crosier
0b4c77155e fix: NetworkSelect mobile toggle bug (#3698)
* fix windows dev environment bugs

* fix NetworkSelector toggle bug

* revert:  add `prei18n:extract` script back

this change to make the script Windows-compatible will be dealt with in a separate PR

* revert:  revert prettier endOfLine fix

Will be dealt with in a separate PR

* updates

Co-authored-by: Vignesh Mohankumar <vignesh@vigneshmohankumar.com>
Co-authored-by: Vignesh Mohankumar <me@vig.xyz>
2022-07-11 15:55:59 -04:00
Vignesh Mohankumar
e36722ccb4 refactor: remove coinbase wallet resetState (#4024)
* refactor: remove coinbase wallet resetState

* unused import

* bump web3-react

* rm unused

* bump everything
2022-07-11 13:49:49 -04:00
Ian Lapham
ec0b94a920 fix: Fix spacing type (#4073)
* fix: Fix spacing type

* prettier

Co-authored-by: Vignesh Mohankumar <me@vig.xyz>
2022-07-11 13:37:40 -04:00
Zach Pomerantz
d5eed8b15f build: wait 1m between release tests (#4077) 2022-07-11 13:24:01 -04:00
Zach Pomerantz
2447afc43e build: wait on passing cypress (#4076)
* build: wait on passing cypress

* build: video upload
2022-07-11 18:55:03 +02:00
Zach Pomerantz
8eef757f7f refactor: analytics initialization (#4070)
* refactor: analytics initialization

* fix: typings
2022-07-11 12:46:58 -04:00
Zach Pomerantz
b1c29b3bf1 build: resolve cypress matrix to single job (#4075)
* build: resolve cypress matrix to single job

* build: output on cypress-tests

* build: explicitly name matrix steps

* build: quote cypress string

* build: omit protocol

* build: test

* build: fix indentation

* build: test

* build: test

* build: test

* build: cleanup

* build: cleanup
2022-07-11 17:36:48 +02:00
Zach Pomerantz
b211c9f150 build: wait on tests (#4074) 2022-07-11 16:42:52 +02:00
lynn
66cae715f4 feat: implement initial setup of amplitude SDK (#4044)
* init commit

* add amplitude ts sdk to package.json

* add more comments and documentation

* respond to vm comments

* respond to cmcewen comments

* fix: remove unused constants

* fix: respond to cmcewen comments + initialize analytics in app.tsx + add missing return statement
2022-07-08 11:57:47 -04:00
github-actions[bot]
5a4a2782e8 chore(i18n): new Crowdin translations (#4045)
chore(i18n): synchronize translations from crowdin [skip ci]

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2022-07-07 13:03:44 -07:00
Vignesh Mohankumar
4e462ddbef refactor: extract Web3Provider hooks, create internal Connection representation (#4040)
* refactor: separate hooks file for Web3Provider

* move utils

* rename + comments

* rename Wallet enum to ConnectionType

* more wallet -> connectiontype

* more wallet -> connectiontype

* move hooks

* use Connection everywhere

* connector -> connection

* generic getConnection

* rename injected -> injectedConnection

* check connectionType

* rm unused
2022-07-07 15:17:49 -04:00
Zach Pomerantz
48a962a750 build: enable auto-release (#4058) 2022-07-07 11:56:03 -07:00
Zach Pomerantz
9a55402bdf build: add sleep in release (#4057) 2022-07-07 11:09:47 -07:00
lynn
663644553e feat: update privacy policy to include amplitude (#4046)
init commit
2022-07-06 18:15:12 -04:00
Vignesh Mohankumar
ceec3f0e65 feat: remove Tally Ho specific rendering (#4023)
feat: remove tally
2022-07-06 16:39:24 -04:00
Vignesh Mohankumar
904d1835d2 style: rename library to provider (#4038) 2022-07-06 12:36:54 -04:00
lynn
77366bf81b feat: configure blocks per fetch for l2s (#4028)
* init commit

* update redux multicall version to 1.1.5 in package.json

* fix respond to zzmp comments

* update optimism blocks per fetch to 15

* simplify

Co-authored-by: Lynn Yu <lynn.yu@uniswap.org>
2022-07-05 12:13:20 -04:00
Zach Pomerantz
cd8b048829 fix: deploy after pinning 2022-07-05 09:04:13 -07:00
Zach Pomerantz
d62596ecfc fix: release file 2022-07-05 08:52:54 -07:00
Zach Pomerantz
2b496c62f1 build: deploy without needing check suite 2022-07-05 08:50:28 -07:00
Zach Pomerantz
a3c77708e2 build: deploy without waiting on check suite 2022-07-05 08:49:11 -07:00
Zach Pomerantz
b9e8139699 fix: alter headers on cached response (#4032)
* fix: alter headers on cached response

* test: deflake
2022-07-05 08:31:06 -07:00
Zach Pomerantz
c82dcabd19 build: disable scheduled release (#4022) 2022-07-01 15:26:42 -07:00
Zach Pomerantz
26b37d5274 build: fix await-check-suite with (#4021)
* build: fix await-check-suites

* build: fix await-check-suite with
2022-07-01 15:12:51 -07:00
Zach Pomerantz
d5c464b26b build: fix await-check-suites (#4020) 2022-07-01 15:10:08 -07:00
Zach Pomerantz
c48d4c5425 build: simplify actions (#4014)
* build: simplify actions

* build: add checkout

* build: fix path

* build: fix all paths

* build: missing steps

* build: update build name

* build: rename action

* build: add shell

* build: formalize lint

* build: cleanup

* build: update release

* build: comment workflows
2022-07-01 15:05:37 -07:00
Kaylee George
b28cd9c8b0 fix: token button jump (#4017)
* fix token button jump

* Update index.tsx

* move inline style to CSS
2022-07-01 16:18:46 -04:00
Vignesh Mohankumar
071017879c feat: don't allow disconnect/change on injected mobile wallets (#4015)
* feat: don't allow disconnect/change on injected mobile wallets

* new variable
2022-07-01 13:57:15 -04:00
github-actions[bot]
5535c83db5 chore(i18n): new Crowdin translations (#4013)
chore(i18n): synchronize translations from crowdin [skip ci]

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2022-07-01 09:03:06 -07:00
Andrii Bodnar
8f9eccabaf fix: Crowdin translations download (#3927) 2022-07-01 09:00:20 -07:00
Vignesh Mohankumar
322cdaf888 refactor: rm useActiveWeb3React (#4004)
* rm activeweb3react

* wrap in web3provider?
2022-06-30 16:38:02 -07:00
Vignesh Mohankumar
edcdbfd8f5 feat: disconnect for coinbase wallet (#3993)
* feat: disconnect for coinbase wallet

* change isActive logic

* remove logs

* reset state for coinbase wallet

* active -> isActive

* rm data-cy
2022-06-30 18:04:42 -04:00
306 changed files with 9338 additions and 6118 deletions

View File

@@ -1,3 +1,4 @@
REACT_APP_AMPLITUDE_KEY="1c694b28cd089acc2c386d518f93a775"
REACT_APP_INFURA_KEY="099fc58e0de9451d80b18d7c74caa7c1"
REACT_APP_FORTMATIC_KEY="pk_live_F937DF033A1666BF"
REACT_APP_GOOGLE_ANALYTICS_ID="G-KDP9B6W4H8"

21
.github/actions/setup/action.yml vendored Normal file
View File

@@ -0,0 +1,21 @@
name: Setup
runs:
using: composite
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 14
registry-url: https://registry.npmjs.org
cache: yarn
- uses: actions/cache@v3
id: install-cache
with:
path: node_modules/
key: ${{ runner.os }}-install-${{ hashFiles('**/yarn.lock') }}
- if: steps.install-cache.outputs.cache-hit != 'true'
run: yarn install --frozen-lockfile --ignore-scripts
shell: bash

View File

@@ -2,9 +2,9 @@ version: 2
updates:
- package-ecosystem: npm
# Files stored in repository root
directory: "/"
directory: '/'
schedule:
interval: "daily"
interval: 'daily'
allow:
- dependency-name: "@uniswap/token-lists"
- dependency-name: "@uniswap/default-token-list"
- dependency-name: '@uniswap/token-lists'
- dependency-name: '@uniswap/default-token-list'

View File

@@ -1,4 +1,4 @@
name: "Check PR Title"
name: Check PR Title
on:
pull_request_target:
@@ -8,8 +8,8 @@ on:
- synchronize
jobs:
check-pr-title:
name: Check PR Title
# Ensures that the PR title adheres to [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/).
conventional-commit:
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v3.4.0

View File

@@ -2,34 +2,18 @@ name: Crowdin Download
on:
schedule:
- cron: '0 * * * *' # every hour we download translations and update the pr from crowdin
# Download translations every hour.
# This is not done as part of the build so that builds remain reproducible.
- cron: '0 * * * *'
# manual trigger
workflow_dispatch:
jobs:
download-translations:
name: Download translations
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 14
registry-url: https://registry.npmjs.org
cache: 'yarn'
- uses: actions/cache@v3
id: install-cache
with:
path: node_modules/
key: ${{ runner.os }}-install-${{ hashFiles('**/yarn.lock') }}
- if: steps.install-cache.outputs.cache-hit != 'true'
run: yarn install --frozen-lockfile --ignore-scripts
- uses: ./.github/actions/setup
- run: yarn i18n:extract
- name: Download Crowdin translations
@@ -41,8 +25,9 @@ jobs:
token: ${{ secrets.CROWDIN_PERSONAL_TOKEN_SECRET }}
source: 'src/locales/en-US.po'
translation: 'src/locales/%locale%.po'
create_pull_request: false
localization_branch_name: main
commit_message: "chore(i18n): synchronize translations from crowdin [skip ci]"
create_pull_request: true
pull_request_title: 'chore(i18n): new Crowdin translations'
localization_branch_name: l10n_crowdin
commit_message: 'chore(i18n): synchronize translations from crowdin [skip ci]'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -6,28 +6,11 @@ on:
- main
jobs:
synchronize-with-crowdin:
name: Upload sources to Crowdin
upload-sources:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 14
registry-url: https://registry.npmjs.org
cache: 'yarn'
- uses: actions/cache@v3
id: install-cache
with:
path: node_modules/
key: ${{ runner.os }}-install-${{ hashFiles('**/yarn.lock') }}
- if: steps.install-cache.outputs.cache-hit != 'true'
run: yarn install --frozen-lockfile --ignore-scripts
- uses: ./.github/actions/setup
- run: yarn i18n:extract
- name: Upload Crowdin sources

View File

@@ -1,45 +0,0 @@
name: Lint
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
run-linters:
name: Run linters
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 14
registry-url: https://registry.npmjs.org
cache: 'yarn'
- uses: actions/cache@v3
id: install-cache
with:
path: node_modules/
key: ${{ runner.os }}-install-${{ hashFiles('**/yarn.lock') }}
- if: steps.install-cache.outputs.cache-hit != 'true'
run: yarn install --frozen-lockfile --ignore-scripts
- name: Run eslint w/ autofix
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.owner.login == github.repository_owner }}
uses: wearerequired/lint-action@36c7e6689e80d785d27a22f71d970f3a3b4fcb70
with:
github_token: ${{ secrets.github_token }}
eslint: true
eslint_args: "-c .eslintrc.json"
auto_fix: true
- name: Run eslint
if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.owner.login != github.repository_owner }}
run: yarn eslint .

View File

@@ -1,62 +1,58 @@
name: Release
on:
# disable deploys until this action is amended to include seeding cloudflare IPFS
# schedule:
# - cron: '0 12 * * 1-4' # every day 12:00 UTC Monday-Thursday
schedule:
- cron: '0 12 * * 1-4' # every day 12:00 UTC Monday-Thursday
# manual trigger
workflow_dispatch:
jobs:
bump_version:
name: Bump Version
wait-on-tests:
runs-on: ubuntu-latest
steps:
- id: unit-tests
uses: fountainhead/action-wait-for-check@v1.0.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
checkName: unit-tests
- id: cypress-tests
uses: fountainhead/action-wait-for-check@v1.0.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
checkName: cypress-tests
- if: steps.unit-tests.outputs.conclusion != 'success' || steps.cypress-tests.outputs.conclusion != 'success'
run: exit 1
tag:
needs: wait-on-tests
runs-on: ubuntu-latest
outputs:
new_tag: ${{ steps.github_tag_action.outputs.new_tag }}
changelog: ${{ steps.github_tag_action.outputs.changelog }}
new_tag: ${{ steps.github-tag-action.outputs.new_tag }}
changelog: ${{ steps.github-tag-action.outputs.changelog }}
steps:
- uses: actions/checkout@v3
- name: Bump version and push tag
id: github_tag_action
uses: mathieudutour/github-tag-action@331898d5052eedac9b15fec867b5ba66ebf9b692
- name: Bump and tag
id: github-tag-action
uses: mathieudutour/github-tag-action@v6.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
release_branches: .*
default_bump: false
default_bump: patch
create_release:
name: Create Release
release:
needs: tag
if: ${{ needs.tag.outputs.new_tag != null }}
runs-on: ubuntu-latest
needs: bump_version
if: ${{ needs.bump_version.outputs.new_tag != null }}
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 14
registry-url: https://registry.npmjs.org
cache: 'yarn'
- uses: actions/cache@v3
id: install-cache
with:
path: node_modules/
key: ${{ runner.os }}-install-${{ hashFiles('**/yarn.lock') }}
- if: steps.install-cache.outputs.cache-hit != 'true'
run: yarn install --frozen-lockfile --ignore-scripts
- uses: ./.github/actions/setup
- run: yarn prepare
- run: yarn build
- name: Pin to IPFS
id: upload
id: pinata
uses: anantaramdas/ipfs-pinata-deploy-action@39bbda1ce1fe24c69c6f57861b8038278d53688d
with:
pin-name: Uniswap ${{ needs.bump_version.outputs.new_tag }}
pin-name: Uniswap ${{ needs.tag.outputs.new_tag }}
path: './build'
pinata-api-key: ${{ secrets.PINATA_API_KEY }}
pinata-secret-api-key: ${{ secrets.PINATA_API_SECRET_KEY }}
@@ -70,12 +66,24 @@ jobs:
seeds: ${{ secrets.CRUST_SEEDS }}
- name: Convert CIDv0 to CIDv1
id: convert_cidv0
id: convert-cidv0
uses: uniswap/convert-cidv0-cidv1@v1.0.0
with:
cidv0: ${{ steps.upload.outputs.hash }}
- run: sleep 600
cidv0: ${{ steps.pinata.outputs.hash }}
- uses: actions/cache@v3
id: cypress-cache
with:
path: /home/runner/.cache/Cypress
key: ${{ runner.os }}-cypress-${{ hashFiles('node_modules/cypress') }}
- if: steps.cypress-cache.outputs.cache-hit != 'true'
run: yarn cypress install
- uses: cypress-io/github-action@v4
with:
install: false
browser: chrome
config-file: cypress.release.config.ts
config: baseUrl=https://cloudflare-ipfs.com/ipfs/${{ steps.pinata.outputs.hash }}
- name: Update DNS with new IPFS hash
env:
@@ -85,20 +93,19 @@ jobs:
CLOUDFLARE_ZONE_ID: ${{ secrets.CLOUDFLARE_ZONE_ID }}
uses: textileio/cloudflare-update-dnslink@0fe7b7a1ffc865db3a4da9773f0f987447ad5848
with:
cid: ${{ steps.upload.outputs.hash }}
cid: ${{ steps.pinata.outputs.hash }}
- name: Create GitHub Release
id: create_release
- name: Release
uses: actions/create-release@v1.1.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ needs.bump_version.outputs.new_tag }}
release_name: Release ${{ needs.bump_version.outputs.new_tag }}
tag_name: ${{ needs.tag.outputs.new_tag }}
release_name: Release ${{ needs.tag.outputs.new_tag }}
body: |
IPFS hash of the deployment:
- CIDv0: `${{ steps.upload.outputs.hash }}`
- CIDv1: `${{ steps.convert_cidv0.outputs.cidv1 }}`
- CIDv0: `${{ steps.pinata.outputs.hash }}`
- CIDv1: `${{ steps.convert-cidv0.outputs.cidv1 }}`
The latest release is always accessible via our alias to the Cloudflare IPFS gateway at [app.uniswap.org](https://app.uniswap.org).
@@ -108,8 +115,8 @@ jobs:
Your Uniswap settings are never remembered across different URLs.
IPFS gateways:
- https://${{ steps.convert_cidv0.outputs.cidv1 }}.ipfs.dweb.link/
- https://${{ steps.convert_cidv0.outputs.cidv1 }}.ipfs.cf-ipfs.com/
- [ipfs://${{ steps.upload.outputs.hash }}/](ipfs://${{ steps.upload.outputs.hash }}/)
- https://${{ steps.convert-cidv0.outputs.cidv1 }}.ipfs.dweb.link/
- https://${{ steps.convert-cidv0.outputs.cidv1 }}.ipfs.cf-ipfs.com/
- [ipfs://${{ steps.upload.outputs.hash }}/](ipfs://${{ steps.pinata.outputs.hash }}/)
${{ needs.bump_version.outputs.changelog }}
${{ needs.tag.outputs.changelog }}

View File

@@ -1,4 +1,4 @@
name: End-to-End Tests
name: Test
on:
push:
@@ -7,33 +7,40 @@ on:
pull_request:
branches:
- main
# manual trigger
workflow_dispatch:
jobs:
build:
name: Build
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- run: yarn lint
- uses: actions/setup-node@v3
with:
node-version: 14
registry-url: https://registry.npmjs.org
cache: 'yarn'
deps-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- run: npx yarn-deduplicate --strategy=highest --list --fail
- uses: actions/cache@v3
id: install-cache
with:
path: node_modules/
key: ${{ runner.os }}-install-${{ hashFiles('**/yarn.lock') }}
- if: steps.install-cache.outputs.cache-hit != 'true'
run: yarn install --frozen-lockfile --ignore-scripts
unit-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- run: yarn prepare
- run: yarn test
cypress-build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- run: yarn prepare
- run: yarn build
- uses: actions/upload-artifact@v2
with:
name: build
@@ -45,35 +52,19 @@ jobs:
with:
path: /home/runner/.cache/Cypress
key: ${{ runner.os }}-cypress-${{ hashFiles('node_modules/cypress') }}
- if: steps.cypress-cache.outputs.cache-hit != 'true'
run: yarn cypress install
cypress-tests:
name: Run tests
cypress-test-matrix:
needs: cypress-build
runs-on: ubuntu-latest
needs: build
strategy:
fail-fast: false
matrix:
containers: [1, 2, 3, 4]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 14
registry-url: https://registry.npmjs.org
cache: 'yarn'
- uses: actions/cache@v3
id: install-cache
with:
path: node_modules/ # this should always be a cache hit, from install
key: ${{ runner.os }}-install-${{ hashFiles('**/yarn.lock') }}
- if: steps.install-cache.outputs.cache-hit != 'true'
run: yarn install --frozen-lockfile --ignore-scripts
- uses: ./.github/actions/setup
- uses: actions/download-artifact@v2
with:
@@ -85,7 +76,6 @@ jobs:
with:
path: /home/runner/.cache/Cypress
key: ${{ runner.os }}-cypress-${{ hashFiles('node_modules/cypress') }}
- if: steps.cypress-cache.outputs.cache-hit != 'true'
run: yarn cypress install
@@ -98,6 +88,12 @@ jobs:
record: true
parallel: true
env:
CI: false # disables lint checks when building
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Included as a single job to check against for cypress test success, as cypress runs in a matrix.
cypress-tests:
needs: cypress-test-matrix
runs-on: ubuntu-latest
steps:
- run: echo 'Finished cypress tests https\://dashboard.cypress.io/projects/yp82ef'

View File

@@ -1,35 +0,0 @@
name: Unit Tests
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
unit-tests:
name: Run tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 14
registry-url: https://registry.npmjs.org
cache: 'yarn'
- uses: actions/cache@v3
id: install-cache
with:
path: node_modules/
key: ${{ runner.os }}-install-${{ hashFiles('**/yarn.lock') }}
- if: steps.install-cache.outputs.cache-hit != 'true'
run: yarn install --frozen-lockfile --ignore-scripts
- run: yarn prepare
- run: yarn test

View File

@@ -48,4 +48,4 @@ The Uniswap Interface supports swapping, adding liquidity, removing liquidity an
## Accessing Uniswap V1
The Uniswap V1 interface for mainnet and testnets is accessible via IPFS gateways
linked from the [v1.0.0 release](https://github.com/Uniswap/uniswap-interface/releases/tag/v1.0.0).
linked from the [v1.0.0 release](https://github.com/Uniswap/uniswap-interface/releases/tag/v1.0.0).

View File

@@ -0,0 +1,8 @@
import { defineConfig } from 'cypress'
export default defineConfig({
projectId: 'yp82ef',
e2e: {
specPattern: 'cypress/release.ts',
},
})

8
cypress/e2e/link.test.ts Normal file
View File

@@ -0,0 +1,8 @@
// see https://github.com/Uniswap/interface/pull/4115
describe('Link', () => {
it('should update route', () => {
cy.visit('/')
cy.get('[data-cy="pool-nav-link"]').click()
cy.get('[data-cy="join-pool-button"]').should('exist')
})
})

View File

@@ -1,5 +1,5 @@
describe('Swap', () => {
beforeEach(() => {
before(() => {
cy.visit('/swap')
})
@@ -11,73 +11,43 @@ describe('Swap', () => {
})
it('can enter an amount into input', () => {
cy.get('#swap-currency-input .token-amount-input')
.clear()
.type('0.001', { delay: 200 })
.should('have.value', '0.001')
cy.get('#swap-currency-input .token-amount-input').clear().type('0.001').should('have.value', '0.001')
})
it('zero swap amount', () => {
cy.get('#swap-currency-input .token-amount-input').clear().type('0.0', { delay: 200 }).should('have.value', '0.0')
cy.get('#swap-currency-input .token-amount-input').clear().type('0.0').should('have.value', '0.0')
})
it('invalid swap amount', () => {
cy.get('#swap-currency-input .token-amount-input').clear().type('\\', { delay: 200 }).should('have.value', '')
cy.get('#swap-currency-input .token-amount-input').clear().type('\\').should('have.value', '')
})
it('can enter an amount into output', () => {
cy.get('#swap-currency-output .token-amount-input').type('0.001', { delay: 200 }).should('have.value', '0.001')
cy.get('#swap-currency-output .token-amount-input').clear().type('0.001').should('have.value', '0.001')
})
it('zero output amount', () => {
cy.get('#swap-currency-output .token-amount-input').type('0.0', { delay: 200 }).should('have.value', '0.0')
cy.get('#swap-currency-output .token-amount-input').clear().type('0.0').should('have.value', '0.0')
})
it.skip('can swap ETH for DAI', () => {
cy.get('#swap-currency-output .open-currency-select-button').click()
cy.get('.token-item-0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735').should('be.visible')
cy.get('.token-item-0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735').click({ force: true })
cy.get('#swap-currency-input .token-amount-input').should('be.visible')
cy.get('#swap-currency-input .token-amount-input').type('0.001', { force: true, delay: 200 })
cy.get('.token-item-0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735').click()
cy.get('#swap-currency-input .token-amount-input').clear().type('0.0000001')
cy.get('#swap-currency-output .token-amount-input').should('not.equal', '')
cy.get('#swap-button').click()
cy.get('#confirm-swap-or-send').should('contain', 'Confirm Swap')
cy.get('[data-cy="confirmation-close-icon"]').click()
})
it.skip('add a recipient does not exist unless in expert mode', () => {
it('add a recipient does not exist unless in expert mode', () => {
cy.get('#add-recipient-button').should('not.exist')
})
it('ETH to wETH is same value (wrapped swaps have no price impact)', () => {
it.skip('ETH to wETH is same value (wrapped swaps have no price impact)', () => {
cy.get('#swap-currency-output .open-currency-select-button').click()
cy.get('.token-item-0xc778417E063141139Fce010982780140Aa0cD5Ab').click({ force: true })
cy.get('#swap-currency-input .token-amount-input').type('0.01', { force: true, delay: 100 })
cy.get('.token-item-0xc778417E063141139Fce010982780140Aa0cD5Ab').click()
cy.get('#swap-currency-input .token-amount-input').clear().type('0.01')
cy.get('#swap-currency-output .token-amount-input').should('have.value', '0.01')
})
describe('expert mode', () => {
beforeEach(() => {
cy.window().then((win) => {
cy.stub(win, 'prompt').returns('confirm')
})
cy.get('#open-settings-dialog-button').click()
cy.get('#toggle-expert-mode-button').click()
cy.get('#confirm-expert-mode').click()
})
it.skip('add a recipient is visible', () => {
cy.get('#add-recipient-button').should('be.visible')
})
it.skip('add a recipient', () => {
cy.get('#add-recipient-button').click()
cy.get('#recipient').should('exist')
})
it.skip('remove recipient', () => {
cy.get('#add-recipient-button').click()
cy.get('#remove-recipient-button').click()
cy.get('#recipient').should('not.exist')
})
})
})

20
cypress/release.ts Normal file
View File

@@ -0,0 +1,20 @@
const ONE_MINUTE = 60_000
describe(
'Release',
{
pageLoadTimeout: ONE_MINUTE,
retries: 30,
},
() => {
it('loads swap page', () => {
// We *must* wait in order to space out the retry attempts.
cy.wait(ONE_MINUTE)
.visit('/', {
retryOnStatusCodeFailure: true,
retryOnNetworkFailure: true,
})
.get('#swap-page')
})
}
)

View File

@@ -50,3 +50,9 @@ beforeEach(() => {
res.continue()
})
})
Cypress.on('uncaught:exception', (_err, _runnable) => {
// returning false here prevents Cypress from
// failing the test
return false
})

View File

@@ -1,5 +1,5 @@
{
"name": "@uniswap/widgets",
"name": "@uniswap/interface",
"version": "1.0.7",
"description": "Uniswap Interface",
"homepage": ".",
@@ -9,7 +9,7 @@
"contracts:compile:v3": "typechain --target ethers-v5 --out-dir src/types/v3 \"./node_modules/@uniswap/**/artifacts/contracts/**/*[!dbg].json\"",
"contracts:compile": "yarn contracts:compile:abi && yarn contracts:compile:v3",
"graphql:generate": "graphql-codegen --config codegen.yml",
"prei18n:extract": "touch src/locales/en-US.po",
"prei18n:extract": "node prei18n-extract.js",
"i18n:extract": "lingui extract --locale en-US",
"i18n:compile": "yarn i18n:extract && lingui compile",
"i18n:pseudo": "lingui extract --locale pseudo && lingui compile",
@@ -17,6 +17,7 @@
"start": "react-scripts start",
"build": "react-scripts build",
"serve": "serve build -l 3000",
"lint": "yarn eslint .",
"test": "react-scripts test --coverage",
"cypress:open": "cypress open --browser chrome --e2e",
"cypress:run": "cypress run --browser chrome --e2e"
@@ -60,9 +61,8 @@
"@graphql-codegen/typescript-operations": "^1.18.2",
"@graphql-codegen/typescript-rtk-query": "^1.1.1",
"@lingui/cli": "^3.9.0",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^12.0.0",
"@testing-library/react-hooks": "^7.0.2",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.1",
"@typechain/ethers-v5": "^7.0.0",
"@types/array.prototype.flat": "^1.2.1",
"@types/array.prototype.flatmap": "^1.2.2",
@@ -75,20 +75,20 @@
"@types/multicodec": "^1.0.0",
"@types/node": "^13.13.5",
"@types/qs": "^6.9.2",
"@types/react": "^17.0.2",
"@types/react-dom": "^17.0.1",
"@types/react-redux": "^7.1.16",
"@types/react-router-dom": "^5.0.0",
"@types/react": "^18.0.15",
"@types/react-dom": "^18.0.6",
"@types/react-redux": "^7.1.24",
"@types/react-router-dom": "^5.3.3",
"@types/react-virtualized-auto-sizer": "^1.0.0",
"@types/react-window": "^1.8.2",
"@types/rebass": "^4.0.7",
"@types/styled-components": "^5.1.0",
"@types/styled-components": "^5.1.25",
"@types/testing-library__cypress": "^5.0.5",
"@types/ua-parser-js": "^0.7.35",
"@types/wcag-contrast": "^3.0.0",
"@typescript-eslint/eslint-plugin": "^4.1.0",
"@typescript-eslint/parser": "^4.1.0",
"cypress": "^10.1.0",
"@typescript-eslint/eslint-plugin": "^4",
"@typescript-eslint/parser": "^4",
"cypress": "^10.3.1",
"env-cmd": "^10.1.0",
"eslint": "^7.11.0",
"eslint-config-prettier": "^6.11.0",
@@ -98,19 +98,22 @@
"eslint-plugin-react-hooks": "^4.0.0",
"eslint-plugin-simple-import-sort": "^7.0.0",
"eslint-plugin-unused-imports": "^2.0.0",
"jest-styled-components": "^7.0.8",
"ms.macro": "^2.0.0",
"prettier": "^2.7.1",
"react-scripts": "^4.0.3",
"serve": "^11.3.2",
"typechain": "^5.0.0",
"typescript": "^4.4.3"
},
"dependencies": {
"@coinbase/wallet-sdk": "^3.2.0",
"@amplitude/analytics-browser": "^0.5.1",
"@coinbase/wallet-sdk": "^3.3.0",
"@fontsource/ibm-plex-mono": "^4.5.1",
"@fontsource/inter": "^4.5.1",
"@lingui/core": "^3.9.0",
"@lingui/macro": "^3.9.0",
"@lingui/react": "^3.9.0",
"@lingui/core": "^3.14.0",
"@lingui/macro": "^3.14.0",
"@lingui/react": "^3.14.0",
"@metamask/jazzicon": "^2.0.0",
"@popperjs/core": "^2.4.4",
"@reach/dialog": "^0.10.3",
@@ -120,8 +123,8 @@
"@uniswap/governance": "^1.0.2",
"@uniswap/liquidity-staker": "^1.0.2",
"@uniswap/merkle-distributor": "1.0.1",
"@uniswap/redux-multicall": "^1.1.1",
"@uniswap/router-sdk": "^1.0.3",
"@uniswap/redux-multicall": "^1.1.5",
"@uniswap/router-sdk": "^1.0.6",
"@uniswap/sdk-core": "^3.0.1",
"@uniswap/smart-order-router": "^2.5.26",
"@uniswap/token-lists": "^1.0.0-beta.30",
@@ -130,18 +133,18 @@
"@uniswap/v2-sdk": "^3.0.1",
"@uniswap/v3-core": "1.0.0",
"@uniswap/v3-periphery": "^1.1.1",
"@uniswap/v3-sdk": "^3.8.2",
"@uniswap/v3-sdk": "^3.9.0",
"@walletconnect/ethereum-provider": "1.7.1",
"@web3-react/coinbase-wallet": "^8.0.33-beta.0",
"@web3-react/core": "^8.0.33-beta.0",
"@web3-react/eip1193": "^8.0.25-beta.0",
"@web3-react/empty": "^8.0.19-beta.0",
"@web3-react/gnosis-safe": "^8.0.5-beta.0",
"@web3-react/metamask": "^8.0.26-beta.0",
"@web3-react/network": "^8.0.26-beta.0",
"@web3-react/types": "^8.0.19-beta.0",
"@web3-react/url": "^8.0.24-beta.0",
"@web3-react/walletconnect": "^8.0.34-beta.0",
"@web3-react/coinbase-wallet": "^8.0.34-beta.0",
"@web3-react/core": "^8.0.35-beta.0",
"@web3-react/eip1193": "^8.0.26-beta.0",
"@web3-react/empty": "^8.0.20-beta.0",
"@web3-react/gnosis-safe": "^8.0.6-beta.0",
"@web3-react/metamask": "^8.0.28-beta.0",
"@web3-react/network": "^8.0.27-beta.0",
"@web3-react/types": "^8.0.20-beta.0",
"@web3-react/url": "^8.0.25-beta.0",
"@web3-react/walletconnect": "^8.0.35-beta.0",
"ajv": "^6.12.3",
"array.prototype.flat": "^1.2.4",
"array.prototype.flatmap": "^1.2.4",
@@ -155,7 +158,6 @@
"graphql-request": "^3.4.0",
"immer": "^9.0.6",
"inter-ui": "^3.13.1",
"jest-styled-components": "^7.0.5",
"jotai": "^1.3.7",
"jsbi": "^3.1.4",
"make-plural": "^7.0.0",
@@ -165,18 +167,17 @@
"polished": "^3.3.2",
"polyfill-object.fromentries": "^1.0.1",
"popper-max-size-modifier": "^0.2.0",
"prettier": "^2.2.1",
"qs": "^6.9.4",
"react": "^17.0.1",
"react": "^18.2.0",
"react-confetti": "^6.0.0",
"react-dom": "^17.0.1",
"react-dom": "^18.2.0",
"react-feather": "^2.0.8",
"react-ga4": "^1.4.1",
"react-is": "^17.0.2",
"react-markdown": "^4.3.1",
"react-popper": "^2.2.3",
"react-redux": "^7.2.2",
"react-router-dom": "^5.0.0",
"react-redux": "^8.0.2",
"react-router-dom": "^5.3.3",
"react-spring": "^8.0.27",
"react-use-gesture": "^6.0.14",
"react-virtualized-auto-sizer": "^1.0.2",
@@ -185,11 +186,11 @@
"redux": "^4.1.2",
"redux-localstorage-simple": "^2.3.1",
"setimmediate": "^1.0.5",
"styled-components": "^5.3.0",
"styled-components": "^5.3.5",
"tiny-invariant": "^1.2.0",
"ua-parser-js": "^0.7.28",
"use-count-up": "^2.2.5",
"use-resize-observer": "^8.0.0",
"use-resize-observer": "^9.0.2",
"wcag-contrast": "^3.0.0",
"web-vitals": "^2.1.0",
"workbox-core": "^6.1.0",

9
prei18n-extract.js Normal file
View File

@@ -0,0 +1,9 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const exec = require('child_process').exec
const isWindows = process.platform === 'win32' || /^(msys|cygwin)$/.test(process.env.OSTYPE)
if (isWindows) {
exec(`type nul > src/locales/en-US.po`)
} else {
exec(`touch src/locales/en-US.po`)
}

View File

@@ -24,83 +24,83 @@
-->
<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;
}
* {
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);
font-feature-settings: 'ss01' on, 'ss02' on, 'cv01' on, 'cv03' on;
}
#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;
}
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);
font-feature-settings: 'ss01' on, 'ss02' on, 'cv01' on, 'cv03' on;
background-color: #212429;
}
#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;
}
}
@media (prefers-color-scheme: light) {
html {
min-height: 100%;
}
@media (prefers-color-scheme: dark) {
html {
background-color: #212429;
}
}
@media (prefers-color-scheme: light) {
html {
background-color: #F7F8FA;
}
background-color: #f7f8fa;
}
}
</style>
</head>
<body>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -0,0 +1 @@
<svg id="Celo_Rings" data-name="Celo Rings" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 950 950"><defs><style>.cls-1{fill:#fbcc5c;}.cls-2{fill:#35d07f;}.cls-3{fill:#5ea33b;}</style></defs><title>Artboard 1</title><path id="Bottom_Ring" data-name="Bottom Ring" class="cls-1" d="M375,850c151.88,0,275-123.12,275-275S526.88,300,375,300,100,423.12,100,575,223.12,850,375,850Zm0,100C167.9,950,0,782.1,0,575S167.9,200,375,200,750,367.9,750,575,582.1,950,375,950Z"/><path id="Top_Ring" data-name="Top Ring" class="cls-2" d="M575,650c151.88,0,275-123.12,275-275S726.88,100,575,100,300,223.12,300,375,423.12,650,575,650Zm0,100c-207.1,0-375-167.9-375-375S367.9,0,575,0,950,167.9,950,375,782.1,750,575,750Z"/><path id="Rings_Overlap" data-name="Rings Overlap" class="cls-3" d="M587.39,750a274.38,274.38,0,0,0,54.55-108.06A274.36,274.36,0,0,0,750,587.4a373.63,373.63,0,0,1-29.16,133.45A373.62,373.62,0,0,1,587.39,750ZM308.06,308.06A274.36,274.36,0,0,0,200,362.6a373.63,373.63,0,0,1,29.16-133.45A373.62,373.62,0,0,1,362.61,200,274.38,274.38,0,0,0,308.06,308.06Z"/></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -6,7 +6,7 @@ import styled from 'styled-components/macro'
import { LinkStyledButton } from 'theme'
const CopyIcon = styled(LinkStyledButton)`
color: ${({ color, theme }) => color || theme.text3};
color: ${({ color, theme }) => color || theme.deprecated_text3};
flex-shrink: 0;
display: flex;
text-decoration: none;
@@ -14,7 +14,7 @@ const CopyIcon = styled(LinkStyledButton)`
:active,
:focus {
text-decoration: none;
color: ${({ color, theme }) => color || theme.text2};
color: ${({ color, theme }) => color || theme.deprecated_text2};
}
`
const StyledText = styled.span`

View File

@@ -1,4 +1,4 @@
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useWeb3React } from '@web3-react/core'
import { CheckCircle, Triangle } from 'react-feather'
import styled from 'styled-components/macro'
@@ -27,15 +27,16 @@ const TransactionState = styled(ExternalLink)<{ pending: boolean; success?: bool
padding: 0.25rem 0rem;
font-weight: 500;
font-size: 0.825rem;
color: ${({ theme }) => theme.primary1};
color: ${({ theme }) => theme.deprecated_primary1};
`
const IconWrapper = styled.div<{ pending: boolean; success?: boolean }>`
color: ${({ pending, success, theme }) => (pending ? theme.primary1 : success ? theme.green1 : theme.red1)};
color: ${({ pending, success, theme }) =>
pending ? theme.deprecated_primary1 : success ? theme.deprecated_green1 : theme.deprecated_red1};
`
export default function Transaction({ hash }: { hash: string }) {
const { chainId } = useActiveWeb3React()
const { chainId } = useWeb3React()
const allTransactions = useAllTransactions()
const tx = allTransactions?.[hash]

View File

@@ -1,16 +1,16 @@
import { Trans } from '@lingui/macro'
import { Connector } from '@web3-react/types'
import { useWeb3React } from '@web3-react/core'
import CopyHelper from 'components/AccountDetails/Copy'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useCallback, useContext } from 'react'
import { getConnection, getConnectionName, getIsCoinbaseWallet, getIsMetaMask } from 'connection/utils'
import { Context, useCallback, useContext } from 'react'
import { ExternalLink as LinkIcon } from 'react-feather'
import { useAppDispatch } from 'state/hooks'
import { updateSelectedWallet } from 'state/user/reducer'
import { DefaultTheme } from 'styled-components/macro'
import styled, { ThemeContext } from 'styled-components/macro'
import { isMobile } from 'utils/userAgent'
import { ReactComponent as Close } from '../../assets/images/x.svg'
import { coinbaseWallet, injected } from '../../connectors'
import { SUPPORTED_WALLETS } from '../../constants/wallet'
import { clearAllTransactions } from '../../state/transactions/reducer'
import { ExternalLink, LinkStyledButton, ThemedText } from '../../theme'
import { shortenAddress } from '../../utils'
@@ -24,7 +24,7 @@ const HeaderRow = styled.div`
${({ theme }) => theme.flexRowNoWrap};
padding: 1rem 1rem;
font-weight: 500;
color: ${(props) => (props.color === 'blue' ? ({ theme }) => theme.primary1 : 'inherit')};
color: ${(props) => (props.color === 'blue' ? ({ theme }) => theme.deprecated_primary1 : 'inherit')};
${({ theme }) => theme.mediaWidth.upToMedium`
padding: 1rem;
`};
@@ -52,7 +52,7 @@ const UpperSection = styled.div`
const InfoCard = styled.div`
padding: 1rem;
border: 1px solid ${({ theme }) => theme.bg3};
border: 1px solid ${({ theme }) => theme.deprecated_bg3};
border-radius: 20px;
position: relative;
display: grid;
@@ -65,7 +65,7 @@ const AccountGroupingRow = styled.div`
justify-content: space-between;
align-items: center;
font-weight: 400;
color: ${({ theme }) => theme.text1};
color: ${({ theme }) => theme.deprecated_text1};
div {
${({ theme }) => theme.flexRowNoWrap}
@@ -95,14 +95,14 @@ const LowerSection = styled.div`
padding: 1.5rem;
flex-grow: 1;
overflow: auto;
background-color: ${({ theme }) => theme.bg2};
background-color: ${({ theme }) => theme.deprecated_bg2};
border-bottom-left-radius: 20px;
border-bottom-right-radius: 20px;
h5 {
margin: 0;
font-weight: 400;
color: ${({ theme }) => theme.text3};
color: ${({ theme }) => theme.deprecated_text3};
}
`
@@ -130,12 +130,12 @@ const AccountControl = styled.div`
const AddressLink = styled(ExternalLink)<{ hasENS: boolean; isENS: boolean }>`
font-size: 0.825rem;
color: ${({ theme }) => theme.text3};
color: ${({ theme }) => theme.deprecated_text3};
margin-left: 1rem;
font-size: 0.825rem;
display: flex;
:hover {
color: ${({ theme }) => theme.text2};
color: ${({ theme }) => theme.deprecated_text2};
}
`
@@ -151,7 +151,7 @@ const CloseIcon = styled.div`
const CloseColor = styled(Close)`
path {
stroke: ${({ theme }) => theme.text4};
stroke: ${({ theme }) => theme.deprecated_text4};
}
`
@@ -159,32 +159,9 @@ const WalletName = styled.div`
width: initial;
font-size: 0.825rem;
font-weight: 500;
color: ${({ theme }) => theme.text3};
color: ${({ theme }) => theme.deprecated_text3};
`
const IconWrapper = styled.div<{ size?: number }>`
${({ theme }) => theme.flexColumnNoWrap};
align-items: center;
justify-content: center;
margin-right: 8px;
& > img,
span {
height: ${({ size }) => (size ? size + 'px' : '32px')};
width: ${({ size }) => (size ? size + 'px' : '32px')};
}
${({ theme }) => theme.mediaWidth.upToMedium`
align-items: flex-end;
`};
`
function WrappedStatusIcon({ connector }: { connector: Connector }) {
return (
<IconWrapper size={16}>
<StatusIcon connector={connector} />
</IconWrapper>
)
}
const TransactionListWrapper = styled.div`
${({ theme }) => theme.flexColumnNoWrap};
`
@@ -226,22 +203,20 @@ export default function AccountDetails({
ENSName,
openOptions,
}: AccountDetailsProps) {
const { chainId, account, connector } = useActiveWeb3React()
const theme = useContext(ThemeContext)
const { chainId, account, connector } = useWeb3React()
const connectionType = getConnection(connector).type
const theme = useContext(ThemeContext as Context<DefaultTheme>)
const dispatch = useAppDispatch()
const isMetaMask = getIsMetaMask()
const isCoinbaseWallet = getIsCoinbaseWallet()
const isInjectedMobileBrowser = (isMetaMask || isCoinbaseWallet) && isMobile
function formatConnectorName() {
const { ethereum } = window
const isMetaMask = !!(ethereum && ethereum.isMetaMask)
const name = Object.keys(SUPPORTED_WALLETS)
.filter(
(k) =>
SUPPORTED_WALLETS[k].connector === connector && (connector !== injected || isMetaMask === (k === 'METAMASK'))
)
.map((k) => SUPPORTED_WALLETS[k].name)[0]
return (
<WalletName>
<Trans>Connected with {name}</Trans>
<Trans>Connected with</Trans> {getConnectionName(connectionType, isMetaMask)}
</WalletName>
)
}
@@ -265,46 +240,41 @@ export default function AccountDetails({
<AccountGroupingRow>
{formatConnectorName()}
<div>
{/* Coinbase Wallet reloads the page right now, which breaks the selectedWallet from being set properly on localStorage */}
{connector !== coinbaseWallet && (
<WalletAction
style={{ fontSize: '.825rem', fontWeight: 400, marginRight: '8px' }}
onClick={() => {
connector.deactivate ? connector.deactivate() : connector.resetState()
dispatch(updateSelectedWallet({ wallet: undefined }))
openOptions()
}}
>
<Trans>Disconnect</Trans>
</WalletAction>
{!isInjectedMobileBrowser && (
<>
<WalletAction
style={{ fontSize: '.825rem', fontWeight: 400, marginRight: '8px' }}
onClick={() => {
if (connector.deactivate) {
connector.deactivate()
} else {
connector.resetState()
}
dispatch(updateSelectedWallet({ wallet: undefined }))
openOptions()
}}
>
<Trans>Disconnect</Trans>
</WalletAction>
<WalletAction
style={{ fontSize: '.825rem', fontWeight: 400 }}
onClick={() => {
openOptions()
}}
>
<Trans>Change</Trans>
</WalletAction>
</>
)}
<WalletAction
style={{ fontSize: '.825rem', fontWeight: 400 }}
onClick={() => {
openOptions()
}}
>
<Trans>Change</Trans>
</WalletAction>
</div>
</AccountGroupingRow>
<AccountGroupingRow data-testid="web3-account-identifier-row">
<AccountControl>
{ENSName ? (
<>
<div>
{connector && <WrappedStatusIcon connector={connector} />}
<p> {ENSName}</p>
</div>
</>
) : (
<>
<div>
{connector && <WrappedStatusIcon connector={connector} />}
<p> {account && shortenAddress(account)}</p>
</div>
</>
)}
<div>
<StatusIcon connectionType={connectionType} />
<p>{ENSName ? ENSName : account && shortenAddress(account)}</p>
</div>
</AccountControl>
</AccountGroupingRow>
<AccountGroupingRow>
@@ -381,7 +351,7 @@ export default function AccountDetails({
</LowerSection>
) : (
<LowerSection>
<ThemedText.Body color={theme.text1}>
<ThemedText.Body color={theme.deprecated_text1}>
<Trans>Your transactions will appear here...</Trans>
</ThemedText.Body>
</LowerSection>

View File

@@ -1,9 +1,9 @@
import { Trans } from '@lingui/macro'
// eslint-disable-next-line no-restricted-imports
import { t } from '@lingui/macro'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { ReactNode, useCallback, useContext } from 'react'
import styled, { ThemeContext } from 'styled-components/macro'
import { useWeb3React } from '@web3-react/core'
import { ChangeEvent, Context, ReactNode, useCallback, useContext } from 'react'
import styled, { DefaultTheme, ThemeContext } from 'styled-components/macro'
import useENS from '../../hooks/useENS'
import { ExternalLink, ThemedText } from '../../theme'
@@ -15,7 +15,7 @@ const InputPanel = styled.div`
${({ theme }) => theme.flexColumnNoWrap}
position: relative;
border-radius: 1.25rem;
background-color: ${({ theme }) => theme.bg1};
background-color: ${({ theme }) => theme.deprecated_bg1};
z-index: 1;
width: 100%;
`
@@ -25,10 +25,10 @@ const ContainerRow = styled.div<{ error: boolean }>`
justify-content: center;
align-items: center;
border-radius: 1.25rem;
border: 1px solid ${({ error, theme }) => (error ? theme.red1 : theme.bg2)};
border: 1px solid ${({ error, theme }) => (error ? theme.deprecated_red1 : theme.deprecated_bg2)};
transition: border-color 300ms ${({ error }) => (error ? 'step-end' : 'step-start')},
color 500ms ${({ error }) => (error ? 'step-end' : 'step-start')};
background-color: ${({ theme }) => theme.bg1};
background-color: ${({ theme }) => theme.deprecated_bg1};
`
const InputContainer = styled.div`
@@ -42,15 +42,15 @@ const Input = styled.input<{ error?: boolean }>`
border: none;
flex: 1 1 auto;
width: 0;
background-color: ${({ theme }) => theme.bg1};
background-color: ${({ theme }) => theme.deprecated_bg1};
transition: color 300ms ${({ error }) => (error ? 'step-end' : 'step-start')};
color: ${({ error, theme }) => (error ? theme.red1 : theme.text1)};
color: ${({ error, theme }) => (error ? theme.deprecated_red1 : theme.deprecated_text1)};
overflow: hidden;
text-overflow: ellipsis;
font-weight: 500;
width: 100%;
::placeholder {
color: ${({ theme }) => theme.text4};
color: ${({ theme }) => theme.deprecated_text4};
}
padding: 0px;
-webkit-appearance: textfield;
@@ -65,7 +65,7 @@ const Input = styled.input<{ error?: boolean }>`
}
::placeholder {
color: ${({ theme }) => theme.text4};
color: ${({ theme }) => theme.deprecated_text4};
}
`
@@ -86,13 +86,13 @@ export default function AddressInputPanel({
// triggers whenever the typed value changes
onChange: (value: string) => void
}) {
const { chainId } = useActiveWeb3React()
const theme = useContext(ThemeContext)
const { chainId } = useWeb3React()
const theme = useContext(ThemeContext as Context<DefaultTheme>)
const { address, loading, name } = useENS(value)
const handleInput = useCallback(
(event) => {
(event: ChangeEvent<HTMLInputElement>) => {
const input = event.target.value
const withoutSpaces = input.replace(/\s+/g, '')
onChange(withoutSpaces)
@@ -108,7 +108,7 @@ export default function AddressInputPanel({
<InputContainer>
<AutoColumn gap="md">
<RowBetween>
<ThemedText.Black color={theme.text2} fontWeight={500} fontSize={14}>
<ThemedText.Black color={theme.deprecated_text2} fontWeight={500} fontSize={14}>
{label ?? <Trans>Recipient</Trans>}
</ThemedText.Black>
{address && chainId && (

View File

@@ -0,0 +1,57 @@
import { createContext, memo, PropsWithChildren, useContext, useEffect, useMemo } from 'react'
import { sendAnalyticsEvent } from '.'
import { ElementName, EventName, ModalName, PageName, SectionName } from './constants'
export interface ITraceContext {
// Highest order context: eg Swap or Explore.
page?: PageName
// Enclosed section name. For contexts with modals, refers to the
// section of the page from which the user triggered the modal.
section?: SectionName
modal?: ModalName
// Element name mostly used to identify events sources
// Does not need to be unique given the higher order page and section.
element?: ElementName
}
export const TraceContext = createContext<ITraceContext>({})
type TraceProps = {
shouldLogImpression?: boolean // whether to log impression on mount
name?: EventName
properties?: Record<string, unknown>
} & ITraceContext
/**
* Sends an analytics event on mount (if shouldLogImpression is set),
* and propagates the context to child traces.
*/
export const Trace = memo(
({ shouldLogImpression, name, children, page, section, element, properties }: PropsWithChildren<TraceProps>) => {
const parentTrace = useContext(TraceContext)
const combinedProps = useMemo(
() => ({
...parentTrace,
...Object.fromEntries(Object.entries({ page, section, element }).filter(([_, v]) => v !== undefined)),
}),
[element, parentTrace, page, section]
)
useEffect(() => {
if (shouldLogImpression) {
sendAnalyticsEvent(name ?? EventName.PAGE_VIEWED, { ...combinedProps, ...properties })
}
// Impressions should only be logged on mount.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
return <TraceContext.Provider value={combinedProps}>{children}</TraceContext.Provider>
}
)
Trace.displayName = 'Trace'

View File

@@ -0,0 +1,75 @@
import { Children, cloneElement, isValidElement, memo, PropsWithChildren, SyntheticEvent } from 'react'
import { sendAnalyticsEvent } from '.'
import { Event, EventName } from './constants'
import { ITraceContext, Trace, TraceContext } from './Trace'
type TraceEventProps = {
events: Event[]
name: EventName
properties?: Record<string, unknown>
shouldLogImpression?: boolean
} & ITraceContext
/**
* Analytics instrumentation component that wraps event callbacks with logging logic.
*
* @example
* <TraceEvent events={[Event.onClick]} element={ElementName.SWAP_BUTTON}>
* <Button onClick={() => console.log('clicked')}>Click me</Button>
* </TraceEvent>
*/
export const TraceEvent = memo((props: PropsWithChildren<TraceEventProps>) => {
const { shouldLogImpression, name, properties, events, children, ...traceProps } = props
return (
<Trace {...traceProps}>
<TraceContext.Consumer>
{(traceContext) =>
Children.map(children, (child) => {
if (!isValidElement(child)) {
return child
}
// For each child, augment event handlers defined in `events` with event tracing.
return cloneElement(
child,
getEventHandlers(child, traceContext, events, name, properties, shouldLogImpression)
)
})
}
</TraceContext.Consumer>
</Trace>
)
})
TraceEvent.displayName = 'TraceEvent'
/**
* Given a set of child element and event props, returns a spreadable
* object of the event handlers augmented with analytics logging.
*/
function getEventHandlers(
child: React.ReactElement,
traceContext: ITraceContext,
events: Event[],
name: EventName,
properties?: Record<string, unknown>,
shouldLogImpression = true
) {
const eventHandlers: Partial<Record<Event, (e: SyntheticEvent<Element, Event>) => void>> = {}
for (const event of events) {
eventHandlers[event] = (eventHandlerArgs: unknown) => {
// call child event handler with original arguments, must be in array
const args = Array.isArray(eventHandlerArgs) ? eventHandlerArgs : [eventHandlerArgs]
child.props[event]?.apply(child, args)
// augment handler with analytics logging
if (shouldLogImpression) sendAnalyticsEvent(name, { ...traceContext, ...properties, action: event })
}
}
// return a spreadable event handler object
return eventHandlers
}

View File

@@ -0,0 +1,88 @@
/**
* Event names that can occur in this application.
*
* Subject to change as new features are added and new events are defined
* and logged.
*/
export enum EventName {
CONNECT_WALLET_BUTTON_CLICKED = 'Connect Wallet Button Clicked',
PAGE_VIEWED = 'Page Viewed',
SWAP_AUTOROUTER_VISUALIZATION_EXPANDED = 'Swap Autorouter Visualization Expanded',
SWAP_DETAILS_EXPANDED = 'Swap Details Expanded',
SWAP_MAX_TOKEN_AMOUNT_SELECTED = 'Swap Max Token Amount Selected',
SWAP_QUOTE_RECEIVED = 'Swap Quote Received',
SWAP_SUBMITTED = 'Swap Submitted',
SWAP_TOKENS_REVERSED = 'Swap Tokens Reversed',
TOKEN_IMPORTED = 'Token Imported',
TOKEN_SELECTED = 'Token Selected',
TOKEN_SELECTOR_OPENED = 'Token Selector Opened',
WALLET_CONNECT_TXN_COMPLETED = 'Wallet Connect Transaction Completed',
WALLET_SELECTED = 'Wallet Selected',
// alphabetize additional event names.
}
export enum WALLET_CONNECTION_RESULT {
SUCCEEDED = 'Succeeded',
FAILED = 'Failed',
}
/**
* Known pages in the app. Highest order context.
*/
export const enum PageName {
EXPLORE_PAGE = 'explore-page',
POOL_PAGE = 'pool-page',
SWAP_PAGE = 'swap-page',
VOTE_PAGE = 'vote-page',
// alphabetize additional page names.
}
/**
* Sections. Disambiguates low-level elements that may share a name.
* eg a `back` button in a modal will have the same `element`,
* but a different `section`.
*/
export const enum SectionName {
CURRENCY_INPUT_PANEL = 'swap-currency-input',
CURRENCY_OUTPUT_PANEL = 'swap-currency-output',
// alphabetize additional section names.
}
/** Known modals for analytics purposes. */
export const enum ModalName {
CONFIRM_SWAP = 'confirm-swap-modal',
TOKEN_SELECTOR = 'token-selector-modal',
// alphabetize additional modal names.
}
/**
* Known element names for analytics purposes.
* Use to identify low-level components given a TraceContext
*/
export const enum ElementName {
AUTOROUTER_VISUALIZATION_ROW = 'expandable-autorouter-visualization-row',
COMMON_BASES_CURRENCY_BUTTON = 'common-bases-currency-button',
CONFIRM_SWAP_BUTTON = 'confirm-swap-or-send',
CONNECT_WALLET_BUTTON = 'connect-wallet-button',
IMPORT_TOKEN_BUTTON = 'import-token-button',
MAX_TOKEN_AMOUNT_BUTTON = 'max-token-amount-button',
SWAP_BUTTON = 'swap-button',
SWAP_DETAILS_DROPDOWN = 'swap-details-dropdown',
SWAP_TOKENS_REVERSE_ARROW_BUTTON = 'swap-tokens-reverse-arrow-button',
SWAP_TRADE_PRICE_ROW = 'swap-trade-price-row',
TOKEN_SELECTOR_ROW = 'token-selector-row',
WALLET_TYPE_OPTION = 'wallet-type-option',
// alphabetize additional element names.
}
/**
* Known events that trigger callbacks.
* @example
* <TraceEvent events={[Event.onClick]} element={name}>
*/
export enum Event {
onClick = 'onClick',
onKeyPress = 'onKeyPress',
onSelect = 'onSelect',
// alphabetize additional events.
}

View File

@@ -0,0 +1,88 @@
import { Identify, identify, init, track } from '@amplitude/analytics-browser'
/**
* Initializes Amplitude with API key for project.
*
* Uniswap has two Amplitude projects: test and production. You must be a
* member of the organization on Amplitude to view details.
*/
export function initializeAnalytics(isDevEnvironment = process.env.NODE_ENV === 'development') {
if (isDevEnvironment) return
const API_KEY = process.env.REACT_APP_AMPLITUDE_KEY
if (typeof API_KEY === 'undefined') {
throw new Error(`REACT_APP_AMPLITUDE_KEY must be a defined environment variable`)
}
init(
API_KEY,
/* userId= */ undefined, // User ID should be undefined to let Amplitude default to Device ID
/* options= */ {
// Disable tracking of private user information by Amplitude
trackingOptions: {
ipAddress: false,
carrier: false,
city: false,
region: false,
country: false,
dma: false, // designated market area
},
}
)
}
/** Sends an event to Amplitude. */
export function sendAnalyticsEvent(eventName: string, eventProperties?: Record<string, unknown>) {
if (process.env.NODE_ENV === 'development') {
console.log(`[amplitude(${eventName})]: ${JSON.stringify(eventProperties)}`)
return
}
track(eventName, eventProperties)
}
/**
* Class that exposes methods to mutate the User Model's properties in
* Amplitude that represents the current session's user.
*
* See https://help.amplitude.com/hc/en-us/articles/115002380567-User-properties-and-event-properties
* for details.
*/
class UserModel {
constructor(private isDevEnvironment = process.env.NODE_ENV === 'development') {}
private log(method: string, ...parameters: unknown[]) {
console.debug(`[amplitude(Identify)]: ${method}(${parameters})`)
}
private call(mutate: (event: Identify) => Identify) {
if (this.isDevEnvironment) {
const log = (_: Identify, method: string) => this.log.bind(this, method)
mutate(new Proxy(new Identify(), { get: log }))
return
}
identify(mutate(new Identify()))
}
set(key: string, value: string | number) {
this.call((event) => event.set(key, value))
}
setOnce(key: string, value: string | number) {
this.call((event) => event.setOnce(key, value))
}
add(key: string, value: string | number) {
this.call((event) => event.add(key, typeof value === 'number' ? value : 0))
}
postInsert(key: string, value: string | number) {
this.call((event) => event.postInsert(key, value))
}
remove(key: string, value: string | number) {
this.call((event) => event.remove(key, value))
}
}
export const user = new UserModel()

View File

@@ -0,0 +1,13 @@
import { Currency, CurrencyAmount, Percent, Token } from '@uniswap/sdk-core'
export const getDurationTillTimestampSinceEpoch = (futureTimestampSinceEpoch?: number): number | undefined => {
if (!futureTimestampSinceEpoch) return undefined
return futureTimestampSinceEpoch - new Date().getTime() / 1000
}
export const getNumberFormattedToDecimalPlace = (
intialNumberObject: Percent | CurrencyAmount<Token | Currency>,
decimalPlace: number
): number => parseFloat(intialNumberObject.toFixed(decimalPlace))
export const formatPercentInBasisPointsNumber = (percent: Percent): number => parseFloat(percent.toFixed(2)) * 100

View File

@@ -17,7 +17,7 @@ const BadgeText = styled.div`
`
const ActiveDot = styled.span`
background-color: ${({ theme }) => theme.success};
background-color: ${({ theme }) => theme.deprecated_success};
border-radius: 50%;
height: 8px;
width: 8px;

View File

@@ -20,24 +20,24 @@ interface BadgeProps {
function pickBackgroundColor(variant: BadgeVariant | undefined, theme: DefaultTheme): Color {
switch (variant) {
case BadgeVariant.NEGATIVE:
return theme.error
return theme.deprecated_error
case BadgeVariant.POSITIVE:
return theme.success
return theme.deprecated_success
case BadgeVariant.PRIMARY:
return theme.primary1
return theme.deprecated_primary1
case BadgeVariant.WARNING:
return theme.warning
return theme.deprecated_warning
case BadgeVariant.WARNING_OUTLINE:
return 'transparent'
default:
return theme.bg2
return theme.deprecated_bg2
}
}
function pickBorder(variant: BadgeVariant | undefined, theme: DefaultTheme): string {
switch (variant) {
case BadgeVariant.WARNING_OUTLINE:
return `1px solid ${theme.warning}`
return `1px solid ${theme.deprecated_warning}`
default:
return 'unset'
}
@@ -46,15 +46,15 @@ function pickBorder(variant: BadgeVariant | undefined, theme: DefaultTheme): str
function pickFontColor(variant: BadgeVariant | undefined, theme: DefaultTheme): string {
switch (variant) {
case BadgeVariant.NEGATIVE:
return readableColor(theme.error)
return readableColor(theme.deprecated_error)
case BadgeVariant.POSITIVE:
return readableColor(theme.success)
return readableColor(theme.deprecated_success)
case BadgeVariant.WARNING:
return readableColor(theme.warning)
return readableColor(theme.deprecated_warning)
case BadgeVariant.WARNING_OUTLINE:
return theme.warning
return theme.deprecated_warning
default:
return readableColor(theme.bg2)
return readableColor(theme.deprecated_bg2)
}
}

View File

@@ -1,5 +1,5 @@
import { Trans } from '@lingui/macro'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useWeb3React } from '@web3-react/core'
import { ReactNode, useMemo } from 'react'
const BLOCKED_ADDRESSES: string[] = [
@@ -38,7 +38,7 @@ const BLOCKED_ADDRESSES: string[] = [
]
export default function Blocklist({ children }: { children: ReactNode }) {
const { account } = useActiveWeb3React()
const { account } = useWeb3React()
const blocked: boolean = useMemo(() => Boolean(account && BLOCKED_ADDRESSES.indexOf(account) !== -1), [account])
if (blocked) {
return (

View File

@@ -23,7 +23,7 @@ export const BaseButton = styled(RebassButton)<
border-radius: ${({ $borderRadius }) => $borderRadius ?? '20px'};
outline: none;
border: 1px solid transparent;
color: ${({ theme }) => theme.text1};
color: ${({ theme }) => theme.deprecated_text1};
text-decoration: none;
display: flex;
justify-content: center;
@@ -52,24 +52,24 @@ export const BaseButton = styled(RebassButton)<
`
export const ButtonPrimary = styled(BaseButton)`
background-color: ${({ theme }) => theme.primary1};
background-color: ${({ theme }) => theme.deprecated_primary1};
color: white;
&:focus {
box-shadow: 0 0 0 1pt ${({ theme }) => darken(0.05, theme.primary1)};
background-color: ${({ theme }) => darken(0.05, theme.primary1)};
box-shadow: 0 0 0 1pt ${({ theme }) => darken(0.05, theme.deprecated_primary1)};
background-color: ${({ theme }) => darken(0.05, theme.deprecated_primary1)};
}
&:hover {
background-color: ${({ theme }) => darken(0.05, theme.primary1)};
background-color: ${({ theme }) => darken(0.05, theme.deprecated_primary1)};
}
&:active {
box-shadow: 0 0 0 1pt ${({ theme }) => darken(0.1, theme.primary1)};
background-color: ${({ theme }) => darken(0.1, theme.primary1)};
box-shadow: 0 0 0 1pt ${({ theme }) => darken(0.1, theme.deprecated_primary1)};
background-color: ${({ theme }) => darken(0.1, theme.deprecated_primary1)};
}
&:disabled {
background-color: ${({ theme, altDisabledStyle, disabled }) =>
altDisabledStyle ? (disabled ? theme.primary1 : theme.bg2) : theme.bg2};
altDisabledStyle ? (disabled ? theme.deprecated_primary1 : theme.deprecated_bg2) : theme.deprecated_bg2};
color: ${({ altDisabledStyle, disabled, theme }) =>
altDisabledStyle ? (disabled ? theme.white : theme.text2) : theme.text2};
altDisabledStyle ? (disabled ? theme.deprecated_white : theme.deprecated_text2) : theme.deprecated_text2};
cursor: auto;
box-shadow: none;
border: 1px solid transparent;
@@ -78,26 +78,26 @@ export const ButtonPrimary = styled(BaseButton)`
`
export const ButtonLight = styled(BaseButton)`
background-color: ${({ theme }) => theme.primary5};
color: ${({ theme }) => theme.primaryText1};
background-color: ${({ theme }) => theme.deprecated_primary5};
color: ${({ theme }) => theme.deprecated_primaryText1};
font-size: 16px;
font-weight: 500;
&:focus {
box-shadow: 0 0 0 1pt ${({ theme, disabled }) => !disabled && darken(0.03, theme.primary5)};
background-color: ${({ theme, disabled }) => !disabled && darken(0.03, theme.primary5)};
box-shadow: 0 0 0 1pt ${({ theme, disabled }) => !disabled && darken(0.03, theme.deprecated_primary5)};
background-color: ${({ theme, disabled }) => !disabled && darken(0.03, theme.deprecated_primary5)};
}
&:hover {
background-color: ${({ theme, disabled }) => !disabled && darken(0.03, theme.primary5)};
background-color: ${({ theme, disabled }) => !disabled && darken(0.03, theme.deprecated_primary5)};
}
&:active {
box-shadow: 0 0 0 1pt ${({ theme, disabled }) => !disabled && darken(0.05, theme.primary5)};
background-color: ${({ theme, disabled }) => !disabled && darken(0.05, theme.primary5)};
box-shadow: 0 0 0 1pt ${({ theme, disabled }) => !disabled && darken(0.05, theme.deprecated_primary5)};
background-color: ${({ theme, disabled }) => !disabled && darken(0.05, theme.deprecated_primary5)};
}
:disabled {
opacity: 0.4;
:hover {
cursor: auto;
background-color: ${({ theme }) => theme.primary5};
background-color: ${({ theme }) => theme.deprecated_primary5};
box-shadow: none;
border: 1px solid transparent;
outline: none;
@@ -106,37 +106,37 @@ export const ButtonLight = styled(BaseButton)`
`
export const ButtonGray = styled(BaseButton)`
background-color: ${({ theme }) => theme.bg1};
color: ${({ theme }) => theme.text2};
background-color: ${({ theme }) => theme.deprecated_bg1};
color: ${({ theme }) => theme.deprecated_text2};
font-size: 16px;
font-weight: 500;
&:hover {
background-color: ${({ theme, disabled }) => !disabled && darken(0.05, theme.bg2)};
background-color: ${({ theme, disabled }) => !disabled && darken(0.05, theme.deprecated_bg2)};
}
&:active {
background-color: ${({ theme, disabled }) => !disabled && darken(0.1, theme.bg2)};
background-color: ${({ theme, disabled }) => !disabled && darken(0.1, theme.deprecated_bg2)};
}
`
export const ButtonSecondary = styled(BaseButton)`
border: 1px solid ${({ theme }) => theme.primary4};
color: ${({ theme }) => theme.primary1};
border: 1px solid ${({ theme }) => theme.deprecated_primary4};
color: ${({ theme }) => theme.deprecated_primary1};
background-color: transparent;
font-size: 16px;
border-radius: 12px;
padding: ${({ padding }) => (padding ? padding : '10px')};
&:focus {
box-shadow: 0 0 0 1pt ${({ theme }) => theme.primary4};
border: 1px solid ${({ theme }) => theme.primary3};
box-shadow: 0 0 0 1pt ${({ theme }) => theme.deprecated_primary4};
border: 1px solid ${({ theme }) => theme.deprecated_primary3};
}
&:hover {
border: 1px solid ${({ theme }) => theme.primary3};
border: 1px solid ${({ theme }) => theme.deprecated_primary3};
}
&:active {
box-shadow: 0 0 0 1pt ${({ theme }) => theme.primary4};
border: 1px solid ${({ theme }) => theme.primary3};
box-shadow: 0 0 0 1pt ${({ theme }) => theme.deprecated_primary4};
border: 1px solid ${({ theme }) => theme.deprecated_primary3};
}
&:disabled {
opacity: 50%;
@@ -148,17 +148,17 @@ export const ButtonSecondary = styled(BaseButton)`
`
export const ButtonOutlined = styled(BaseButton)`
border: 1px solid ${({ theme }) => theme.bg2};
border: 1px solid ${({ theme }) => theme.deprecated_bg2};
background-color: transparent;
color: ${({ theme }) => theme.text1};
color: ${({ theme }) => theme.deprecated_text1};
&:focus {
box-shadow: 0 0 0 1px ${({ theme }) => theme.bg4};
box-shadow: 0 0 0 1px ${({ theme }) => theme.deprecated_bg4};
}
&:hover {
box-shadow: 0 0 0 1px ${({ theme }) => theme.bg4};
box-shadow: 0 0 0 1px ${({ theme }) => theme.deprecated_bg4};
}
&:active {
box-shadow: 0 0 0 1px ${({ theme }) => theme.bg4};
box-shadow: 0 0 0 1px ${({ theme }) => theme.deprecated_bg4};
}
&:disabled {
opacity: 50%;
@@ -167,21 +167,21 @@ export const ButtonOutlined = styled(BaseButton)`
`
export const ButtonYellow = styled(BaseButton)`
background-color: ${({ theme }) => theme.yellow3};
background-color: ${({ theme }) => theme.deprecated_yellow3};
color: white;
&:focus {
box-shadow: 0 0 0 1pt ${({ theme }) => darken(0.05, theme.yellow3)};
background-color: ${({ theme }) => darken(0.05, theme.yellow3)};
box-shadow: 0 0 0 1pt ${({ theme }) => darken(0.05, theme.deprecated_yellow3)};
background-color: ${({ theme }) => darken(0.05, theme.deprecated_yellow3)};
}
&:hover {
background-color: ${({ theme }) => darken(0.05, theme.yellow3)};
background-color: ${({ theme }) => darken(0.05, theme.deprecated_yellow3)};
}
&:active {
box-shadow: 0 0 0 1pt ${({ theme }) => darken(0.1, theme.yellow3)};
background-color: ${({ theme }) => darken(0.1, theme.yellow3)};
box-shadow: 0 0 0 1pt ${({ theme }) => darken(0.1, theme.deprecated_yellow3)};
background-color: ${({ theme }) => darken(0.1, theme.deprecated_yellow3)};
}
&:disabled {
background-color: ${({ theme }) => theme.yellow3};
background-color: ${({ theme }) => theme.deprecated_yellow3};
opacity: 50%;
cursor: auto;
}
@@ -189,7 +189,7 @@ export const ButtonYellow = styled(BaseButton)`
export const ButtonEmpty = styled(BaseButton)`
background-color: transparent;
color: ${({ theme }) => theme.primary1};
color: ${({ theme }) => theme.deprecated_primary1};
display: flex;
justify-content: center;
align-items: center;
@@ -232,39 +232,39 @@ export const ButtonText = styled(BaseButton)`
`
const ButtonConfirmedStyle = styled(BaseButton)`
background-color: ${({ theme }) => theme.bg3};
color: ${({ theme }) => theme.text1};
/* border: 1px solid ${({ theme }) => theme.green1}; */
background-color: ${({ theme }) => theme.deprecated_bg3};
color: ${({ theme }) => theme.deprecated_text1};
/* border: 1px solid ${({ theme }) => theme.deprecated_green1}; */
&:disabled {
opacity: 50%;
background-color: ${({ theme }) => theme.bg2};
color: ${({ theme }) => theme.text2};
background-color: ${({ theme }) => theme.deprecated_bg2};
color: ${({ theme }) => theme.deprecated_text2};
cursor: auto;
}
`
const ButtonErrorStyle = styled(BaseButton)`
background-color: ${({ theme }) => theme.red1};
border: 1px solid ${({ theme }) => theme.red1};
background-color: ${({ theme }) => theme.deprecated_red1};
border: 1px solid ${({ theme }) => theme.deprecated_red1};
&:focus {
box-shadow: 0 0 0 1pt ${({ theme }) => darken(0.05, theme.red1)};
background-color: ${({ theme }) => darken(0.05, theme.red1)};
box-shadow: 0 0 0 1pt ${({ theme }) => darken(0.05, theme.deprecated_red1)};
background-color: ${({ theme }) => darken(0.05, theme.deprecated_red1)};
}
&:hover {
background-color: ${({ theme }) => darken(0.05, theme.red1)};
background-color: ${({ theme }) => darken(0.05, theme.deprecated_red1)};
}
&:active {
box-shadow: 0 0 0 1pt ${({ theme }) => darken(0.1, theme.red1)};
background-color: ${({ theme }) => darken(0.1, theme.red1)};
box-shadow: 0 0 0 1pt ${({ theme }) => darken(0.1, theme.deprecated_red1)};
background-color: ${({ theme }) => darken(0.1, theme.deprecated_red1)};
}
&:disabled {
opacity: 50%;
cursor: auto;
box-shadow: none;
background-color: ${({ theme }) => theme.red1};
border: 1px solid ${({ theme }) => theme.red1};
background-color: ${({ theme }) => theme.deprecated_red1};
border: 1px solid ${({ theme }) => theme.deprecated_red1};
}
`
@@ -312,14 +312,14 @@ export function ButtonDropdownLight({ disabled = false, children, ...rest }: { d
const ActiveOutlined = styled(ButtonOutlined)`
border: 1px solid;
border-color: ${({ theme }) => theme.primary1};
border-color: ${({ theme }) => theme.deprecated_primary1};
`
const Circle = styled.div`
height: 17px;
width: 17px;
border-radius: 50%;
background-color: ${({ theme }) => theme.primary1};
background-color: ${({ theme }) => theme.deprecated_primary1};
display: flex;
align-items: center;
justify-content: center;
@@ -354,7 +354,7 @@ export function ButtonRadioChecked({ active = false, children, ...rest }: { acti
{children}
<CheckboxWrapper>
<Circle>
<ResponsiveCheck size={13} stroke={theme.white} />
<ResponsiveCheck size={13} stroke={theme.deprecated_white} />
</Circle>
</CheckboxWrapper>
</RowBetween>

View File

@@ -10,38 +10,38 @@ const Card = styled(Box)<{ width?: string; padding?: string; border?: string; $b
export default Card
export const LightCard = styled(Card)`
border: 1px solid ${({ theme }) => theme.bg2};
background-color: ${({ theme }) => theme.bg1};
border: 1px solid ${({ theme }) => theme.deprecated_bg2};
background-color: ${({ theme }) => theme.deprecated_bg1};
`
export const LightGreyCard = styled(Card)`
background-color: ${({ theme }) => theme.bg2};
background-color: ${({ theme }) => theme.deprecated_bg2};
`
export const GreyCard = styled(Card)`
background-color: ${({ theme }) => theme.bg3};
background-color: ${({ theme }) => theme.deprecated_bg3};
`
export const DarkGreyCard = styled(Card)`
background-color: ${({ theme }) => theme.bg2};
background-color: ${({ theme }) => theme.deprecated_bg2};
`
export const DarkCard = styled(Card)`
background-color: ${({ theme }) => theme.bg0};
background-color: ${({ theme }) => theme.deprecated_bg0};
`
export const OutlineCard = styled(Card)`
border: 1px solid ${({ theme }) => theme.bg3};
border: 1px solid ${({ theme }) => theme.deprecated_bg3};
`
export const YellowCard = styled(Card)`
background-color: rgba(243, 132, 30, 0.05);
color: ${({ theme }) => theme.yellow3};
color: ${({ theme }) => theme.deprecated_yellow3};
font-weight: 500;
`
export const BlueCard = styled(Card)`
background-color: ${({ theme }) => theme.primary5};
color: ${({ theme }) => theme.blue2};
background-color: ${({ theme }) => theme.deprecated_primary5};
color: ${({ theme }) => theme.deprecated_blue2};
border-radius: 12px;
`

View File

@@ -16,7 +16,7 @@ const ContentWrapper = styled(Column)`
const WarningIcon = styled(AlertOctagon)`
min-height: 22px;
min-width: 22px;
color: ${({ theme }) => theme.warning};
color: ${({ theme }) => theme.deprecated_warning};
`
const Copy = styled(CopyHelper)`
font-size: 12px;
@@ -49,7 +49,7 @@ export default function ConnectedAccountBlocked(props: ConnectedAccountBlockedPr
<ThemedText.Main fontSize={12}>
<Trans>If you believe this is an error, please send an email including your address to </Trans>{' '}
</ThemedText.Main>
<Copy iconSize={12} toCopy="compliance@uniswap.org" color={theme.primary1} iconPosition="right">
<Copy iconSize={12} toCopy="compliance@uniswap.org" color={theme.deprecated_primary1} iconPosition="right">
compliance@uniswap.org
</Copy>
</ContentWrapper>

View File

@@ -20,24 +20,24 @@ export function FiatValue({
const theme = useTheme()
const priceImpactColor = useMemo(() => {
if (!priceImpact) return undefined
if (priceImpact.lessThan('0')) return theme.green1
if (priceImpact.lessThan('0')) return theme.deprecated_green1
const severity = warningSeverity(priceImpact)
if (severity < 1) return theme.text3
if (severity < 3) return theme.yellow1
return theme.red1
}, [priceImpact, theme.green1, theme.red1, theme.text3, theme.yellow1])
if (severity < 1) return theme.deprecated_text3
if (severity < 3) return theme.deprecated_yellow1
return theme.deprecated_red1
}, [priceImpact, theme.deprecated_green1, theme.deprecated_red1, theme.deprecated_text3, theme.deprecated_yellow1])
const p = Number(fiatValue?.toFixed())
const visibleDecimalPlaces = p < 1.05 ? 4 : 2
return (
<ThemedText.Body fontSize={14} color={fiatValue ? theme.text3 : theme.text4}>
<ThemedText.Body fontSize={14} color={fiatValue ? theme.deprecated_text3 : theme.deprecated_text4}>
{fiatValue ? (
<Trans>
$
<HoverInlineText
text={fiatValue?.toFixed(visibleDecimalPlaces, { groupSeparator: ',' })}
textColor={fiatValue ? theme.text3 : theme.text4}
textColor={fiatValue ? theme.deprecated_text3 : theme.deprecated_text4}
/>
</Trans>
) : (

View File

@@ -1,9 +1,12 @@
import { Trans } from '@lingui/macro'
import { Currency, CurrencyAmount, Percent, Token } from '@uniswap/sdk-core'
import { Pair } from '@uniswap/v2-sdk'
import { useWeb3React } from '@web3-react/core'
import { ElementName, Event, EventName } from 'components/AmplitudeAnalytics/constants'
import { TraceEvent } from 'components/AmplitudeAnalytics/TraceEvent'
import { AutoColumn } from 'components/Column'
import { LoadingOpacityContainer, loadingOpacityMixin } from 'components/Loader/styled'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { isSupportedChain } from 'constants/chains'
import { darken } from 'polished'
import { ReactNode, useCallback, useState } from 'react'
import { Lock } from 'react-feather'
@@ -12,7 +15,7 @@ import { formatCurrencyAmount } from 'utils/formatCurrencyAmount'
import { ReactComponent as DropDown } from '../../assets/images/dropdown.svg'
import useTheme from '../../hooks/useTheme'
import { useCurrencyBalance } from '../../state/wallet/hooks'
import { useCurrencyBalance } from '../../state/connection/hooks'
import { ThemedText } from '../../theme'
import { ButtonGray } from '../Button'
import CurrencyLogo from '../CurrencyLogo'
@@ -26,7 +29,7 @@ const InputPanel = styled.div<{ hideInput?: boolean }>`
${({ theme }) => theme.flexColumnNoWrap}
position: relative;
border-radius: ${({ hideInput }) => (hideInput ? '16px' : '20px')};
background-color: ${({ theme, hideInput }) => (hideInput ? 'transparent' : theme.bg2)};
background-color: ${({ theme, hideInput }) => (hideInput ? 'transparent' : theme.deprecated_bg2)};
z-index: 1;
width: ${({ hideInput }) => (hideInput ? '100%' : 'initial')};
transition: height 1s ease;
@@ -38,30 +41,40 @@ const FixedContainer = styled.div`
height: 100%;
position: absolute;
border-radius: 20px;
background-color: ${({ theme }) => theme.bg2};
background-color: ${({ theme }) => theme.deprecated_bg2};
display: flex;
align-items: center;
justify-content: center;
z-index: 2;
`
const Container = styled.div<{ hideInput: boolean }>`
const Container = styled.div<{ hideInput: boolean; disabled: boolean }>`
border-radius: ${({ hideInput }) => (hideInput ? '16px' : '20px')};
border: 1px solid ${({ theme }) => theme.bg0};
background-color: ${({ theme }) => theme.bg1};
border: 1px solid ${({ theme }) => theme.deprecated_bg0};
background-color: ${({ theme }) => theme.deprecated_bg1};
width: ${({ hideInput }) => (hideInput ? '100%' : 'initial')};
:focus,
:hover {
border: 1px solid ${({ theme, hideInput }) => (hideInput ? ' transparent' : theme.bg3)};
}
${({ theme, hideInput, disabled }) =>
!disabled &&
`
:focus,
:hover {
border: 1px solid ${hideInput ? ' transparent' : theme.deprecated_bg3};
}
`}
`
const CurrencySelect = styled(ButtonGray)<{ visible: boolean; selected: boolean; hideInput?: boolean }>`
const CurrencySelect = styled(ButtonGray)<{
visible: boolean
selected: boolean
hideInput?: boolean
disabled?: boolean
}>`
align-items: center;
background-color: ${({ selected, theme }) => (selected ? theme.bg2 : theme.primary1)};
background-color: ${({ selected, theme }) => (selected ? theme.deprecated_bg2 : theme.deprecated_primary1)};
opacity: ${({ disabled }) => (!disabled ? 1 : 0.4)};
box-shadow: ${({ selected }) => (selected ? 'none' : '0px 6px 10px rgba(0, 0, 0, 0.075)')};
box-shadow: 0px 6px 10px rgba(0, 0, 0, 0.075);
color: ${({ selected, theme }) => (selected ? theme.text1 : theme.white)};
color: ${({ selected, theme }) => (selected ? theme.deprecated_text1 : theme.deprecated_white)};
cursor: pointer;
border-radius: 16px;
outline: none;
@@ -76,7 +89,8 @@ const CurrencySelect = styled(ButtonGray)<{ visible: boolean; selected: boolean;
margin-left: ${({ hideInput }) => (hideInput ? '0' : '12px')};
:focus,
:hover {
background-color: ${({ selected, theme }) => (selected ? theme.bg3 : darken(0.05, theme.primary1))};
background-color: ${({ selected, theme }) =>
selected ? theme.deprecated_bg3 : darken(0.05, theme.deprecated_primary1)};
}
visibility: ${({ visible }) => (visible ? 'visible' : 'hidden')};
`
@@ -91,18 +105,19 @@ const InputRow = styled.div<{ selected: boolean }>`
const LabelRow = styled.div`
${({ theme }) => theme.flexRowNoWrap}
align-items: center;
color: ${({ theme }) => theme.text1};
color: ${({ theme }) => theme.deprecated_text1};
font-size: 0.75rem;
line-height: 1rem;
padding: 0 1rem 1rem;
span:hover {
cursor: pointer;
color: ${({ theme }) => darken(0.2, theme.text2)};
color: ${({ theme }) => darken(0.2, theme.deprecated_text2)};
}
`
const FiatRow = styled(LabelRow)`
justify-content: flex-end;
height: 16px;
`
const Aligner = styled.span`
@@ -117,7 +132,7 @@ const StyledDropDown = styled(DropDown)<{ selected: boolean }>`
height: 35%;
path {
stroke: ${({ selected, theme }) => (selected ? theme.text1 : theme.white)};
stroke: ${({ selected, theme }) => (selected ? theme.deprecated_text1 : theme.deprecated_white)};
stroke-width: 1.5px;
}
`
@@ -129,10 +144,10 @@ const StyledTokenName = styled.span<{ active?: boolean }>`
const StyledBalanceMax = styled.button<{ disabled?: boolean }>`
background-color: transparent;
background-color: ${({ theme }) => theme.primary5};
background-color: ${({ theme }) => theme.deprecated_primary5};
border: none;
border-radius: 12px;
color: ${({ theme }) => theme.primary1};
color: ${({ theme }) => theme.deprecated_primary1};
cursor: pointer;
font-size: 11px;
font-weight: 500;
@@ -201,7 +216,7 @@ export default function CurrencyInputPanel({
...rest
}: CurrencyInputPanelProps) {
const [modalOpen, setModalOpen] = useState(false)
const { account } = useActiveWeb3React()
const { account, chainId } = useWeb3React()
const selectedCurrencyBalance = useCurrencyBalance(account ?? undefined, currency ?? undefined)
const theme = useTheme()
@@ -209,6 +224,8 @@ export default function CurrencyInputPanel({
setModalOpen(false)
}, [setModalOpen])
const chainAllowed = isSupportedChain(chainId)
return (
<InputPanel id={id} hideInput={hideInput} {...rest}>
{locked && (
@@ -221,18 +238,20 @@ export default function CurrencyInputPanel({
</AutoColumn>
</FixedContainer>
)}
<Container hideInput={hideInput}>
<Container hideInput={hideInput} disabled={!chainAllowed}>
<InputRow style={hideInput ? { padding: '0', borderRadius: '8px' } : {}} selected={!onCurrencySelect}>
{!hideInput && (
<StyledNumericalInput
className="token-amount-input"
value={value}
onUserInput={onUserInput}
disabled={!chainAllowed}
$loading={loading}
/>
)}
<CurrencySelect
disabled={!chainAllowed}
visible={currency !== undefined}
selected={!!currency}
hideInput={hideInput}
@@ -280,7 +299,7 @@ export default function CurrencyInputPanel({
<RowFixed style={{ height: '17px' }}>
<ThemedText.Body
onClick={onMax}
color={theme.text3}
color={theme.deprecated_text3}
fontWeight={500}
fontSize={14}
style={{ display: 'inline', cursor: 'pointer' }}
@@ -294,9 +313,15 @@ export default function CurrencyInputPanel({
) : null}
</ThemedText.Body>
{showMaxButton && selectedCurrencyBalance ? (
<StyledBalanceMax onClick={onMax}>
<Trans>MAX</Trans>
</StyledBalanceMax>
<TraceEvent
events={[Event.onClick]}
name={EventName.SWAP_MAX_TOKEN_AMOUNT_SELECTED}
element={ElementName.MAX_TOKEN_AMOUNT_BUTTON}
>
<StyledBalanceMax onClick={onMax}>
<Trans>MAX</Trans>
</StyledBalanceMax>
</TraceEvent>
) : null}
</RowFixed>
) : (

View File

@@ -1,6 +1,6 @@
import { Trans } from '@lingui/macro'
import { useWeb3React } from '@web3-react/core'
import { SupportedChainId } from 'constants/chains'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { AlertOctagon } from 'react-feather'
import styled from 'styled-components/macro'
import { ExternalLink } from 'theme'
@@ -42,7 +42,7 @@ function Wrapper({ children }: { children: React.ReactNode }) {
* Shows a downtime warning for the network if it's relevant
*/
export default function DowntimeWarning() {
const { chainId } = useActiveWeb3React()
const { chainId } = useWeb3React()
if (!isL2ChainId(chainId)) {
return null
}

View File

@@ -1,6 +1,6 @@
import { Trans } from '@lingui/macro'
import { sendEvent } from 'components/analytics'
import React, { ErrorInfo } from 'react'
import React, { ErrorInfo, PropsWithChildren } from 'react'
import styled from 'styled-components/macro'
import store, { AppState } from '../../state'
@@ -24,18 +24,18 @@ const BodyWrapper = styled.div<{ margin?: string }>`
`
const CodeBlockWrapper = styled.div`
background: ${({ theme }) => theme.bg0};
background: ${({ theme }) => theme.deprecated_bg0};
overflow: auto;
white-space: pre;
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: 24px;
padding: 18px 24px;
color: ${({ theme }) => theme.text1};
color: ${({ theme }) => theme.deprecated_text1};
`
const LinkWrapper = styled.div`
color: ${({ theme }) => theme.blue1};
color: ${({ theme }) => theme.deprecated_blue1};
padding: 6px 24px;
`
@@ -56,8 +56,8 @@ async function updateServiceWorker(): Promise<ServiceWorkerRegistration> {
return ready.update() as unknown as Promise<ServiceWorkerRegistration>
}
export default class ErrorBoundary extends React.Component<unknown, ErrorBoundaryState> {
constructor(props: unknown) {
export default class ErrorBoundary extends React.Component<PropsWithChildren<unknown>, ErrorBoundaryState> {
constructor(props: PropsWithChildren<unknown>) {
super(props)
this.state = { error: null }
}

View File

@@ -1,12 +1,12 @@
import { Trans } from '@lingui/macro'
import { Currency } from '@uniswap/sdk-core'
import { FeeAmount } from '@uniswap/v3-sdk'
import { useWeb3React } from '@web3-react/core'
import { sendEvent } from 'components/analytics'
import { ButtonGray } from 'components/Button'
import Card from 'components/Card'
import { AutoColumn } from 'components/Column'
import { RowBetween } from 'components/Row'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useFeeTierDistribution } from 'hooks/useFeeTierDistribution'
import { PoolState, usePools } from 'hooks/usePools'
import usePrevious from 'hooks/usePrevious'
@@ -34,8 +34,8 @@ const pulse = (color: string) => keyframes`
}
`
const FocusedOutlineCard = styled(Card)<{ pulsing: boolean }>`
border: 1px solid ${({ theme }) => theme.bg2};
animation: ${({ pulsing, theme }) => pulsing && pulse(theme.primary1)} 0.6s linear;
border: 1px solid ${({ theme }) => theme.deprecated_bg2};
animation: ${({ pulsing, theme }) => pulsing && pulse(theme.deprecated_primary1)} 0.6s linear;
align-self: center;
`
@@ -59,7 +59,7 @@ export default function FeeSelector({
currencyA?: Currency | undefined
currencyB?: Currency | undefined
}) {
const { chainId } = useActiveWeb3React()
const { chainId } = useWeb3React()
const { isLoading, isError, largestUsageFeeTier, distributions } = useFeeTierDistribution(currencyA, currencyB)

View File

@@ -1,7 +1,7 @@
import { Trans } from '@lingui/macro'
import { FeeAmount } from '@uniswap/v3-sdk'
import { ALL_SUPPORTED_CHAIN_IDS, SupportedChainId } from 'constants/chains'
import { ReactNode } from 'react'
import type { ReactNode } from 'react'
export const FEE_AMOUNT_DETAIL: Record<
FeeAmount,
@@ -10,7 +10,14 @@ export const FEE_AMOUNT_DETAIL: Record<
[FeeAmount.LOWEST]: {
label: '0.01',
description: <Trans>Best for very stable pairs.</Trans>,
supportedChains: [SupportedChainId.MAINNET, SupportedChainId.POLYGON, SupportedChainId.POLYGON_MUMBAI],
supportedChains: [
SupportedChainId.MAINNET,
SupportedChainId.POLYGON,
SupportedChainId.POLYGON_MUMBAI,
SupportedChainId.CELO,
SupportedChainId.CELO_ALFAJORES,
SupportedChainId.OPTIMISM,
],
},
[FeeAmount.LOW]: {
label: '0.05',

View File

@@ -1,20 +1,20 @@
import { Trans } from '@lingui/macro'
import { CHAIN_INFO, L2ChainInfo } from 'constants/chainInfo'
import { useWeb3React } from '@web3-react/core'
import { getChainInfoOrDefault, L2ChainInfo } from 'constants/chainInfo'
import { SupportedChainId } from 'constants/chains'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { AlertOctagon } from 'react-feather'
import styled from 'styled-components/macro'
import { ExternalLink, MEDIA_WIDTHS } from 'theme'
const BodyRow = styled.div`
color: ${({ theme }) => theme.black};
color: ${({ theme }) => theme.deprecated_black};
font-size: 12px;
`
const CautionIcon = styled(AlertOctagon)`
color: ${({ theme }) => theme.black};
color: ${({ theme }) => theme.deprecated_black};
`
const Link = styled(ExternalLink)`
color: ${({ theme }) => theme.black};
color: ${({ theme }) => theme.deprecated_black};
text-decoration: underline;
`
const TitleRow = styled.div`
@@ -31,7 +31,7 @@ const TitleText = styled.div`
margin: 0px 12px;
`
const Wrapper = styled.div`
background-color: ${({ theme }) => theme.yellow3};
background-color: ${({ theme }) => theme.deprecated_yellow3};
border-radius: 12px;
bottom: 60px;
display: none;
@@ -45,8 +45,8 @@ const Wrapper = styled.div`
`
export function ChainConnectivityWarning() {
const { chainId } = useActiveWeb3React()
const info = CHAIN_INFO[chainId ?? SupportedChainId.MAINNET]
const { chainId } = useWeb3React()
const info = getChainInfoOrDefault(chainId)
const label = info?.label
return (

View File

@@ -1,23 +1,24 @@
import { Trans } from '@lingui/macro'
import { getWalletForConnector } from 'connectors'
import { CHAIN_INFO } from 'constants/chainInfo'
import { useWeb3React } from '@web3-react/core'
import { getConnection } from 'connection/utils'
import { getChainInfo } from 'constants/chainInfo'
import { CHAIN_IDS_TO_NAMES, SupportedChainId } from 'constants/chains'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useOnClickOutside } from 'hooks/useOnClickOutside'
import useParsedQueryString from 'hooks/useParsedQueryString'
import usePrevious from 'hooks/usePrevious'
import { darken } from 'polished'
import { ParsedQs } from 'qs'
import { useCallback, useEffect, useRef } from 'react'
import { ArrowDownCircle, ChevronDown } from 'react-feather'
import { useCallback, useEffect, useRef, useState } from 'react'
import { AlertTriangle, ArrowDownCircle, ChevronDown } from 'react-feather'
import { useHistory } from 'react-router-dom'
import { useModalOpen, useToggleModal } from 'state/application/hooks'
import { useCloseModal, useModalIsOpen, useOpenModal, useToggleModal } from 'state/application/hooks'
import { addPopup, ApplicationModal } from 'state/application/reducer'
import { updateConnectionError } from 'state/connection/reducer'
import { useAppDispatch } from 'state/hooks'
import { updateWalletError } from 'state/wallet/reducer'
import styled from 'styled-components/macro'
import { ExternalLink, MEDIA_WIDTHS } from 'theme'
import { replaceURLParam } from 'utils/routes'
import { isChainAllowed, switchChain } from 'utils/switchChain'
import { isMobile } from 'utils/userAgent'
const ActiveRowLinkList = styled.div`
display: flex;
@@ -25,7 +26,7 @@ const ActiveRowLinkList = styled.div`
padding: 0 8px;
& > a {
align-items: center;
color: ${({ theme }) => theme.text2};
color: ${({ theme }) => theme.deprecated_text2};
display: flex;
flex-direction: row;
font-size: 14px;
@@ -41,14 +42,14 @@ const ActiveRowLinkList = styled.div`
}
`
const ActiveRowWrapper = styled.div`
background-color: ${({ theme }) => theme.bg1};
background-color: ${({ theme }) => theme.deprecated_bg1};
border-radius: 8px;
cursor: pointer;
padding: 8px;
width: 100%;
`
const FlyoutHeader = styled.div`
color: ${({ theme }) => theme.text2};
color: ${({ theme }) => theme.deprecated_text2};
font-weight: 400;
`
const FlyoutMenu = styled.div`
@@ -63,7 +64,7 @@ const FlyoutMenu = styled.div`
`
const FlyoutMenuContents = styled.div`
align-items: flex-start;
background-color: ${({ theme }) => theme.bg0};
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;
@@ -78,7 +79,7 @@ const FlyoutMenuContents = styled.div`
`
const FlyoutRow = styled.div<{ active: boolean }>`
align-items: center;
background-color: ${({ active, theme }) => (active ? theme.bg1 : 'transparent')};
background-color: ${({ active, theme }) => (active ? theme.deprecated_bg1 : 'transparent')};
border-radius: 8px;
cursor: pointer;
display: flex;
@@ -89,7 +90,7 @@ const FlyoutRow = styled.div<{ active: boolean }>`
width: 100%;
`
const FlyoutRowActiveIndicator = styled.div`
background-color: ${({ theme }) => theme.green1};
background-color: ${({ theme }) => theme.deprecated_green1};
border-radius: 50%;
height: 9px;
width: 9px;
@@ -121,20 +122,41 @@ const SelectorLabel = styled(NetworkLabel)`
margin-right: 8px;
}
`
const SelectorControls = styled.div<{ interactive: boolean }>`
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.upToSmall}px) {
display: block;
}
`
const SelectorControls = styled.div<{ supportedChain: boolean }>`
align-items: center;
background-color: ${({ theme }) => theme.bg0};
border: 2px solid ${({ theme }) => theme.bg0};
background-color: ${({ theme }) => theme.deprecated_bg0};
border: 2px solid ${({ theme }) => theme.deprecated_bg0};
border-radius: 16px;
color: ${({ theme }) => theme.text1};
cursor: ${({ interactive }) => (interactive ? 'pointer' : 'auto')};
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};
`}
:focus {
background-color: ${({ theme }) => darken(0.1, theme.deprecated_red1)};
}
`
const SelectorLogo = styled(Logo)<{ interactive?: boolean }>`
margin-right: ${({ interactive }) => (interactive ? 8 : 0)}px;
const SelectorLogo = styled(Logo)`
@media screen and (min-width: ${MEDIA_WIDTHS.upToSmall}px) {
margin-right: 8px;
}
@@ -147,6 +169,14 @@ const SelectorWrapper = styled.div`
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:
@@ -158,6 +188,9 @@ const BridgeLabel = ({ chainId }: { chainId: SupportedChainId }) => {
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>
}
@@ -173,6 +206,9 @@ const ExplorerLabel = ({ chainId }: { chainId: SupportedChainId }) => {
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>
}
@@ -185,12 +221,12 @@ function Row({
targetChain: SupportedChainId
onSelectChain: (targetChain: number) => void
}) {
const { provider, chainId } = useActiveWeb3React()
const { provider, chainId } = useWeb3React()
if (!provider || !chainId) {
return null
}
const active = chainId === targetChain
const { helpCenterUrl, explorer, bridge, label, logoUrl } = CHAIN_INFO[targetChain]
const { helpCenterUrl, explorer, bridge, label, logoUrl } = getChainInfo(targetChain)
const rowContent = (
<FlyoutRow onClick={() => onSelectChain(targetChain)} active={active}>
@@ -242,9 +278,9 @@ function Row({
const getParsedChainId = (parsedQs?: ParsedQs) => {
const chain = parsedQs?.chain
if (!chain || typeof chain !== 'string') return { urlChain: undefined, urlChainId: undefined }
if (!chain || typeof chain !== 'string') return
return { urlChain: chain.toLowerCase(), urlChainId: getChainIdFromName(chain) }
return getChainIdFromName(chain)
}
const getChainIdFromName = (name: string) => {
@@ -263,86 +299,126 @@ const NETWORK_SELECTOR_CHAINS = [
SupportedChainId.POLYGON,
SupportedChainId.OPTIMISM,
SupportedChainId.ARBITRUM_ONE,
SupportedChainId.CELO,
]
export default function NetworkSelector() {
const dispatch = useAppDispatch()
const { chainId, provider, connector } = useActiveWeb3React()
const previousChainId = usePrevious(chainId)
const { chainId, provider, connector, isActive } = useWeb3React()
const [previousChainId, setPreviousChainId] = useState<number | undefined>(undefined)
// Can't use `usePrevious` because `chainId` can be undefined while activating.
useEffect(() => {
if (chainId && chainId !== previousChainId) {
setPreviousChainId(chainId)
}
}, [chainId, previousChainId])
const parsedQs = useParsedQueryString()
const { urlChain, urlChainId } = getParsedChainId(parsedQs)
const urlChainId = getParsedChainId(parsedQs)
const previousUrlChainId = usePrevious(urlChainId)
const node = useRef<HTMLDivElement>()
const open = useModalOpen(ApplicationModal.NETWORK_SELECTOR)
const toggle = useToggleModal(ApplicationModal.NETWORK_SELECTOR)
useOnClickOutside(node, open ? toggle : undefined)
const history = useHistory()
const info = chainId ? CHAIN_INFO[chainId] : undefined
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 replaceURLChainParam = useCallback(() => {
if (chainId) {
history.replace({ search: replaceURLParam(history.location.search, 'chain', getChainNameFromId(chainId)) })
}
}, [chainId, history])
const onSelectChain = useCallback(
async (targetChain: number, skipToggle?: boolean) => {
async (targetChain: SupportedChainId, skipClose?: boolean) => {
if (!connector) return
const wallet = getWalletForConnector(connector)
const connectionType = getConnection(connector).type
try {
dispatch(updateWalletError({ wallet, error: undefined }))
dispatch(updateConnectionError({ connectionType, error: undefined }))
await switchChain(connector, targetChain)
} catch (error) {
console.error('Failed to switch networks', error)
dispatch(updateWalletError({ wallet, error: error.message }))
dispatch(updateConnectionError({ connectionType, error: error.message }))
dispatch(addPopup({ content: { failedSwitchNetwork: targetChain }, key: `failed-network-switch` }))
// If we activate a chain and it fails, reset the query param to the current chainId
replaceURLChainParam()
}
if (!skipToggle) {
toggle()
if (!skipClose) {
closeModal()
}
},
[connector, toggle, dispatch]
[connector, closeModal, dispatch, replaceURLChainParam]
)
// If there is no chain query param, set it to the current chain
useEffect(() => {
if (!chainId || !previousChainId) return
// when network change originates from wallet or dropdown selector, just update URL
if (chainId !== previousChainId && chainId !== urlChainId) {
history.replace({ search: replaceURLParam(history.location.search, 'chain', getChainNameFromId(chainId)) })
// otherwise assume network change originates from URL
} else if (urlChainId && urlChainId !== previousUrlChainId && urlChainId !== chainId) {
onSelectChain(urlChainId, true).catch(() => {
// we want app network <-> chainId param to be in sync, so if user changes the network by changing the URL
// but the request fails, revert the URL back to current chainId
history.replace({ search: replaceURLParam(history.location.search, 'chain', getChainNameFromId(chainId)) })
})
const chainQueryUnpopulated = !urlChainId
if (chainQueryUnpopulated && chainId) {
replaceURLChainParam()
}
}, [chainId, urlChainId, previousChainId, previousUrlChainId, onSelectChain, history])
}, [chainId, urlChainId, replaceURLChainParam])
// set chain parameter on initial load if not there
// If the chain changed but the query param is stale, update to the current chain
useEffect(() => {
if (chainId && !urlChainId) {
history.replace({ search: replaceURLParam(history.location.search, 'chain', getChainNameFromId(chainId)) })
const chainChanged = chainId !== previousChainId
const chainQueryStale = urlChainId !== chainId
if (chainChanged && chainQueryStale) {
replaceURLChainParam()
}
}, [chainId, history, urlChainId, urlChain])
}, [chainId, previousChainId, replaceURLChainParam, urlChainId])
if (!chainId || !info || !provider) {
// If the query param changed, and the chain didn't change, then activate the new chain
useEffect(() => {
const chainQueryManuallyUpdated = urlChainId && urlChainId !== previousUrlChainId
if (chainQueryManuallyUpdated && isActive) {
onSelectChain(urlChainId, true)
}
}, [onSelectChain, urlChainId, previousUrlChainId, isActive])
if (!chainId || !provider) {
return null
}
const onSupportedChain = info !== undefined
return (
<SelectorWrapper ref={node as any} onMouseEnter={toggle} onMouseLeave={toggle}>
<SelectorControls interactive>
<SelectorLogo interactive src={info.logoUrl} />
<SelectorLabel>{info.label}</SelectorLabel>
<StyledChevronDown />
<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>
{open && (
{isOpen && (
<FlyoutMenu>
<FlyoutMenuContents>
<FlyoutHeader>
<Trans>Select a network</Trans>
<Trans>Select a {!onSupportedChain ? ' supported ' : ''}network</Trans>
</FlyoutHeader>
{NETWORK_SELECTOR_CHAINS.map((chainId: SupportedChainId) =>
isChainAllowed(connector, chainId) ? (

View File

@@ -1,7 +1,7 @@
import { Trans } from '@lingui/macro'
import { useWeb3React } from '@web3-react/core'
import { RowFixed } from 'components/Row'
import { CHAIN_INFO } from 'constants/chainInfo'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { getChainInfo } from 'constants/chainInfo'
import useCurrentBlockTimestamp from 'hooks/useCurrentBlockTimestamp'
import useGasPrice from 'hooks/useGasPrice'
import useMachineTimeMs from 'hooks/useMachineTime'
@@ -24,7 +24,7 @@ const StyledPolling = styled.div<{ warning: boolean }>`
right: 0;
bottom: 0;
padding: 1rem;
color: ${({ theme, warning }) => (warning ? theme.yellow3 : theme.green1)};
color: ${({ theme, warning }) => (warning ? theme.deprecated_yellow3 : theme.deprecated_green1)};
transition: 250ms ease color;
${({ theme }) => theme.mediaWidth.upToMedium`
@@ -53,12 +53,12 @@ const StyledPollingDot = styled.div<{ warning: boolean }>`
min-width: 8px;
border-radius: 50%;
position: relative;
background-color: ${({ theme, warning }) => (warning ? theme.yellow3 : theme.green1)};
background-color: ${({ theme, warning }) => (warning ? theme.deprecated_yellow3 : theme.deprecated_green1)};
transition: 250ms ease background-color;
`
const StyledGasDot = styled.div`
background-color: ${({ theme }) => theme.text3};
background-color: ${({ theme }) => theme.deprecated_text3};
border-radius: 50%;
height: 4px;
min-height: 4px;
@@ -84,7 +84,7 @@ const Spinner = styled.div<{ warning: boolean }>`
border-top: 1px solid transparent;
border-right: 1px solid transparent;
border-bottom: 1px solid transparent;
border-left: 2px solid ${({ theme, warning }) => (warning ? theme.yellow3 : theme.green1)};
border-left: 2px solid ${({ theme, warning }) => (warning ? theme.deprecated_yellow3 : theme.deprecated_green1)};
background: transparent;
width: 14px;
height: 14px;
@@ -100,7 +100,7 @@ const DEFAULT_MS_BEFORE_WARNING = ms`10m`
const NETWORK_HEALTH_CHECK_MS = ms`10s`
export default function Polling() {
const { chainId } = useActiveWeb3React()
const { chainId } = useWeb3React()
const blockNumber = useBlockNumber()
const [isMounting, setIsMounting] = useState(false)
const [isHover, setIsHover] = useState(false)
@@ -112,7 +112,7 @@ export default function Polling() {
const priceGwei = ethGasPrice ? JSBI.divide(ethGasPrice, JSBI.BigInt(1000000000)) : undefined
const waitMsBeforeWarning =
(chainId ? CHAIN_INFO[chainId]?.blockWaitMsBeforeWarning : DEFAULT_MS_BEFORE_WARNING) ?? DEFAULT_MS_BEFORE_WARNING
(chainId ? getChainInfo(chainId)?.blockWaitMsBeforeWarning : DEFAULT_MS_BEFORE_WARNING) ?? DEFAULT_MS_BEFORE_WARNING
const warning = Boolean(!!blockTime && machineTime - blockTime.mul(1000).toNumber() > waitMsBeforeWarning)
@@ -143,7 +143,7 @@ export default function Polling() {
<ExternalLink href={'https://etherscan.io/gastracker'}>
{priceGwei ? (
<RowFixed style={{ marginRight: '8px' }}>
<ThemedText.Main fontSize="11px" mr="8px" color={theme.text3}>
<ThemedText.Main fontSize="11px" mr="8px" color={theme.deprecated_text3}>
<MouseoverTooltip
text={
<Trans>

View File

@@ -1,19 +1,18 @@
import { Trans } from '@lingui/macro'
import useScrollPosition from '@react-hook/window-scroll'
import { CHAIN_INFO } from 'constants/chainInfo'
import { useWeb3React } from '@web3-react/core'
import { getChainInfoOrDefault } from 'constants/chainInfo'
import { SupportedChainId } from 'constants/chains'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import useTheme from 'hooks/useTheme'
import { darken } from 'polished'
import { NavLink } 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 { useNativeCurrencyBalances } from 'state/wallet/hooks'
import styled from 'styled-components/macro'
import { isChainAllowed } from 'utils/switchChain'
import { ReactComponent as Logo } from '../../assets/svg/logo.svg'
import { ExternalLink, ThemedText } from '../../theme'
@@ -40,10 +39,10 @@ const HeaderFrame = styled.div<{ showBackground: boolean }>`
z-index: 21;
position: relative;
/* Background slide effect on scroll. */
background-image: ${({ theme }) => `linear-gradient(to bottom, transparent 50%, ${theme.bg0} 50% )}}`};
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.bg2 : 'transparent;')};
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;
@@ -89,7 +88,7 @@ const HeaderElement = styled.div`
const HeaderLinks = styled(Row)`
justify-self: center;
background-color: ${({ theme }) => theme.bg0};
background-color: ${({ theme }) => theme.deprecated_bg0};
width: fit-content;
padding: 2px;
border-radius: 16px;
@@ -99,7 +98,7 @@ const HeaderLinks = styled(Row)`
overflow: auto;
align-items: center;
${({ theme }) => theme.mediaWidth.upToLarge`
justify-self: start;
justify-self: start;
`};
${({ theme }) => theme.mediaWidth.upToMedium`
justify-self: center;
@@ -113,8 +112,8 @@ const HeaderLinks = styled(Row)`
bottom: 0; right: 50%;
transform: translate(50%,-50%);
margin: 0 auto;
background-color: ${({ theme }) => theme.bg0};
border: 1px solid ${({ theme }) => theme.bg2};
background-color: ${({ theme }) => theme.deprecated_bg0};
border: 1px solid ${({ theme }) => theme.deprecated_bg2};
box-shadow: 0px 6px 10px rgb(0 0 0 / 2%);
`};
`
@@ -123,7 +122,7 @@ const AccountElement = styled.div<{ active: boolean }>`
display: flex;
flex-direction: row;
align-items: center;
background-color: ${({ theme, active }) => (!active ? theme.bg0 : theme.bg0)};
background-color: ${({ theme, active }) => (!active ? theme.deprecated_bg0 : theme.deprecated_bg0)};
border-radius: 16px;
white-space: nowrap;
width: 100%;
@@ -139,7 +138,7 @@ const UNIAmount = styled(AccountElement)`
padding: 4px 8px;
height: 36px;
font-weight: 500;
background-color: ${({ theme }) => theme.bg3};
background-color: ${({ theme }) => theme.deprecated_bg3};
background: radial-gradient(174.47% 188.91% at 1.84% 0%, #ff007a 0%, #2172e5 100%), #edeef2;
`
@@ -197,7 +196,7 @@ const StyledNavLink = styled(NavLink).attrs({
outline: none;
cursor: pointer;
text-decoration: none;
color: ${({ theme }) => theme.text2};
color: ${({ theme }) => theme.deprecated_text2};
font-size: 1rem;
font-weight: 500;
padding: 8px 12px;
@@ -208,13 +207,13 @@ const StyledNavLink = styled(NavLink).attrs({
border-radius: 14px;
font-weight: 600;
justify-content: center;
color: ${({ theme }) => theme.text1};
background-color: ${({ theme }) => theme.bg1};
color: ${({ theme }) => theme.deprecated_text1};
background-color: ${({ theme }) => theme.deprecated_bg1};
}
:hover,
:focus {
color: ${({ theme }) => darken(0.1, theme.text1)};
color: ${({ theme }) => darken(0.1, theme.deprecated_text1)};
}
`
@@ -227,7 +226,7 @@ const StyledExternalLink = styled(ExternalLink).attrs({
outline: none;
cursor: pointer;
text-decoration: none;
color: ${({ theme }) => theme.text2};
color: ${({ theme }) => theme.deprecated_text2};
font-size: 1rem;
width: fit-content;
margin: 0 12px;
@@ -236,24 +235,22 @@ const StyledExternalLink = styled(ExternalLink).attrs({
&.${activeClassName} {
border-radius: 14px;
font-weight: 600;
color: ${({ theme }) => theme.text1};
color: ${({ theme }) => theme.deprecated_text1};
}
:hover,
:focus {
color: ${({ theme }) => darken(0.1, theme.text1)};
color: ${({ theme }) => darken(0.1, theme.deprecated_text1)};
text-decoration: none;
}
`
export default function Header() {
const { account, chainId, connector } = useActiveWeb3React()
const chainAllowed = chainId && isChainAllowed(connector, chainId)
const { account, chainId } = useWeb3React()
const userEthBalance = useNativeCurrencyBalances(account ? [account] : [])?.[account ?? '']
const [darkMode] = useDarkModeManager()
const { white, black } = useTheme()
const { deprecated_white, deprecated_black } = useTheme()
const toggleClaimModal = useToggleSelfClaimModal()
@@ -268,14 +265,14 @@ export default function Header() {
const {
infoLink,
nativeCurrency: { symbol: nativeCurrencySymbol },
} = CHAIN_INFO[!chainId || !chainAllowed ? SupportedChainId.MAINNET : chainId]
} = getChainInfoOrDefault(chainId)
return (
<HeaderFrame showBackground={scrollY > 45}>
<ClaimModal />
<Title href=".">
<UniIcon>
<Logo fill={darkMode ? white : black} width="24px" height="100%" title="logo" />
<Logo fill={darkMode ? deprecated_white : deprecated_black} width="24px" height="100%" title="logo" />
<HolidayOrnament />
</UniIcon>
</Title>
@@ -284,6 +281,7 @@ export default function Header() {
<Trans>Swap</Trans>
</StyledNavLink>
<StyledNavLink
data-cy="pool-nav-link"
id={`pool-nav-link`}
to={'/pool'}
isActive={(match, { pathname }) =>
@@ -330,7 +328,7 @@ export default function Header() {
)}
<AccountElement active={!!account}>
{account && userEthBalance ? (
<BalanceText style={{ flexShrink: 0, userSelect: 'none' }} pl="0.75rem" pr="0.5rem" fontWeight={500}>
<BalanceText style={{ flexShrink: 0, userSelect: 'none' }} pl="0.75rem" pr=".4rem" fontWeight={500}>
<Trans>
{userEthBalance?.toSignificant(3)} {nativeCurrencySymbol}
</Trans>

View File

@@ -10,7 +10,7 @@ const TextWrapper = styled.span<{
textColor?: string
}>`
margin-left: ${({ margin }) => margin && '4px'};
color: ${({ theme, link, textColor }) => (link ? theme.blue1 : textColor ?? theme.text1)};
color: ${({ theme, link, textColor }) => (link ? theme.deprecated_blue1 : textColor ?? theme.deprecated_text1)};
font-size: ${({ fontSize }) => fontSize ?? 'inherit'};
@media screen and (max-width: 600px) {

View File

@@ -1,22 +1,42 @@
import { Connector } from '@web3-react/types'
import { ConnectionType } from 'connection'
import styled from 'styled-components/macro'
import CoinbaseWalletIcon from '../../assets/images/coinbaseWalletIcon.svg'
import FortmaticIcon from '../../assets/images/fortmaticIcon.png'
import WalletConnectIcon from '../../assets/images/walletConnectIcon.svg'
import { coinbaseWallet, fortmatic, injected, walletConnect } from '../../connectors'
import Identicon from '../Identicon'
export default function StatusIcon({ connector }: { connector: Connector }) {
switch (connector) {
case injected:
return <Identicon />
case walletConnect:
return <img src={WalletConnectIcon} alt="WalletConnect" />
case coinbaseWallet:
return <img src={CoinbaseWalletIcon} alt="Coinbase Wallet" />
case fortmatic:
return <img src={FortmaticIcon} alt="Fortmatic" />
default:
return null
const IconWrapper = styled.div<{ size?: number }>`
${({ theme }) => theme.flexColumnNoWrap};
align-items: center;
justify-content: center;
margin-right: 8px;
& > img,
span {
height: ${({ size }) => (size ? size + 'px' : '32px')};
width: ${({ size }) => (size ? size + 'px' : '32px')};
}
${({ theme }) => theme.mediaWidth.upToMedium`
align-items: flex-end;
`};
`
export default function StatusIcon({ connectionType }: { connectionType: ConnectionType }) {
let image
switch (connectionType) {
case ConnectionType.INJECTED:
image = <Identicon />
break
case ConnectionType.WALLET_CONNECT:
image = <img src={WalletConnectIcon} alt="WalletConnect" />
break
case ConnectionType.COINBASE_WALLET:
image = <img src={CoinbaseWalletIcon} alt="Coinbase Wallet" />
break
case ConnectionType.FORTMATIC:
image = <img src={FortmaticIcon} alt="Fortmatic" />
break
}
return <IconWrapper size={16}>{image}</IconWrapper>
}

View File

@@ -1,5 +1,5 @@
import jazzicon from '@metamask/jazzicon'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useWeb3React } from '@web3-react/core'
import useENSAvatar from 'hooks/useENSAvatar'
import { useLayoutEffect, useMemo, useRef, useState } from 'react'
import styled from 'styled-components/macro'
@@ -8,7 +8,7 @@ const StyledIdenticon = styled.div`
height: 1rem;
width: 1rem;
border-radius: 1.125rem;
background-color: ${({ theme }) => theme.bg4};
background-color: ${({ theme }) => theme.deprecated_bg4};
font-size: initial;
`
@@ -19,7 +19,7 @@ const StyledAvatar = styled.img`
`
export default function Identicon() {
const { account } = useActiveWeb3React()
const { account } = useWeb3React()
const { avatar } = useENSAvatar(account ?? undefined)
const [fetchable, setFetchable] = useState(true)

View File

@@ -36,9 +36,9 @@ const SmallButton = styled(ButtonGray)`
`
const FocusedOutlineCard = styled(OutlineCard)<{ active?: boolean; pulsing?: boolean }>`
border-color: ${({ active, theme }) => active && theme.blue1};
border-color: ${({ active, theme }) => active && theme.deprecated_blue1};
padding: 12px;
animation: ${({ pulsing, theme }) => pulsing && pulse(theme.blue1)} 0.8s linear;
animation: ${({ pulsing, theme }) => pulsing && pulse(theme.deprecated_blue1)} 0.8s linear;
`
const StyledInput = styled(NumericalInput)<{ usePercent?: boolean }>`
@@ -58,13 +58,13 @@ const StyledInput = styled(NumericalInput)<{ usePercent?: boolean }>`
`
const InputTitle = styled(ThemedText.Small)`
color: ${({ theme }) => theme.text2};
color: ${({ theme }) => theme.deprecated_text2};
font-size: 12px;
font-weight: 500;
`
const ButtonLabel = styled(ThemedText.White)<{ disabled: boolean }>`
color: ${({ theme, disabled }) => (disabled ? theme.text2 : theme.text1)} !important;
color: ${({ theme, disabled }) => (disabled ? theme.deprecated_text2 : theme.deprecated_text1)} !important;
`
interface StepCounterProps {

View File

@@ -6,8 +6,8 @@ import { ChartEntry } from './types'
const Path = styled.path<{ fill: string | undefined }>`
opacity: 0.5;
stroke: ${({ fill, theme }) => fill ?? theme.blue2};
fill: ${({ fill, theme }) => fill ?? theme.blue2};
stroke: ${({ fill, theme }) => fill ?? theme.deprecated_blue2};
fill: ${({ fill, theme }) => fill ?? theme.deprecated_blue2};
`
export const Area = ({

View File

@@ -8,7 +8,7 @@ const StyledGroup = styled.g`
}
text {
color: ${({ theme }) => theme.text2};
color: ${({ theme }) => theme.deprecated_text2};
transform: translateY(5px);
}
`

View File

@@ -18,7 +18,7 @@ const HandleAccent = styled.path`
pointer-events: none;
stroke-width: 1.5;
stroke: ${({ theme }) => theme.white};
stroke: ${({ theme }) => theme.deprecated_white};
opacity: 0.6;
`
@@ -28,13 +28,13 @@ const LabelGroup = styled.g<{ visible: boolean }>`
`
const TooltipBackground = styled.rect`
fill: ${({ theme }) => theme.bg2};
fill: ${({ theme }) => theme.deprecated_bg2};
`
const Tooltip = styled.text`
text-anchor: middle;
font-size: 13px;
fill: ${({ theme }) => theme.text1};
fill: ${({ theme }) => theme.deprecated_text1};
`
// flips the handles draggers when close to the container edges

View File

@@ -5,7 +5,7 @@ import styled from 'styled-components/macro'
const StyledLine = styled.line`
opacity: 0.5;
stroke-width: 2;
stroke: ${({ theme }) => theme.text1};
stroke: ${({ theme }) => theme.deprecated_text1};
fill: none;
`

View File

@@ -18,8 +18,8 @@ const Wrapper = styled.div<{ count: number }>`
const Button = styled(ButtonGray)`
&:hover {
background-color: ${({ theme }) => theme.bg2};
color: ${({ theme }) => theme.text1};
background-color: ${({ theme }) => theme.deprecated_bg2};
color: ${({ theme }) => theme.deprecated_text1};
}
width: 32px;

View File

@@ -103,7 +103,7 @@ export default function LiquidityChartRangeInput({
})
const onBrushDomainChangeEnded = useCallback(
(domain, mode) => {
(domain: [number, number], mode: string | undefined) => {
let leftRangeValue = Number(domain[0])
const rightRangeValue = Number(domain[1])
@@ -166,19 +166,19 @@ export default function LiquidityChartRangeInput({
{isUninitialized ? (
<InfoBox
message={<Trans>Your position will appear here.</Trans>}
icon={<Inbox size={56} stroke={theme.text1} />}
icon={<Inbox size={56} stroke={theme.deprecated_text1} />}
/>
) : isLoading ? (
<InfoBox icon={<Loader size="40px" stroke={theme.text4} />} />
<InfoBox icon={<Loader size="40px" stroke={theme.deprecated_text4} />} />
) : isError ? (
<InfoBox
message={<Trans>Liquidity data not available.</Trans>}
icon={<CloudOff size={56} stroke={theme.text4} />}
icon={<CloudOff size={56} stroke={theme.deprecated_text4} />}
/>
) : !formattedData || formattedData === [] || !price ? (
<InfoBox
message={<Trans>There is no liquidity data.</Trans>}
icon={<BarChart2 size={56} stroke={theme.text4} />}
icon={<BarChart2 size={56} stroke={theme.deprecated_text4} />}
/>
) : (
<ChartWrapper>
@@ -188,12 +188,12 @@ export default function LiquidityChartRangeInput({
margins={{ top: 10, right: 2, bottom: 20, left: 0 }}
styles={{
area: {
selection: theme.blue1,
selection: theme.deprecated_blue1,
},
brush: {
handle: {
west: saturate(0.1, tokenAColor) ?? theme.red1,
east: saturate(0.1, tokenBColor) ?? theme.blue1,
west: saturate(0.1, tokenAColor) ?? theme.deprecated_red1,
east: saturate(0.1, tokenBColor) ?? theme.deprecated_blue1,
},
},
}}

View File

@@ -14,7 +14,7 @@ const StyledSVG = styled.svg<{ size: string; stroke?: string }>`
height: ${({ size }) => size};
width: ${({ size }) => size};
path {
stroke: ${({ stroke, theme }) => stroke ?? theme.primary1};
stroke: ${({ stroke, theme }) => stroke ?? theme.deprecated_primary1};
}
`

View File

@@ -17,9 +17,9 @@ export const LoadingRows = styled.div`
animation-fill-mode: both;
background: linear-gradient(
to left,
${({ theme }) => theme.bg1} 25%,
${({ theme }) => theme.bg2} 50%,
${({ theme }) => theme.bg1} 75%
${({ theme }) => theme.deprecated_bg1} 25%,
${({ theme }) => theme.deprecated_bg2} 50%,
${({ theme }) => theme.deprecated_bg1} 75%
);
background-size: 400%;
border-radius: 12px;

View File

@@ -35,5 +35,5 @@ export default function Logo({ srcs, alt, style, ...rest }: LogoProps) {
)
}
return <Slash {...rest} style={{ ...style, color: theme.bg4 }} />
return <Slash {...rest} style={{ ...style, color: theme.deprecated_bg4 }} />
}

View File

@@ -1,12 +1,12 @@
// eslint-disable-next-line no-restricted-imports
import { t, Trans } from '@lingui/macro'
import { useWeb3React } from '@web3-react/core'
import { PrivacyPolicyModal } from 'components/PrivacyPolicy'
import { L2_CHAIN_IDS } from 'constants/chains'
import { LOCALE_LABEL, SUPPORTED_LOCALES, SupportedLocale } from 'constants/locales'
import { useActiveLocale } from 'hooks/useActiveLocale'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useLocationLinkProps } from 'hooks/useLocationLinkProps'
import React, { useEffect, useRef, useState } from 'react'
import { FunctionComponent, PropsWithChildren, useEffect, useRef, useState } from 'react'
import {
BookOpen,
Check,
@@ -26,7 +26,7 @@ import styled, { css } from 'styled-components/macro'
import { ReactComponent as MenuIcon } from '../../assets/images/menu.svg'
import { useOnClickOutside } from '../../hooks/useOnClickOutside'
import { useModalOpen, useToggleModal } from '../../state/application/hooks'
import { useModalIsOpen, useToggleModal } from '../../state/application/hooks'
import { ApplicationModal } from '../../state/application/reducer'
import { ExternalLink } from '../../theme'
import { ButtonPrimary } from '../Button'
@@ -38,7 +38,7 @@ export enum FlyoutAlignment {
const StyledMenuIcon = styled(MenuIcon)`
path {
stroke: ${({ theme }) => theme.text1};
stroke: ${({ theme }) => theme.deprecated_text1};
}
`
@@ -50,8 +50,8 @@ const StyledMenuButton = styled.button`
margin: 0;
padding: 0;
height: 40px;
background-color: ${({ theme }) => theme.bg0};
border: 1px solid ${({ theme }) => theme.bg0};
background-color: ${({ theme }) => theme.deprecated_bg0};
border: 1px solid ${({ theme }) => theme.deprecated_bg0};
padding: 0.15rem 0.5rem;
border-radius: 16px;
@@ -59,7 +59,7 @@ const StyledMenuButton = styled.button`
:focus {
cursor: pointer;
outline: none;
border: 1px solid ${({ theme }) => theme.bg3};
border: 1px solid ${({ theme }) => theme.deprecated_bg3};
}
svg {
@@ -68,7 +68,7 @@ const StyledMenuButton = styled.button`
`
const UNIbutton = styled(ButtonPrimary)`
background-color: ${({ theme }) => theme.bg3};
background-color: ${({ theme }) => theme.deprecated_bg3};
background: radial-gradient(174.47% 188.91% at 1.84% 0%, #ff007a 0%, #2172e5 100%), #edeef2;
border: none;
`
@@ -86,10 +86,10 @@ const MenuFlyout = styled.span<{ flyoutAlignment?: FlyoutAlignment }>`
min-width: 196px;
max-height: 350px;
overflow: auto;
background-color: ${({ theme }) => theme.bg1};
background-color: ${({ theme }) => theme.deprecated_bg1};
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: 1px solid ${({ theme }) => theme.bg0};
border: 1px solid ${({ theme }) => theme.deprecated_bg0};
border-radius: 12px;
padding: 0.5rem;
display: flex;
@@ -121,9 +121,9 @@ const MenuItem = styled(ExternalLink)`
align-items: center;
padding: 0.5rem 0.5rem;
justify-content: space-between;
color: ${({ theme }) => theme.text2};
color: ${({ theme }) => theme.deprecated_text2};
:hover {
color: ${({ theme }) => theme.text1};
color: ${({ theme }) => theme.deprecated_text1};
cursor: pointer;
text-decoration: none;
}
@@ -132,9 +132,9 @@ const MenuItem = styled(ExternalLink)`
const InternalMenuItem = styled(Link)`
flex: 1;
padding: 0.5rem 0.5rem;
color: ${({ theme }) => theme.text2};
color: ${({ theme }) => theme.deprecated_text2};
:hover {
color: ${({ theme }) => theme.text1};
color: ${({ theme }) => theme.deprecated_text1};
cursor: pointer;
text-decoration: none;
}
@@ -151,7 +151,7 @@ const InternalLinkMenuItem = styled(InternalMenuItem)`
justify-content: space-between;
text-decoration: none;
:hover {
color: ${({ theme }) => theme.text1};
color: ${({ theme }) => theme.deprecated_text1};
cursor: pointer;
text-decoration: none;
}
@@ -170,9 +170,9 @@ const ToggleMenuItem = styled.button`
justify-content: space-between;
font-size: 1rem;
font-weight: 500;
color: ${({ theme }) => theme.text2};
color: ${({ theme }) => theme.deprecated_text2};
:hover {
color: ${({ theme }) => theme.text1};
color: ${({ theme }) => theme.deprecated_text1};
cursor: pointer;
text-decoration: none;
}
@@ -207,10 +207,10 @@ function LanguageMenu({ close }: { close: () => void }) {
}
export default function Menu() {
const { account, chainId } = useActiveWeb3React()
const { account, chainId } = useWeb3React()
const node = useRef<HTMLDivElement>()
const open = useModalOpen(ApplicationModal.MENU)
const open = useModalIsOpen(ApplicationModal.MENU)
const toggleMenu = useToggleModal(ApplicationModal.MENU)
useOnClickOutside(node, open ? toggleMenu : undefined)
const togglePrivacyPolicy = useToggleModal(ApplicationModal.PRIVACY_POLICY)
@@ -311,7 +311,7 @@ export default function Menu() {
interface NewMenuProps {
flyoutAlignment?: FlyoutAlignment
ToggleUI?: React.FunctionComponent
ToggleUI?: FunctionComponent<PropsWithChildren<unknown>>
menuItems: {
content: any
link: string
@@ -334,7 +334,7 @@ const ExternalMenuItem = styled(MenuItem)`
export const NewMenu = ({ flyoutAlignment = FlyoutAlignment.RIGHT, ToggleUI, menuItems, ...rest }: NewMenuProps) => {
const node = useRef<HTMLDivElement>()
const open = useModalOpen(ApplicationModal.POOL_OVERVIEW_OPTIONS)
const open = useModalIsOpen(ApplicationModal.POOL_OVERVIEW_OPTIONS)
const toggle = useToggleModal(ApplicationModal.POOL_OVERVIEW_OPTIONS)
useOnClickOutside(node, open ? toggle : undefined)
const ToggleElement = ToggleUI || StyledMenuIcon

View File

@@ -19,7 +19,7 @@ const StyledDialogOverlay = styled(AnimatedDialogOverlay)`
align-items: center;
justify-content: center;
background-color: ${({ theme }) => theme.modalBG};
background-color: ${({ theme }) => theme.deprecated_modalBG};
}
`
@@ -35,8 +35,8 @@ const StyledDialogContent = styled(({ minHeight, maxHeight, mobile, isOpen, ...r
&[data-reach-dialog-content] {
margin: 0 0 2rem 0;
background-color: ${({ theme }) => theme.bg0};
border: 1px solid ${({ theme }) => theme.bg1};
background-color: ${({ theme }) => theme.deprecated_bg0};
border: 1px solid ${({ theme }) => theme.deprecated_bg1};
box-shadow: 0 4px 8px 0 ${({ theme }) => transparentize(0.95, theme.shadow1)};
padding: 0px;
width: 50vw;

View File

@@ -1,5 +1,5 @@
import { Trans } from '@lingui/macro'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useWeb3React } from '@web3-react/core'
import { useContext } from 'react'
import { ArrowUpCircle } from 'react-feather'
import styled, { ThemeContext } from 'styled-components/macro'
@@ -50,7 +50,7 @@ export function SubmittedView({
hash: string | undefined
}) {
const theme = useContext(ThemeContext)
const { chainId } = useActiveWeb3React()
const { chainId } = useWeb3React()
return (
<ConfirmOrLoadingWrapper>
@@ -59,7 +59,7 @@ export function SubmittedView({
<CloseIcon onClick={onDismiss} />
</RowBetween>
<ConfirmedIcon>
<ArrowUpCircle strokeWidth={0.5} size={90} color={theme.primary1} />
<ArrowUpCircle strokeWidth={0.5} size={90} color={theme.deprecated_primary1} />
</ConfirmedIcon>
<AutoColumn gap="100px" justify={'center'}>
{children}

View File

@@ -1,10 +1,9 @@
import { Trans } from '@lingui/macro'
import { Percent } from '@uniswap/sdk-core'
import useTheme from 'hooks/useTheme'
import { darken } from 'polished'
import { ReactNode } from 'react'
import { ArrowLeft } from 'react-feather'
import { Link as HistoryLink, NavLink, useLocation } from 'react-router-dom'
import { Link as HistoryLink, useLocation } from 'react-router-dom'
import { Box } from 'rebass'
import { useAppDispatch } from 'state/hooks'
import { resetMintState } from 'state/mint/actions'
@@ -22,34 +21,6 @@ const Tabs = styled.div`
justify-content: space-evenly;
`
const activeClassName = 'ACTIVE'
const StyledNavLink = styled(NavLink).attrs({
activeClassName,
})`
${({ theme }) => theme.flexRowNoWrap}
align-items: center;
justify-content: center;
height: 3rem;
border-radius: 3rem;
outline: none;
cursor: pointer;
text-decoration: none;
color: ${({ theme }) => theme.text3};
font-size: 20px;
&.${activeClassName} {
border-radius: 12px;
font-weight: 500;
color: ${({ theme }) => theme.text1};
}
:hover,
:focus {
color: ${({ theme }) => darken(0.1, theme.text1)};
}
`
const StyledHistoryLink = styled(HistoryLink)<{ flex: string | undefined }>`
flex: ${({ flex }) => flex ?? 'none'};
@@ -65,22 +36,9 @@ const ActiveText = styled.div`
`
const StyledArrowLeft = styled(ArrowLeft)`
color: ${({ theme }) => theme.text1};
color: ${({ theme }) => theme.deprecated_text1};
`
export function SwapPoolTabs({ active }: { active: 'swap' | 'pool' }) {
return (
<Tabs style={{ marginBottom: '20px', display: 'none', padding: '1rem 1rem 0 1rem' }}>
<StyledNavLink id={`swap-nav-link`} to={'/swap'} isActive={() => active === 'swap'}>
<Trans>Swap</Trans>
</StyledNavLink>
<StyledNavLink id={`pool-nav-link`} to={'/pool'} isActive={() => active === 'pool'}>
<Trans>Pool</Trans>
</StyledNavLink>
</Tabs>
)
}
export function FindPoolTabs({ origin }: { origin: string }) {
return (
<Tabs>
@@ -134,7 +92,7 @@ export function AddRemoveTabs({
}}
flex={children ? '1' : undefined}
>
<StyledArrowLeft stroke={theme.text2} />
<StyledArrowLeft stroke={theme.deprecated_text2} />
</StyledHistoryLink>
<ThemedText.MediumHeader
fontWeight={500}

View File

@@ -1,7 +1,7 @@
import { Trans } from '@lingui/macro'
import { CHAIN_INFO } from 'constants/chainInfo'
import { useWeb3React } from '@web3-react/core'
import { getChainInfo } from 'constants/chainInfo'
import { SupportedChainId } from 'constants/chains'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { ArrowUpRight } from 'react-feather'
import { useDarkModeManager } from 'state/user/hooks'
import styled from 'styled-components/macro'
@@ -42,6 +42,8 @@ const SHOULD_SHOW_ALERT = {
[SupportedChainId.ARBITRUM_RINKEBY]: true,
[SupportedChainId.POLYGON]: true,
[SupportedChainId.POLYGON_MUMBAI]: true,
[SupportedChainId.CELO]: true,
[SupportedChainId.CELO_ALFAJORES]: true,
}
type NetworkAlertChains = keyof typeof SHOULD_SHOW_ALERT
@@ -54,6 +56,10 @@ const BG_COLORS_BY_DARK_MODE_AND_CHAIN_ID: {
'radial-gradient(100% 93.36% at 0% 6.64%, rgba(160, 108, 247, 0.1) 0%, rgba(82, 32, 166, 0.1) 100%)',
[SupportedChainId.POLYGON_MUMBAI]:
'radial-gradient(100% 93.36% at 0% 6.64%, rgba(160, 108, 247, 0.1) 0%, rgba(82, 32, 166, 0.1) 100%)',
[SupportedChainId.CELO]:
'radial-gradient(182.71% 150.59% at 2.81% 7.69%, rgba(90, 190, 170, 0.15) 0%, rgba(80, 160, 40, 0.15) 100%)',
[SupportedChainId.CELO_ALFAJORES]:
'radial-gradient(182.71% 150.59% at 2.81% 7.69%, rgba(90, 190, 170, 0.15) 0%, rgba(80, 160, 40, 0.15) 100%)',
[SupportedChainId.OPTIMISM]:
'radial-gradient(948% 292% at 42% 0%, rgba(255, 58, 212, 0.01) 0%, rgba(255, 255, 255, 0.04) 100%),radial-gradient(98% 96% at 2% 0%, rgba(255, 39, 39, 0.01) 0%, rgba(235, 0, 255, 0.01) 96%)',
[SupportedChainId.OPTIMISTIC_KOVAN]:
@@ -68,6 +74,10 @@ const BG_COLORS_BY_DARK_MODE_AND_CHAIN_ID: {
'radial-gradient(182.71% 205.59% at 2.81% 7.69%, rgba(130, 71, 229, 0.2) 0%, rgba(167, 202, 255, 0.2) 100%)',
[SupportedChainId.POLYGON_MUMBAI]:
'radial-gradient(182.71% 205.59% at 2.81% 7.69%, rgba(130, 71, 229, 0.2) 0%, rgba(167, 202, 255, 0.2) 100%)',
[SupportedChainId.CELO]:
'radial-gradient(182.71% 150.59% at 2.81% 7.69%, rgba(63, 208, 137, 0.15) 0%, rgba(49, 205, 50, 0.15) 100%)',
[SupportedChainId.CELO_ALFAJORES]:
'radial-gradient(182.71% 150.59% at 2.81% 7.69%, rgba(63, 208, 137, 0.15) 0%, rgba(49, 205, 50, 0.15) 100%)',
[SupportedChainId.OPTIMISM]:
'radial-gradient(92% 105% at 50% 7%, rgba(255, 58, 212, 0.04) 0%, rgba(255, 255, 255, 0.03) 100%),radial-gradient(100% 97% at 0% 12%, rgba(235, 0, 255, 0.1) 0%, rgba(243, 19, 19, 0.1) 100%), hsla(0, 0%, 100%, 0.1)',
[SupportedChainId.OPTIMISTIC_KOVAN]:
@@ -129,6 +139,8 @@ const StyledArrowUpRight = styled(ArrowUpRight)`
const TEXT_COLORS: { [chainId in NetworkAlertChains]: string } = {
[SupportedChainId.POLYGON]: 'rgba(130, 71, 229)',
[SupportedChainId.POLYGON_MUMBAI]: 'rgba(130, 71, 229)',
[SupportedChainId.CELO]: 'rgba(53, 178, 97)',
[SupportedChainId.CELO_ALFAJORES]: 'rgba(53, 178, 97)',
[SupportedChainId.OPTIMISM]: '#ff3856',
[SupportedChainId.OPTIMISTIC_KOVAN]: '#ff3856',
[SupportedChainId.ARBITRUM_ONE]: '#0490ed',
@@ -140,14 +152,14 @@ function shouldShowAlert(chainId: number | undefined): chainId is NetworkAlertCh
}
export function NetworkAlert() {
const { chainId } = useActiveWeb3React()
const { chainId } = useWeb3React()
const [darkMode] = useDarkModeManager()
if (!shouldShowAlert(chainId)) {
return null
}
const { label, logoUrl, bridge } = CHAIN_INFO[chainId]
const { label, logoUrl, bridge } = getChainInfo(chainId)
const textColor = TEXT_COLORS[chainId]
return bridge ? (

View File

@@ -4,14 +4,14 @@ import styled from 'styled-components/macro'
import { escapeRegExp } from '../../utils'
const StyledInput = styled.input<{ error?: boolean; fontSize?: string; align?: string }>`
color: ${({ error, theme }) => (error ? theme.red1 : theme.text1)};
color: ${({ error, theme }) => (error ? theme.deprecated_red1 : theme.deprecated_text1)};
width: 0;
position: relative;
font-weight: 500;
outline: none;
border: none;
flex: 1 1 auto;
background-color: ${({ theme }) => theme.bg1};
background-color: ${({ theme }) => theme.deprecated_bg1};
font-size: ${({ fontSize }) => fontSize ?? '28px'};
text-align: ${({ align }) => align && align};
white-space: nowrap;
@@ -35,7 +35,7 @@ const StyledInput = styled.input<{ error?: boolean; fontSize?: string; align?: s
}
::placeholder {
color: ${({ theme }) => theme.text4};
color: ${({ theme }) => theme.deprecated_text4};
}
`

View File

@@ -10,7 +10,7 @@ const PopoverContainer = styled.div<{ show: boolean }>`
visibility: ${(props) => (props.show ? 'visible' : 'hidden')};
opacity: ${(props) => (props.show ? 1 : 0)};
transition: visibility 150ms linear, opacity 150ms linear;
color: ${({ theme }) => theme.text2};
color: ${({ theme }) => theme.deprecated_text2};
`
const ReferenceElement = styled.div`
@@ -26,16 +26,17 @@ const Arrow = styled.div`
position: absolute;
width: 8px;
height: 8px;
box-sizing: border-box;
z-index: 9998;
content: '';
border: 1px solid ${({ theme }) => theme.bg2};
border: 1px solid ${({ theme }) => theme.deprecated_bg2};
transform: rotate(45deg);
background: ${({ theme }) => theme.bg0};
background: ${({ theme }) => theme.deprecated_bg0};
}
&.arrow-top {
bottom: -5px;
bottom: -4px;
::before {
border-top: none;
border-left: none;
@@ -43,7 +44,7 @@ const Arrow = styled.div`
}
&.arrow-bottom {
top: -5px;
top: -4px;
::before {
border-bottom: none;
border-right: none;
@@ -51,7 +52,7 @@ const Arrow = styled.div`
}
&.arrow-left {
right: -5px;
right: -4px;
::before {
border-bottom: none;
@@ -60,7 +61,7 @@ const Arrow = styled.div`
}
&.arrow-right {
left: -5px;
left: -4px;
::before {
border-right: none;
border-top: none;

View File

@@ -1,14 +1,14 @@
import { Trans } from '@lingui/macro'
import { CurrencyAmount, Token } from '@uniswap/sdk-core'
import { useWeb3React } from '@web3-react/core'
import { sendEvent } from 'components/analytics'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useCallback, useEffect } from 'react'
import { Heart, X } from 'react-feather'
import styled, { keyframes } from 'styled-components/macro'
import tokenLogo from '../../assets/images/token-logo.png'
import {
useModalOpen,
useModalIsOpen,
useShowClaimPopup,
useToggleSelfClaimModal,
useToggleShowClaimPopup,
@@ -55,14 +55,14 @@ const UniToken = styled.img`
`
export default function ClaimPopup() {
const { account } = useActiveWeb3React()
const { account } = useWeb3React()
// dont store these in persisted state yet
const showClaimPopup: boolean = useShowClaimPopup()
const toggleShowClaimPopup = useToggleShowClaimPopup()
// toggle for showing this modal
const showClaimModal = useModalOpen(ApplicationModal.SELF_CLAIM)
const showClaimModal = useModalIsOpen(ApplicationModal.SELF_CLAIM)
const toggleSelfClaimModal = useToggleSelfClaimModal()
const handleToggleSelfClaimModal = useCallback(() => {
sendEvent({

View File

@@ -1,5 +1,5 @@
import { Trans } from '@lingui/macro'
import { CHAIN_INFO } from 'constants/chainInfo'
import { getChainInfo } from 'constants/chainInfo'
import { SupportedChainId } from 'constants/chains'
import { useContext } from 'react'
import { AlertCircle } from 'react-feather'
@@ -14,13 +14,13 @@ const RowNoFlex = styled(AutoRow)`
`
export default function FailedNetworkSwitchPopup({ chainId }: { chainId: SupportedChainId }) {
const chainInfo = CHAIN_INFO[chainId]
const chainInfo = getChainInfo(chainId)
const theme = useContext(ThemeContext)
return (
<RowNoFlex>
<div style={{ paddingRight: 16 }}>
<AlertCircle color={theme.red1} size={24} />
<AlertCircle color={theme.deprecated_red1} size={24} />
</div>
<AutoColumn gap="8px">
<ThemedText.Body fontWeight={500}>

View File

@@ -22,7 +22,7 @@ const Popup = styled.div`
display: inline-block;
width: 100%;
padding: 1em;
background-color: ${({ theme }) => theme.bg0};
background-color: ${({ theme }) => theme.deprecated_bg0};
position: relative;
border-radius: 10px;
padding: 20px;
@@ -42,7 +42,7 @@ const Fader = styled.div`
left: 0px;
width: 100%;
height: 2px;
background-color: ${({ theme }) => theme.bg3};
background-color: ${({ theme }) => theme.deprecated_bg3};
`
const AnimatedFader = animated(Fader)
@@ -90,7 +90,7 @@ export default function PopupItem({
return (
<Popup>
<StyledClose color={theme.text2} onClick={removeThisPopup} />
<StyledClose color={theme.deprecated_text2} onClick={removeThisPopup} />
{popupContent}
{removeAfterMs !== null ? <AnimatedFader style={faderStyle} /> : null}
</Popup>

View File

@@ -19,7 +19,7 @@ const Wrapper = styled(AutoColumn)`
padding: 18px;
max-width: 360px;
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
color: ${({ theme }) => theme.text1};
color: ${({ theme }) => theme.deprecated_text1};
overflow: hidden;
${({ theme }) => theme.mediaWidth.upToSmall`
@@ -90,13 +90,18 @@ export default function SurveyPopup() {
<BGOrb src={BGImage} />
<ExternalLink href="https://www.surveymonkey.com/r/YGWV9VD">
<RowFixed>
<MessageCircle stroke={theme.black} size="20px" strokeWidth="1px" />
<ThemedText.White fontWeight={600} color={theme.black} ml="6px">
<MessageCircle stroke={theme.deprecated_black} size="20px" strokeWidth="1px" />
<ThemedText.White fontWeight={600} color={theme.deprecated_black} ml="6px">
<Trans>Tell us what you think </Trans>
</ThemedText.White>
</RowFixed>
</ExternalLink>
<ThemedText.Black style={{ zIndex: Z_INDEX.fixed }} fontWeight={400} fontSize="12px" color={theme.black}>
<ThemedText.Black
style={{ zIndex: Z_INDEX.fixed }}
fontWeight={400}
fontSize="12px"
color={theme.deprecated_black}
>
<Trans>Take a 10 minute survey to help us improve your experience in the Uniswap app.</Trans>
</ThemedText.Black>
</Wrapper>

View File

@@ -1,4 +1,4 @@
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useWeb3React } from '@web3-react/core'
import { useContext } from 'react'
import { AlertCircle, CheckCircle } from 'react-feather'
import styled, { ThemeContext } from 'styled-components/macro'
@@ -16,7 +16,7 @@ const RowNoFlex = styled(AutoRow)`
`
export default function TransactionPopup({ hash }: { hash: string }) {
const { chainId } = useActiveWeb3React()
const { chainId } = useWeb3React()
const tx = useTransaction(hash)
const theme = useContext(ThemeContext)
@@ -27,7 +27,11 @@ export default function TransactionPopup({ hash }: { hash: string }) {
return (
<RowNoFlex>
<div style={{ paddingRight: 16 }}>
{success ? <CheckCircle color={theme.green1} size={24} /> : <AlertCircle color={theme.red1} size={24} />}
{success ? (
<CheckCircle color={theme.deprecated_green1} size={24} />
) : (
<AlertCircle color={theme.deprecated_red1} size={24} />
)}
</div>
<AutoColumn gap="8px">
<ThemedText.Body fontWeight={500}>

View File

@@ -1,5 +1,5 @@
import { useWeb3React } from '@web3-react/core'
import { SupportedChainId } from 'constants/chains'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import styled from 'styled-components/macro'
import { MEDIA_WIDTHS } from 'theme'
@@ -63,7 +63,7 @@ export default function Popups() {
const urlWarningActive = useURLWarningVisible()
// need extra padding if network is not L1 Ethereum
const { chainId } = useActiveWeb3React()
const { chainId } = useWeb3React()
const isNotOnMainnet = Boolean(chainId && chainId !== SupportedChainId.MAINNET)
return (

View File

@@ -20,7 +20,7 @@ import { FixedHeightRow } from '.'
const StyledPositionCard = styled(LightCard)<{ bgColor: any }>`
border: none;
background: ${({ theme, bgColor }) =>
`radial-gradient(91.85% 100% at 1.84% 0%, ${transparentize(0.8, bgColor)} 0%, ${theme.bg3} 100%) `};
`radial-gradient(91.85% 100% at 1.84% 0%, ${transparentize(0.8, bgColor)} 0%, ${theme.deprecated_bg3} 100%) `};
position: relative;
overflow: hidden;
`

View File

@@ -1,7 +1,7 @@
import { Trans } from '@lingui/macro'
import { CurrencyAmount, Percent, Token } from '@uniswap/sdk-core'
import { Pair } from '@uniswap/v2-sdk'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useWeb3React } from '@web3-react/core'
import JSBI from 'jsbi'
import { transparentize } from 'polished'
import { useState } from 'react'
@@ -13,7 +13,7 @@ import styled from 'styled-components/macro'
import { BIG_INT_ZERO } from '../../constants/misc'
import { useColor } from '../../hooks/useColor'
import { useTotalSupply } from '../../hooks/useTotalSupply'
import { useTokenBalance } from '../../state/wallet/hooks'
import { useTokenBalance } from '../../state/connection/hooks'
import { currencyId } from '../../utils/currencyId'
import { unwrappedToken } from '../../utils/unwrappedToken'
import { ButtonEmpty, ButtonPrimary, ButtonSecondary } from '../Button'
@@ -29,7 +29,7 @@ import { FixedHeightRow } from '.'
const StyledPositionCard = styled(LightCard)<{ bgColor: any }>`
border: none;
background: ${({ theme, bgColor }) =>
`radial-gradient(91.85% 100% at 1.84% 0%, ${transparentize(0.8, bgColor)} 0%, ${theme.bg3} 100%) `};
`radial-gradient(91.85% 100% at 1.84% 0%, ${transparentize(0.8, bgColor)} 0%, ${theme.deprecated_bg3} 100%) `};
position: relative;
overflow: hidden;
`
@@ -42,7 +42,7 @@ interface PositionCardProps {
}
export default function V2PositionCard({ pair, border, stakedBalance }: PositionCardProps) {
const { account } = useActiveWeb3React()
const { account } = useWeb3React()
const currency0 = unwrappedToken(pair.token0)
const currency1 = unwrappedToken(pair.token1)

View File

@@ -1,7 +1,7 @@
import { Trans } from '@lingui/macro'
import { CurrencyAmount, Percent, Token } from '@uniswap/sdk-core'
import { Pair } from '@uniswap/v2-sdk'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useWeb3React } from '@web3-react/core'
import JSBI from 'jsbi'
import { transparentize } from 'polished'
import { useState } from 'react'
@@ -13,7 +13,7 @@ import styled from 'styled-components/macro'
import { BIG_INT_ZERO } from '../../constants/misc'
import { useColor } from '../../hooks/useColor'
import { useTotalSupply } from '../../hooks/useTotalSupply'
import { useTokenBalance } from '../../state/wallet/hooks'
import { useTokenBalance } from '../../state/connection/hooks'
import { ExternalLink, ThemedText } from '../../theme'
import { currencyId } from '../../utils/currencyId'
import { unwrappedToken } from '../../utils/unwrappedToken'
@@ -33,7 +33,7 @@ export const FixedHeightRow = styled(RowBetween)`
const StyledPositionCard = styled(LightCard)<{ bgColor: any }>`
border: none;
background: ${({ theme, bgColor }) =>
`radial-gradient(91.85% 100% at 1.84% 0%, ${transparentize(0.8, bgColor)} 0%, ${theme.bg3} 100%) `};
`radial-gradient(91.85% 100% at 1.84% 0%, ${transparentize(0.8, bgColor)} 0%, ${theme.deprecated_bg3} 100%) `};
position: relative;
overflow: hidden;
`
@@ -46,7 +46,7 @@ interface PositionCardProps {
}
export function MinimalPositionCard({ pair, showUnwrapped = false, border }: PositionCardProps) {
const { account } = useActiveWeb3React()
const { account } = useWeb3React()
const currency0 = showUnwrapped ? pair.token0 : unwrappedToken(pair.token0)
const currency1 = showUnwrapped ? pair.token1 : unwrappedToken(pair.token1)
@@ -158,7 +158,7 @@ export function MinimalPositionCard({ pair, showUnwrapped = false, border }: Pos
}
export default function FullPositionCard({ pair, border, stakedBalance }: PositionCardProps) {
const { account } = useActiveWeb3React()
const { account } = useWeb3React()
const currency0 = unwrappedToken(pair.token0)
const currency1 = unwrappedToken(pair.token1)

View File

@@ -31,12 +31,12 @@ const LinkRow = styled(Link)`
flex-direction: column;
justify-content: space-between;
color: ${({ theme }) => theme.text1};
color: ${({ theme }) => theme.deprecated_text1};
margin: 8px 0;
padding: 16px;
text-decoration: none;
font-weight: 500;
background-color: ${({ theme }) => theme.bg1};
background-color: ${({ theme }) => theme.deprecated_bg1};
&:last-of-type {
margin: 8px 0 0 0;
@@ -45,7 +45,7 @@ const LinkRow = styled(Link)`
text-align: center;
}
:hover {
background-color: ${({ theme }) => theme.bg2};
background-color: ${({ theme }) => theme.deprecated_bg2};
}
@media screen and (min-width: ${MEDIA_WIDTHS.upToSmall}px) {
@@ -79,7 +79,7 @@ const RangeLineItem = styled(DataLineItem)`
width: 100%;
${({ theme }) => theme.mediaWidth.upToSmall`
background-color: ${({ theme }) => theme.bg2};
background-color: ${({ theme }) => theme.deprecated_bg2};
border-radius: 12px;
padding: 8px 0;
`};
@@ -87,7 +87,7 @@ const RangeLineItem = styled(DataLineItem)`
const DoubleArrow = styled.span`
margin: 0 2px;
color: ${({ theme }) => theme.text3};
color: ${({ theme }) => theme.deprecated_text3};
${({ theme }) => theme.mediaWidth.upToSmall`
margin: 4px;
padding: 20px;
@@ -95,13 +95,13 @@ const DoubleArrow = styled.span`
`
const RangeText = styled.span`
/* background-color: ${({ theme }) => theme.bg2}; */
/* background-color: ${({ theme }) => theme.deprecated_bg2}; */
padding: 0.25rem 0.5rem;
border-radius: 8px;
`
const ExtentsText = styled.span`
color: ${({ theme }) => theme.text3};
color: ${({ theme }) => theme.deprecated_text3};
font-size: 14px;
margin-right: 4px;
${({ theme }) => theme.mediaWidth.upToSmall`

View File

@@ -135,7 +135,7 @@ export const PositionPreview = ({
{quoteCurrency.symbol} per {baseCurrency.symbol}
</Trans>
</ThemedText.Main>
<ThemedText.Small textAlign="center" color={theme.text3} style={{ marginTop: '4px' }}>
<ThemedText.Small textAlign="center" color={theme.deprecated_text3} style={{ marginTop: '4px' }}>
<Trans>Your position will be 100% composed of {baseCurrency?.symbol} at this price</Trans>
</ThemedText.Small>
</AutoColumn>
@@ -156,7 +156,7 @@ export const PositionPreview = ({
{quoteCurrency.symbol} per {baseCurrency.symbol}
</Trans>
</ThemedText.Main>
<ThemedText.Small textAlign="center" color={theme.text3} style={{ marginTop: '4px' }}>
<ThemedText.Small textAlign="center" color={theme.deprecated_text3} style={{ marginTop: '4px' }}>
<Trans>Your position will be 100% composed of {quoteCurrency?.symbol} at this price</Trans>
</ThemedText.Small>
</AutoColumn>

View File

@@ -8,7 +8,7 @@ import styled from 'styled-components/macro'
import { ExternalLink, ThemedText } from 'theme'
import { isMobile } from 'utils/userAgent'
import { useModalOpen, useTogglePrivacyPolicy } from '../../state/application/hooks'
import { useModalIsOpen, useTogglePrivacyPolicy } from '../../state/application/hooks'
import { ApplicationModal } from '../../state/application/reducer'
import { AutoColumn } from '../Column'
import Modal from '../Modal'
@@ -20,20 +20,20 @@ const Wrapper = styled.div`
`
const StyledExternalCard = styled(Card)`
background-color: ${({ theme }) => theme.primary5};
background-color: ${({ theme }) => theme.deprecated_primary5};
padding: 0.5rem;
width: 100%;
:hover,
:focus,
:active {
background-color: ${({ theme }) => theme.primary4};
background-color: ${({ theme }) => theme.deprecated_primary4};
}
`
const HoverText = styled.div`
text-decoration: none;
color: ${({ theme }) => theme.text1};
color: ${({ theme }) => theme.deprecated_text1};
display: flex;
align-items: center;
@@ -70,7 +70,7 @@ const EXTERNAL_APIS = [
),
},
{
name: 'Google Analytics',
name: 'Google Analytics & Amplitude',
description: <Trans>The app logs anonymized usage statistics in order to improve over time.</Trans>,
},
{
@@ -81,7 +81,7 @@ const EXTERNAL_APIS = [
export function PrivacyPolicyModal() {
const node = useRef<HTMLDivElement>()
const open = useModalOpen(ApplicationModal.PRIVACY_POLICY)
const open = useModalIsOpen(ApplicationModal.PRIVACY_POLICY)
const toggle = useTogglePrivacyPolicy()
useEffect(() => {
@@ -128,7 +128,7 @@ export function PrivacyPolicy() {
<RowBetween>
<AutoRow gap="4px">
<Info size={20} />
<ThemedText.Main fontSize={14} color={'primaryText1'}>
<ThemedText.Main fontSize={14} color={'deprecated_primaryText1'}>
<Trans>Uniswap Labs&apos; Terms of Service</Trans>
</ThemedText.Main>
</AutoRow>
@@ -141,7 +141,7 @@ export function PrivacyPolicy() {
<RowBetween>
<AutoRow gap="4px">
<Info size={20} />
<ThemedText.Main fontSize={14} color={'primaryText1'}>
<ThemedText.Main fontSize={14} color={'deprecated_primaryText1'}>
<Trans>Protocol Disclaimer</Trans>
</ThemedText.Main>
</AutoRow>
@@ -159,7 +159,7 @@ export function PrivacyPolicy() {
<AutoColumn gap="8px">
<AutoRow gap="4px">
<Info size={18} />
<ThemedText.Main fontSize={14} color={'text1'}>
<ThemedText.Main fontSize={14} color={'deprecated_text1'}>
{name}
</ThemedText.Main>
</AutoRow>

View File

@@ -13,7 +13,7 @@ const Wrapper = styled(AutoColumn)`
const Grouping = styled(AutoColumn)`
width: fit-content;
padding: 4px;
/* background-color: ${({ theme }) => theme.bg2}; */
/* background-color: ${({ theme }) => theme.deprecated_bg2}; */
border-radius: 16px;
`
@@ -21,9 +21,9 @@ const Circle = styled.div<{ confirmed?: boolean; disabled?: boolean }>`
width: 48px;
height: 48px;
background-color: ${({ theme, confirmed, disabled }) =>
disabled ? theme.bg3 : confirmed ? theme.green1 : theme.primary1};
disabled ? theme.deprecated_bg3 : confirmed ? theme.deprecated_green1 : theme.deprecated_primary1};
border-radius: 50%;
color: ${({ theme, disabled }) => (disabled ? theme.text3 : theme.text1)};
color: ${({ theme, disabled }) => (disabled ? theme.deprecated_text3 : theme.deprecated_text1)};
display: flex;
align-items: center;
justify-content: center;
@@ -65,7 +65,7 @@ export default function ProgressCircles({ steps, disabled = false, ...rest }: Pr
<Circle confirmed={step} disabled={disabled || (!steps[i - 1] && i !== 0)}>
{step ? '✓' : i + 1 + '.'}
</Circle>
<ThemedText.Main color={theme.text4}>|</ThemedText.Main>
<ThemedText.Main color={theme.deprecated_text4}>|</ThemedText.Main>
</CircleRow>
)
})}

View File

@@ -16,8 +16,8 @@ const QuestionWrapper = styled.div`
cursor: default;
border-radius: 36px;
font-size: 12px;
background-color: ${({ theme }) => theme.bg2};
color: ${({ theme }) => theme.text2};
background-color: ${({ theme }) => theme.deprecated_bg2};
color: ${({ theme }) => theme.deprecated_text2};
:hover,
:focus {

View File

@@ -10,7 +10,7 @@ const Button = styled(ButtonOutlined).attrs(() => ({
padding: '8px',
$borderRadius: '8px',
}))`
color: ${({ theme }) => theme.text1};
color: ${({ theme }) => theme.deprecated_text1};
flex: 1;
`

View File

@@ -1,10 +1,11 @@
import { Protocol } from '@uniswap/router-sdk'
import { Currency, Percent } from '@uniswap/sdk-core'
import { FeeAmount } from '@uniswap/v3-sdk'
import { RoutingDiagramEntry } from 'components/swap/SwapRoute'
import { DAI, USDC_MAINNET, WBTC } from 'constants/tokens'
import { render } from 'test-utils'
import RoutingDiagram, { RoutingDiagramEntry } from './RoutingDiagram'
import RoutingDiagram from './RoutingDiagram'
const percent = (strings: TemplateStringsArray) => new Percent(parseInt(strings[0]), 100)

View File

@@ -48,12 +48,12 @@ const DottedLine = styled.div`
const DotColor = styled(DotLine)`
path {
stroke: ${({ theme }) => theme.bg4};
stroke: ${({ theme }) => theme.deprecated_bg4};
}
`
const OpaqueBadge = styled(Badge)`
background-color: ${({ theme }) => theme.bg2};
background-color: ${({ theme }) => theme.deprecated_bg2};
border-radius: 8px;
display: grid;
font-size: 12px;
@@ -65,9 +65,9 @@ const OpaqueBadge = styled(Badge)`
`
const ProtocolBadge = styled(Badge)`
background-color: ${({ theme }) => theme.bg3};
background-color: ${({ theme }) => theme.deprecated_bg3};
border-radius: 4px;
color: ${({ theme }) => theme.text2};
color: ${({ theme }) => theme.deprecated_text2};
font-size: 10px;
padding: 2px 4px;
z-index: ${Z_INDEX.sticky + 1};

View File

@@ -2,46 +2,185 @@
exports[`renders multi route 1`] = `
<DocumentFragment>
<div
class="RoutingDiagram__Wrapper-sc-i2tbb-0 ivndgC css-vurnku"
.c7 {
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
background-color: #EDEEF2;
border: unset;
border-radius: 0.5rem;
color: #000;
display: -webkit-inline-box;
display: -webkit-inline-flex;
display: -ms-inline-flexbox;
display: inline-flex;
padding: 4px 6px;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
font-weight: 500;
}
.c1 {
box-sizing: border-box;
margin: 0;
min-width: 0;
}
.c11 {
box-sizing: border-box;
margin: 0;
min-width: 0;
width: 100%;
}
.c2 {
width: 100%;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
padding: 0;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
}
.c12 {
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
margin: -1px;
}
.c12 > * {
margin: 1px !important;
}
.c0 {
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
width: 100%;
}
.c3 {
display: grid;
grid-template-columns: 24px 1fr 24px;
}
.c4 {
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
padding: 0.1rem 0.5rem;
position: relative;
}
.c5 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
position: absolute;
width: calc(100%);
z-index: 1;
opacity: 0.5;
}
.c6 path {
stroke: #888D9B;
}
.c8 {
background-color: #EDEEF2;
border-radius: 8px;
display: grid;
font-size: 12px;
grid-gap: 4px;
grid-auto-flow: column;
-webkit-box-pack: start;
-webkit-justify-content: start;
-ms-flex-pack: start;
justify-content: start;
padding: 4px 6px 4px 4px;
z-index: 1020;
}
.c9 {
background-color: #CED0D9;
border-radius: 4px;
color: #565A69;
font-size: 10px;
padding: 2px 4px;
z-index: 1021;
}
.c10 {
word-break: normal;
}
<div
class="c0 css-vurnku"
>
<div
class="sc-bdnxRM Row-sc-u7azg8-0 RoutingDiagram__RouteContainerRow-sc-i2tbb-1 lmTMKd hLLNig hDkZVB"
class="c1 c2 c3"
>
CurrencyLogo currency=USDC
<div
class="sc-bdnxRM Row-sc-u7azg8-0 RoutingDiagram__RouteRow-sc-i2tbb-2 lmTMKd hLLNig hUDqOH"
class="c1 c2 c4"
>
<div
class="RoutingDiagram__DottedLine-sc-i2tbb-4 cKqYfU"
class="c5"
>
<svg
class="RoutingDiagram__DotColor-sc-i2tbb-5 fhSaBA"
class="c6"
>
dot_line.svg
</svg>
</div>
<div
class="Badge-sc-3epor3-0 RoutingDiagram__OpaqueBadge-sc-i2tbb-6 knpfHF gGARxH"
class="c7 c8"
>
<div
class="Badge-sc-3epor3-0 RoutingDiagram__ProtocolBadge-sc-i2tbb-7 knpfHF lbdUti"
class="c7 c9"
>
<div
class="theme__TextWrapper-sc-5lu8um-0 chxxqs RoutingDiagram__BadgeText-sc-i2tbb-8 ijjHig css-15li2d9"
class="c10 css-15li2d9"
>
V2
</div>
</div>
<div
class="theme__TextWrapper-sc-5lu8um-0 chxxqs RoutingDiagram__BadgeText-sc-i2tbb-8 ijjHig css-1aekuku"
class="c10 css-1aekuku"
style="min-width: auto;"
>
75%
</div>
</div>
<div
class="sc-bdnxRM Row-sc-u7azg8-0 Row__AutoRow-sc-u7azg8-3 iqvZFe hLLNig cUhARX"
class="c11 c2 c12"
style="justify-content: space-evenly; z-index: 2;"
width="100%"
>
@@ -51,42 +190,42 @@ exports[`renders multi route 1`] = `
CurrencyLogo currency=DAI
</div>
<div
class="sc-bdnxRM Row-sc-u7azg8-0 RoutingDiagram__RouteContainerRow-sc-i2tbb-1 lmTMKd hLLNig hDkZVB"
class="c1 c2 c3"
>
CurrencyLogo currency=USDC
<div
class="sc-bdnxRM Row-sc-u7azg8-0 RoutingDiagram__RouteRow-sc-i2tbb-2 lmTMKd hLLNig hUDqOH"
class="c1 c2 c4"
>
<div
class="RoutingDiagram__DottedLine-sc-i2tbb-4 cKqYfU"
class="c5"
>
<svg
class="RoutingDiagram__DotColor-sc-i2tbb-5 fhSaBA"
class="c6"
>
dot_line.svg
</svg>
</div>
<div
class="Badge-sc-3epor3-0 RoutingDiagram__OpaqueBadge-sc-i2tbb-6 knpfHF gGARxH"
class="c7 c8"
>
<div
class="Badge-sc-3epor3-0 RoutingDiagram__ProtocolBadge-sc-i2tbb-7 knpfHF lbdUti"
class="c7 c9"
>
<div
class="theme__TextWrapper-sc-5lu8um-0 chxxqs RoutingDiagram__BadgeText-sc-i2tbb-8 ijjHig css-15li2d9"
class="c10 css-15li2d9"
>
V3
</div>
</div>
<div
class="theme__TextWrapper-sc-5lu8um-0 chxxqs RoutingDiagram__BadgeText-sc-i2tbb-8 ijjHig css-1aekuku"
class="c10 css-1aekuku"
style="min-width: auto;"
>
25%
</div>
</div>
<div
class="sc-bdnxRM Row-sc-u7azg8-0 Row__AutoRow-sc-u7azg8-3 iqvZFe hLLNig cUhARX"
class="c11 c2 c12"
style="justify-content: space-evenly; z-index: 2;"
width="100%"
>
@@ -101,46 +240,185 @@ exports[`renders multi route 1`] = `
exports[`renders single route 1`] = `
<DocumentFragment>
<div
class="RoutingDiagram__Wrapper-sc-i2tbb-0 ivndgC css-vurnku"
.c7 {
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
background-color: #EDEEF2;
border: unset;
border-radius: 0.5rem;
color: #000;
display: -webkit-inline-box;
display: -webkit-inline-flex;
display: -ms-inline-flexbox;
display: inline-flex;
padding: 4px 6px;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
font-weight: 500;
}
.c1 {
box-sizing: border-box;
margin: 0;
min-width: 0;
}
.c11 {
box-sizing: border-box;
margin: 0;
min-width: 0;
width: 100%;
}
.c2 {
width: 100%;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
padding: 0;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
}
.c12 {
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
margin: -1px;
}
.c12 > * {
margin: 1px !important;
}
.c0 {
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
width: 100%;
}
.c3 {
display: grid;
grid-template-columns: 24px 1fr 24px;
}
.c4 {
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
padding: 0.1rem 0.5rem;
position: relative;
}
.c5 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
position: absolute;
width: calc(100%);
z-index: 1;
opacity: 0.5;
}
.c6 path {
stroke: #888D9B;
}
.c8 {
background-color: #EDEEF2;
border-radius: 8px;
display: grid;
font-size: 12px;
grid-gap: 4px;
grid-auto-flow: column;
-webkit-box-pack: start;
-webkit-justify-content: start;
-ms-flex-pack: start;
justify-content: start;
padding: 4px 6px 4px 4px;
z-index: 1020;
}
.c9 {
background-color: #CED0D9;
border-radius: 4px;
color: #565A69;
font-size: 10px;
padding: 2px 4px;
z-index: 1021;
}
.c10 {
word-break: normal;
}
<div
class="c0 css-vurnku"
>
<div
class="sc-bdnxRM Row-sc-u7azg8-0 RoutingDiagram__RouteContainerRow-sc-i2tbb-1 lmTMKd hLLNig hDkZVB"
class="c1 c2 c3"
>
CurrencyLogo currency=USDC
<div
class="sc-bdnxRM Row-sc-u7azg8-0 RoutingDiagram__RouteRow-sc-i2tbb-2 lmTMKd hLLNig hUDqOH"
class="c1 c2 c4"
>
<div
class="RoutingDiagram__DottedLine-sc-i2tbb-4 cKqYfU"
class="c5"
>
<svg
class="RoutingDiagram__DotColor-sc-i2tbb-5 fhSaBA"
class="c6"
>
dot_line.svg
</svg>
</div>
<div
class="Badge-sc-3epor3-0 RoutingDiagram__OpaqueBadge-sc-i2tbb-6 knpfHF gGARxH"
class="c7 c8"
>
<div
class="Badge-sc-3epor3-0 RoutingDiagram__ProtocolBadge-sc-i2tbb-7 knpfHF lbdUti"
class="c7 c9"
>
<div
class="theme__TextWrapper-sc-5lu8um-0 chxxqs RoutingDiagram__BadgeText-sc-i2tbb-8 ijjHig css-15li2d9"
class="c10 css-15li2d9"
>
V3
</div>
</div>
<div
class="theme__TextWrapper-sc-5lu8um-0 chxxqs RoutingDiagram__BadgeText-sc-i2tbb-8 ijjHig css-1aekuku"
class="c10 css-1aekuku"
style="min-width: auto;"
>
100%
</div>
</div>
<div
class="sc-bdnxRM Row-sc-u7azg8-0 Row__AutoRow-sc-u7azg8-3 iqvZFe hLLNig cUhARX"
class="c11 c2 c12"
style="justify-content: space-evenly; z-index: 2;"
width="100%"
>
@@ -155,8 +433,16 @@ exports[`renders single route 1`] = `
exports[`renders when no routes are provided 1`] = `
<DocumentFragment>
<div
class="RoutingDiagram__Wrapper-sc-i2tbb-0 ivndgC css-vurnku"
.c0 {
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
width: 100%;
}
<div
class="c0 css-vurnku"
/>
</DocumentFragment>
`;

View File

@@ -37,7 +37,7 @@ const Header = styled.div`
width: 100%;
`
const Icon = styled(AlertCircle)`
stroke: ${({ theme }) => theme.text2};
stroke: ${({ theme }) => theme.deprecated_text2};
width: 48px;
height: 48px;
`

View File

@@ -1,4 +1,6 @@
import { Currency } from '@uniswap/sdk-core'
import { Currency, Token } from '@uniswap/sdk-core'
import { ElementName, Event, EventName } from 'components/AmplitudeAnalytics/constants'
import { TraceEvent } from 'components/AmplitudeAnalytics/TraceEvent'
import { AutoColumn } from 'components/Column'
import CurrencyLogo from 'components/CurrencyLogo'
import { AutoRow } from 'components/Row'
@@ -15,7 +17,7 @@ const MobileWrapper = styled(AutoColumn)`
`
const BaseWrapper = styled.div<{ disable?: boolean }>`
border: 1px solid ${({ theme, disable }) => (disable ? 'transparent' : theme.bg3)};
border: 1px solid ${({ theme, disable }) => (disable ? 'transparent' : theme.deprecated_bg3)};
border-radius: 10px;
display: flex;
padding: 6px;
@@ -23,22 +25,43 @@ const BaseWrapper = styled.div<{ disable?: boolean }>`
align-items: center;
:hover {
cursor: ${({ disable }) => !disable && 'pointer'};
background-color: ${({ theme, disable }) => !disable && theme.bg2};
background-color: ${({ theme, disable }) => !disable && theme.deprecated_bg2};
}
color: ${({ theme, disable }) => disable && theme.text3};
background-color: ${({ theme, disable }) => disable && theme.bg3};
color: ${({ theme, disable }) => disable && theme.deprecated_text3};
background-color: ${({ theme, disable }) => disable && theme.deprecated_bg3};
filter: ${({ disable }) => disable && 'grayscale(1)'};
`
const formatAnalyticsEventProperties = (
currency: Currency,
tokenAddress: string | undefined,
searchQuery: string,
isAddressSearch: string | false
) => ({
token_symbol: currency?.symbol,
token_chain_id: currency?.chainId,
...(tokenAddress ? { token_address: tokenAddress } : {}),
is_suggested_token: true,
is_selected_from_list: false,
is_imported_by_user: false,
...(isAddressSearch === false
? { search_token_symbol_input: searchQuery }
: { search_token_address_input: isAddressSearch }),
})
export default function CommonBases({
chainId,
onSelect,
selectedCurrency,
searchQuery,
isAddressSearch,
}: {
chainId?: number
selectedCurrency?: Currency | null
onSelect: (currency: Currency) => void
searchQuery: string
isAddressSearch: string | false
}) {
const bases = typeof chainId !== 'undefined' ? COMMON_BASES[chainId] ?? [] : []
@@ -47,19 +70,29 @@ export default function CommonBases({
<AutoRow gap="4px">
{bases.map((currency: Currency) => {
const isSelected = selectedCurrency?.equals(currency)
const tokenAddress = currency instanceof Token ? currency?.address : undefined
return (
<BaseWrapper
tabIndex={0}
onKeyPress={(e) => !isSelected && e.key === 'Enter' && onSelect(currency)}
onClick={() => !isSelected && onSelect(currency)}
disable={isSelected}
<TraceEvent
events={[Event.onClick, Event.onKeyPress]}
name={EventName.TOKEN_SELECTED}
properties={formatAnalyticsEventProperties(currency, tokenAddress, searchQuery, isAddressSearch)}
element={ElementName.COMMON_BASES_CURRENCY_BUTTON}
key={currencyId(currency)}
>
<CurrencyLogoFromList currency={currency} />
<Text fontWeight={500} fontSize={16}>
{currency.symbol}
</Text>
</BaseWrapper>
<BaseWrapper
tabIndex={0}
onKeyPress={(e) => !isSelected && e.key === 'Enter' && onSelect(currency)}
onClick={() => !isSelected && onSelect(currency)}
disable={isSelected}
key={currencyId(currency)}
>
<CurrencyLogoFromList currency={currency} />
<Text fontWeight={500} fontSize={16}>
{currency.symbol}
</Text>
</BaseWrapper>
</TraceEvent>
)
})}
</AutoRow>

View File

@@ -2,20 +2,82 @@
exports[`renders currency rows correctly when currencies list is non-empty 1`] = `
<DocumentFragment>
<div
.c5 {
color: #6E727D;
}
.c0 {
box-sizing: border-box;
margin: 0;
min-width: 0;
}
.c4 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
}
.c1 {
width: 100%;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
padding: 0;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;
}
.c2 {
-webkit-box-pack: justify;
-webkit-justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
}
.c3 {
padding: 4px 20px;
height: 56px;
display: grid;
grid-template-columns: auto minmax(auto,1fr) auto minmax(0,72px);
grid-gap: 16px;
cursor: pointer;
opacity: 1;
}
.c3:hover {
background-color: #EDEEF2;
}
<div
style="position: relative; height: 10px; width: 100%; overflow: auto; will-change: transform; direction: ltr;"
>
<div
style="height: 168px; width: 100%;"
>
<div
class="sc-bdnxRM Row-sc-u7azg8-0 Row__RowBetween-sc-u7azg8-1 styleds__MenuItem-sc-muzgnq-3 lmTMKd hLLNig hzJkYd firMKT token-item-0x6B175474E89094C44Da98b954EedeAC495271d0F"
class="c0 c1 c2 c3 token-item-0x6B175474E89094C44Da98b954EedeAC495271d0F"
style="position: absolute; left: 0px; top: 0px; height: 56px; width: 100%;"
tabindex="0"
>
CurrencyLogo currency=DAI
<div
class="Column-sc-1r2yyln-0 cYEAJI"
class="c4"
>
<div
class="css-8mokm4"
@@ -24,7 +86,7 @@ exports[`renders currency rows correctly when currencies list is non-empty 1`] =
DAI
</div>
<div
class="theme__TextWrapper-sc-5lu8um-0 gVIOIC css-165qfk5"
class="c5 css-1j6a53a"
>
Dai Stablecoin
</div>
@@ -32,13 +94,13 @@ exports[`renders currency rows correctly when currencies list is non-empty 1`] =
<span />
</div>
<div
class="sc-bdnxRM Row-sc-u7azg8-0 Row__RowBetween-sc-u7azg8-1 styleds__MenuItem-sc-muzgnq-3 lmTMKd hLLNig hzJkYd firMKT token-item-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
class="c0 c1 c2 c3 token-item-0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
style="position: absolute; left: 0px; top: 56px; height: 56px; width: 100%;"
tabindex="0"
>
CurrencyLogo currency=USDC
<div
class="Column-sc-1r2yyln-0 cYEAJI"
class="c4"
>
<div
class="css-8mokm4"
@@ -47,7 +109,7 @@ exports[`renders currency rows correctly when currencies list is non-empty 1`] =
USDC
</div>
<div
class="theme__TextWrapper-sc-5lu8um-0 gVIOIC css-165qfk5"
class="c5 css-1j6a53a"
>
USD//C
</div>
@@ -55,13 +117,13 @@ exports[`renders currency rows correctly when currencies list is non-empty 1`] =
<span />
</div>
<div
class="sc-bdnxRM Row-sc-u7azg8-0 Row__RowBetween-sc-u7azg8-1 styleds__MenuItem-sc-muzgnq-3 lmTMKd hLLNig hzJkYd firMKT token-item-0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"
class="c0 c1 c2 c3 token-item-0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"
style="position: absolute; left: 0px; top: 112px; height: 56px; width: 100%;"
tabindex="0"
>
CurrencyLogo currency=WBTC
<div
class="Column-sc-1r2yyln-0 cYEAJI"
class="c4"
>
<div
class="css-8mokm4"
@@ -70,7 +132,7 @@ exports[`renders currency rows correctly when currencies list is non-empty 1`] =
WBTC
</div>
<div
class="theme__TextWrapper-sc-5lu8um-0 gVIOIC css-165qfk5"
class="c5 css-1j6a53a"
>
Wrapped BTC
</div>

View File

@@ -33,7 +33,7 @@ jest.mock('@web3-react/core', () => {
}
})
jest.mock('../../../state/wallet/hooks', () => {
jest.mock('../../../state/connection/hooks', () => {
return {
useCurrencyBalance: (currency: Currency) => {
return mockCurrencyAmt[(currency as mockToken)?.address]

View File

@@ -1,6 +1,8 @@
import { Trans } from '@lingui/macro'
import { Currency, CurrencyAmount, Token } from '@uniswap/sdk-core'
import { useWeb3React } from '@web3-react/core'
import { ElementName, Event, EventName } from 'components/AmplitudeAnalytics/constants'
import { TraceEvent } from 'components/AmplitudeAnalytics/TraceEvent'
import { LightGreyCard } from 'components/Card'
import QuestionHelper from 'components/QuestionHelper'
import useTheme from 'hooks/useTheme'
@@ -11,9 +13,9 @@ import styled from 'styled-components/macro'
import TokenListLogo from '../../../assets/svg/tokenlist.svg'
import { useIsUserAddedToken } from '../../../hooks/Tokens'
import { useCurrencyBalance } from '../../../state/connection/hooks'
import { useCombinedActiveList } from '../../../state/lists/hooks'
import { WrappedTokenInfo } from '../../../state/lists/wrappedTokenInfo'
import { useCurrencyBalance } from '../../../state/wallet/hooks'
import { ThemedText } from '../../../theme'
import { isTokenOnList } from '../../../utils'
import Column from '../../Column'
@@ -36,8 +38,8 @@ const StyledBalanceText = styled(Text)`
`
const Tag = styled.div`
background-color: ${({ theme }) => theme.bg3};
color: ${({ theme }) => theme.text2};
background-color: ${({ theme }) => theme.deprecated_bg3};
color: ${({ theme }) => theme.deprecated_text2};
font-size: 14px;
border-radius: 4px;
padding: 0.25rem 0.3rem 0.25rem 0.3rem;
@@ -106,6 +108,7 @@ function CurrencyRow({
otherSelected,
style,
showCurrencyAmount,
eventProperties,
}: {
currency: Currency
onSelect: () => void
@@ -113,6 +116,7 @@ function CurrencyRow({
otherSelected: boolean
style: CSSProperties
showCurrencyAmount?: boolean
eventProperties: Record<string, unknown>
}) {
const { account } = useWeb3React()
const key = currencyKey(currency)
@@ -123,35 +127,42 @@ function CurrencyRow({
// only show add or remove buttons if not on selected list
return (
<MenuItem
tabIndex={0}
style={style}
className={`token-item-${key}`}
onKeyPress={(e) => (!isSelected && e.key === 'Enter' ? onSelect() : null)}
onClick={() => (isSelected ? null : onSelect())}
disabled={isSelected}
selected={otherSelected}
<TraceEvent
events={[Event.onClick, Event.onKeyPress]}
name={EventName.TOKEN_SELECTED}
properties={{ is_imported_by_user: customAdded, ...eventProperties }}
element={ElementName.TOKEN_SELECTOR_ROW}
>
<CurrencyLogo currency={currency} size={'24px'} />
<Column>
<Text title={currency.name} fontWeight={500}>
{currency.symbol}
</Text>
<ThemedText.DarkGray ml="0px" fontSize={'12px'} fontWeight={300}>
{!currency.isNative && !isOnSelectedList && customAdded ? (
<Trans>{currency.name} Added by user</Trans>
) : (
currency.name
)}
</ThemedText.DarkGray>
</Column>
<TokenTags currency={currency} />
{showCurrencyAmount && (
<RowFixed style={{ justifySelf: 'flex-end' }}>
{balance ? <Balance balance={balance} /> : account ? <Loader /> : null}
</RowFixed>
)}
</MenuItem>
<MenuItem
tabIndex={0}
style={style}
className={`token-item-${key}`}
onKeyPress={(e) => (!isSelected && e.key === 'Enter' ? onSelect() : null)}
onClick={() => (isSelected ? null : onSelect())}
disabled={isSelected}
selected={otherSelected}
>
<CurrencyLogo currency={currency} size={'24px'} />
<Column>
<Text title={currency.name} fontWeight={500}>
{currency.symbol}
</Text>
<ThemedText.DarkGray ml="0px" fontSize={'12px'} fontWeight={300}>
{!currency.isNative && !isOnSelectedList && customAdded ? (
<Trans>{currency.name} Added by user</Trans>
) : (
currency.name
)}
</ThemedText.DarkGray>
</Column>
<TokenTags currency={currency} />
{showCurrencyAmount && (
<RowFixed style={{ justifySelf: 'flex-end' }}>
{balance ? <Balance balance={balance} /> : account ? <Loader /> : null}
</RowFixed>
)}
</MenuItem>
</TraceEvent>
)
}
@@ -169,7 +180,7 @@ function BreakLineComponent({ style }: { style: CSSProperties }) {
<RowBetween>
<RowFixed>
<TokenListLogoWrapper src={TokenListLogo} />
<ThemedText.Main ml="6px" fontSize="12px" color={theme.text1}>
<ThemedText.Main ml="6px" fontSize="12px" color={theme.deprecated_text1}>
<Trans>Expanded results from inactive Token Lists</Trans>
</ThemedText.Main>
</RowFixed>
@@ -186,6 +197,31 @@ function BreakLineComponent({ style }: { style: CSSProperties }) {
)
}
interface TokenRowProps {
data: Array<Currency | BreakLine>
index: number
style: CSSProperties
}
const formatAnalyticsEventProperties = (
token: Token,
index: number,
data: any[],
searchQuery: string,
isAddressSearch: string | false
) => ({
token_symbol: token?.symbol,
token_address: token?.address,
is_suggested_token: false,
is_selected_from_list: true,
scroll_position: '',
token_list_index: index,
token_list_length: data.length,
...(isAddressSearch === false
? { search_token_symbol_input: searchQuery }
: { search_token_address_input: isAddressSearch }),
})
export default function CurrencyList({
height,
currencies,
@@ -198,6 +234,8 @@ export default function CurrencyList({
setImportToken,
showCurrencyAmount,
isLoading,
searchQuery,
isAddressSearch,
}: {
height: number
currencies: Currency[]
@@ -210,6 +248,8 @@ export default function CurrencyList({
setImportToken: (token: Token) => void
showCurrencyAmount?: boolean
isLoading: boolean
searchQuery: string
isAddressSearch: string | false
}) {
const itemData: (Currency | BreakLine)[] = useMemo(() => {
if (otherListTokens && otherListTokens?.length > 0) {
@@ -219,7 +259,7 @@ export default function CurrencyList({
}, [currencies, otherListTokens])
const Row = useCallback(
function TokenRow({ data, index, style }) {
function TokenRow({ data, index, style }: TokenRowProps) {
const row: Currency | BreakLine = data[index]
if (isBreakLine(row)) {
@@ -257,6 +297,7 @@ export default function CurrencyList({
onSelect={handleSelect}
otherSelected={otherSelected}
showCurrencyAmount={showCurrencyAmount}
eventProperties={formatAnalyticsEventProperties(token, index, data, searchQuery, isAddressSearch)}
/>
)
} else {
@@ -272,6 +313,8 @@ export default function CurrencyList({
showImportView,
showCurrencyAmount,
isLoading,
isAddressSearch,
searchQuery,
]
)

View File

@@ -1,8 +1,10 @@
// eslint-disable-next-line no-restricted-imports
import { t, Trans } from '@lingui/macro'
import { Currency, Token } from '@uniswap/sdk-core'
import { useWeb3React } from '@web3-react/core'
import { EventName, ModalName } from 'components/AmplitudeAnalytics/constants'
import { Trace } from 'components/AmplitudeAnalytics/Trace'
import { sendEvent } from 'components/analytics'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import useDebounce from 'hooks/useDebounce'
import { useOnClickOutside } from 'hooks/useOnClickOutside'
import useTheme from 'hooks/useTheme'
@@ -10,12 +12,12 @@ import useToggle from 'hooks/useToggle'
import useNativeCurrency from 'lib/hooks/useNativeCurrency'
import { getTokenFilter } from 'lib/hooks/useTokenList/filtering'
import { tokenComparator, useSortTokensByQuery } from 'lib/hooks/useTokenList/sorting'
import { KeyboardEvent, RefObject, useCallback, useEffect, useMemo, useRef, useState } from 'react'
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'
import { useAllTokenBalances } from 'state/wallet/hooks'
import { useAllTokenBalances } from 'state/connection/hooks'
import styled from 'styled-components/macro'
import { useAllTokens, useIsUserAddedToken, useSearchInactiveTokenLists, useToken } from '../../hooks/Tokens'
@@ -40,8 +42,8 @@ const Footer = styled.div`
padding: 20px;
border-top-left-radius: 0;
border-top-right-radius: 0;
background-color: ${({ theme }) => theme.bg1};
border-top: 1px solid ${({ theme }) => theme.bg2};
background-color: ${({ theme }) => theme.deprecated_bg1};
border-top: 1px solid ${({ theme }) => theme.deprecated_bg2};
`
interface CurrencySearchProps {
@@ -71,7 +73,7 @@ export function CurrencySearch({
showImportView,
setImportToken,
}: CurrencySearchProps) {
const { chainId } = useActiveWeb3React()
const { chainId } = useWeb3React()
const theme = useTheme()
const [tokenLoaderTimerElapsed, setTokenLoaderTimerElapsed] = useState(false)
@@ -116,11 +118,15 @@ export function CurrencySearch({
const native = useNativeCurrency()
const filteredSortedTokensWithETH: Currency[] = useMemo(() => {
if (!native) return filteredSortedTokens
// Use Celo ERC20 Implementation and exclude the native asset
if (!native) {
return filteredSortedTokens
}
const s = debouncedQuery.toLowerCase().trim()
if (native.symbol?.toLowerCase()?.indexOf(s) !== -1) {
return native ? [native, ...filteredSortedTokens] : filteredSortedTokens
// Always bump the native token to the top of the list.
return native ? [native, ...filteredSortedTokens.filter((t) => !t.equals(native))] : filteredSortedTokens
}
return filteredSortedTokens
}, [debouncedQuery, native, filteredSortedTokens])
@@ -140,7 +146,7 @@ export function CurrencySearch({
// manage focus on modal show
const inputRef = useRef<HTMLInputElement>()
const handleInput = useCallback((event) => {
const handleInput = useCallback((event: ChangeEvent<HTMLInputElement>) => {
const input = event.target.value
const checksummedInput = isAddress(input)
setSearchQuery(checksummedInput || input)
@@ -185,76 +191,86 @@ export function CurrencySearch({
}, [])
return (
<ContentWrapper>
<PaddedColumn gap="16px">
<RowBetween>
<Text fontWeight={500} fontSize={16}>
<Trans>Select a token</Trans>
</Text>
<CloseIcon onClick={onDismiss} />
</RowBetween>
<Row>
<SearchInput
type="text"
id="token-search-input"
placeholder={t`Search name or paste address`}
autoComplete="off"
value={searchQuery}
ref={inputRef as RefObject<HTMLInputElement>}
onChange={handleInput}
onKeyDown={handleEnter}
/>
</Row>
{showCommonBases && (
<CommonBases chainId={chainId} onSelect={handleCurrencySelect} selectedCurrency={selectedCurrency} />
<Trace name={EventName.TOKEN_SELECTOR_OPENED} modal={ModalName.TOKEN_SELECTOR} shouldLogImpression={true}>
<ContentWrapper>
<PaddedColumn gap="16px">
<RowBetween>
<Text fontWeight={500} fontSize={16}>
<Trans>Select a token</Trans>
</Text>
<CloseIcon onClick={onDismiss} />
</RowBetween>
<Row>
<SearchInput
type="text"
id="token-search-input"
placeholder={t`Search name or paste address`}
autoComplete="off"
value={searchQuery}
ref={inputRef as RefObject<HTMLInputElement>}
onChange={handleInput}
onKeyDown={handleEnter}
/>
</Row>
{showCommonBases && (
<CommonBases
chainId={chainId}
onSelect={handleCurrencySelect}
selectedCurrency={selectedCurrency}
searchQuery={searchQuery}
isAddressSearch={isAddressSearch}
/>
)}
</PaddedColumn>
<Separator />
{searchToken && !searchTokenIsAdded ? (
<Column style={{ padding: '20px 0', height: '100%' }}>
<ImportRow token={searchToken} showImportView={showImportView} setImportToken={setImportToken} />
</Column>
) : filteredSortedTokens?.length > 0 || filteredInactiveTokens?.length > 0 ? (
<div style={{ flex: '1' }}>
<AutoSizer disableWidth>
{({ height }) => (
<CurrencyList
height={height}
currencies={disableNonToken ? filteredSortedTokens : filteredSortedTokensWithETH}
otherListTokens={filteredInactiveTokens}
onCurrencySelect={handleCurrencySelect}
otherCurrency={otherSelectedCurrency}
selectedCurrency={selectedCurrency}
fixedListRef={fixedList}
showImportView={showImportView}
setImportToken={setImportToken}
showCurrencyAmount={showCurrencyAmount}
isLoading={balancesIsLoading && !tokenLoaderTimerElapsed}
searchQuery={searchQuery}
isAddressSearch={isAddressSearch}
/>
)}
</AutoSizer>
</div>
) : (
<Column style={{ padding: '20px', height: '100%' }}>
<ThemedText.Main color={theme.deprecated_text3} textAlign="center" mb="20px">
<Trans>No results found.</Trans>
</ThemedText.Main>
</Column>
)}
</PaddedColumn>
<Separator />
{searchToken && !searchTokenIsAdded ? (
<Column style={{ padding: '20px 0', height: '100%' }}>
<ImportRow token={searchToken} showImportView={showImportView} setImportToken={setImportToken} />
</Column>
) : filteredSortedTokens?.length > 0 || filteredInactiveTokens?.length > 0 ? (
<div style={{ flex: '1' }}>
<AutoSizer disableWidth>
{({ height }) => (
<CurrencyList
height={height}
currencies={disableNonToken ? filteredSortedTokens : filteredSortedTokensWithETH}
otherListTokens={filteredInactiveTokens}
onCurrencySelect={handleCurrencySelect}
otherCurrency={otherSelectedCurrency}
selectedCurrency={selectedCurrency}
fixedListRef={fixedList}
showImportView={showImportView}
setImportToken={setImportToken}
showCurrencyAmount={showCurrencyAmount}
isLoading={balancesIsLoading && !tokenLoaderTimerElapsed}
/>
)}
</AutoSizer>
</div>
) : (
<Column style={{ padding: '20px', height: '100%' }}>
<ThemedText.Main color={theme.text3} textAlign="center" mb="20px">
<Trans>No results found.</Trans>
</ThemedText.Main>
</Column>
)}
<Footer>
<Row justify="center">
<ButtonText onClick={showManageView} color={theme.primary1} className="list-token-manage-button">
<RowFixed>
<IconWrapper size="16px" marginRight="6px" stroke={theme.primaryText1}>
<Edit />
</IconWrapper>
<ThemedText.Main color={theme.primaryText1}>
<Trans>Manage Token Lists</Trans>
</ThemedText.Main>
</RowFixed>
</ButtonText>
</Row>
</Footer>
</ContentWrapper>
<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.Main color={theme.deprecated_primaryText1}>
<Trans>Manage Token Lists</Trans>
</ThemedText.Main>
</RowFixed>
</ButtonText>
</Row>
</Footer>
</ContentWrapper>
</Trace>
)
}

View File

@@ -90,7 +90,7 @@ export function ImportList({ listURL, list, setModalView, onDismiss }: ImportPro
<SectionBreak />
<PaddedColumn gap="md">
<AutoColumn gap="md">
<Card backgroundColor={theme.bg2} padding="12px 20px">
<Card backgroundColor={theme.deprecated_bg2} padding="12px 20px">
<RowBetween>
<RowFixed>
{list.logoURI && <ListLogo logoURI={list.logoURI} size="40px" />}
@@ -105,7 +105,7 @@ export function ImportList({ listURL, list, setModalView, onDismiss }: ImportPro
</ThemedText.Main>
</RowFixed>
<ExternalLink href={`https://tokenlists.org/token-list?url=${listURL}`}>
<ThemedText.Main fontSize={'12px'} color={theme.blue1}>
<ThemedText.Main fontSize={'12px'} color={theme.deprecated_blue1}>
{listURL}
</ThemedText.Main>
</ExternalLink>
@@ -113,23 +113,23 @@ export function ImportList({ listURL, list, setModalView, onDismiss }: ImportPro
</RowFixed>
</RowBetween>
</Card>
<Card style={{ backgroundColor: transparentize(0.8, theme.red1) }}>
<Card style={{ backgroundColor: transparentize(0.8, theme.deprecated_red1) }}>
<AutoColumn justify="center" style={{ textAlign: 'center', gap: '16px', marginBottom: '12px' }}>
<AlertTriangle stroke={theme.red1} size={32} />
<ThemedText.Body fontWeight={500} fontSize={20} color={theme.red1}>
<AlertTriangle stroke={theme.deprecated_red1} size={32} />
<ThemedText.Body fontWeight={500} fontSize={20} color={theme.deprecated_red1}>
<Trans>Import at your own risk</Trans>
</ThemedText.Body>
</AutoColumn>
<AutoColumn style={{ textAlign: 'center', gap: '16px', marginBottom: '12px' }}>
<ThemedText.Body fontWeight={500} color={theme.red1}>
<ThemedText.Body fontWeight={500} color={theme.deprecated_red1}>
<Trans>
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.
</Trans>
</ThemedText.Body>
<ThemedText.Body fontWeight={600} color={theme.red1}>
<ThemedText.Body fontWeight={600} color={theme.deprecated_red1}>
<Trans>If you purchase a token from this list, you may not be able to sell it back.</Trans>
</ThemedText.Body>
</AutoColumn>
@@ -140,7 +140,7 @@ export function ImportList({ listURL, list, setModalView, onDismiss }: ImportPro
checked={confirmed}
onChange={() => setConfirmed(!confirmed)}
/>
<ThemedText.Body ml="10px" fontSize="16px" color={theme.red1} fontWeight={500}>
<ThemedText.Body ml="10px" fontSize="16px" color={theme.deprecated_red1} fontWeight={500}>
<Trans>I understand</Trans>
</ThemedText.Body>
</AutoRow>

View File

@@ -29,7 +29,7 @@ const CheckIcon = styled(CheckCircle)`
height: 16px;
width: 16px;
margin-right: 6px;
stroke: ${({ theme }) => theme.green1};
stroke: ${({ theme }) => theme.deprecated_green1};
`
const NameOverflow = styled.div`
@@ -74,7 +74,7 @@ export default function ImportRow({
</AutoRow>
{list && list.logoURI && (
<RowFixed>
<ThemedText.Small mr="4px" color={theme.text3}>
<ThemedText.Small mr="4px" color={theme.deprecated_text3}>
<Trans>via {list.name} </Trans>
</ThemedText.Small>
<ListLogo logoURI={list.logoURI} size="12px" />
@@ -97,7 +97,7 @@ export default function ImportRow({
) : (
<RowFixed style={{ minWidth: 'fit-content' }}>
<CheckIcon />
<ThemedText.Main color={theme.green1}>
<ThemedText.Main color={theme.deprecated_green1}>
<Trans>Active</Trans>
</ThemedText.Main>
</RowFixed>

View File

@@ -1,6 +1,8 @@
import { Plural, Trans } from '@lingui/macro'
import { Currency, Token } from '@uniswap/sdk-core'
import { TokenList } from '@uniswap/token-lists'
import { ElementName, Event, EventName } from 'components/AmplitudeAnalytics/constants'
import { TraceEvent } from 'components/AmplitudeAnalytics/TraceEvent'
import { ButtonPrimary } from 'components/Button'
import { AutoColumn } from 'components/Column'
import { RowBetween } from 'components/Row'
@@ -30,6 +32,12 @@ interface ImportProps {
handleCurrencySelect?: (currency: Currency) => void
}
const formatAnalyticsEventProperties = (tokens: Token[]) => ({
token_symbols: tokens.map((token) => token?.symbol),
token_addresses: tokens.map((token) => token?.address),
token_chain_ids: tokens.map((token) => token?.chainId),
})
export function ImportToken(props: ImportProps) {
const { tokens, list, onBack, onDismiss, handleCurrencySelect } = props
const theme = useTheme()
@@ -42,6 +50,7 @@ export function ImportToken(props: ImportProps) {
if (intersection.size > 0) {
return <BlockedToken onBack={onBack} onDismiss={onDismiss} blockedTokens={Array.from(intersection)} />
}
return (
<Wrapper>
<PaddedColumn gap="14px" style={{ width: '100%', flex: '1 1' }}>
@@ -56,7 +65,7 @@ export function ImportToken(props: ImportProps) {
<SectionBreak />
<AutoColumn gap="md" style={{ marginBottom: '32px', padding: '1rem' }}>
<AutoColumn justify="center" style={{ textAlign: 'center', gap: '16px', padding: '1rem' }}>
<AlertCircle size={48} stroke={theme.text2} strokeWidth={1} />
<AlertCircle size={48} stroke={theme.deprecated_text2} strokeWidth={1} />
<ThemedText.Body fontWeight={400} fontSize={16}>
<Trans>
This token doesn&apos;t appear on the active token list(s). Make sure this is the token that you want to
@@ -67,18 +76,25 @@ export function ImportToken(props: ImportProps) {
{tokens.map((token) => (
<TokenImportCard token={token} list={list} key={'import' + token.address} />
))}
<ButtonPrimary
altDisabledStyle={true}
$borderRadius="20px"
padding="10px 1rem"
onClick={() => {
tokens.map((token) => addToken(token))
handleCurrencySelect && handleCurrencySelect(tokens[0])
}}
className=".token-dismiss-button"
<TraceEvent
events={[Event.onClick]}
name={EventName.TOKEN_IMPORTED}
properties={formatAnalyticsEventProperties(tokens)}
element={ElementName.IMPORT_TOKEN_BUTTON}
>
<Trans>Import</Trans>
</ButtonPrimary>
<ButtonPrimary
altDisabledStyle={true}
$borderRadius="20px"
padding="10px 1rem"
onClick={() => {
tokens.map((token) => addToken(token))
handleCurrencySelect && handleCurrencySelect(tokens[0])
}}
className=".token-dismiss-button"
>
<Trans>Import</Trans>
</ButtonPrimary>
</TraceEvent>
</AutoColumn>
</Wrapper>
)

View File

@@ -21,7 +21,7 @@ const Wrapper = styled.div`
`
const ToggleWrapper = styled(RowBetween)`
background-color: ${({ theme }) => theme.bg3};
background-color: ${({ theme }) => theme.deprecated_bg3};
border-radius: 12px;
padding: 6px;
`
@@ -34,8 +34,8 @@ const ToggleOption = styled.div<{ active?: boolean }>`
justify-content: center;
border-radius: 12px;
font-weight: 600;
background-color: ${({ theme, active }) => (active ? theme.bg1 : theme.bg3)};
color: ${({ theme, active }) => (active ? theme.text1 : theme.text2)};
background-color: ${({ theme, active }) => (active ? theme.deprecated_bg1 : theme.deprecated_bg3)};
color: ${({ theme, active }) => (active ? theme.deprecated_text1 : theme.deprecated_text2)};
user-select: none;
:hover {

View File

@@ -1,14 +1,14 @@
// eslint-disable-next-line no-restricted-imports
import { t, Trans } from '@lingui/macro'
import { TokenList } from '@uniswap/token-lists'
import { useWeb3React } from '@web3-react/core'
import { sendEvent } from 'components/analytics'
import Card from 'components/Card'
import { UNSUPPORTED_LIST_URLS } from 'constants/lists'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useListColor } from 'hooks/useColor'
import parseENSAddress from 'lib/utils/parseENSAddress'
import uriToHttp from 'lib/utils/uriToHttp'
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { ChangeEvent, memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { CheckCircle, Settings } from 'react-feather'
import { usePopper } from 'react-popper'
import { useAppDispatch, useAppSelector } from 'state/hooks'
@@ -46,11 +46,11 @@ const PopoverContainer = styled.div<{ show: boolean }>`
visibility: ${(props) => (props.show ? 'visible' : 'hidden')};
opacity: ${(props) => (props.show ? 1 : 0)};
transition: visibility 150ms linear, opacity 150ms linear;
background: ${({ theme }) => theme.bg2};
border: 1px solid ${({ theme }) => theme.bg3};
background: ${({ theme }) => theme.deprecated_bg2};
border: 1px solid ${({ theme }) => theme.deprecated_bg3};
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);
color: ${({ theme }) => theme.text2};
color: ${({ theme }) => theme.deprecated_text2};
border-radius: 0.5rem;
padding: 1rem;
display: grid;
@@ -73,16 +73,16 @@ const StyledTitleText = styled.div<{ active: boolean }>`
overflow: hidden;
text-overflow: ellipsis;
font-weight: 600;
color: ${({ theme, active }) => (active ? theme.white : theme.text2)};
color: ${({ theme, active }) => (active ? theme.deprecated_white : theme.deprecated_text2)};
`
const StyledListUrlText = styled(ThemedText.Main)<{ active: boolean }>`
font-size: 12px;
color: ${({ theme, active }) => (active ? theme.white : theme.text2)};
color: ${({ theme, active }) => (active ? theme.deprecated_white : theme.deprecated_text2)};
`
const RowWrapper = styled(Row)<{ bgColor: string; active: boolean; hasActiveTokens: boolean }>`
background-color: ${({ bgColor, active, theme }) => (active ? bgColor ?? 'transparent' : theme.bg2)};
background-color: ${({ bgColor, active, theme }) => (active ? bgColor ?? 'transparent' : theme.deprecated_bg2)};
opacity: ${({ hasActiveTokens }) => (hasActiveTokens ? 1 : 0.4)};
transition: 200ms;
align-items: center;
@@ -95,7 +95,7 @@ function listUrlRowHTMLId(listUrl: string) {
}
const ListRow = memo(function ListRow({ listUrl }: { listUrl: string }) {
const { chainId } = useActiveWeb3React()
const { chainId } = useWeb3React()
const listsByUrl = useAppSelector((state) => state.lists.byUrl)
const dispatch = useAppDispatch()
const { current: list, pendingUpdate: pending } = listsByUrl[listUrl]
@@ -193,7 +193,7 @@ const ListRow = memo(function ListRow({ listUrl }: { listUrl: string }) {
</StyledListUrlText>
<StyledMenu ref={node as any}>
<ButtonEmpty onClick={toggle} ref={setReferenceElement} padding="0">
<Settings stroke={isActive ? theme.bg1 : theme.text1} size={12} />
<Settings stroke={isActive ? theme.deprecated_bg1 : theme.deprecated_text1} size={12} />
</ButtonEmpty>
{open && (
<PopoverContainer show={true} ref={setPopperElement as any} style={styles.popper} {...attributes.popper}>
@@ -242,7 +242,7 @@ export function ManageLists({
setImportList: (list: TokenList) => void
setListUrl: (url: string) => void
}) {
const { chainId } = useActiveWeb3React()
const { chainId } = useWeb3React()
const theme = useTheme()
const [listUrlInput, setListUrlInput] = useState<string>('')
@@ -266,7 +266,7 @@ export function ManageLists({
// sort by active but only if not visible
const activeListUrls = useActiveListUrls()
const handleInput = useCallback((e) => {
const handleInput = useCallback((e: ChangeEvent<HTMLInputElement>) => {
setListUrlInput(e.target.value)
}, [])
@@ -369,7 +369,7 @@ export function ManageLists({
</PaddedColumn>
{tempList && (
<PaddedColumn style={{ paddingTop: 0 }}>
<Card backgroundColor={theme.bg2} padding="12px 20px">
<Card backgroundColor={theme.deprecated_bg2} padding="12px 20px">
<RowBetween>
<RowFixed>
{tempList.logoURI && <ListLogo logoURI={tempList.logoURI} size="40px" />}
@@ -382,10 +382,10 @@ export function ManageLists({
</RowFixed>
{isImported ? (
<RowFixed>
<IconWrapper stroke={theme.text2} size="16px" marginRight={'10px'}>
<IconWrapper stroke={theme.deprecated_text2} size="16px" marginRight={'10px'}>
<CheckCircle />
</IconWrapper>
<ThemedText.Body color={theme.text2}>
<ThemedText.Body color={theme.deprecated_text2}>
<Trans>Loaded</Trans>
</ThemedText.Body>
</RowFixed>

View File

@@ -1,12 +1,12 @@
import { Trans } from '@lingui/macro'
import { Token } from '@uniswap/sdk-core'
import { useWeb3React } from '@web3-react/core'
import Card from 'components/Card'
import Column from 'components/Column'
import CurrencyLogo from 'components/CurrencyLogo'
import Row, { RowBetween, RowFixed } from 'components/Row'
import { useToken } from 'hooks/Tokens'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { RefObject, useCallback, useMemo, useRef, useState } from 'react'
import { ChangeEvent, RefObject, useCallback, useMemo, useRef, useState } from 'react'
import { useRemoveUserAddedToken, useUserAddedTokens } from 'state/user/hooks'
import styled from 'styled-components/macro'
import { ButtonText, ExternalLink, ExternalLinkIcon, ThemedText, TrashIcon } from 'theme'
@@ -32,7 +32,7 @@ const Footer = styled.div`
border-radius: 20px;
border-top-right-radius: 0;
border-top-left-radius: 0;
border-top: 1px solid ${({ theme }) => theme.bg3};
border-top: 1px solid ${({ theme }) => theme.deprecated_bg3};
padding: 20px;
text-align: center;
`
@@ -44,14 +44,14 @@ export default function ManageTokens({
setModalView: (view: CurrencyModalView) => void
setImportToken: (token: Token) => void
}) {
const { chainId } = useActiveWeb3React()
const { chainId } = useWeb3React()
const [searchQuery, setSearchQuery] = useState<string>('')
const theme = useTheme()
// manage focus on modal show
const inputRef = useRef<HTMLInputElement>()
const handleInput = useCallback((event) => {
const handleInput = useCallback((event: ChangeEvent<HTMLInputElement>) => {
const input = event.target.value
const checksummedInput = isAddress(input)
setSearchQuery(checksummedInput || input)
@@ -116,7 +116,7 @@ export default function ManageTokens({
</ThemedText.Error>
)}
{searchToken && (
<Card backgroundColor={theme.bg2} padding="10px 0">
<Card backgroundColor={theme.deprecated_bg2} padding="10px 0">
<ImportRow
token={searchToken}
showImportView={() => setModalView(CurrencyModalView.importToken)}

View File

@@ -1,12 +1,12 @@
import { Trans } from '@lingui/macro'
import { Token } from '@uniswap/sdk-core'
import { TokenList } from '@uniswap/token-lists'
import { useWeb3React } from '@web3-react/core'
import Card from 'components/Card'
import { AutoColumn } from 'components/Column'
import CurrencyLogo from 'components/CurrencyLogo'
import ListLogo from 'components/ListLogo'
import { RowFixed } from 'components/Row'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { transparentize } from 'polished'
import { AlertCircle } from 'react-feather'
import styled, { useTheme } from 'styled-components/macro'
@@ -15,7 +15,7 @@ import { ExplorerDataType, getExplorerLink } from 'utils/getExplorerLink'
const WarningWrapper = styled(Card)<{ highWarning: boolean }>`
background-color: ${({ theme, highWarning }) =>
highWarning ? transparentize(0.8, theme.red1) : transparentize(0.8, theme.yellow2)};
highWarning ? transparentize(0.8, theme.deprecated_red1) : transparentize(0.8, theme.deprecated_yellow2)};
width: fit-content;
`
@@ -33,9 +33,9 @@ interface TokenImportCardProps {
}
const TokenImportCard = ({ list, token }: TokenImportCardProps) => {
const theme = useTheme()
const { chainId } = useActiveWeb3React()
const { chainId } = useWeb3React()
return (
<Card backgroundColor={theme.bg2} padding="2rem">
<Card backgroundColor={theme.deprecated_bg2} padding="2rem">
<AutoColumn gap="10px" justify="center">
<CurrencyLogo currency={token} size={'32px'} />
<AutoColumn gap="4px" justify="center">
@@ -54,15 +54,15 @@ const TokenImportCard = ({ list, token }: TokenImportCardProps) => {
{list !== undefined ? (
<RowFixed>
{list.logoURI && <ListLogo logoURI={list.logoURI} size="16px" />}
<ThemedText.Small ml="6px" fontSize={14} color={theme.text3}>
<ThemedText.Small ml="6px" fontSize={14} color={theme.deprecated_text3}>
<Trans>via {list.name} token list</Trans>
</ThemedText.Small>
</RowFixed>
) : (
<WarningWrapper $borderRadius="4px" padding="4px" highWarning={true}>
<RowFixed>
<AlertCircle stroke={theme.red1} size="10px" />
<ThemedText.Body color={theme.red1} ml="4px" fontSize="10px" fontWeight={500}>
<AlertCircle stroke={theme.deprecated_red1} size="10px" />
<ThemedText.Body color={theme.deprecated_red1} ml="4px" fontSize="10px" fontWeight={500}>
<Trans>Unknown Source</Trans>
</ThemedText.Body>
</RowFixed>

View File

@@ -7,12 +7,12 @@ import { RowBetween } from '../Row'
export const TextDot = styled.div`
height: 3px;
width: 3px;
background-color: ${({ theme }) => theme.text2};
background-color: ${({ theme }) => theme.deprecated_text2};
border-radius: 50%;
`
export const Checkbox = styled.input`
border: 1px solid ${({ theme }) => theme.red3};
border: 1px solid ${({ theme }) => theme.deprecated_red3};
height: 20px;
margin: 0;
`
@@ -30,7 +30,7 @@ export const MenuItem = styled(RowBetween)`
cursor: ${({ disabled }) => !disabled && 'pointer'};
pointer-events: ${({ disabled }) => disabled && 'none'};
:hover {
background-color: ${({ theme, disabled }) => !disabled && theme.bg2};
background-color: ${({ theme, disabled }) => !disabled && theme.deprecated_bg2};
}
opacity: ${({ disabled, selected }) => (disabled || selected ? 0.5 : 1)};
`
@@ -46,32 +46,32 @@ export const SearchInput = styled.input`
border: none;
outline: none;
border-radius: 20px;
color: ${({ theme }) => theme.text1};
color: ${({ theme }) => theme.deprecated_text1};
border-style: solid;
border: 1px solid ${({ theme }) => theme.bg3};
border: 1px solid ${({ theme }) => theme.deprecated_bg3};
-webkit-appearance: none;
font-size: 18px;
::placeholder {
color: ${({ theme }) => theme.text3};
color: ${({ theme }) => theme.deprecated_text3};
}
transition: border 100ms;
:focus {
border: 1px solid ${({ theme }) => theme.primary1};
border: 1px solid ${({ theme }) => theme.deprecated_primary1};
outline: none;
}
`
export const Separator = styled.div`
width: 100%;
height: 1px;
background-color: ${({ theme }) => theme.bg2};
background-color: ${({ theme }) => theme.deprecated_bg2};
`
export const SeparatorDark = styled.div`
width: 100%;
height: 1px;
background-color: ${({ theme }) => theme.bg3};
background-color: ${({ theme }) => theme.deprecated_bg3};
`
export const LoadingRows = styled(BaseLoadingRows)`

View File

@@ -1,16 +1,16 @@
// eslint-disable-next-line no-restricted-imports
import { t, Trans } from '@lingui/macro'
import { Percent } from '@uniswap/sdk-core'
import { useWeb3React } from '@web3-react/core'
import { sendEvent } from 'components/analytics'
import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { AUTO_ROUTER_SUPPORTED_CHAINS } from 'lib/hooks/routing/clientSideSmartOrderRouter'
import { isSupportedChainId } from 'lib/hooks/routing/clientSideSmartOrderRouter'
import { useContext, useRef, useState } from 'react'
import { Settings, X } from 'react-feather'
import { Text } from 'rebass'
import styled, { ThemeContext } from 'styled-components/macro'
import { useOnClickOutside } from '../../hooks/useOnClickOutside'
import { useModalOpen, useToggleSettingsMenu } from '../../state/application/hooks'
import { useModalIsOpen, useToggleSettingsMenu } from '../../state/application/hooks'
import { ApplicationModal } from '../../state/application/reducer'
import { useClientSideRouter, useExpertModeManager } from '../../state/user/hooks'
import { ThemedText } from '../../theme'
@@ -27,11 +27,7 @@ const StyledMenuIcon = styled(Settings)`
width: 20px;
> * {
stroke: ${({ theme }) => theme.text1};
}
:hover {
opacity: 0.7;
stroke: ${({ theme }) => theme.deprecated_text1};
}
`
@@ -43,11 +39,11 @@ const StyledCloseIcon = styled(X)`
}
> * {
stroke: ${({ theme }) => theme.text1};
stroke: ${({ theme }) => theme.deprecated_text1};
}
`
const StyledMenuButton = styled.button`
const StyledMenuButton = styled.button<{ disabled: boolean }>`
position: relative;
width: 100%;
height: 100%;
@@ -58,11 +54,16 @@ const StyledMenuButton = styled.button`
border-radius: 0.5rem;
height: 20px;
:hover,
:focus {
cursor: pointer;
outline: none;
}
${({ disabled }) =>
!disabled &&
`
:hover,
:focus {
cursor: pointer;
outline: none;
opacity: 0.7;
}
`}
`
const EmojiWrapper = styled.div`
position: absolute;
@@ -83,8 +84,8 @@ const StyledMenu = styled.div`
const MenuFlyout = styled.span`
min-width: 20.125rem;
background-color: ${({ theme }) => theme.bg2};
border: 1px solid ${({ theme }) => theme.bg3};
background-color: ${({ theme }) => theme.deprecated_bg2};
border: 1px solid ${({ theme }) => theme.deprecated_bg3};
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: 12px;
@@ -106,7 +107,7 @@ const MenuFlyout = styled.span`
const Break = styled.div`
width: 100%;
height: 1px;
background-color: ${({ theme }) => theme.bg3};
background-color: ${({ theme }) => theme.deprecated_bg3};
`
const ModalContentWrapper = styled.div`
@@ -114,15 +115,15 @@ const ModalContentWrapper = styled.div`
align-items: center;
justify-content: center;
padding: 2rem 0;
background-color: ${({ theme }) => theme.bg2};
background-color: ${({ theme }) => theme.deprecated_bg2};
border-radius: 20px;
`
export default function SettingsTab({ placeholderSlippage }: { placeholderSlippage: Percent }) {
const { chainId } = useActiveWeb3React()
const { chainId } = useWeb3React()
const node = useRef<HTMLDivElement>()
const open = useModalOpen(ApplicationModal.SETTINGS)
const open = useModalIsOpen(ApplicationModal.SETTINGS)
const toggle = useToggleSettingsMenu()
const theme = useContext(ThemeContext)
@@ -179,7 +180,12 @@ export default function SettingsTab({ placeholderSlippage }: { placeholderSlippa
</AutoColumn>
</ModalContentWrapper>
</Modal>
<StyledMenuButton onClick={toggle} id="open-settings-dialog-button" aria-label={t`Transaction Settings`}>
<StyledMenuButton
disabled={!isSupportedChainId(chainId)}
onClick={toggle}
id="open-settings-dialog-button"
aria-label={t`Transaction Settings`}
>
<StyledMenuIcon />
{expertMode ? (
<EmojiWrapper>
@@ -199,10 +205,10 @@ export default function SettingsTab({ placeholderSlippage }: { placeholderSlippa
<Text fontWeight={600} fontSize={14}>
<Trans>Interface Settings</Trans>
</Text>
{chainId && AUTO_ROUTER_SUPPORTED_CHAINS.includes(chainId) && (
{isSupportedChainId(chainId) && (
<RowBetween>
<RowFixed>
<ThemedText.Black fontWeight={400} fontSize={14} color={theme.text2}>
<ThemedText.Black fontWeight={400} fontSize={14} color={theme.deprecated_text2}>
<Trans>Auto Router API</Trans>
</ThemedText.Black>
<QuestionHelper text={<Trans>Use the Uniswap Labs API to get faster quotes.</Trans>} />
@@ -222,7 +228,7 @@ export default function SettingsTab({ placeholderSlippage }: { placeholderSlippa
)}
<RowBetween>
<RowFixed>
<ThemedText.Black fontWeight={400} fontSize={14} color={theme.text2}>
<ThemedText.Black fontWeight={400} fontSize={14} color={theme.deprecated_text2}>
<Trans>Expert Mode</Trans>
</ThemedText.Black>
<QuestionHelper

View File

@@ -1,4 +1,4 @@
import { useCallback } from 'react'
import { ChangeEvent, useCallback } from 'react'
import styled from 'styled-components/macro'
const StyledRangeInput = styled.input<{ size: number }>`
@@ -19,11 +19,11 @@ const StyledRangeInput = styled.input<{ size: number }>`
-webkit-appearance: none;
height: ${({ size }) => size}px;
width: ${({ size }) => size}px;
background-color: ${({ theme }) => theme.blue1};
background-color: ${({ theme }) => theme.deprecated_blue1};
border-radius: 100%;
border: none;
transform: translateY(-50%);
color: ${({ theme }) => theme.bg1};
color: ${({ theme }) => theme.deprecated_bg1};
&:hover,
&:focus {
@@ -38,7 +38,7 @@ const StyledRangeInput = styled.input<{ size: number }>`
background-color: #565a69;
border-radius: 100%;
border: none;
color: ${({ theme }) => theme.bg1};
color: ${({ theme }) => theme.deprecated_bg1};
&:hover,
&:focus {
@@ -52,7 +52,7 @@ const StyledRangeInput = styled.input<{ size: number }>`
width: ${({ size }) => size}px;
background-color: #565a69;
border-radius: 100%;
color: ${({ theme }) => theme.bg1};
color: ${({ theme }) => theme.deprecated_bg1};
&:hover,
&:focus {
@@ -62,12 +62,16 @@ const StyledRangeInput = styled.input<{ size: number }>`
}
&::-webkit-slider-runnable-track {
background: linear-gradient(90deg, ${({ theme }) => theme.blue1}, ${({ theme }) => theme.blue2});
background: linear-gradient(
90deg,
${({ theme }) => theme.deprecated_blue1},
${({ theme }) => theme.deprecated_blue2}
);
height: 2px;
}
&::-moz-range-track {
background: linear-gradient(90deg, ${({ theme }) => theme.bg5}, ${({ theme }) => theme.bg3});
background: linear-gradient(90deg, ${({ theme }) => theme.deprecated_bg5}, ${({ theme }) => theme.deprecated_bg3});
height: 2px;
}
@@ -76,14 +80,14 @@ const StyledRangeInput = styled.input<{ size: number }>`
border-color: transparent;
color: transparent;
background: ${({ theme }) => theme.bg5};
background: ${({ theme }) => theme.deprecated_bg5};
height: 2px;
}
&::-ms-fill-lower {
background: ${({ theme }) => theme.bg5};
background: ${({ theme }) => theme.deprecated_bg5};
}
&::-ms-fill-upper {
background: ${({ theme }) => theme.bg3};
background: ${({ theme }) => theme.deprecated_bg3};
}
`
@@ -106,7 +110,7 @@ export default function Slider({
...rest
}: InputSliderProps) {
const changeCallback = useCallback(
(e) => {
(e: ChangeEvent<HTMLInputElement>) => {
onChange(parseInt(e.target.value))
},
[onChange]

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