Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c9721c42bf | ||
|
|
4414134bb2 | ||
|
|
44ba54e44a | ||
|
|
9ec3109f72 | ||
|
|
e75793676a | ||
|
|
32006ded21 | ||
|
|
d4f1c579d8 | ||
|
|
95f3541807 | ||
|
|
da4ca73a1d | ||
|
|
e75bf8d003 | ||
|
|
236f68a459 | ||
|
|
9f07baaad2 | ||
|
|
c75464e1aa | ||
|
|
bc80585bb4 | ||
|
|
ad45b2b7bb | ||
|
|
63ac89e9f3 | ||
|
|
1b6ae0d3db | ||
|
|
7d67819604 |
2
.env
2
.env
@@ -1,2 +1,2 @@
|
|||||||
REACT_APP_CHAIN_ID="1"
|
REACT_APP_CHAIN_ID="1"
|
||||||
REACT_APP_NETWORK_URL="https://mainnet.infura.io/v3/b8800ce81b8c451698081d269b86692b"
|
REACT_APP_NETWORK_URL="https://mainnet.infura.io/v3/acb7e55995d04c49bfb52b7141599467"
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
REACT_APP_CHAIN_ID="1"
|
REACT_APP_CHAIN_ID="1"
|
||||||
REACT_APP_NETWORK_URL="https://mainnet.infura.io/v3/2acb2baa4c06402792e0c701a3697d10"
|
REACT_APP_NETWORK_URL="https://mainnet.infura.io/v3/febcb10ca2754433a61e0805bc6c047d"
|
||||||
REACT_APP_PORTIS_ID="c0e2bf01-4b08-4fd5-ac7b-8e26b58cd236"
|
REACT_APP_PORTIS_ID="c0e2bf01-4b08-4fd5-ac7b-8e26b58cd236"
|
||||||
REACT_APP_FORTMATIC_KEY="pk_live_F937DF033A1666BF"
|
REACT_APP_FORTMATIC_KEY="pk_live_F937DF033A1666BF"
|
||||||
REACT_APP_GOOGLE_ANALYTICS_ID="UA-128182339-4"
|
REACT_APP_GOOGLE_ANALYTICS_ID="UA-128182339-4"
|
||||||
|
|||||||
68
.github/workflows/release.yaml
vendored
68
.github/workflows/release.yaml
vendored
@@ -1,36 +1,47 @@
|
|||||||
name: Release
|
name: Release
|
||||||
# every morning
|
|
||||||
on:
|
on:
|
||||||
|
# every morning
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 12 * * *'
|
- cron: '0 12 * * *'
|
||||||
|
|
||||||
|
# releases are triggered on changes to this file
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- '.github/workflows/release.yaml'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
create-release:
|
bump_version:
|
||||||
name: Create Release
|
name: Bump Version
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
new_tag: ${{ steps.github_tag_action.outputs.new_tag }}
|
||||||
|
changelog: ${{ steps.github_tag_action.outputs.changelog }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v1
|
uses: actions/checkout@v1
|
||||||
|
|
||||||
- name: Bump version and push tag
|
- name: Bump version and push tag
|
||||||
id: bump_version
|
id: github_tag_action
|
||||||
uses: mathieudutour/github-tag-action@v4
|
uses: mathieudutour/github-tag-action@v4
|
||||||
with:
|
with:
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
release_branches: .*
|
release_branches: .*
|
||||||
|
|
||||||
- name: Cancel this build if no new commits
|
create_release:
|
||||||
if: ${{ steps.bump_version.outputs.new_tag == null }}
|
name: Create Release
|
||||||
uses: andymckay/cancel-action@0.2
|
runs-on: ubuntu-latest
|
||||||
|
needs: bump_version
|
||||||
|
if: ${{ needs.bump_version.outputs.new_tag != null }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
|
||||||
- uses: actions/setup-node@v1
|
- uses: actions/setup-node@v1
|
||||||
with:
|
with:
|
||||||
node-version: '12'
|
node-version: '12'
|
||||||
|
|
||||||
- name: Install yarn
|
|
||||||
run: npm install -g yarn
|
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: yarn
|
run: yarn install --ignore-scripts --frozen-lockfile
|
||||||
|
|
||||||
- name: Build the IPFS bundle
|
- name: Build the IPFS bundle
|
||||||
run: yarn ipfs-build
|
run: yarn ipfs-build
|
||||||
@@ -39,14 +50,26 @@ jobs:
|
|||||||
id: upload
|
id: upload
|
||||||
uses: anantaramdas/ipfs-pinata-deploy-action@v1.5.2
|
uses: anantaramdas/ipfs-pinata-deploy-action@v1.5.2
|
||||||
with:
|
with:
|
||||||
pin-name: Uniswap ${{ steps.bump_version.outputs.new_tag }}
|
pin-name: Uniswap ${{ needs.bump_version.outputs.new_tag }}
|
||||||
path: './build'
|
path: './build'
|
||||||
pinata-api-key: ${{ secrets.PINATA_API_KEY }}
|
pinata-api-key: ${{ secrets.PINATA_API_KEY }}
|
||||||
pinata-secret-api-key: ${{ secrets.PINATA_API_SECRET_KEY }}
|
pinata-secret-api-key: ${{ secrets.PINATA_API_SECRET_KEY }}
|
||||||
|
|
||||||
|
- name: Convert CIDv0 to CIDv1
|
||||||
|
id: convert_cidv0
|
||||||
|
uses: uniswap/convert-cidv0-cidv1@v1.0.0
|
||||||
|
with:
|
||||||
|
cidv0: ${{ steps.upload.outputs.hash }}
|
||||||
|
|
||||||
- name: Update DNS with new IPFS hash
|
- name: Update DNS with new IPFS hash
|
||||||
id: update_dns
|
uses: uniswap/replace-vercel-dns-records@v1.0.0
|
||||||
run: npx vercel --token ${{ secrets.VERCEL_TOKEN }} --scope uniswap dns add uniswap.org _dnslink.app TXT "dnslink=/ipfs/${{ steps.upload.outputs.hash }}"
|
with:
|
||||||
|
domain: 'uniswap.org'
|
||||||
|
subdomain: '_dnslink.app'
|
||||||
|
record-type: 'TXT'
|
||||||
|
value: /ipfs/${{ steps.upload.outputs.hash }}
|
||||||
|
token: ${{ secrets.VERCEL_TOKEN }}
|
||||||
|
team-name: 'uniswap'
|
||||||
|
|
||||||
- name: Create GitHub Release
|
- name: Create GitHub Release
|
||||||
id: create_release
|
id: create_release
|
||||||
@@ -54,24 +77,27 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
with:
|
with:
|
||||||
tag_name: ${{ steps.bump_version.outputs.new_tag }}
|
tag_name: ${{ needs.bump_version.outputs.new_tag }}
|
||||||
release_name: Release ${{ steps.bump_version.outputs.new_tag }}
|
release_name: Release ${{ needs.bump_version.outputs.new_tag }}
|
||||||
body: |
|
body: |
|
||||||
Release built from commit
|
Release built from commit [`${{ github.sha }}`](https://github.com/Uniswap/uniswap-frontend/tree/${{ github.sha }})
|
||||||
[`${{ github.sha }}`](https://github.com/Uniswap/uniswap-frontend/tree/${{ github.sha }})
|
|
||||||
|
|
||||||
The IPFS hash of the bundle is `${{ steps.upload.outputs.hash }}`
|
The IPFS hash of the bundle is:
|
||||||
|
- CIDv0: `${{ steps.upload.outputs.hash }}`
|
||||||
|
- CIDv1: `${{ steps.convert_cidv0.outputs.cidv1 }}`
|
||||||
|
|
||||||
Uniswap uses [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) to store your settings.
|
Uniswap uses [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) to store your settings.
|
||||||
**Beware** that other sites you access via the _same_ IPFS gateway can read and modify your settings on Uniswap without your permission.
|
**Beware** that other sites you access via the _same_ IPFS gateway can read and modify your settings on Uniswap without your permission.
|
||||||
|
You can avoid this issue by using a subdomain IPFS gateway. The preferred gateway URLs below utilize the CIDv1 of the release in the subdomain, and are relatively safer.
|
||||||
|
|
||||||
Preferred URLs:
|
Preferred URLs:
|
||||||
|
- 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 }}/)
|
- [ipfs://${{ steps.upload.outputs.hash }}/](ipfs://${{ steps.upload.outputs.hash }}/)
|
||||||
- https://dweb.link/ipfs/${{ steps.upload.outputs.hash }}/
|
|
||||||
|
|
||||||
Other IPFS gateways:
|
Other IPFS gateways:
|
||||||
- https://cloudflare-ipfs.com/ipfs/${{ steps.upload.outputs.hash }}/
|
- https://cloudflare-ipfs.com/ipfs/${{ steps.upload.outputs.hash }}/
|
||||||
- https://ipfs.infura.io/ipfs/${{ steps.upload.outputs.hash }}/
|
- https://ipfs.infura.io/ipfs/${{ steps.upload.outputs.hash }}/
|
||||||
- https://ipfs.io/ipfs/${{ steps.upload.outputs.hash }}/
|
- https://ipfs.io/ipfs/${{ steps.upload.outputs.hash }}/
|
||||||
|
|
||||||
${{ steps.bump_version.outputs.changelog }}
|
${{ needs.bump_version.outputs.changelog }}
|
||||||
6
.github/workflows/tests.yaml
vendored
6
.github/workflows/tests.yaml
vendored
@@ -26,7 +26,7 @@ jobs:
|
|||||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-yarn-
|
${{ runner.os }}-yarn-
|
||||||
- run: yarn
|
- run: yarn install
|
||||||
- run: yarn integration-test
|
- run: yarn integration-test
|
||||||
|
|
||||||
unit-tests:
|
unit-tests:
|
||||||
@@ -48,7 +48,7 @@ jobs:
|
|||||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-yarn-
|
${{ runner.os }}-yarn-
|
||||||
- run: yarn
|
- run: yarn install --ignore-scripts --frozen-lockfile
|
||||||
- run: yarn test
|
- run: yarn test
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
@@ -70,6 +70,6 @@ jobs:
|
|||||||
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-yarn-
|
${{ runner.os }}-yarn-
|
||||||
- run: yarn
|
- run: yarn install --ignore-scripts --frozen-lockfile
|
||||||
- run: yarn lint
|
- run: yarn lint
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
# Uniswap Frontend
|
# Uniswap Frontend
|
||||||
|
|
||||||
[](https://app.netlify.com/sites/uniswap/deploys)
|
[](https://app.netlify.com/sites/uniswap/deploys)
|
||||||
[](https://github.com/Uniswap/uniswap-frontend/actions?query=workflow%3ATests)
|
[](https://github.com/Uniswap/uniswap-frontend/actions?query=workflow%3ATests)
|
||||||
[](https://prettier.io/)
|
[](https://prettier.io/)
|
||||||
[](https://github.com/Uniswap/uniswap-frontend/actions?query=workflow%3ARelease)
|
[](https://github.com/Uniswap/uniswap-frontend/actions?query=workflow%3ARelease)
|
||||||
|
|
||||||
An open source interface for Uniswap -- a protocol for decentralized exchange of Ethereum tokens.
|
An open source interface for Uniswap -- a protocol for decentralized exchange of Ethereum tokens.
|
||||||
|
|
||||||
|
|||||||
@@ -71,10 +71,9 @@ Cypress.Commands.overwrite('visit', (original, url, options) => {
|
|||||||
...options,
|
...options,
|
||||||
onBeforeLoad(win) {
|
onBeforeLoad(win) {
|
||||||
options && options.onBeforeLoad && options.onBeforeLoad(win)
|
options && options.onBeforeLoad && options.onBeforeLoad(win)
|
||||||
const provider = new JsonRpcProvider('https://rinkeby.infura.io/v3/b8800ce81b8c451698081d269b86692b', 4)
|
const provider = new JsonRpcProvider('https://rinkeby.infura.io/v3/acb7e55995d04c49bfb52b7141599467', 4)
|
||||||
const signer = new Wallet(PRIVATE_KEY_TEST_NEVER_USE, provider)
|
const signer = new Wallet(PRIVATE_KEY_TEST_NEVER_USE, provider)
|
||||||
const bridge = new CustomizedBridge(signer, provider)
|
win.ethereum = new CustomizedBridge(signer, provider)
|
||||||
win.ethereum = bridge
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
20
src/hooks/useIsWindowVisible.ts
Normal file
20
src/hooks/useIsWindowVisible.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the window is currently visible to the user.
|
||||||
|
*/
|
||||||
|
export default function useIsWindowVisible(): boolean {
|
||||||
|
const [focused, setFocused] = useState<boolean>(true)
|
||||||
|
const listener = useCallback(() => {
|
||||||
|
setFocused(document.visibilityState !== 'hidden')
|
||||||
|
}, [setFocused])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
document.addEventListener('visibilitychange', listener)
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('visibilitychange', listener)
|
||||||
|
}
|
||||||
|
}, [listener])
|
||||||
|
|
||||||
|
return focused
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { useDebounce, useActiveWeb3React } from '../../hooks'
|
import { useDebounce, useActiveWeb3React } from '../../hooks'
|
||||||
|
import useIsWindowVisible from '../../hooks/useIsWindowVisible'
|
||||||
import { updateBlockNumber } from './actions'
|
import { updateBlockNumber } from './actions'
|
||||||
import { useDispatch } from 'react-redux'
|
import { useDispatch } from 'react-redux'
|
||||||
|
|
||||||
@@ -7,6 +8,7 @@ export default function Updater() {
|
|||||||
const { library, chainId } = useActiveWeb3React()
|
const { library, chainId } = useActiveWeb3React()
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
|
|
||||||
|
const windowVisible = useIsWindowVisible()
|
||||||
const [maxBlockNumber, setMaxBlockNumber] = useState<number | null>(null)
|
const [maxBlockNumber, setMaxBlockNumber] = useState<number | null>(null)
|
||||||
// because blocks arrive in bunches with longer polling periods, we just want
|
// because blocks arrive in bunches with longer polling periods, we just want
|
||||||
// to process the latest one.
|
// to process the latest one.
|
||||||
@@ -38,8 +40,10 @@ export default function Updater() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!chainId || !debouncedMaxBlockNumber) return
|
if (!chainId || !debouncedMaxBlockNumber) return
|
||||||
dispatch(updateBlockNumber({ chainId, blockNumber: debouncedMaxBlockNumber }))
|
if (windowVisible) {
|
||||||
}, [chainId, debouncedMaxBlockNumber, dispatch])
|
dispatch(updateBlockNumber({ chainId, blockNumber: debouncedMaxBlockNumber }))
|
||||||
|
}
|
||||||
|
}, [chainId, debouncedMaxBlockNumber, windowVisible, dispatch])
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user