Compare commits

...

119 Commits

Author SHA1 Message Date
lynn
594dcb90e3 feat: Web 262 user model custom properties first PR (#4190)
* init commit

* abstract amplitude stuff away to separate function
2022-07-26 23:07:03 +00:00
Kaylee George
d0f7c8d6f3 fix: update critical red HEX (#4191)
change red
2022-07-26 17:35:40 -04:00
Daniel James
352e016621 style: Add Deprecated prefix to ThemedText components (#4192)
* Add Deprecated prefix to ThemedText components

* Fix lint errors
2022-07-26 17:14:43 -04:00
Sam Chen
2a7b1e7ff0 chore: upgrade react-router-dom to v6 (#4143)
* chore: upgrade react-router-dom to v6

* migrate Redirect to Navigate

* use Routes instead of Switch

* migrate useHistory to useNavigate

* use To type

* use element

* work around activeClassName

* fix typing for useParams

* deduplicate

* fix Navigate

* add e2e tests

* visit /swap directly

Co-authored-by: Vignesh Mohankumar <me@vig.xyz>
2022-07-26 17:10:57 -04:00
Akshit Choudhary
8836ae1986 fix: updated external docs link for Propose (#4186)
FIxed Propose External Docs Link
2022-07-26 15:17:42 +00:00
Rachel-Eichenberger
0bf694a1ff fix: Update V2 Pool Document link (#4188)
Update V2 Pool Document link

Current link line 163 point to old documents, and gives error page
changed to

https://docs.uniswap.org/protocol/V2/concepts/core-concepts/pools

current version of pool documents for V2
2022-07-26 11:14:57 -04:00
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
Vignesh Mohankumar
d36f13d7e2 fix: resolves network switch race condition (#4005)
* don't need undo logic

* maybe need to return connector

* make sure the urlChainId doesn't equal existing chainId

* fix network switching

* add back revert logic

* undo changes to switchChain

* move revert logic into the hook
2022-06-30 11:51:23 -05:00
Vignesh Mohankumar
8548b33bd9 feat: show injected options in wallet browsers (#3995)
* feat: show injected options in wallet browsers

* initial testing

* more mocking

* mock more

* mobile tests

* updates

* add data test

* finally got the mock to work

* WORKING

* uncomment

* rm console.log

* fix

* check length

* fix tests to use useWeb3React

* rm

* rename tests
2022-06-30 12:26:22 -04:00
Vignesh Mohankumar
0e148bb1b3 style: use data-testid in cypress test (#4001)
* use data-testid

* findByTestId

test -> it

add types

temp

rm exclude

get -> find

* Revert "findByTestId"

This reverts commit 1e1c483ef9.

* rm some test ids

* fix
2022-06-29 16:57:21 -04:00
Vignesh Mohankumar
9ddb37a982 chore: move cypress to devDependencies (#4002) 2022-06-29 13:41:20 -07:00
Zach Pomerantz
63227cd2c5 build: dedup lockfile (#3985)
* build: dedup ethers

* build: dedup token-lists

* build: dedup deps

* build: clean deps
2022-06-29 09:43:01 -07:00
Zach Pomerantz
dc38dc1c10 build: disable release (#3994) 2022-06-28 18:03:40 -07:00
Zach Pomerantz
2c6757ff62 fix: set content-type on cached document (#3990)
* fix: set content-type on cached document

* fix: delete old content-types

* fix: avoid immutable headers

* test: content-type

* fix: do not destructure response

* test: serve from cache with vercel

* fix: inject cache marker into body
2022-06-28 16:31:05 -07:00
Zach Pomerantz
0d03b09ae9 build: sleep for 10m after pinning (#3991) 2022-06-28 15:40:33 -07:00
Jordan Frankfurt
566da07448 feat(risk): cache risk check with ttl (#3965) 2022-06-24 11:11:32 -05:00
Vignesh Mohankumar
31a3840b1f feat: fix metamask mobile browser connection (#3964)
* fix metamask

* forceActivate

* remove forceActivate

* unused change
2022-06-23 16:50:04 -04:00
Vignesh Mohankumar
f89d7ccd5e feat: empty to deploy 628417f696 (#3962)
feat: empty to deploy
2022-06-23 12:29:46 -04:00
matteenm
628417f696 chore(deps): bump token-lists (#3929) 2022-06-21 15:52:09 -04:00
Kaylee George
ea8c7326d6 fix: crash on HOP token search (#3904) (#3928)
fix: ensure token address is checksummed on construction
2022-06-17 11:54:07 -04:00
Zach Pomerantz
dd5feaacb2 fix: serviceworker request path (#3926)
* fix: serviceworker request path

Always requests the app-shell from the same path as the cache key, in
order to guarantee that the etags will match should the cache be valid.

* fix: avoid returning redirects
2022-06-16 17:51:46 -04:00
Zach Pomerantz
cc919ab3df build: optimize github actions (#3922)
* build: parallelize cypress

- Parallelizes cypress CI runs
- Cleans up CI workflow files

* build: fix typo

* build: cache node_modules

* build: cache node_modules everywhere

* fix: action/cache usage

* fix: do not cache dynamically built files

* build: use standard container for cypress

* fix: cache cypress

* fix: cache cypress
2022-06-16 17:42:18 -04:00
Kaylee George
53d6eb0922 fix: show no price impact eth to weth (#3923)
* fix: show no price impact eth to weth

Fixed the price estimate values to reflect the correct price estimates depending on whether it is a wrapped trade

* fix: show no price impact eth to weth

Fixed to display the correct price estimates depending on whether it is a wrapped trade (eth -> weth should show no price impact)

* Added ETH->wETH testing

Added a Cypress test to check wrapped value swap has no price impact

* make Cypress test cleaner
2022-06-16 15:09:57 -04:00
Vignesh Mohankumar
db0d3cf3fa feat: upgrade to web3-react v8 (#3759)
* initial

* comment more stuff out for now

* more changes

* more temp

* remove walletconnect bug logic

* switch to provider not connector

* remove fortmatic

* remove some usage of network connector

* fix initialize connector

* more changes

* remove switch to network

* connect eagerly

* active -> isActive

* add initial option cards

* upgrade web3-react

* delete tryActivation

* delete pending view, reset option code

* fix hooks

* library -> provider

* rm getLibrary

* eagerly connect

* comment all this code for now

* add back app

* dont connect eagerly here

* deactivate

* switchToNetwork

* switch to useWeb3React

* rm Web3ReactManager

* add back og wallet modal code

* switch back to old option logic

* add account logic back

* add back more network switch logic

* Revert "switch to useWeb3React"

This reverts commit 08ac6319d4.

* add back skip disconnect logic

* check for network connector

* use promise.then again

* remove unnecessary pending error logic

* reset useAddTokenToMetamask

* upgrade packages

* use watchAsset

* add gnosis

* rm fortmatic

* close on disconnection

* add Wallet enum

* remove fortmatic imports

* add wallet state

* set/clear override wallet

* resolve empty

* remove some wallet modal view logic

* useWeb3ReactListener

* move to use effect

* add setwalletoverride in deactivate for now

* start to fix the wallet modal bug

* back button should open options

* connect eagerly to all

* Revert "add setwalletoverride in deactivate for now"

This reverts commit fbc990a924.

* useSelectedIsActive

* switch the enum to not be a bug

* actually dispatch the wallet override

* remove connection useEffect for now

* Revert "remove connection useEffect for now"

This reverts commit 0b92eee689.

* add back the activation useeffect

* handle resetting eagerly connecting

* dont disconnect from coinbase wallet

* disconnect except for coinbase wallet, bc their reload breaks things

* handle eager activation edge case

* backfill wallet override

* rename wrapper components

* update test

* network if override undefined

* npx deduplicate

* comment for why coinbase wallet special cased

* connectorPrevious -> previousConnector

* Array.find instead of forEach

* useState instead of useReducer

* add comments and simplify

* Web3Wrapper component

* add type guard

* check for watchAsset

* revert Option.tsx changes

* set -> updateWalletOverride

* generalize connector type usage

* rm comment

* eagerlyConnect comment

* null -> undefined

* add comment for wallet override

* add back pendingError logic

* merge conflicts

* remove provider dep

* add back connect a wallet

* move active prop out of base props

* add back account details test

* add type of isActiveMap

* add back eslint

* add TODO

* Web3Provider

* return null from Updater

* update comment

* integration tests initial

* try updating test

* check for gnosis safe

* fix gnosis safe check

* pr comments

* pr comments

* don't eagerly connect to any wallets other than gnosis or walletOverride

* remove unused branch

* pendingError from hook

* eslint-disable-line

* try connecting to wallets if not backfilled

* move eager connection logic

* remove connect eagerly set logic

* disconnect on change

* simplify ConnectorState

* better solution for changing wallet priority

* merge fixes

* fix tests

* try fixing test again

* add comment

* add fortmatic back

* set walletOverride for fortmatic

* hide other chains

* handle eager connection

* connect everything eagerly if not backfilled

* fix chain switching

* async

* rm error console

* fortmatic update

* log errors

* don't eagerly connect to fortmatic

* onSelectChain + switchChain

* typo

* don't disconnect from coinbase wallet for now

* upgrade web3-react

* close on disconnection/connection again

* simplify account change check

* comment fix

* comment

* fortmatic icon

* comment for fortmatic in network selector

* consolidate useEffect hooks in walletmodal for connection/disconnection

* switchToChain

* comment

* isEagerlyConnecting instead of eagerlyConnectingWallets

* update web3-react

* close modal fortmatic

* remove error log

* chainIdNotAllowed

* handle useToken

* update SupportedChainId

* move if statements around

* move to wallet reducer

* close as error

* export fix

* add back history change

* add back popular

* fortmatic key

* persist wallet

* remove eagerly connect

* call connect eagerly

* handle modal errors

* handle fortmatic close properly

* connector error changes

* go back to options

* change redux wallets

* simplify reducer

* fix eagerly connect / disconnect

* remove account change hook

* simplify connect eagerly

* remove unused var

* revert chain

* walletOverride reducer

* update web3-react

* fix compile errors for now

* show disconnect button

* clear pending connector

* clear error state

* add back skip toggle check

* MAINNET provider for ENS

* add coinbase wallet sdk

* fix test

* add back style but fix syntax highlighting

* dont create separate json rpc provider

* don't use selected hooks

* dont export

* dispatch first

* useConnectors

* comment

* simplify activeMap

* useIsActiveMap

* prettier

* prop change

* move comment

* useCallback

* coinbase wallet link fix

* rm ModalWallet type

* reportError

* isChainAllowed

* NETWORK_SELECTOR_CHAINS

* mainnet provider

* remove unused wallet views

* add back default case

* selected wallet

* comment change

* !chainAllowed

* rm ensResolver

* rm forEach

* re-define reportError

* move effects arounds

* change error message for switching chain

* simplify Web3Provider

* delete use isActive map

* fix test?

* rm disconnect test for now

* error message updates

* const -> function

* move fn

* undo changes for showing connect wallet state

* clear error before activating

* remove special case for fortmatic error

* backfillable/selectable wallets

* log wallet

* Revert "rm disconnect test for now"

This reverts commit 225bc7dc56.

* check if account exists

* unused dep

* remove reload piece of test

* update connect a wallet default state

* headerRow
2022-06-16 14:39:23 -04:00
Zach Pomerantz
ace4276bcb build: revert cypress projectId (#3921) 2022-06-16 10:08:25 -04:00
Zach Pomerantz
50a2dc9560 build: update cypress projectId (#3918)
* build: update cypress projectId

* build: rm unused cypress key

* test: save cypress videos

* build: rm start-server-and-test

* build: update github action cache usage

* build: use cypress action
2022-06-16 09:17:48 -04:00
Jordan Frankfurt
8cdec6188c chore(vscode): add workspace settings.json (#3914)
* chore(vscode): add workspace settings.json

* add newline

* no bad things allowed

* drop hiding . dirs
2022-06-14 17:39:12 -04:00
Kaylee George
5325d0cbe5 fix: adds messaging for unsupported V2 pool networks (#3762 #3777) (#3913)
Fix: Unsupported V2 Pool network messaging

#3762: Added error messaging for unsupported V2 pool networks (Polygon, Optimism, Arbitrum)
2022-06-14 16:20:31 -04:00
Zach Pomerantz
c16e49e774 feat: service worker with etag cache (#3897)
* fix: always-fresh service worker cache

* chore: clarify service-worker

* fix: cache in CacheStorage

* feat: set __isDocumentCached

* add back in manifest precaching

* add unit tests (incomplete)

* test: simplify test env

* test: add service-worker cypress test

* test: service-worker document handler

* fix: CachedDocument ctor

* fix: Readable for ReadableStream in jest

* build: clean up module loading

* fix: rename commands->ethereum

* build: simplify package.json deps

* build: clean up cypress usage

* build: clean up yarn.lock

* build: record cypress runs

* build: disable chromeWebSecurity in cypress tests

* build: rm babel

* build: disable sw in ci cypress

* build: nits

* build: update workbox version

* chore: fix merge

* test: cache

* test: cypress-ify the before hook

* test: clear sw before each test

* fix: cy then

* test: cypress shenanigans

* style: lint

* chore: rm todo

* test: fail fast for service worker with dev builds

* docs: update contributing to tests

* fix: clean up tests after merge

- Add fast fail in case of dev server, which lacks ServiceWorker

* fix: inject ethereum

* test: service worker

* test: increase sw timeout

* test: sw state

* test: run cypress in chrome

* feat: add on-demand caching to improve sw startup time

* test: test dynamically

* fix: simplify cached doc

* fix: optional sw

* fix: expose response on cached doc

* fix: stub out sw req

* fix: intercept

Co-authored-by: Christine Legge <christine.legge@uniswap.org>
2022-06-14 15:40:52 -04:00
Jordan Frankfurt
7e709e10db fix(L2): removes network-specific polling (#3912) 2022-06-14 14:51:24 -04:00
gzeon
7389b178fd perf: remove Arbitrum polling override (#3907) 2022-06-14 12:45:35 -04:00
Zach Pomerantz
48f8c6a141 test: update cypress (#3908)
* test: update cypress

* chore: comment on infura origin

* test: split build and serve

* chore: rm setupNodeEvents
2022-06-13 17:43:58 -04:00
Noah Zinsmeister
091876a374 feat: add Queue and Execute buttons (#3905)
* add queue and execute buttons

* eta is timestamp not block number

* address comments

* add execute text

* address comments
2022-06-13 13:23:15 -04:00
349 changed files with 12294 additions and 8440 deletions

3
.env
View File

@@ -1,2 +1,3 @@
REACT_APP_INFURA_KEY="4bf032f2d38a4ed6bb975b80d6340847"
REACT_APP_LOCALES="locales"
REACT_APP_FORTMATIC_KEY="pk_live_357F77728B8EB880"
REACT_APP_LOCALES="locales"

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

@@ -1,47 +1,22 @@
name: Crowdin Download
# hourly we sync translations from Crowdin
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:
- name: Checkout
uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- run: yarn i18n:extract
- name: Set up node
uses: actions/setup-node@v2
with:
node-version: 14
registry-url: https://registry.npmjs.org
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Extract translations
run: "yarn i18n:extract"
- name: Synchronize
- name: Download Crowdin translations
uses: crowdin/github-action@1.4.9
with:
upload_sources: false
@@ -50,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

@@ -1,45 +1,19 @@
name: Crowdin Upload
# on any push to main, we upload the translations to be translated
on:
push:
branches:
- main
jobs:
synchronize-with-crowdin:
name: Upload sources to Crowdin
upload-sources:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- run: yarn i18n:extract
- name: Set up node
uses: actions/setup-node@v2
with:
node-version: 14
registry-url: https://registry.npmjs.org
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Extract translations
run: "yarn i18n:extract"
- name: Synchronize
- name: Upload Crowdin sources
uses: crowdin/github-action@1.1.0
with:
upload_sources: true

View File

@@ -1,47 +0,0 @@
name: Integration Tests
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
integration-tests:
name: Cypress
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up node
uses: actions/setup-node@v2
with:
node-version: 14
registry-url: https://registry.npmjs.org
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install dependencies
run: yarn install --frozen-lockfile
- run: yarn build:e2e
env:
CI: false # disables lint checks when building
- run: yarn test:e2e:ci
env:
CYPRESS_INTEGRATION_TEST_PRIVATE_KEY: ${{ secrets.CYPRESS_INTEGRATION_TEST_PRIVATE_KEY }}
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}

View File

@@ -1,52 +0,0 @@
name: Lint
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
run-linters:
name: Run linters
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up node
uses: actions/setup-node@v2
with:
node-version: 14
registry-url: https://registry.npmjs.org
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install dependencies
run: yarn install --frozen-lockfile
- 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,56 +1,58 @@
name: Release
on:
schedule:
- cron: '0 12 * * 1-4' # every day 12:00 UTC Monday-Thursday
- 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:
- name: Checkout
uses: actions/checkout@v2
- name: Bump version and push tag
id: github_tag_action
uses: mathieudutour/github-tag-action@331898d5052eedac9b15fec867b5ba66ebf9b692
- uses: actions/checkout@v3
- 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:
- name: Checkout
uses: actions/checkout@v2
- name: Set up node
uses: actions/setup-node@v2
with:
node-version: 14
registry-url: https://registry.npmjs.org
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Build the IPFS bundle
run: yarn build
- uses: actions/checkout@v3
- 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 }}
@@ -64,10 +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 }}
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:
@@ -77,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).
@@ -100,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 }}

99
.github/workflows/test.yml vendored Normal file
View File

@@ -0,0 +1,99 @@
name: Test
on:
push:
branches:
- main
pull_request:
branches:
- main
# manual trigger
workflow_dispatch:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- run: yarn lint
deps-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- run: npx yarn-deduplicate --strategy=highest --list --fail
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
path: build
if-no-files-found: error
- 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
cypress-test-matrix:
needs: cypress-build
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
containers: [1, 2, 3, 4]
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup
- uses: actions/download-artifact@v2
with:
name: build
path: build
- 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
start: yarn serve
wait-on: 'http://localhost:3000'
browser: chrome
record: true
parallel: true
env:
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,40 +0,0 @@
name: Unit Tests
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
unit-tests:
name: Unit tests
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up node
uses: actions/setup-node@v2
with:
node-version: 14
registry-url: https://registry.npmjs.org
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Run unit tests
run: yarn test

7
.gitignore vendored
View File

@@ -3,9 +3,6 @@
# generated contract types
/src/types/v3
/src/abis/types
/src/lib/locales/**/*.js
/src/lib/locales/**/en-US.po
/src/lib/locales/**/pseudo.po
/src/locales/**/*.js
/src/locales/**/en-US.po
/src/locales/**/pseudo.po
@@ -37,10 +34,8 @@ yarn-error.log*
notes.txt
.idea/
.vscode/
package-lock.json
cypress/videos
cypress/screenshots
cypress/fixtures/example.json

19
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,19 @@
{
"npm.packageManager": "yarn",
"typescript.updateImportsOnFileMove.enabled": "always",
"javascript.updateImportsOnFileMove.enabled": "always",
"editor.formatOnSaveMode": "file",
"editor.tabCompletion": "on",
"editor.tabSize": 2,
"editor.formatOnSave": true,
"editor.inlineSuggest.enabled": true,
"editor.codeActionsOnSave": {
"source.fixAll": true
},
"files.eol": "\n",
"eslint.enable": true,
"eslint.debug": true,
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}

View File

@@ -4,25 +4,65 @@ Thank you for your interest in contributing to the Uniswap interface! 🦄
# Development
Before running anything, you'll need to install the dependencies:
```
yarn install
```
## Running the interface locally
1. `yarn install`
1. `yarn start`
```
yarn start
```
The interface should automatically open. If it does not, navigate to [http://localhost:3000].
## Creating a production build
1. `yarn install`
1. `yarn build`
```
yarn build
```
To serve the production build:
```
yarn serve
```
Then, navigate to [http://localhost:3000] to see it.
## Running unit tests
- Run unit tests: `yarn test`
- Run unit tests and show test coverage info for all tests: `yarn test --watchAll`
```
yarn test
```
## Running cypress integration tests
By default, this runs only unit tests that have been affected since the last commit. To run _all_ unit tests:
1. `yarn build:e2e`
2. `yarn test:e2e`
```
yarn test --watchAll
```
## Running integration tests (cypress)
Integration tests require a server to be running. In order to see your changes quickly, run `start` in its own tab/window:
```
yarn start
```
Integration tests are run using `cypress`. When developing locally, use `cypress:open` for an interactive UI, and to inspect the rendered page:
```
yarn cypress:open
```
To run _all_ cypress integration tests _from the command line_:
```
yarn cypress:run
```
## Engineering standards

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).

20
cypress.config.ts Normal file
View File

@@ -0,0 +1,20 @@
import { defineConfig } from 'cypress'
export default defineConfig({
projectId: 'yp82ef',
videoUploadOnPasses: false,
defaultCommandTimeout: 10000,
chromeWebSecurity: false,
e2e: {
setupNodeEvents(on, config) {
return {
...config,
// Only enable Chrome.
// Electron (the default) has issues injecting window.ethereum before pageload, so it is not viable.
browsers: config.browsers.filter(({ name }) => name === 'chrome'),
}
},
baseUrl: 'http://localhost:3000',
specPattern: 'cypress/e2e/**/*.{js,jsx,ts,tsx}',
},
})

View File

@@ -1,8 +0,0 @@
{
"projectId": "yp82ef",
"baseUrl": "http://localhost:3000",
"pluginsFile": false,
"supportFile": "cypress/support/index.ts",
"video": false,
"defaultCommandTimeout": 10000
}

View File

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

View File

@@ -1,5 +1,3 @@
import { TEST_ADDRESS_NEVER_USE_SHORTENED } from '../support/ethereum'
describe('Landing Page', () => {
beforeEach(() => cy.visit('/'))
it('loads swap page', () => {
@@ -15,9 +13,4 @@ describe('Landing Page', () => {
cy.get('#pool-nav-link').click()
cy.url().should('include', '/pool')
})
it('is connected', () => {
cy.get('#web3-status-connected').click()
cy.get('#web3-account-identifier-row').contains(TEST_ADDRESS_NEVER_USE_SHORTENED)
})
})

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,6 @@
describe('Pool', () => {
beforeEach(() => cy.visit('/pool'))
it('add liquidity links to /add/ETH', () => {
cy.get('#join-pool-button').click()
cy.url().should('contain', '/add/ETH')

View File

@@ -0,0 +1,10 @@
describe('Redirect', () => {
it('should redirect to /vote/create-proposal when visiting /create-proposal', () => {
cy.visit('/create-proposal')
cy.url().should('match', /\/vote\/create-proposal/)
})
it('should redirect to /swap when visiting nonexist url', () => {
cy.visit('/none-exist-url')
cy.url().should('match', /\/swap/)
})
})

View File

@@ -0,0 +1,84 @@
import assert = require('assert')
describe('Service Worker', () => {
before(() => {
// Fail fast if there is no Service Worker on this build.
cy.request({ url: '/service-worker.js', headers: { 'Service-Worker': 'script' } }).then((response) => {
const isValid = isValidServiceWorker(response)
if (!isValid) {
throw new Error(
'\n' +
'Service Worker tests must be run on a production-like build\n' +
'To test, build with `yarn build:e2e` and serve with `yarn serve`'
)
}
})
function isValidServiceWorker(response: Cypress.Response<any>) {
const contentType = response.headers['content-type']
return !(response.status === 404 || (contentType != null && contentType.indexOf('javascript') === -1))
}
})
function unregister() {
return cy.log('unregister service worker').then(async () => {
const cacheKeys = await window.caches.keys()
const cacheKey = cacheKeys.find((key) => key.match(/precache/))
if (cacheKey) {
await window.caches.delete(cacheKey)
}
const sw = await window.navigator.serviceWorker.getRegistration(Cypress.config().baseUrl ?? undefined)
await sw?.unregister()
})
}
before(unregister)
after(unregister)
beforeEach(() => {
cy.intercept({ hostname: 'www.google-analytics.com' }, (req) => {
const body = req.body.toString()
if (req.query['ep.event_category'] === 'Service Worker' || body.includes('Service%20Worker')) {
if (req.query['en'] === 'Not Installed' || body.includes('Not%20Installed')) {
req.alias = 'NotInstalled'
} else if (req.query['en'] === 'Cache Hit' || body.includes('Cache%20Hit')) {
req.alias = 'CacheHit'
} else if (req.query['en'] === 'Cache Miss' || body.includes('Cache%20Miss')) {
req.alias = 'CacheMiss'
}
}
})
})
it('installs a ServiceWorker', () => {
cy.visit('/', { serviceWorker: true })
.get('#swap-page')
.wait('@NotInstalled', { timeout: 20000 })
.window({ timeout: 20000 })
.and((win) => {
expect(win.navigator.serviceWorker.controller?.state).to.equal('activated')
})
})
it('records a cache hit', () => {
cy.visit('/', { serviceWorker: true }).get('#swap-page').wait('@CacheHit', { timeout: 20000 })
})
it('records a cache miss', () => {
cy.then(async () => {
const cacheKeys = await window.caches.keys()
const cacheKey = cacheKeys.find((key) => key.match(/precache/))
assert(cacheKey)
const cache = await window.caches.open(cacheKey)
const keys = await cache.keys()
const key = keys.find((key) => key.url.match(/index/))
assert(key)
await cache.put(key, new Response())
})
.visit('/', { serviceWorker: true })
.get('#swap-page')
.wait('@CacheMiss', { timeout: 20000 })
})
})

53
cypress/e2e/swap.test.ts Normal file
View File

@@ -0,0 +1,53 @@
describe('Swap', () => {
before(() => {
cy.visit('/swap')
})
it('starts with ETH selected by default', () => {
cy.get('#swap-currency-input .token-amount-input').should('have.value', '')
cy.get('#swap-currency-input .token-symbol-container').should('contain.text', 'ETH')
cy.get('#swap-currency-output .token-amount-input').should('not.have.value')
cy.get('#swap-currency-output .token-symbol-container').should('contain.text', 'Select a token')
})
it('can enter an amount into input', () => {
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').should('have.value', '0.0')
})
it('invalid swap amount', () => {
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').clear().type('0.001').should('have.value', '0.001')
})
it('zero output amount', () => {
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').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('add a recipient does not exist unless in expert mode', () => {
cy.get('#add-recipient-button').should('not.exist')
})
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()
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')
})
})

View File

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

View File

@@ -1,76 +0,0 @@
describe('Swap', () => {
beforeEach(() => {
cy.visit('/swap')
})
it('starts with ETH selected by default', () => {
cy.get('#swap-currency-input .token-amount-input').should('have.value', '')
cy.get('#swap-currency-input .token-symbol-container').should('contain.text', 'ETH')
cy.get('#swap-currency-output .token-amount-input').should('not.have.value')
cy.get('#swap-currency-output .token-symbol-container').should('contain.text', 'Select a token')
})
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')
})
it('zero swap amount', () => {
cy.get('#swap-currency-input .token-amount-input').clear().type('0.0', { delay: 200 }).should('have.value', '0.0')
})
it('invalid swap amount', () => {
cy.get('#swap-currency-input .token-amount-input').clear().type('\\', { delay: 200 }).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')
})
it('zero output amount', () => {
cy.get('#swap-currency-output .token-amount-input').type('0.0', { delay: 200 }).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('#swap-currency-output .token-amount-input').should('not.equal', '')
cy.get('#swap-button').click()
cy.get('#confirm-swap-or-send').should('contain', 'Confirm Swap')
})
it.skip('add a recipient does not exist unless in expert mode', () => {
cy.get('#add-recipient-button').should('not.exist')
})
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')
})
}
)

58
cypress/support/e2e.ts Normal file
View File

@@ -0,0 +1,58 @@
// ***********************************************************
// This file is processed and loaded automatically before your test files.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.ts using ES2015 syntax:
import { injected } from './ethereum'
import assert = require('assert')
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace Cypress {
interface ApplicationWindow {
ethereum: typeof injected
}
interface VisitOptions {
serviceWorker?: true
}
}
}
// sets up the injected provider to be a mock ethereum provider with the given mnemonic/index
// eslint-disable-next-line no-undef
Cypress.Commands.overwrite(
'visit',
(original, url: string | Partial<Cypress.VisitOptions>, options?: Partial<Cypress.VisitOptions>) => {
assert(typeof url === 'string')
cy.intercept('/service-worker.js', options?.serviceWorker ? undefined : { statusCode: 404 }).then(() => {
original({
...options,
url: (url.startsWith('/') && url.length > 2 && !url.startsWith('/#') ? `/#${url}` : url) + '?chain=rinkeby',
onBeforeLoad(win) {
options?.onBeforeLoad?.(win)
win.localStorage.clear()
win.ethereum = injected
},
})
})
}
)
beforeEach(() => {
// Infura security policies are based on Origin headers.
// These are stripped by cypress because chromeWebSecurity === false; this adds them back in.
cy.intercept(/infura.io/, (res) => {
res.headers['origin'] = 'http://localhost:3000'
res.continue()
})
})
Cypress.on('uncaught:exception', (_err, _runnable) => {
// returning false here prevents Cypress from
// failing the test
return false
})

View File

@@ -18,7 +18,9 @@ export const TEST_ADDRESS_NEVER_USE_SHORTENED = `${TEST_ADDRESS_NEVER_USE.substr
6
)}...${TEST_ADDRESS_NEVER_USE.substr(-4, 4)}`
class CustomizedBridge extends Eip1193Bridge {
const provider = new JsonRpcProvider('https://rinkeby.infura.io/v3/4bf032f2d38a4ed6bb975b80d6340847', 4)
const signer = new Wallet(TEST_PRIVATE_KEY, provider)
export const injected = new (class extends Eip1193Bridge {
chainId = 4
async sendAsync(...args: any[]) {
@@ -69,19 +71,4 @@ class CustomizedBridge extends Eip1193Bridge {
}
}
}
}
// sets up the injected provider to be a mock ethereum provider with the given mnemonic/index
// eslint-disable-next-line no-undef
Cypress.Commands.overwrite('visit', (original, url, options) => {
return original(url.startsWith('/') && url.length > 2 && !url.startsWith('/#') ? `/#${url}` : url, {
...options,
onBeforeLoad(win: Window & { ethereum?: CustomizedBridge }) {
options?.onBeforeLoad?.(win)
win.localStorage.clear()
const provider = new JsonRpcProvider('https://rinkeby.infura.io/v3/4bf032f2d38a4ed6bb975b80d6340847', 4)
const signer = new Wallet(TEST_PRIVATE_KEY, provider)
win.ethereum = new CustomizedBridge(signer, provider)
},
})
})
})(signer, provider)

View File

@@ -1,9 +0,0 @@
// ***********************************************************
// This file is processed and loaded automatically before your test files.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.ts using ES2015 syntax:
import './ethereum'

View File

@@ -1,7 +1,6 @@
{
"compilerOptions": {
"strict": true,
"baseUrl": "../node_modules",
"target": "es5",
"lib": ["es5", "dom"],
"types": ["cypress"]

View File

@@ -1,5 +1,5 @@
{
"name": "@uniswap/widgets",
"name": "@uniswap/interface",
"version": "1.0.7",
"description": "Uniswap Interface",
"homepage": ".",
@@ -9,26 +9,26 @@
"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",
"prepare": "yarn contracts:compile && yarn graphql:generate && yarn i18n:compile",
"start": "react-scripts start",
"build": "react-scripts build",
"serve": "serve build -l 3000",
"lint": "yarn eslint .",
"test": "react-scripts test --coverage",
"build:e2e": "env-cmd -f .env yarn build",
"test:e2e": "start-server-and-test 'serve build -l 3000' http://localhost:3000 'cypress open'",
"test:e2e:ci": "start-server-and-test 'serve build -l 3000' http://localhost:3000 'cypress run --record'"
"cypress:open": "cypress open --browser chrome --e2e",
"cypress:run": "cypress run --browser chrome --e2e"
},
"jest": {
"collectCoverageFrom":
[
"src/components/**/*.ts*",
"src/hooks/**/*.ts*",
"src/lib/hooks/**/*.ts*",
"src/lib/state/**/*.ts*",
"src/lib/utils/**/*.ts*",
"collectCoverageFrom": [
"src/components/**/*.ts*",
"src/hooks/**/*.ts*",
"src/lib/hooks/**/*.ts*",
"src/lib/state/**/*.ts*",
"src/lib/utils/**/*.ts*",
"src/pages/**/*.ts*",
"src/state/**/*.ts*",
"src/utils/**/*.ts*"
@@ -54,28 +54,15 @@
"last 1 safari version"
]
},
"dependencies": {
"devDependencies": {
"@ethersproject/experimental": "^5.4.0",
"@fontsource/ibm-plex-mono": "^4.5.1",
"@fontsource/inter": "^4.5.1",
"@gnosis.pm/safe-apps-web3-react": "^0.6.0",
"@graphql-codegen/cli": "1.21.5",
"@graphql-codegen/typescript": "1.22.3",
"@graphql-codegen/typescript-operations": "^1.18.2",
"@graphql-codegen/typescript-rtk-query": "^1.1.1",
"@lingui/cli": "^3.9.0",
"@lingui/core": "^3.9.0",
"@lingui/macro": "^3.9.0",
"@lingui/react": "^3.9.0",
"@metamask/jazzicon": "^2.0.0",
"@popperjs/core": "^2.4.4",
"@reach/dialog": "^0.10.3",
"@reach/portal": "^0.10.3",
"@react-hook/window-scroll": "^1.3.0",
"@reduxjs/toolkit": "^1.6.1",
"@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",
@@ -88,48 +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",
"@uniswap/default-token-list": "^3.0.0",
"@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/sdk-core": "^3.0.1",
"@uniswap/smart-order-router": "^2.5.26",
"@uniswap/token-lists": "^1.0.0-beta.27",
"@uniswap/v2-core": "1.0.0",
"@uniswap/v2-periphery": "^1.1.0-beta.0",
"@uniswap/v2-sdk": "^3.0.1",
"@uniswap/v3-core": "1.0.0",
"@uniswap/v3-periphery": "^1.1.1",
"@uniswap/v3-sdk": "^3.8.2",
"@web3-react/core": "^8.0.23-beta.0",
"@web3-react/eip1193": "^8.0.18-beta.0",
"@web3-react/empty": "^8.0.12-beta.0",
"@web3-react/metamask": "^8.0.19-beta.0",
"@web3-react/types": "^8.0.12-beta.0",
"@web3-react/url": "^8.0.17-beta.0",
"@web3-react/walletconnect": "^8.0.26-beta.0",
"ajv": "^6.12.3",
"array.prototype.flat": "^1.2.4",
"array.prototype.flatmap": "^1.2.4",
"cids": "^1.0.0",
"copy-to-clipboard": "^3.2.0",
"cypress": "^7.7.0",
"d3": "^7.0.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",
@@ -139,36 +98,86 @@
"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": {
"@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.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",
"@reach/portal": "^0.10.3",
"@react-hook/window-scroll": "^1.3.0",
"@reduxjs/toolkit": "^1.6.1",
"@uniswap/governance": "^1.0.2",
"@uniswap/liquidity-staker": "^1.0.2",
"@uniswap/merkle-distributor": "1.0.1",
"@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",
"@uniswap/v2-core": "1.0.0",
"@uniswap/v2-periphery": "^1.1.0-beta.0",
"@uniswap/v2-sdk": "^3.0.1",
"@uniswap/v3-core": "1.0.0",
"@uniswap/v3-periphery": "^1.1.1",
"@uniswap/v3-sdk": "^3.9.0",
"@walletconnect/ethereum-provider": "1.7.1",
"@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",
"cids": "^1.0.0",
"copy-to-clipboard": "^3.2.0",
"d3": "^7.0.0",
"ethers": "^5.1.4",
"firebase": "^9.1.3",
"fortmatic": "^2.4.0",
"graphql": "^15.5.0",
"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",
"ms.macro": "^2.0.0",
"multicodec": "^3.0.1",
"multihashes": "^4.0.2",
"node-vibrant": "^3.2.1-alpha.1",
"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-scripts": "^4.0.3",
"react-redux": "^8.0.2",
"react-router-dom": "^6.3.0",
"react-spring": "^8.0.27",
"react-use-gesture": "^6.0.14",
"react-virtualized-auto-sizer": "^1.0.2",
@@ -176,32 +185,17 @@
"rebass": "^4.0.7",
"redux": "^4.1.2",
"redux-localstorage-simple": "^2.3.1",
"sass": "^1.45.1",
"serve": "^11.3.2",
"setimmediate": "^1.0.5",
"start-server-and-test": "^1.11.0",
"styled-components": "^5.3.0",
"styled-components": "^5.3.5",
"tiny-invariant": "^1.2.0",
"typechain": "^5.0.0",
"typescript": "^4.4.3",
"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",
"web3-react-abstract-connector": "npm:@web3-react/abstract-connector@^6.0.7",
"web3-react-core": "npm:@web3-react/core@^6.0.9",
"web3-react-fortmatic-connector": "npm:@web3-react/fortmatic-connector@^6.0.9",
"web3-react-injected-connector": "npm:@web3-react/injected-connector@^6.0.7",
"web3-react-types": "npm:@web3-react/types@^6.0.7",
"web3-react-walletconnect-connector": "npm:@web3-react/walletconnect-connector@^7.0.2-alpha.0",
"web3-react-walletlink-connector": "npm:@web3-react/walletlink-connector@^6.2.13",
"wicg-inert": "^3.1.1",
"workbox-core": "^6.1.0",
"workbox-navigation-preload": "^6.1.0",
"workbox-precaching": "^6.1.0",
"workbox-routing": "^6.1.0"
},
"resolutions": {
"@walletconnect/ethereum-provider": "1.7.1"
}
}

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

@@ -17,7 +17,9 @@ import {
DepositLiquidityStakingTransactionInfo,
ExactInputSwapTransactionInfo,
ExactOutputSwapTransactionInfo,
ExecuteTransactionInfo,
MigrateV2LiquidityToV3TransactionInfo,
QueueTransactionInfo,
RemoveLiquidityV3TransactionInfo,
SubmitProposalTransactionInfo,
TransactionInfo,
@@ -126,6 +128,16 @@ function VoteSummary({ info }: { info: VoteTransactionInfo }) {
}
}
function QueueSummary({ info }: { info: QueueTransactionInfo }) {
const proposalKey = `${info.governorAddress}/${info.proposalId}`
return <Trans>Queue proposal {proposalKey}.</Trans>
}
function ExecuteSummary({ info }: { info: ExecuteTransactionInfo }) {
const proposalKey = `${info.governorAddress}/${info.proposalId}`
return <Trans>Execute proposal {proposalKey}.</Trans>
}
function DelegateSummary({ info: { delegatee } }: { info: DelegateTransactionInfo }) {
const { ENSName } = useENSName(delegatee)
return <Trans>Delegate voting power to {ENSName ?? delegatee}</Trans>
@@ -339,6 +351,12 @@ export function TransactionSummary({ info }: { info: TransactionInfo }) {
case TransactionType.REMOVE_LIQUIDITY_V3:
return <RemoveLiquidityV3Summary info={info} />
case TransactionType.QUEUE:
return <QueueSummary info={info} />
case TransactionType.EXECUTE:
return <ExecuteSummary info={info} />
case TransactionType.SUBMIT_PROPOSAL:
return <SubmitProposalTransactionSummary info={info} />
}

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 { AbstractConnector } from 'web3-react-abstract-connector'
import { isMobile } from 'utils/userAgent'
import { ReactComponent as Close } from '../../assets/images/x.svg'
import { injected, walletlink } 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: AbstractConnector | 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,43 +240,41 @@ export default function AccountDetails({
<AccountGroupingRow>
{formatConnectorName()}
<div>
{connector !== injected && connector !== walletlink && (
<WalletAction
style={{ fontSize: '.825rem', fontWeight: 400, marginRight: '8px' }}
onClick={() => {
;(connector as any).close()
}}
>
<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 id="web3-account-identifier-row">
<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>
@@ -366,9 +339,9 @@ export default function AccountDetails({
{!!pendingTransactions.length || !!confirmedTransactions.length ? (
<LowerSection>
<AutoRow mb={'1rem'} style={{ justifyContent: 'space-between' }}>
<ThemedText.Body>
<ThemedText.DeprecatedBody>
<Trans>Recent Transactions</Trans>
</ThemedText.Body>
</ThemedText.DeprecatedBody>
<LinkStyledButton onClick={clearAllTransactionsCallback}>
<Trans>(clear all)</Trans>
</LinkStyledButton>
@@ -378,9 +351,9 @@ export default function AccountDetails({
</LowerSection>
) : (
<LowerSection>
<ThemedText.Body color={theme.text1}>
<ThemedText.DeprecatedBody color={theme.deprecated_text1}>
<Trans>Your transactions will appear here...</Trans>
</ThemedText.Body>
</ThemedText.DeprecatedBody>
</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,9 +108,9 @@ export default function AddressInputPanel({
<InputContainer>
<AutoColumn gap="md">
<RowBetween>
<ThemedText.Black color={theme.text2} fontWeight={500} fontSize={14}>
<ThemedText.DeprecatedBlack color={theme.deprecated_text2} fontWeight={500} fontSize={14}>
{label ?? <Trans>Recipient</Trans>}
</ThemedText.Black>
</ThemedText.DeprecatedBlack>
{address && chainId && (
<ExternalLink
href={getExplorerLink(chainId, name ?? address, ExplorerDataType.ADDRESS)}

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,100 @@
/**
* 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 CUSTOM_USER_PROPERTIES {
WALLET_ADDRESS = 'wallet_address',
WALLET_TYPE = 'wallet_type',
USER_LAST_SEEN_DATE = 'user_last_seen_date',
USER_FIRST_SEEN_DATE = 'user_first_seen_date',
WALLET_CHAIN_IDS = 'all_wallet_chain_ids',
ALL_WALLET_ADDRESSES_CONNECTED = 'all_wallet_addresses_connected',
SCREEN_RESOLUTION = 'screen_resolution',
BROWSER = 'browser',
LIGHT_MODE = 'light_mode',
}
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,91 @@
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= */ {
// See documentation: https://www.docs.developers.amplitude.com/data/sdks/javascript/#track-referrers
includeReferrer: true,
// See documentation: https://www.docs.developers.amplitude.com/data/sdks/javascript/#track-utm-parameters
includeUtm: true,
// Disable tracking of private user information by Amplitude
trackingOptions: {
ipAddress: false,
carrier: false,
city: false,
region: 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;
@@ -33,23 +33,23 @@ export default function ConnectedAccountBlocked(props: ConnectedAccountBlockedPr
<Modal isOpen={props.isOpen} onDismiss={Function.prototype()}>
<ContentWrapper>
<WarningIcon />
<ThemedText.LargeHeader lineHeight={2} marginBottom={1} marginTop={1}>
<ThemedText.DeprecatedLargeHeader lineHeight={2} marginBottom={1} marginTop={1}>
<Trans>Blocked Address</Trans>
</ThemedText.LargeHeader>
<ThemedText.DarkGray fontSize={12} marginBottom={12}>
</ThemedText.DeprecatedLargeHeader>
<ThemedText.DeprecatedDarkGray fontSize={12} marginBottom={12}>
{props.account}
</ThemedText.DarkGray>
<ThemedText.Main fontSize={14} marginBottom={12}>
</ThemedText.DeprecatedDarkGray>
<ThemedText.DeprecatedMain fontSize={14} marginBottom={12}>
<Trans>This address is blocked on the Uniswap Labs interface because it is associated with one or more</Trans>{' '}
<ExternalLink href="https://help.uniswap.org/en/articles/6149816">
<Trans>blocked activities</Trans>
</ExternalLink>
.
</ThemedText.Main>
<ThemedText.Main fontSize={12}>
</ThemedText.DeprecatedMain>
<ThemedText.DeprecatedMain 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">
</ThemedText.DeprecatedMain>
<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.DeprecatedBody 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>
) : (
@@ -51,6 +51,6 @@ export function FiatValue({
</MouseoverTooltip>
</span>
) : null}
</ThemedText.Body>
</ThemedText.DeprecatedBody>
)
}

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,30 +224,34 @@ export default function CurrencyInputPanel({
setModalOpen(false)
}, [setModalOpen])
const chainAllowed = isSupportedChain(chainId)
return (
<InputPanel id={id} hideInput={hideInput} {...rest}>
{locked && (
<FixedContainer>
<AutoColumn gap="sm" justify="center">
<Lock />
<ThemedText.Label fontSize="12px" textAlign="center" padding="0 12px">
<ThemedText.DeprecatedLabel fontSize="12px" textAlign="center" padding="0 12px">
<Trans>The market price is outside your specified price range. Single-asset deposit only.</Trans>
</ThemedText.Label>
</ThemedText.DeprecatedLabel>
</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}
@@ -278,9 +297,9 @@ export default function CurrencyInputPanel({
</LoadingOpacityContainer>
{account ? (
<RowFixed style={{ height: '17px' }}>
<ThemedText.Body
<ThemedText.DeprecatedBody
onClick={onMax}
color={theme.text3}
color={theme.deprecated_text3}
fontWeight={500}
fontSize={14}
style={{ display: 'inline', cursor: 'pointer' }}
@@ -292,11 +311,17 @@ export default function CurrencyInputPanel({
<Trans>Balance: {formatCurrencyAmount(selectedCurrencyBalance, 4)}</Trans>
)
) : null}
</ThemedText.Body>
</ThemedText.DeprecatedBody>
{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 }
}
@@ -101,13 +101,13 @@ export default class ErrorBoundary extends React.Component<unknown, ErrorBoundar
<BodyWrapper>
<AutoColumn gap={'md'}>
<SomethingWentWrongWrapper>
<ThemedText.Label fontSize={24} fontWeight={600}>
<ThemedText.DeprecatedLabel fontSize={24} fontWeight={600}>
<Trans>Something went wrong</Trans>
</ThemedText.Label>
</ThemedText.DeprecatedLabel>
</SomethingWentWrongWrapper>
<CodeBlockWrapper>
<code>
<ThemedText.Main fontSize={10}>{error.stack}</ThemedText.Main>
<ThemedText.DeprecatedMain fontSize={10}>{error.stack}</ThemedText.DeprecatedMain>
</code>
</CodeBlockWrapper>
{IS_UNISWAP ? (
@@ -120,18 +120,18 @@ export default class ErrorBoundary extends React.Component<unknown, ErrorBoundar
)}`}
target="_blank"
>
<ThemedText.Link fontSize={16}>
<ThemedText.DeprecatedLink fontSize={16}>
<Trans>Create an issue on GitHub</Trans>
<span></span>
</ThemedText.Link>
</ThemedText.DeprecatedLink>
</ExternalLink>
</LinkWrapper>
<LinkWrapper>
<ExternalLink id="get-support-on-discord" href="https://discord.gg/FCfyBSbCU5" target="_blank">
<ThemedText.Link fontSize={16}>
<ThemedText.DeprecatedLink fontSize={16}>
<Trans>Get support on Discord</Trans>
<span></span>
</ThemedText.Link>
</ThemedText.DeprecatedLink>
</ExternalLink>
</LinkWrapper>
</AutoRow>

View File

@@ -11,7 +11,7 @@ import { ThemedText } from 'theme'
import { FeeTierPercentageBadge } from './FeeTierPercentageBadge'
import { FEE_AMOUNT_DETAIL } from './shared'
const ResponsiveText = styled(ThemedText.Label)`
const ResponsiveText = styled(ThemedText.DeprecatedLabel)`
line-height: 16px;
font-size: 14px;
@@ -37,9 +37,9 @@ export function FeeOption({ feeAmount, active, poolState, distributions, onClick
<ResponsiveText>
<Trans>{FEE_AMOUNT_DETAIL[feeAmount].label}%</Trans>
</ResponsiveText>
<ThemedText.Main fontWeight={400} fontSize="12px" textAlign="left">
<ThemedText.DeprecatedMain fontWeight={400} fontSize="12px" textAlign="left">
{FEE_AMOUNT_DETAIL[feeAmount].description}
</ThemedText.Main>
</ThemedText.DeprecatedMain>
</AutoColumn>
{distributions && (

View File

@@ -17,7 +17,7 @@ export function FeeTierPercentageBadge({
}) {
return (
<Badge>
<ThemedText.Label fontSize={10}>
<ThemedText.DeprecatedLabel fontSize={10}>
{!distributions || poolState === PoolState.NOT_EXISTS || poolState === PoolState.INVALID ? (
<Trans>Not created</Trans>
) : distributions[feeAmount] !== undefined ? (
@@ -25,7 +25,7 @@ export function FeeTierPercentageBadge({
) : (
<Trans>No data</Trans>
)}
</ThemedText.Label>
</ThemedText.DeprecatedLabel>
</Badge>
)
}

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)
@@ -149,18 +149,18 @@ export default function FeeSelector({
<AutoColumn id="add-liquidity-selected-fee">
{!feeAmount ? (
<>
<ThemedText.Label>
<ThemedText.DeprecatedLabel>
<Trans>Fee tier</Trans>
</ThemedText.Label>
<ThemedText.Main fontWeight={400} fontSize="12px" textAlign="left">
</ThemedText.DeprecatedLabel>
<ThemedText.DeprecatedMain fontWeight={400} fontSize="12px" textAlign="left">
<Trans>The % you will earn in fees.</Trans>
</ThemedText.Main>
</ThemedText.DeprecatedMain>
</>
) : (
<>
<ThemedText.Label className="selected-fee-label">
<ThemedText.DeprecatedLabel className="selected-fee-label">
<Trans>{FEE_AMOUNT_DETAIL[feeAmount].label}% fee tier</Trans>
</ThemedText.Label>
</ThemedText.DeprecatedLabel>
<Box style={{ width: 'fit-content', marginTop: '8px' }} className="selected-fee-percentage">
{distributions && (
<FeeTierPercentageBadge

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,22 +1,24 @@
import { Trans } from '@lingui/macro'
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 { useHistory } from 'react-router-dom'
import { useModalOpen, useToggleModal } from 'state/application/hooks'
import { useCallback, useEffect, useRef, useState } from 'react'
import { AlertTriangle, ArrowDownCircle, ChevronDown } from 'react-feather'
import { useLocation, useNavigate } from 'react-router-dom'
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 styled from 'styled-components/macro'
import { ExternalLink, MEDIA_WIDTHS } from 'theme'
import { replaceURLParam } from 'utils/routes'
import { useAppDispatch } from '../../state/hooks'
import { switchToNetwork } from '../../utils/switchToNetwork'
import { isChainAllowed, switchChain } from 'utils/switchChain'
import { isMobile } from 'utils/userAgent'
const ActiveRowLinkList = styled.div`
display: flex;
@@ -24,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;
@@ -40,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`
@@ -62,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;
@@ -77,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;
@@ -88,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;
@@ -120,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;
}
@@ -146,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:
@@ -157,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>
}
@@ -172,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>
}
@@ -184,12 +221,12 @@ function Row({
targetChain: SupportedChainId
onSelectChain: (targetChain: number) => void
}) {
const { library, chainId } = useActiveWeb3React()
if (!library || !chainId) {
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}>
@@ -241,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) => {
@@ -257,93 +294,138 @@ const getChainNameFromId = (id: string | number) => {
return CHAIN_IDS_TO_NAMES[id as SupportedChainId] || ''
}
const NETWORK_SELECTOR_CHAINS = [
SupportedChainId.MAINNET,
SupportedChainId.POLYGON,
SupportedChainId.OPTIMISM,
SupportedChainId.ARBITRUM_ONE,
SupportedChainId.CELO,
]
export default function NetworkSelector() {
const { chainId, library } = useActiveWeb3React()
const parsedQs = useParsedQueryString()
const { urlChain, urlChainId } = getParsedChainId(parsedQs)
const prevChainId = usePrevious(chainId)
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 dispatch = useAppDispatch()
const handleChainSwitch = useCallback(
(targetChain: number, skipToggle?: boolean) => {
if (!library?.provider) return
switchToNetwork({ provider: library.provider, chainId: targetChain })
.then(() => {
if (!skipToggle) {
toggle()
}
history.replace({
search: replaceURLParam(history.location.search, 'chain', getChainNameFromId(targetChain)),
})
})
.catch((error) => {
console.error('Failed to switch networks', error)
const { chainId, provider, connector, isActive } = useWeb3React()
const [previousChainId, setPreviousChainId] = useState<number | undefined>(undefined)
// 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
if (chainId) {
history.replace({ search: replaceURLParam(history.location.search, 'chain', getChainNameFromId(chainId)) })
}
// Can't use `usePrevious` because `chainId` can be undefined while activating.
useEffect(() => {
if (chainId && chainId !== previousChainId) {
setPreviousChainId(chainId)
}
}, [chainId, previousChainId])
if (!skipToggle) {
toggle()
}
const parsedQs = useParsedQueryString()
const urlChainId = getParsedChainId(parsedQs)
const previousUrlChainId = usePrevious(urlChainId)
dispatch(addPopup({ content: { failedSwitchNetwork: targetChain }, key: `failed-network-switch` }))
})
const navigate = useNavigate()
const { search } = useLocation()
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) {
navigate({ search: replaceURLParam(search, 'chain', getChainNameFromId(chainId)) }, { replace: true })
}
}, [chainId, search, navigate])
const onSelectChain = useCallback(
async (targetChain: SupportedChainId, skipClose?: boolean) => {
if (!connector) return
const connectionType = getConnection(connector).type
try {
dispatch(updateConnectionError({ connectionType, error: undefined }))
await switchChain(connector, targetChain)
} catch (error) {
console.error('Failed to switch networks', error)
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 (!skipClose) {
closeModal()
}
},
[dispatch, library, toggle, history, chainId]
[connector, closeModal, dispatch, replaceURLChainParam]
)
// If there is no chain query param, set it to the current chain
useEffect(() => {
if (!chainId || !prevChainId) return
// when network change originates from wallet or dropdown selector, just update URL
if (chainId !== prevChainId) {
history.replace({ search: replaceURLParam(history.location.search, 'chain', getChainNameFromId(chainId)) })
// otherwise assume network change originates from URL
} else if (urlChainId && urlChainId !== chainId) {
handleChainSwitch(urlChainId, true)
const chainQueryUnpopulated = !urlChainId
if (chainQueryUnpopulated && chainId) {
replaceURLChainParam()
}
}, [chainId, urlChainId, prevChainId, handleChainSwitch, 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 || !library) {
// 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>
<Row onSelectChain={handleChainSwitch} targetChain={SupportedChainId.MAINNET} />
<Row onSelectChain={handleChainSwitch} targetChain={SupportedChainId.POLYGON} />
<Row onSelectChain={handleChainSwitch} targetChain={SupportedChainId.OPTIMISM} />
<Row onSelectChain={handleChainSwitch} targetChain={SupportedChainId.ARBITRUM_ONE} />
{NETWORK_SELECTOR_CHAINS.map((chainId: SupportedChainId) =>
isChainAllowed(connector, chainId) ? (
<Row onSelectChain={onSelectChain} targetChain={chainId} key={chainId} />
) : null
)}
</FlyoutMenuContents>
</FlyoutMenu>
)}

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,14 +24,14 @@ 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`
display: none;
`}
`
const StyledPollingNumber = styled(ThemedText.Small)<{ breathe: boolean; hovering: boolean }>`
const StyledPollingNumber = styled(ThemedText.DeprecatedSmall)<{ breathe: boolean; hovering: boolean }>`
transition: opacity 0.25s ease;
opacity: ${({ breathe, hovering }) => (hovering ? 0.7 : breathe ? 1 : 0.5)};
:hover {
@@ -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.DeprecatedMain fontSize="11px" mr="8px" color={theme.deprecated_text3}>
<MouseoverTooltip
text={
<Trans>
@@ -154,7 +154,7 @@ export default function Polling() {
>
{priceGwei.toString()} <Trans>gwei</Trans>
</MouseoverTooltip>
</ThemedText.Main>
</ThemedText.DeprecatedMain>
<StyledGasDot />
</RowFixed>
) : null}

View File

@@ -1,17 +1,17 @@
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 { NavLink, useLocation } from 'react-router-dom'
import { Text } from 'rebass'
import { useShowClaimPopup, useToggleSelfClaimModal } from 'state/application/hooks'
import { useUserHasAvailableClaim } from 'state/claim/hooks'
import { useNativeCurrencyBalances } from 'state/connection/hooks'
import { useUserHasSubmittedClaim } from 'state/transactions/hooks'
import { useDarkModeManager } from 'state/user/hooks'
import { useNativeCurrencyBalances } from 'state/wallet/hooks'
import styled from 'styled-components/macro'
import { ReactComponent as Logo } from '../../assets/svg/logo.svg'
@@ -39,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;
@@ -76,7 +76,7 @@ const HeaderElement = styled.div`
margin-left: 0.5em;
}
/* addresses safari's lack of support for "gap" */
/* addresses safaris lack of support for "gap" */
& > *:not(:first-child) {
margin-left: 8px;
}
@@ -88,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;
@@ -98,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;
@@ -112,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%);
`};
`
@@ -122,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%;
@@ -138,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;
`
@@ -185,18 +185,18 @@ const UniIcon = styled.div`
position: relative;
`
const activeClassName = 'ACTIVE'
// can't be customized under react-router-dom v6
// so we have to persist to the default one, i.e., .active
const activeClassName = 'active'
const StyledNavLink = styled(NavLink).attrs({
activeClassName,
})`
const StyledNavLink = styled(NavLink)`
${({ theme }) => theme.flexRowNoWrap}
align-items: left;
border-radius: 3rem;
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;
@@ -207,26 +207,24 @@ 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)};
}
`
const StyledExternalLink = styled(ExternalLink).attrs({
activeClassName,
})<{ isActive?: boolean }>`
const StyledExternalLink = styled(ExternalLink)`
${({ theme }) => theme.flexRowNoWrap}
align-items: left;
border-radius: 3rem;
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;
@@ -235,22 +233,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 } = useActiveWeb3React()
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()
@@ -262,17 +260,28 @@ export default function Header() {
const scrollY = useScrollPosition()
const { pathname } = useLocation()
const {
infoLink,
nativeCurrency: { symbol: nativeCurrencySymbol },
} = CHAIN_INFO[chainId ? chainId : SupportedChainId.MAINNET]
} = getChainInfoOrDefault(chainId)
// work around https://github.com/remix-run/react-router/issues/8161
// as we can't pass function `({isActive}) => ''` to className with styled-components
const isPoolActive =
pathname.startsWith('/pool') ||
pathname.startsWith('/add') ||
pathname.startsWith('/remove') ||
pathname.startsWith('/increase') ||
pathname.startsWith('/find')
return (
<HeaderFrame showBackground={scrollY > 45}>
<ClaimModal />
<Title href=".">
<UniIcon>
<Logo fill={darkMode ? white : black} width="24px" height="100%" title="logo" />
<Logo fill={darkMode ? deprecated_white : deprecated_black} width="24px" height="100%" title="logo" />
<HolidayOrnament />
</UniIcon>
</Title>
@@ -281,15 +290,10 @@ export default function Header() {
<Trans>Swap</Trans>
</StyledNavLink>
<StyledNavLink
data-cy="pool-nav-link"
id={`pool-nav-link`}
to={'/pool'}
isActive={(match, { pathname }) =>
Boolean(match) ||
pathname.startsWith('/add') ||
pathname.startsWith('/remove') ||
pathname.startsWith('/increase') ||
pathname.startsWith('/find')
}
className={isPoolActive ? activeClassName : undefined}
>
<Trans>Pool</Trans>
</StyledNavLink>
@@ -312,7 +316,7 @@ export default function Header() {
{availableClaim && !showClaimPopup && (
<UNIWrapper onClick={toggleClaimModal}>
<UNIAmount active={!!account && !availableClaim} style={{ pointerEvents: 'auto' }}>
<ThemedText.White padding="0 2px">
<ThemedText.DeprecatedWhite padding="0 2px">
{claimTxn && !claimTxn?.receipt ? (
<Dots>
<Trans>Claiming UNI</Trans>
@@ -320,14 +324,14 @@ export default function Header() {
) : (
<Trans>Claim UNI</Trans>
)}
</ThemedText.White>
</ThemedText.DeprecatedWhite>
</UNIAmount>
<CardNoise />
</UNIWrapper>
)}
<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,23 +1,42 @@
import { Connector } from '@web3-react/types'
import { AbstractConnector } from 'web3-react-abstract-connector'
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 { fortmatic, injected, walletconnect, walletlink } from '../../connectors'
import Identicon from '../Identicon'
export default function StatusIcon({ connector }: { connector: AbstractConnector | Connector }) {
switch (connector) {
case injected:
return <Identicon />
case walletconnect:
return <img src={WalletConnectIcon} alt={'WalletConnect'} />
case walletlink:
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 }>`
@@ -57,14 +57,14 @@ const StyledInput = styled(NumericalInput)<{ usePercent?: boolean }>`
`};
`
const InputTitle = styled(ThemedText.Small)`
color: ${({ theme }) => theme.text2};
const InputTitle = styled(ThemedText.DeprecatedSmall)`
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;
const ButtonLabel = styled(ThemedText.DeprecatedWhite)<{ disabled: boolean }>`
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

@@ -58,9 +58,9 @@ function InfoBox({ message, icon }: { message?: ReactNode; icon: ReactNode }) {
<ColumnCenter style={{ height: '100%', justifyContent: 'center' }}>
{icon}
{message && (
<ThemedText.MediumHeader padding={10} marginTop="20px" textAlign="center">
<ThemedText.DeprecatedMediumHeader padding={10} marginTop="20px" textAlign="center">
{message}
</ThemedText.MediumHeader>
</ThemedText.DeprecatedMediumHeader>
)}
</ColumnCenter>
)
@@ -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'
@@ -32,9 +32,9 @@ export function LoadingView({ children, onDismiss }: { children: any; onDismiss:
</ConfirmedIcon>
<AutoColumn gap="100px" justify={'center'}>
{children}
<ThemedText.SubHeader>
<ThemedText.DeprecatedSubHeader>
<Trans>Confirm this transaction in your wallet</Trans>
</ThemedText.SubHeader>
</ThemedText.DeprecatedSubHeader>
</AutoColumn>
</ConfirmOrLoadingWrapper>
)
@@ -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}
@@ -68,9 +68,9 @@ export function SubmittedView({
href={getExplorerLink(chainId, hash, ExplorerDataType.TRANSACTION)}
style={{ marginLeft: '4px' }}
>
<ThemedText.SubHeader>
<ThemedText.DeprecatedSubHeader>
<Trans>View transaction on Explorer</Trans>
</ThemedText.SubHeader>
</ThemedText.DeprecatedSubHeader>
</ExternalLink>
)}
</AutoColumn>

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,9 +92,9 @@ export function AddRemoveTabs({
}}
flex={children ? '1' : undefined}
>
<StyledArrowLeft stroke={theme.text2} />
<StyledArrowLeft stroke={theme.deprecated_text2} />
</StyledHistoryLink>
<ThemedText.MediumHeader
<ThemedText.DeprecatedMediumHeader
fontWeight={500}
fontSize={20}
style={{ flex: '1', margin: 'auto', textAlign: children ? 'start' : 'center' }}
@@ -148,7 +106,7 @@ export function AddRemoveTabs({
) : (
<Trans>Remove Liquidity</Trans>
)}
</ThemedText.MediumHeader>
</ThemedText.DeprecatedMediumHeader>
<Box style={{ marginRight: '.5rem' }}>{children}</Box>
<SettingsTab placeholderSlippage={defaultSlippage} />
</RowBetween>

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({
@@ -98,10 +98,14 @@ export default function ClaimPopup() {
<StyledClose stroke="white" onClick={toggleShowClaimPopup} />
<AutoColumn style={{ padding: '2rem 0', zIndex: 10 }} justify="center">
<UniToken width="48px" src={tokenLogo} />{' '}
<ThemedText.White style={{ marginTop: '1rem' }} fontSize={36} fontWeight={600}>
<ThemedText.DeprecatedWhite style={{ marginTop: '1rem' }} fontSize={36} fontWeight={600}>
{unclaimedAmount?.toFixed(0, { groupSeparator: ',' } ?? '-')} UNI
</ThemedText.White>
<ThemedText.White style={{ paddingTop: '1.25rem', textAlign: 'center' }} fontWeight={600} color="white">
</ThemedText.DeprecatedWhite>
<ThemedText.DeprecatedWhite
style={{ paddingTop: '1.25rem', textAlign: 'center' }}
fontWeight={600}
color="white"
>
<span role="img" aria-label="party">
🎉
</span>{' '}
@@ -109,12 +113,12 @@ export default function ClaimPopup() {
<span role="img" aria-label="party">
🎉
</span>
</ThemedText.White>
<ThemedText.SubHeader style={{ paddingTop: '0.5rem', textAlign: 'center' }} color="white">
</ThemedText.DeprecatedWhite>
<ThemedText.DeprecatedSubHeader style={{ paddingTop: '0.5rem', textAlign: 'center' }} color="white">
<Trans>
Thanks for being part of the Uniswap community <Heart size={12} />
</Trans>
</ThemedText.SubHeader>
</ThemedText.DeprecatedSubHeader>
</AutoColumn>
<AutoColumn style={{ zIndex: 10 }} justify="center">
<ButtonPrimary padding="8px" $borderRadius="8px" width={'fit-content'} onClick={handleToggleSelfClaimModal}>

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,21 +14,21 @@ 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}>
<ThemedText.DeprecatedBody fontWeight={500}>
<Trans>
Failed to switch networks from the Uniswap Interface. In order to use Uniswap on {chainInfo.label}, you must
change the network in your wallet.
</Trans>
</ThemedText.Body>
</ThemedText.DeprecatedBody>
</AutoColumn>
</RowNoFlex>
)

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,15 +90,20 @@ 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.DeprecatedWhite fontWeight={600} color={theme.deprecated_black} ml="6px">
<Trans>Tell us what you think </Trans>
</ThemedText.White>
</ThemedText.DeprecatedWhite>
</RowFixed>
</ExternalLink>
<ThemedText.Black style={{ zIndex: Z_INDEX.fixed }} fontWeight={400} fontSize="12px" color={theme.black}>
<ThemedText.DeprecatedBlack
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>
</ThemedText.DeprecatedBlack>
</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,12 +27,16 @@ 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}>
<ThemedText.DeprecatedBody fontWeight={500}>
<TransactionSummary info={tx.info} />
</ThemedText.Body>
</ThemedText.DeprecatedBody>
{chainId && (
<ExternalLink href={getExplorerLink(chainId, hash, ExplorerDataType.TRANSACTION)}>
View on Explorer

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)
@@ -142,7 +142,7 @@ export function MinimalPositionCard({ pair, showUnwrapped = false, border }: Pos
</GreyCard>
) : (
<LightCard>
<ThemedText.SubHeader style={{ textAlign: 'center' }}>
<ThemedText.DeprecatedSubHeader style={{ textAlign: 'center' }}>
<span role="img" aria-label="wizard-icon">
</span>{' '}
@@ -150,7 +150,7 @@ export function MinimalPositionCard({ pair, showUnwrapped = false, border }: Pos
By adding liquidity you&apos;ll earn 0.3% of all trades on this pair proportional to your share of the
pool. Fees are added to the pool, accrue in real time and can be claimed by withdrawing your liquidity.
</Trans>{' '}
</ThemedText.SubHeader>
</ThemedText.DeprecatedSubHeader>
</LightCard>
)}
</>
@@ -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

@@ -70,9 +70,9 @@ export const PositionPreview = ({
size={24}
margin={true}
/>
<ThemedText.Label ml="10px" fontSize="24px">
<ThemedText.DeprecatedLabel ml="10px" fontSize="24px">
{currency0?.symbol} / {currency1?.symbol}
</ThemedText.Label>
</ThemedText.DeprecatedLabel>
</RowFixed>
<RangeBadge removed={removed} inRange={inRange} />
</RowBetween>
@@ -82,36 +82,36 @@ export const PositionPreview = ({
<RowBetween>
<RowFixed>
<CurrencyLogo currency={currency0} />
<ThemedText.Label ml="8px">{currency0?.symbol}</ThemedText.Label>
<ThemedText.DeprecatedLabel ml="8px">{currency0?.symbol}</ThemedText.DeprecatedLabel>
</RowFixed>
<RowFixed>
<ThemedText.Label mr="8px">{position.amount0.toSignificant(4)}</ThemedText.Label>
<ThemedText.DeprecatedLabel mr="8px">{position.amount0.toSignificant(4)}</ThemedText.DeprecatedLabel>
</RowFixed>
</RowBetween>
<RowBetween>
<RowFixed>
<CurrencyLogo currency={currency1} />
<ThemedText.Label ml="8px">{currency1?.symbol}</ThemedText.Label>
<ThemedText.DeprecatedLabel ml="8px">{currency1?.symbol}</ThemedText.DeprecatedLabel>
</RowFixed>
<RowFixed>
<ThemedText.Label mr="8px">{position.amount1.toSignificant(4)}</ThemedText.Label>
<ThemedText.DeprecatedLabel mr="8px">{position.amount1.toSignificant(4)}</ThemedText.DeprecatedLabel>
</RowFixed>
</RowBetween>
<Break />
<RowBetween>
<ThemedText.Label>
<ThemedText.DeprecatedLabel>
<Trans>Fee Tier</Trans>
</ThemedText.Label>
<ThemedText.Label>
</ThemedText.DeprecatedLabel>
<ThemedText.DeprecatedLabel>
<Trans>{position?.pool?.fee / 10000}%</Trans>
</ThemedText.Label>
</ThemedText.DeprecatedLabel>
</RowBetween>
</AutoColumn>
</LightCard>
<AutoColumn gap="md">
<RowBetween>
{title ? <ThemedText.Main>{title}</ThemedText.Main> : <div />}
{title ? <ThemedText.DeprecatedMain>{title}</ThemedText.DeprecatedMain> : <div />}
<RateToggle
currencyA={sorted ? currency0 : currency1}
currencyB={sorted ? currency1 : currency0}
@@ -122,57 +122,65 @@ export const PositionPreview = ({
<RowBetween>
<LightCard width="48%" padding="8px">
<AutoColumn gap="4px" justify="center">
<ThemedText.Main fontSize="12px">
<ThemedText.DeprecatedMain fontSize="12px">
<Trans>Min Price</Trans>
</ThemedText.Main>
<ThemedText.MediumHeader textAlign="center">{`${formatTickPrice(
</ThemedText.DeprecatedMain>
<ThemedText.DeprecatedMediumHeader textAlign="center">{`${formatTickPrice(
priceLower,
ticksAtLimit,
Bound.LOWER
)}`}</ThemedText.MediumHeader>
<ThemedText.Main textAlign="center" fontSize="12px">
)}`}</ThemedText.DeprecatedMediumHeader>
<ThemedText.DeprecatedMain textAlign="center" fontSize="12px">
<Trans>
{quoteCurrency.symbol} per {baseCurrency.symbol}
</Trans>
</ThemedText.Main>
<ThemedText.Small textAlign="center" color={theme.text3} style={{ marginTop: '4px' }}>
</ThemedText.DeprecatedMain>
<ThemedText.DeprecatedSmall
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>
</ThemedText.DeprecatedSmall>
</AutoColumn>
</LightCard>
<LightCard width="48%" padding="8px">
<AutoColumn gap="4px" justify="center">
<ThemedText.Main fontSize="12px">
<ThemedText.DeprecatedMain fontSize="12px">
<Trans>Max Price</Trans>
</ThemedText.Main>
<ThemedText.MediumHeader textAlign="center">{`${formatTickPrice(
</ThemedText.DeprecatedMain>
<ThemedText.DeprecatedMediumHeader textAlign="center">{`${formatTickPrice(
priceUpper,
ticksAtLimit,
Bound.UPPER
)}`}</ThemedText.MediumHeader>
<ThemedText.Main textAlign="center" fontSize="12px">
)}`}</ThemedText.DeprecatedMediumHeader>
<ThemedText.DeprecatedMain textAlign="center" fontSize="12px">
<Trans>
{quoteCurrency.symbol} per {baseCurrency.symbol}
</Trans>
</ThemedText.Main>
<ThemedText.Small textAlign="center" color={theme.text3} style={{ marginTop: '4px' }}>
</ThemedText.DeprecatedMain>
<ThemedText.DeprecatedSmall
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>
</ThemedText.DeprecatedSmall>
</AutoColumn>
</LightCard>
</RowBetween>
<LightCard padding="12px ">
<AutoColumn gap="4px" justify="center">
<ThemedText.Main fontSize="12px">
<ThemedText.DeprecatedMain fontSize="12px">
<Trans>Current price</Trans>
</ThemedText.Main>
<ThemedText.MediumHeader>{`${price.toSignificant(5)} `}</ThemedText.MediumHeader>
<ThemedText.Main textAlign="center" fontSize="12px">
</ThemedText.DeprecatedMain>
<ThemedText.DeprecatedMediumHeader>{`${price.toSignificant(5)} `}</ThemedText.DeprecatedMediumHeader>
<ThemedText.DeprecatedMain textAlign="center" fontSize="12px">
<Trans>
{quoteCurrency.symbol} per {baseCurrency.symbol}
</Trans>
</ThemedText.Main>
</ThemedText.DeprecatedMain>
</AutoColumn>
</LightCard>
</AutoColumn>

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