MERGE development into master (#648)
* Fix #597: USD value not load (#609) * Converts all the addresses to checksum values * Fix for empty address * fix the order of transactions, change updateSafe to upgradeSafe to avoid naming confusion with the updateSafe action (#610) * Fix #596: Notification when safe is already updated (#599) * Fix notification of update if the safe is already updated * Makes the notification clickable Displays the notification for owners only * Identify upgrade tx * Add red badge to Settings tab * Fixs Padding Removes the red dot if the user is not an owner Co-authored-by: Fernando <fernando.greco@gmail.com> * Bug: #482 - Address book Custom transactions Recipient validation (#577) * (fix) text input bottom border * Fix #482 input * Merge branch 'development' of https://github.com/gnosis/safe-react into fix/#482-address-book # Conflicts: # src/components/forms/TextField/index.jsx # src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.jsx # src/routes/safe/components/Balances/SendModal/screens/SendFunds/TokenSelectField/index.jsx # src/routes/safe/components/Balances/SendModal/screens/SendFunds/index.jsx # yarn.lock * Fix custom tx addresses filtering * Merge branch 'development' of https://github.com/gnosis/safe-react into fix/#482-address-book # Conflicts: # yarn.lock * Remove console logs Fixed prettier issues * Remove unnecessary template string * Fix `tokenAddress` string conversion * Use `secondaryBackground` value Co-authored-by: Gabriel Rodríguez Alsina <gabitoesmiapodo@users.noreply.github.com> Co-authored-by: Fernando <fernando.greco@gmail.com> * (feature) Adding origin for Apps Transactions (#576) * Adding origin field when creates a TX * refactor: replace list of arg by object in getApprovalTransaction and getExecutionTransaction function * minor changes * Allow execute if threshold is 1 for the first tx - Related to issue #563 - `lastTx` is required due to #489 * - Normalizing logic between createTransaction and processTransaction - Moving shared function to a new file * Refactor `doesTxNeedApproval` back to the `isExecution`-related meaning * Rename function and variable names * Add tests for `getNewTxNonce` and `shouldExecuteTransaction` functions * Pass `safeInstance` instead of `safeAddress` to `getNewTxNonce` * Update Tests - remove mocked `getGnosisSafeInstanceAt` - pass `safeInstance` instead of `safeAddress` to `getNewTxNonce` Co-authored-by: Fernando <fernando.greco@gmail.com> * (Feature) Add checks into CI (#594) * Repare new dev and staging enviroments to deploy (#618) * Repare new dev and staging enviroments to deploy - Add to `deploy_pull_requests.sh` to the new path. - Replace upload-dir to deploy staging to the new path. * add /app/ public path for the webapp, remove duplicate yarn build from travis * add basename to app * deploy pr to /app * update travis * linter error fixes * fix travis build script Co-authored-by: David Albela Pérez <3659067+davidalbela@users.noreply.github.com> * (fix) sidebar contents' scrolling (#622) * (add) linter sorting rules (#614) * (add) linter sorting rules * (fix) linting errors according to the new rules Co-authored-by: Fernando <fernando.greco@gmail.com> * Rebase master onto development (#624) * v1.7.3 (#611) * Fix #597: USD value not load (#609) * Converts all the addresses to checksum values * Fix for empty address * fix the order of transactions, change updateSafe to upgradeSafe to avoid naming confusion with the updateSafe action (#610) * Fix #596: Notification when safe is already updated (#599) * Fix notification of update if the safe is already updated * Makes the notification clickable Displays the notification for owners only * Identify upgrade tx * Add red badge to Settings tab * Fixs Padding Removes the red dot if the user is not an owner Co-authored-by: Fernando <fernando.greco@gmail.com> Co-authored-by: Fernando <fernando.greco@gmail.com> Co-authored-by: Agustin Pane <agustin.pane@gmail.com> * Update package.json (#612) * Add public url to prod webpack config (#615) * add public url to prod webpack config * modify travis/webpack config to add public url * add slash * cherry pick new travis yml merge commit (#620) * Fix #596: Notification when safe is already updated (#599) * Fix notification of update if the safe is already updated * Makes the notification clickable Displays the notification for owners only * Identify upgrade tx * Add red badge to Settings tab * Fixs Padding Removes the red dot if the user is not an owner Co-authored-by: Fernando <fernando.greco@gmail.com> * Bug: #482 - Address book Custom transactions Recipient validation (#577) * (fix) text input bottom border * Fix #482 input * Merge branch 'development' of https://github.com/gnosis/safe-react into fix/#482-address-book # Conflicts: # src/components/forms/TextField/index.jsx # src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.jsx # src/routes/safe/components/Balances/SendModal/screens/SendFunds/TokenSelectField/index.jsx # src/routes/safe/components/Balances/SendModal/screens/SendFunds/index.jsx # yarn.lock * Fix custom tx addresses filtering * Merge branch 'development' of https://github.com/gnosis/safe-react into fix/#482-address-book # Conflicts: # yarn.lock * Remove console logs Fixed prettier issues * Remove unnecessary template string * Fix `tokenAddress` string conversion * Use `secondaryBackground` value Co-authored-by: Gabriel Rodríguez Alsina <gabitoesmiapodo@users.noreply.github.com> Co-authored-by: Fernando <fernando.greco@gmail.com> * (feature) Adding origin for Apps Transactions (#576) * Adding origin field when creates a TX * refactor: replace list of arg by object in getApprovalTransaction and getExecutionTransaction function * minor changes * Allow execute if threshold is 1 for the first tx - Related to issue #563 - `lastTx` is required due to #489 * - Normalizing logic between createTransaction and processTransaction - Moving shared function to a new file * Refactor `doesTxNeedApproval` back to the `isExecution`-related meaning * Rename function and variable names * Add tests for `getNewTxNonce` and `shouldExecuteTransaction` functions * Pass `safeInstance` instead of `safeAddress` to `getNewTxNonce` * Update Tests - remove mocked `getGnosisSafeInstanceAt` - pass `safeInstance` instead of `safeAddress` to `getNewTxNonce` Co-authored-by: Fernando <fernando.greco@gmail.com> * (Feature) Add checks into CI (#594) * Repare new dev and staging enviroments to deploy (#618) * Repare new dev and staging enviroments to deploy - Add to `deploy_pull_requests.sh` to the new path. - Replace upload-dir to deploy staging to the new path. * add /app/ public path for the webapp, remove duplicate yarn build from travis * add basename to app * deploy pr to /app * update travis * linter error fixes * fix travis build script Co-authored-by: David Albela Pérez <3659067+davidalbela@users.noreply.github.com> * (fix) sidebar contents' scrolling (#622) * (add) linter sorting rules (#614) * (add) linter sorting rules * (fix) linting errors according to the new rules Co-authored-by: Fernando <fernando.greco@gmail.com> Co-authored-by: Mikhail Mikheev <mmvsha73@gmail.com> Co-authored-by: Agustin Pane <agustin.pane@gmail.com> Co-authored-by: Gabriel Rodríguez Alsina <gabitoesmiapodo@users.noreply.github.com> Co-authored-by: nicolas <nicosampler@users.noreply.github.com> Co-authored-by: David Albela Pérez <3659067+davidalbela@users.noreply.github.com> * (feature): [Safe Apps] App Transaction List Details (#601) * Adding IconText component * Get origin for TXs in Redux * Adding Icon and name app to transaction list * Fix customTx condition * Fix HTML element for text * simplify condition * Bug: Accounts/Network are not updated in production build (#625) * Adding Apps info to toast notification (#621) * Adding APP_Name for APPs TXs in toast messages * refactor: save appId instead of appName in origin field * adding fallback icon and message to TX apps table * review changes * review fixes * force build * update Apps list info (#629) * update Apps list info * fix * Feature: replace web3connect with onboardjs (#456) * init onboard.js * dep bump * initial replacement of web3connect with onboard.js * use averta font in the modal * update onboard.js, add handlers for session murder * update preferred wallets * implement reconnecting to injected provider * fix duplicate wallet disconnected notification * update onboard dep * onboardjs fixes * test onboard js with hw * add https to rpcUrl * Added saved wallet and transactions validation * made Transactions validation * bnc-onboard version updated * Fix lock/unlock problem * bump onboardjs version * fixed material-ui lab version * Update onboard version * Added hw wallets integration * Updated preferred wallets * Add ledger modal * Merge with dev * Update onboard * BUmp new version of onboardjs * Added some logs * Added some logs * Update onboardjs version fix ledger connection * Update onboardjs version fix ledger connection * Bump new onboardjs version * Update new version * Made improvements * yarn.lock regenration * remove https=true * Remove comments and added some improvements * Updated package.json dep * Removed unused deps * Remove web3connect dep Co-authored-by: lukasschor <lukas.schor@gnosis.pm> Co-authored-by: Mati Dastugue <matiasdastugue@gmail.com> * Passing ethBalance to Apps component (#636) * (Fix) Update safe modal verbiage (#633) * Fixs verbiage in update safe modal * Fixs yarn lock * Bump dependencies (#639) * Use hash history (#638) * v1.7.3 (#611) * Fix #597: USD value not load (#609) * Converts all the addresses to checksum values * Fix for empty address * fix the order of transactions, change updateSafe to upgradeSafe to avoid naming confusion with the updateSafe action (#610) * Fix #596: Notification when safe is already updated (#599) * Fix notification of update if the safe is already updated * Makes the notification clickable Displays the notification for owners only * Identify upgrade tx * Add red badge to Settings tab * Fixs Padding Removes the red dot if the user is not an owner Co-authored-by: Fernando <fernando.greco@gmail.com> Co-authored-by: Fernando <fernando.greco@gmail.com> Co-authored-by: Agustin Pane <agustin.pane@gmail.com> * Update package.json (#612) * Add public url to prod webpack config (#615) * add public url to prod webpack config * modify travis/webpack config to add public url * add slash * cherry pick new travis yml merge commit (#620) * use hash history Co-authored-by: Fernando <fernando.greco@gmail.com> Co-authored-by: Agustin Pane <agustin.pane@gmail.com> * - Updates how the transactions are ordered, now orders by nonce and then by date (#640) * (Fix) Lowercased safes address in URL (#631) * Return checksummed addrress from `safeParamAddressFromState` selector * Update `yarn.lock` * Remove redundant `toChecksumAddress` call Co-authored-by: Mikhail Mikheev <mmvsha73@gmail.com> * Rebase master into development (#647) * v1.7.3 (#611) * Fix #597: USD value not load (#609) * Converts all the addresses to checksum values * Fix for empty address * fix the order of transactions, change updateSafe to upgradeSafe to avoid naming confusion with the updateSafe action (#610) * Fix #596: Notification when safe is already updated (#599) * Fix notification of update if the safe is already updated * Makes the notification clickable Displays the notification for owners only * Identify upgrade tx * Add red badge to Settings tab * Fixs Padding Removes the red dot if the user is not an owner Co-authored-by: Fernando <fernando.greco@gmail.com> Co-authored-by: Fernando <fernando.greco@gmail.com> Co-authored-by: Agustin Pane <agustin.pane@gmail.com> * Update package.json (#612) * Add public url to prod webpack config (#615) * add public url to prod webpack config * modify travis/webpack config to add public url * add slash * cherry pick new travis yml merge commit (#620) * V1.7.5 release (#641) * use hash history * update package json * BUG: App index.html cached on production (#642) * remove caching for webapp index.html * keep --delete flag * Fix #596: Notification when safe is already updated (#599) * Fix notification of update if the safe is already updated * Makes the notification clickable Displays the notification for owners only * Identify upgrade tx * Add red badge to Settings tab * Fixs Padding Removes the red dot if the user is not an owner Co-authored-by: Fernando <fernando.greco@gmail.com> * Bug: #482 - Address book Custom transactions Recipient validation (#577) * (fix) text input bottom border * Fix #482 input * Merge branch 'development' of https://github.com/gnosis/safe-react into fix/#482-address-book # Conflicts: # src/components/forms/TextField/index.jsx # src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/index.jsx # src/routes/safe/components/Balances/SendModal/screens/SendFunds/TokenSelectField/index.jsx # src/routes/safe/components/Balances/SendModal/screens/SendFunds/index.jsx # yarn.lock * Fix custom tx addresses filtering * Merge branch 'development' of https://github.com/gnosis/safe-react into fix/#482-address-book # Conflicts: # yarn.lock * Remove console logs Fixed prettier issues * Remove unnecessary template string * Fix `tokenAddress` string conversion * Use `secondaryBackground` value Co-authored-by: Gabriel Rodríguez Alsina <gabitoesmiapodo@users.noreply.github.com> Co-authored-by: Fernando <fernando.greco@gmail.com> * (feature) Adding origin for Apps Transactions (#576) * Adding origin field when creates a TX * refactor: replace list of arg by object in getApprovalTransaction and getExecutionTransaction function * minor changes * Allow execute if threshold is 1 for the first tx - Related to issue #563 - `lastTx` is required due to #489 * - Normalizing logic between createTransaction and processTransaction - Moving shared function to a new file * Refactor `doesTxNeedApproval` back to the `isExecution`-related meaning * Rename function and variable names * Add tests for `getNewTxNonce` and `shouldExecuteTransaction` functions * Pass `safeInstance` instead of `safeAddress` to `getNewTxNonce` * Update Tests - remove mocked `getGnosisSafeInstanceAt` - pass `safeInstance` instead of `safeAddress` to `getNewTxNonce` Co-authored-by: Fernando <fernando.greco@gmail.com> * (Feature) Add checks into CI (#594) * Repare new dev and staging enviroments to deploy (#618) * Repare new dev and staging enviroments to deploy - Add to `deploy_pull_requests.sh` to the new path. - Replace upload-dir to deploy staging to the new path. * add /app/ public path for the webapp, remove duplicate yarn build from travis * add basename to app * deploy pr to /app * update travis * linter error fixes * fix travis build script Co-authored-by: David Albela Pérez <3659067+davidalbela@users.noreply.github.com> * (fix) sidebar contents' scrolling (#622) * (add) linter sorting rules (#614) * (add) linter sorting rules * (fix) linting errors according to the new rules Co-authored-by: Fernando <fernando.greco@gmail.com> * (feature): [Safe Apps] App Transaction List Details (#601) * Adding IconText component * Get origin for TXs in Redux * Adding Icon and name app to transaction list * Fix customTx condition * Fix HTML element for text * simplify condition * Bug: Accounts/Network are not updated in production build (#625) * Adding Apps info to toast notification (#621) * Adding APP_Name for APPs TXs in toast messages * refactor: save appId instead of appName in origin field * adding fallback icon and message to TX apps table * review changes * review fixes * force build * update Apps list info (#629) * update Apps list info * fix * Feature: replace web3connect with onboardjs (#456) * init onboard.js * dep bump * initial replacement of web3connect with onboard.js * use averta font in the modal * update onboard.js, add handlers for session murder * update preferred wallets * implement reconnecting to injected provider * fix duplicate wallet disconnected notification * update onboard dep * onboardjs fixes * test onboard js with hw * add https to rpcUrl * Added saved wallet and transactions validation * made Transactions validation * bnc-onboard version updated * Fix lock/unlock problem * bump onboardjs version * fixed material-ui lab version * Update onboard version * Added hw wallets integration * Updated preferred wallets * Add ledger modal * Merge with dev * Update onboard * BUmp new version of onboardjs * Added some logs * Added some logs * Update onboardjs version fix ledger connection * Update onboardjs version fix ledger connection * Bump new onboardjs version * Update new version * Made improvements * yarn.lock regenration * remove https=true * Remove comments and added some improvements * Updated package.json dep * Removed unused deps * Remove web3connect dep Co-authored-by: lukasschor <lukas.schor@gnosis.pm> Co-authored-by: Mati Dastugue <matiasdastugue@gmail.com> * Passing ethBalance to Apps component (#636) * (Fix) Update safe modal verbiage (#633) * Fixs verbiage in update safe modal * Fixs yarn lock * Bump dependencies (#639) * Use hash history (#638) * v1.7.3 (#611) * Fix #597: USD value not load (#609) * Converts all the addresses to checksum values * Fix for empty address * fix the order of transactions, change updateSafe to upgradeSafe to avoid naming confusion with the updateSafe action (#610) * Fix #596: Notification when safe is already updated (#599) * Fix notification of update if the safe is already updated * Makes the notification clickable Displays the notification for owners only * Identify upgrade tx * Add red badge to Settings tab * Fixs Padding Removes the red dot if the user is not an owner Co-authored-by: Fernando <fernando.greco@gmail.com> Co-authored-by: Fernando <fernando.greco@gmail.com> Co-authored-by: Agustin Pane <agustin.pane@gmail.com> * Update package.json (#612) * Add public url to prod webpack config (#615) * add public url to prod webpack config * modify travis/webpack config to add public url * add slash * cherry pick new travis yml merge commit (#620) * use hash history Co-authored-by: Fernando <fernando.greco@gmail.com> Co-authored-by: Agustin Pane <agustin.pane@gmail.com> * - Updates how the transactions are ordered, now orders by nonce and then by date (#640) * (Fix) Lowercased safes address in URL (#631) * Return checksummed addrress from `safeParamAddressFromState` selector * Update `yarn.lock` * Remove redundant `toChecksumAddress` call Co-authored-by: Mikhail Mikheev <mmvsha73@gmail.com> Co-authored-by: Mikhail Mikheev <mmvsha73@gmail.com> Co-authored-by: Agustin Pane <agustin.pane@gmail.com> Co-authored-by: Gabriel Rodríguez Alsina <gabitoesmiapodo@users.noreply.github.com> Co-authored-by: nicolas <nicosampler@users.noreply.github.com> Co-authored-by: David Albela Pérez <3659067+davidalbela@users.noreply.github.com> Co-authored-by: lukasschor <lukas.schor@gnosis.pm> Co-authored-by: Mati Dastugue <matiasdastugue@gmail.com> Co-authored-by: francovenica <francovenica@gmail.com> * Update safe relay and transaction endpoints * Master into development (#655) * Fix NODE_ENV development definition - Define develop build for development branches. - Use POSIX standard to call shell scripts in travis file. * Mark travis shell scripts as executable * Fix conditional statement at travis build.sh file * Set development endpoints to stable staging backends * Sync master dev (#656) * v1.7.3 (#611) * Fix #597: USD value not load (#609) * Converts all the addresses to checksum values * Fix for empty address * fix the order of transactions, change updateSafe to upgradeSafe to avoid naming confusion with the updateSafe action (#610) * Fix #596: Notification when safe is already updated (#599) * Fix notification of update if the safe is already updated * Makes the notification clickable Displays the notification for owners only * Identify upgrade tx * Add red badge to Settings tab * Fixs Padding Removes the red dot if the user is not an owner Co-authored-by: Fernando <fernando.greco@gmail.com> Co-authored-by: Fernando <fernando.greco@gmail.com> Co-authored-by: Agustin Pane <agustin.pane@gmail.com> * Update package.json (#612) * Add public url to prod webpack config (#615) * add public url to prod webpack config * modify travis/webpack config to add public url * add slash * cherry pick new travis yml merge commit (#620) * V1.7.5 release (#641) * use hash history * update package json * BUG: App index.html cached on production (#642) * remove caching for webapp index.html * keep --delete flag Co-authored-by: Mikhail Mikheev <mmvsha73@gmail.com> Co-authored-by: Fernando <fernando.greco@gmail.com> Co-authored-by: Agustin Pane <agustin.pane@gmail.com> Co-authored-by: Agustin Pane <agustin.pane@gmail.com> Co-authored-by: Mikhail Mikheev <mmvsha73@gmail.com> Co-authored-by: Gabriel Rodríguez Alsina <gabitoesmiapodo@users.noreply.github.com> Co-authored-by: nicolas <nicosampler@users.noreply.github.com> Co-authored-by: David Albela Pérez <3659067+davidalbela@users.noreply.github.com> Co-authored-by: lukasschor <lukas.schor@gnosis.pm> Co-authored-by: Mati Dastugue <matiasdastugue@gmail.com> Co-authored-by: francovenica <francovenica@gmail.com> Co-authored-by: Richard Meissner <rmeissner@users.noreply.github.com>
This commit is contained in:
parent
d3bac2f8bb
commit
3193cdc2b4
22
.eslintrc
22
.eslintrc
|
@ -8,7 +8,7 @@
|
|||
"import/extensions": [".js", ".jsx"]
|
||||
},
|
||||
"parser": "babel-eslint",
|
||||
"plugins": ["react", "flowtype", "import", "jsx-a11y", "prettier"],
|
||||
"plugins": ["react", "flowtype", "import", "jsx-a11y", "sort-destructure-keys", "prettier"],
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:react/recommended",
|
||||
|
@ -52,6 +52,12 @@
|
|||
}
|
||||
],
|
||||
"semi": ["error", "never"],
|
||||
"sort-imports": [
|
||||
"error",
|
||||
{
|
||||
"ignoreDeclarationSort": true
|
||||
}
|
||||
],
|
||||
"flowtype/require-valid-file-annotation": [
|
||||
2,
|
||||
"always",
|
||||
|
@ -62,6 +68,16 @@
|
|||
"import/extensions": 0,
|
||||
"import/no-extraneous-dependencies": 0,
|
||||
"import/no-unresolved": 0,
|
||||
"import/order": [
|
||||
"error",
|
||||
{
|
||||
"groups": ["builtin", "external", "parent", "sibling", "index"],
|
||||
"newlines-between": "always",
|
||||
"alphabetize": {
|
||||
"order": "asc"
|
||||
}
|
||||
}
|
||||
],
|
||||
"import/prefer-default-export": 0,
|
||||
"jsx-a11y/anchor-is-valid": [
|
||||
"error",
|
||||
|
@ -88,7 +104,9 @@
|
|||
}
|
||||
],
|
||||
"react/jsx-props-no-spreading": 0,
|
||||
"react/jsx-sort-props": 2,
|
||||
"prettier/prettier": "error",
|
||||
"jsx-a11y/no-autofocus": "warn"
|
||||
"jsx-a11y/no-autofocus": "warn",
|
||||
"sort-destructure-keys/sort-destructure-keys": 2
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,6 +69,6 @@ deploy:
|
|||
on:
|
||||
tags: true
|
||||
- provider: script
|
||||
script: bash config/travis/prepare_production_deployment.sh
|
||||
script: ./config/travis/prepare_production_deployment.sh
|
||||
on:
|
||||
tags: true
|
||||
tags: true
|
||||
|
|
118
package.json
118
package.json
|
@ -43,24 +43,20 @@
|
|||
"dependencies": {
|
||||
"@gnosis.pm/safe-contracts": "1.1.1-dev.1",
|
||||
"@gnosis.pm/util-contracts": "2.0.6",
|
||||
"@material-ui/core": "4.8.0",
|
||||
"@material-ui/icons": "4.5.1",
|
||||
"@material-ui/core": "4.9.5",
|
||||
"@material-ui/icons": "4.9.1",
|
||||
"@material-ui/lab": "4.0.0-alpha.39",
|
||||
"@portis/web3": "^2.0.0-beta.45",
|
||||
"@testing-library/jest-dom": "4.2.4",
|
||||
"@toruslabs/torus-embed": "0.2.10",
|
||||
"@walletconnect/web3-provider": "^1.0.0-beta.37",
|
||||
"@welldone-software/why-did-you-render": "3.4.1",
|
||||
"authereum": "^0.0.4-beta.83",
|
||||
"axios": "0.19.0",
|
||||
"@testing-library/jest-dom": "5.1.1",
|
||||
"@welldone-software/why-did-you-render": "4.0.5",
|
||||
"axios": "0.19.2",
|
||||
"bignumber.js": "9.0.0",
|
||||
"connected-react-router": "6.6.1",
|
||||
"bnc-onboard": "1.3.3",
|
||||
"connected-react-router": "6.7.0",
|
||||
"currency-flags": "^2.1.1",
|
||||
"date-fns": "2.8.1",
|
||||
"date-fns": "2.10.0",
|
||||
"dotenv": "^8.2.0",
|
||||
"ethereum-ens": "0.8.0",
|
||||
"final-form": "4.18.6",
|
||||
"fortmatic": "^1.0.1",
|
||||
"final-form": "4.18.7",
|
||||
"history": "4.10.1",
|
||||
"immortal-db": "^1.0.2",
|
||||
"immutable": "^4.0.0-rc.9",
|
||||
|
@ -71,65 +67,64 @@
|
|||
"optimize-css-assets-webpack-plugin": "5.0.3",
|
||||
"polished": "^3.4.2",
|
||||
"qrcode.react": "1.0.0",
|
||||
"query-string": "6.9.0",
|
||||
"react": "16.12.0",
|
||||
"query-string": "6.11.1",
|
||||
"react": "16.13.0",
|
||||
"react-dev-utils": "^10.0.0",
|
||||
"react-dom": "16.12.0",
|
||||
"react-final-form": "6.3.3",
|
||||
"react-dom": "16.13.0",
|
||||
"react-final-form": "6.3.5",
|
||||
"react-final-form-listeners": "^1.0.2",
|
||||
"react-ga": "^2.7.0",
|
||||
"react-hot-loader": "4.12.18",
|
||||
"react-hot-loader": "4.12.19",
|
||||
"react-qr-reader": "^2.2.1",
|
||||
"react-redux": "7.1.3",
|
||||
"react-redux": "7.2.0",
|
||||
"react-router-dom": "5.1.2",
|
||||
"react-window": "^1.8.5",
|
||||
"recompose": "^0.30.0",
|
||||
"redux": "4.0.4",
|
||||
"redux": "4.0.5",
|
||||
"redux-actions": "^2.6.5",
|
||||
"redux-thunk": "^2.3.0",
|
||||
"reselect": "^4.0.0",
|
||||
"semver": "^7.1.1",
|
||||
"styled-components": "^5.0.1",
|
||||
"web3": "1.2.4",
|
||||
"web3connect": "1.0.0-beta.25"
|
||||
"web3": "1.2.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "7.7.5",
|
||||
"@babel/core": "7.7.5",
|
||||
"@babel/plugin-proposal-class-properties": "7.7.4",
|
||||
"@babel/plugin-proposal-decorators": "7.7.4",
|
||||
"@babel/plugin-proposal-do-expressions": "7.7.4",
|
||||
"@babel/plugin-proposal-export-default-from": "7.7.4",
|
||||
"@babel/plugin-proposal-export-namespace-from": "7.7.4",
|
||||
"@babel/plugin-proposal-function-bind": "7.7.4",
|
||||
"@babel/plugin-proposal-function-sent": "7.7.4",
|
||||
"@babel/plugin-proposal-json-strings": "7.7.4",
|
||||
"@babel/plugin-proposal-logical-assignment-operators": "7.7.4",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator": "7.7.4",
|
||||
"@babel/plugin-proposal-numeric-separator": "7.7.4",
|
||||
"@babel/plugin-proposal-optional-chaining": "7.7.5",
|
||||
"@babel/plugin-proposal-pipeline-operator": "7.7.4",
|
||||
"@babel/plugin-proposal-throw-expressions": "7.7.4",
|
||||
"@babel/plugin-syntax-dynamic-import": "7.7.4",
|
||||
"@babel/plugin-syntax-import-meta": "7.7.4",
|
||||
"@babel/plugin-transform-member-expression-literals": "7.7.4",
|
||||
"@babel/plugin-transform-property-literals": "7.7.4",
|
||||
"@babel/polyfill": "7.7.0",
|
||||
"@babel/preset-env": "7.7.6",
|
||||
"@babel/preset-flow": "7.7.4",
|
||||
"@babel/preset-react": "7.7.4",
|
||||
"@testing-library/react": "9.4.0",
|
||||
"autoprefixer": "9.7.3",
|
||||
"@babel/cli": "7.8.4",
|
||||
"@babel/core": "7.8.7",
|
||||
"@babel/plugin-proposal-class-properties": "7.8.3",
|
||||
"@babel/plugin-proposal-decorators": "7.8.3",
|
||||
"@babel/plugin-proposal-do-expressions": "7.8.3",
|
||||
"@babel/plugin-proposal-export-default-from": "7.8.3",
|
||||
"@babel/plugin-proposal-export-namespace-from": "7.8.3",
|
||||
"@babel/plugin-proposal-function-bind": "7.8.3",
|
||||
"@babel/plugin-proposal-function-sent": "7.8.3",
|
||||
"@babel/plugin-proposal-json-strings": "7.8.3",
|
||||
"@babel/plugin-proposal-logical-assignment-operators": "7.8.3",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator": "7.8.3",
|
||||
"@babel/plugin-proposal-numeric-separator": "7.8.3",
|
||||
"@babel/plugin-proposal-optional-chaining": "7.8.3",
|
||||
"@babel/plugin-proposal-pipeline-operator": "7.8.3",
|
||||
"@babel/plugin-proposal-throw-expressions": "7.8.3",
|
||||
"@babel/plugin-syntax-dynamic-import": "7.8.3",
|
||||
"@babel/plugin-syntax-import-meta": "7.8.3",
|
||||
"@babel/plugin-transform-member-expression-literals": "7.8.3",
|
||||
"@babel/plugin-transform-property-literals": "7.8.3",
|
||||
"@babel/polyfill": "7.8.7",
|
||||
"@babel/preset-env": "7.8.7",
|
||||
"@babel/preset-flow": "7.8.3",
|
||||
"@babel/preset-react": "7.8.3",
|
||||
"@testing-library/react": "9.5.0",
|
||||
"autoprefixer": "9.7.4",
|
||||
"babel-core": "^7.0.0-bridge.0",
|
||||
"babel-eslint": "10.0.3",
|
||||
"babel-jest": "24.9.0",
|
||||
"babel-eslint": "10.1.0",
|
||||
"babel-jest": "25.1.0",
|
||||
"babel-loader": "8.0.6",
|
||||
"babel-plugin-dynamic-import-node": "^2.3.0",
|
||||
"babel-plugin-transform-es3-member-expression-literals": "^6.22.0",
|
||||
"babel-plugin-transform-es3-property-literals": "^6.22.0",
|
||||
"babel-polyfill": "^6.26.0",
|
||||
"classnames": "^2.2.6",
|
||||
"css-loader": "3.4.0",
|
||||
"css-loader": "3.4.2",
|
||||
"detect-port": "^1.3.0",
|
||||
"dotenv-expand": "^5.1.0",
|
||||
"eslint": "^6.8.0",
|
||||
|
@ -139,33 +134,34 @@
|
|||
"eslint-plugin-jsx-a11y": "^6.2.3",
|
||||
"eslint-plugin-prettier": "^3.1.2",
|
||||
"eslint-plugin-react": "^7.18.3",
|
||||
"eslint-plugin-sort-destructure-keys": "^1.3.3",
|
||||
"ethereumjs-abi": "0.6.8",
|
||||
"extract-text-webpack-plugin": "^4.0.0-beta.0",
|
||||
"file-loader": "5.0.2",
|
||||
"flow-bin": "0.114.0",
|
||||
"file-loader": "5.1.0",
|
||||
"flow-bin": "0.120.1",
|
||||
"fs-extra": "8.1.0",
|
||||
"html-loader": "^0.5.5",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"husky": "^4.2.2",
|
||||
"jest": "24.9.0",
|
||||
"jest": "25.1.0",
|
||||
"jest-dom": "4.0.0",
|
||||
"json-loader": "^0.5.7",
|
||||
"mini-css-extract-plugin": "0.8.1",
|
||||
"mini-css-extract-plugin": "0.9.0",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"postcss-mixins": "6.2.3",
|
||||
"postcss-simple-vars": "^5.0.2",
|
||||
"prettier": "^1.19.1",
|
||||
"run-with-testrpc": "0.3.1",
|
||||
"style-loader": "1.0.2",
|
||||
"terser-webpack-plugin": "2.3.1",
|
||||
"truffle": "5.1.4",
|
||||
"style-loader": "1.1.3",
|
||||
"terser-webpack-plugin": "2.3.5",
|
||||
"truffle": "5.1.16",
|
||||
"truffle-contract": "4.0.31",
|
||||
"truffle-solidity-loader": "0.1.32",
|
||||
"url-loader": "3.0.0",
|
||||
"webpack": "4.41.3",
|
||||
"webpack": "4.42.0",
|
||||
"webpack-bundle-analyzer": "3.6.0",
|
||||
"webpack-cli": "3.3.10",
|
||||
"webpack-dev-server": "3.9.0",
|
||||
"webpack-cli": "3.3.11",
|
||||
"webpack-dev-server": "3.10.3",
|
||||
"webpack-manifest-plugin": "2.2.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import Hairline from '~/components/layout/Hairline'
|
||||
import { sm, md } from '~/theme/variables'
|
||||
import ArrowDown from './arrow-down.svg'
|
||||
|
||||
import Hairline from '~/components/layout/Hairline'
|
||||
import { md, sm } from '~/theme/variables'
|
||||
|
||||
const Wrapper = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
@ -22,7 +23,7 @@ type Props = {
|
|||
|
||||
const DividerLine = ({ withArrow }: Props) => (
|
||||
<Wrapper>
|
||||
{withArrow && <img src={ArrowDown} alt="Arrow Down" />}
|
||||
{withArrow && <img alt="Arrow Down" src={ArrowDown} />}
|
||||
<Hairline />
|
||||
</Wrapper>
|
||||
)
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
// @flow
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
|
||||
const Wrapper = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
`
|
||||
const Icon = styled.img`
|
||||
max-width: 15px;
|
||||
max-height: 15px;
|
||||
margin-right: 5px;
|
||||
`
|
||||
const Text = styled.span`
|
||||
height: 17px;
|
||||
`
|
||||
|
||||
const IconText = ({ iconUrl, text }: { iconUrl: string, text: string }) => (
|
||||
<Wrapper>
|
||||
<Icon alt={text} src={iconUrl} />
|
||||
<Text>{text}</Text>
|
||||
</Wrapper>
|
||||
)
|
||||
|
||||
export default IconText
|
|
@ -1,3 +1,4 @@
|
|||
// @flow
|
||||
export { default as DividerLine } from './DividerLine'
|
||||
export { default as TextBox } from './TextBox'
|
||||
export { default as IconText } from './IconText'
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// @flow
|
||||
import React from 'react'
|
||||
import CircularProgress from '@material-ui/core/CircularProgress'
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
|
||||
const Wrapper = styled.div`
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
// @flow
|
||||
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import cn from 'classnames'
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import cn from 'classnames'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
|
||||
// TODO: move these styles to a generic place
|
||||
import styles from './style'
|
||||
|
@ -34,17 +34,17 @@ type Props = {
|
|||
classes: Object,
|
||||
}
|
||||
|
||||
const List = ({ items, activeItem, onItemClick, classes }: Props) => {
|
||||
const List = ({ activeItem, classes, items, onItemClick }: Props) => {
|
||||
return (
|
||||
<Wrapper>
|
||||
{items.map(i => (
|
||||
<Item
|
||||
key={i.id}
|
||||
className={cn(classes.menuOption, activeItem === i.id && classes.active)}
|
||||
key={i.id}
|
||||
onClick={() => onItemClick(i.id)}
|
||||
>
|
||||
<div className="container">
|
||||
{i.iconUrl && <IconImg src={i.iconUrl} alt={i.name} />}
|
||||
{i.iconUrl && <IconImg alt={i.name} src={i.iconUrl} />}
|
||||
<span>{i.name}</span>
|
||||
</div>
|
||||
</Item>
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
// @flow
|
||||
import {
|
||||
xs,
|
||||
sm,
|
||||
md,
|
||||
border,
|
||||
secondary,
|
||||
bolderFont,
|
||||
background,
|
||||
largeFontSize,
|
||||
bolderFont,
|
||||
border,
|
||||
fontColor,
|
||||
largeFontSize,
|
||||
md,
|
||||
screenSm,
|
||||
secondary,
|
||||
sm,
|
||||
xs,
|
||||
} from '~/theme/variables'
|
||||
|
||||
const styles = () => ({
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import EtherscanBtn from '~/components/EtherscanBtn'
|
||||
import CopyBtn from '~/components/CopyBtn'
|
||||
import EtherscanBtn from '~/components/EtherscanBtn'
|
||||
import Identicon from '~/components/Identicon'
|
||||
import Bold from '~/components/layout/Bold'
|
||||
import { xs, border } from '~/theme/variables'
|
||||
import Block from '~/components/layout/Block'
|
||||
import Bold from '~/components/layout/Bold'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import { border, xs } from '~/theme/variables'
|
||||
|
||||
const Wrapper = styled.div`
|
||||
display: flex;
|
||||
|
@ -43,7 +43,7 @@ type Props = {
|
|||
ethBalance: string,
|
||||
}
|
||||
|
||||
const AddressInfo = ({ safeName, safeAddress, ethBalance }: Props) => {
|
||||
const AddressInfo = ({ ethBalance, safeAddress, safeName }: Props) => {
|
||||
return (
|
||||
<Wrapper>
|
||||
<div className="icon-section">
|
||||
|
@ -51,12 +51,12 @@ const AddressInfo = ({ safeName, safeAddress, ethBalance }: Props) => {
|
|||
</div>
|
||||
<div className="data-section">
|
||||
{safeName && (
|
||||
<Paragraph weight="bolder" noMargin>
|
||||
<Paragraph noMargin weight="bolder">
|
||||
{safeName}
|
||||
</Paragraph>
|
||||
)}
|
||||
<div className="address">
|
||||
<Paragraph weight="bolder" noMargin>
|
||||
<Paragraph noMargin weight="bolder">
|
||||
{safeAddress}
|
||||
</Paragraph>
|
||||
<CopyBtn content={safeAddress} />
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// @flow
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import CollapseMUI from '@material-ui/core/Collapse'
|
||||
import IconButton from '@material-ui/core/IconButton'
|
||||
import ExpandLess from '@material-ui/icons/ExpandLess'
|
||||
import ExpandMore from '@material-ui/icons/ExpandMore'
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
|
||||
const Wrapper = styled.div``
|
||||
|
||||
|
@ -21,7 +21,7 @@ type Props = {
|
|||
description: React.Node,
|
||||
}
|
||||
|
||||
const Collapse = ({ title, description, children }: Props) => {
|
||||
const Collapse = ({ children, description, title }: Props) => {
|
||||
const [open, setOpen] = React.useState(false)
|
||||
|
||||
const handleClick = () => {
|
||||
|
@ -32,7 +32,7 @@ const Collapse = ({ title, description, children }: Props) => {
|
|||
<Wrapper>
|
||||
<Title>{title}</Title>
|
||||
<Header>
|
||||
<IconButton disableRipple size="small" onClick={handleClick}>
|
||||
<IconButton disableRipple onClick={handleClick} size="small">
|
||||
{open ? <ExpandLess /> : <ExpandMore />}
|
||||
</IconButton>
|
||||
{description}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
// @flow
|
||||
import IconButton from '@material-ui/core/IconButton'
|
||||
import { createStyles, makeStyles } from '@material-ui/core/styles'
|
||||
import Close from '@material-ui/icons/Close'
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import Close from '@material-ui/icons/Close'
|
||||
import { makeStyles, createStyles } from '@material-ui/core/styles'
|
||||
import IconButton from '@material-ui/core/IconButton'
|
||||
|
||||
import Modal from '~/components/Modal'
|
||||
import Hairline from '~/components/layout/Hairline'
|
||||
|
@ -45,14 +45,14 @@ type Props = {
|
|||
onClose: () => void,
|
||||
}
|
||||
|
||||
const GenericModal = ({ title, body, footer, onClose }: Props) => {
|
||||
const GenericModal = ({ body, footer, onClose, title }: Props) => {
|
||||
const classes = useStyles()
|
||||
|
||||
return (
|
||||
<Modal title="GenericModal" description="GenericModal" handleClose={onClose} paperClassName={classes.paper} open>
|
||||
<Modal description="GenericModal" handleClose={onClose} open paperClassName={classes.paper} title="GenericModal">
|
||||
<TitleSection>
|
||||
{title}
|
||||
<IconButton onClick={onClose} disableRipple>
|
||||
<IconButton disableRipple onClick={onClose}>
|
||||
<StyledClose />
|
||||
</IconButton>
|
||||
</TitleSection>
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import Button from '~/components/layout/Button'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import { lg } from '~/theme/variables'
|
||||
|
||||
const StyledParagraph = styled(Paragraph)`
|
||||
|
@ -20,11 +20,11 @@ const TitleWrapper = styled.div`
|
|||
align-items: center;
|
||||
`
|
||||
|
||||
export const ModalTitle = ({ title, iconUrl }: { title: string, iconUrl: string }) => {
|
||||
export const ModalTitle = ({ iconUrl, title }: { title: string, iconUrl: string }) => {
|
||||
return (
|
||||
<TitleWrapper>
|
||||
{iconUrl && <IconImg src={iconUrl} alt={title} />}
|
||||
<StyledParagraph weight="bolder" noMargin>
|
||||
{iconUrl && <IconImg alt={title} src={iconUrl} />}
|
||||
<StyledParagraph noMargin weight="bolder">
|
||||
{title}
|
||||
</StyledParagraph>
|
||||
</TitleWrapper>
|
||||
|
@ -37,10 +37,10 @@ const FooterWrapper = styled.div`
|
|||
`
|
||||
|
||||
export const ModalFooterConfirmation = ({
|
||||
okText,
|
||||
cancelText,
|
||||
handleOk,
|
||||
handleCancel,
|
||||
handleOk,
|
||||
okText,
|
||||
}: {
|
||||
okText: string,
|
||||
cancelText: string,
|
||||
|
|
|
@ -1,68 +1,99 @@
|
|||
// @flow
|
||||
import Onboard from 'bnc-onboard'
|
||||
import React from 'react'
|
||||
import Web3Connect from 'web3connect'
|
||||
import Torus from '@toruslabs/torus-embed'
|
||||
import WalletConnectProvider from '@walletconnect/web3-provider'
|
||||
import Fortmatic from 'fortmatic'
|
||||
import Portis from '@portis/web3'
|
||||
import Authereum from 'authereum'
|
||||
|
||||
import Button from '~/components/layout/Button'
|
||||
import { fetchProvider, removeProvider } from '~/logic/wallets/store/actions'
|
||||
import { getNetwork } from '~/config'
|
||||
import { getNetworkId } from '~/config'
|
||||
import { getWeb3, setWeb3 } from '~/logic/wallets/getWeb3'
|
||||
import { fetchProvider } from '~/logic/wallets/store/actions'
|
||||
import transactionDataCheck from '~/logic/wallets/transactionDataCheck'
|
||||
import { store } from '~/store'
|
||||
|
||||
const isMainnet = process.env.REACT_APP_NETWORK === 'mainnet'
|
||||
|
||||
const BLOCKNATIVE_API_KEY = isMainnet ? process.env.REACT_APP_BLOCKNATIVE_KEY : '7fbb9cee-7e97-4436-8770-8b29a9a8814c'
|
||||
const PORTIS_DAPP_ID = isMainnet ? process.env.REACT_APP_PORTIS_ID : '852b763d-f28b-4463-80cb-846d7ec5806b'
|
||||
// const SQUARELINK_CLIENT_ID = isMainnet ? process.env.REACT_APP_SQUARELINK_ID : '46ce08fe50913cfa1b78'
|
||||
const FORTMATIC_API_KEY = isMainnet ? process.env.REACT_APP_FORTMATIC_KEY : 'pk_test_CAD437AA29BE0A40'
|
||||
|
||||
export const web3Connect = new Web3Connect.Core({
|
||||
network: getNetwork().toLowerCase(),
|
||||
providerOptions: {
|
||||
walletconnect: {
|
||||
package: WalletConnectProvider,
|
||||
options: {
|
||||
infuraId: process.env.REACT_APP_INFURA_TOKEN,
|
||||
},
|
||||
const wallets = [
|
||||
{ walletName: 'metamask', preferred: true },
|
||||
{
|
||||
walletName: 'walletConnect',
|
||||
preferred: true,
|
||||
infuraKey: process.env.REACT_APP_INFURA_TOKEN,
|
||||
},
|
||||
{
|
||||
walletName: 'trezor',
|
||||
appUrl: 'gnosis-safe.io',
|
||||
preferred: true,
|
||||
email: 'safe@gnosis.io',
|
||||
rpcUrl: 'https://rinkeby.infura.io/v3/b42c928da8fd4c1f90374b18aa9ac6ba',
|
||||
},
|
||||
{
|
||||
walletName: 'ledger',
|
||||
preferred: true,
|
||||
rpcUrl: 'https://rinkeby.infura.io/v3/b42c928da8fd4c1f90374b18aa9ac6ba',
|
||||
},
|
||||
{ walletName: 'trust', preferred: true },
|
||||
{ walletName: 'dapper' },
|
||||
{
|
||||
walletName: 'fortmatic',
|
||||
apiKey: FORTMATIC_API_KEY,
|
||||
},
|
||||
{
|
||||
walletName: 'portis',
|
||||
apiKey: PORTIS_DAPP_ID,
|
||||
label: 'Login with Email',
|
||||
},
|
||||
{ walletName: 'authereum' },
|
||||
{ walletName: 'coinbase' },
|
||||
{ walletName: 'opera' },
|
||||
{ walletName: 'operaTouch' },
|
||||
]
|
||||
|
||||
let lastUsedAddress = ''
|
||||
let providerName
|
||||
|
||||
export const onboard = new Onboard({
|
||||
dappId: BLOCKNATIVE_API_KEY,
|
||||
networkId: getNetworkId(),
|
||||
subscriptions: {
|
||||
wallet: wallet => {
|
||||
if (wallet.provider) {
|
||||
// this function will intialize web3 and store it somewhere available throughout the dapp and
|
||||
// can also instantiate your contracts with the web3 instance
|
||||
setWeb3(wallet.provider)
|
||||
providerName = wallet.name
|
||||
}
|
||||
},
|
||||
portis: {
|
||||
package: Portis,
|
||||
options: {
|
||||
id: PORTIS_DAPP_ID,
|
||||
},
|
||||
},
|
||||
fortmatic: {
|
||||
package: Fortmatic,
|
||||
options: {
|
||||
key: FORTMATIC_API_KEY,
|
||||
},
|
||||
},
|
||||
torus: {
|
||||
package: Torus,
|
||||
options: {
|
||||
enableLogging: false,
|
||||
buttonPosition: 'bottom-left',
|
||||
buildEnv: process.env.NODE_ENV,
|
||||
showTorusButton: true,
|
||||
},
|
||||
},
|
||||
authereum: {
|
||||
package: Authereum,
|
||||
options: {},
|
||||
address: address => {
|
||||
if (!lastUsedAddress && address) {
|
||||
lastUsedAddress = address
|
||||
store.dispatch(fetchProvider(providerName))
|
||||
}
|
||||
|
||||
// we don't have an unsubscribe event so we rely on this
|
||||
if (!address && lastUsedAddress) {
|
||||
lastUsedAddress = ''
|
||||
providerName = undefined
|
||||
}
|
||||
},
|
||||
},
|
||||
walletSelect: {
|
||||
wallets,
|
||||
},
|
||||
walletCheck: [{ checkName: 'connect' }, transactionDataCheck(), { checkName: 'network' }, { checkName: 'accounts' }],
|
||||
})
|
||||
|
||||
web3Connect.on('connect', (provider: any) => {
|
||||
if (provider) {
|
||||
store.dispatch(fetchProvider(provider))
|
||||
}
|
||||
})
|
||||
|
||||
web3Connect.on('disconnect', () => {
|
||||
store.dispatch(removeProvider())
|
||||
})
|
||||
export const onboardUser = async () => {
|
||||
// before calling walletSelect you want to check if web3 has been instantiated
|
||||
// which indicates that a wallet has already been selected
|
||||
// and web3 has been instantiated with that provider
|
||||
const web3 = getWeb3()
|
||||
const walletSelected = web3 ? true : await onboard.walletSelect()
|
||||
return walletSelected && onboard.walletCheck()
|
||||
}
|
||||
|
||||
type Props = {
|
||||
enqueueSnackbar: Function,
|
||||
|
@ -72,11 +103,12 @@ type Props = {
|
|||
const ConnectButton = (props: Props) => (
|
||||
<Button
|
||||
color="primary"
|
||||
variant="contained"
|
||||
minWidth={140}
|
||||
onClick={() => {
|
||||
web3Connect.toggleModal()
|
||||
onClick={async () => {
|
||||
await onboard.walletSelect()
|
||||
await onboard.walletCheck()
|
||||
}}
|
||||
variant="contained"
|
||||
{...props}
|
||||
>
|
||||
Connect
|
||||
|
|
|
@ -1,20 +1,21 @@
|
|||
// @flow
|
||||
import Checkbox from '@material-ui/core/Checkbox'
|
||||
import FormControlLabel from '@material-ui/core/FormControlLabel'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { makeStyles } from '@material-ui/core/styles'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import cn from 'classnames'
|
||||
import Link from '~/components/layout/Link'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
|
||||
import Button from '~/components/layout/Button'
|
||||
import { primary, mainFontFamily, md, screenSm } from '~/theme/variables'
|
||||
import Link from '~/components/layout/Link'
|
||||
import type { CookiesProps } from '~/logic/cookies/model/cookie'
|
||||
import { COOKIES_KEY } from '~/logic/cookies/model/cookie'
|
||||
import { loadFromCookie, saveCookie } from '~/logic/cookies/utils'
|
||||
import { cookieBannerOpen } from '~/logic/cookies/store/selectors'
|
||||
import { openCookieBanner } from '~/logic/cookies/store/actions/openCookieBanner'
|
||||
import { loadIntercom } from '~/utils/intercom'
|
||||
import { cookieBannerOpen } from '~/logic/cookies/store/selectors'
|
||||
import { loadFromCookie, saveCookie } from '~/logic/cookies/utils'
|
||||
import { mainFontFamily, md, primary, screenSm } from '~/theme/variables'
|
||||
import { loadGoogleAnalytics } from '~/utils/googleAnalytics'
|
||||
import { loadIntercom } from '~/utils/intercom'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
container: {
|
||||
|
@ -96,7 +97,7 @@ const CookiesBanner = () => {
|
|||
async function fetchCookiesFromStorage() {
|
||||
const cookiesState: ?CookiesProps = await loadFromCookie(COOKIES_KEY)
|
||||
if (cookiesState) {
|
||||
const { acceptedNecessary, acceptedAnalytics } = cookiesState
|
||||
const { acceptedAnalytics, acceptedNecessary } = cookiesState
|
||||
setLocalAnalytics(acceptedAnalytics)
|
||||
setLocalNecessary(acceptedNecessary)
|
||||
const openBanner = acceptedNecessary === false || showBanner
|
||||
|
@ -133,11 +134,11 @@ const CookiesBanner = () => {
|
|||
const cookieBannerContent = (
|
||||
<div className={classes.container}>
|
||||
<span
|
||||
role="button"
|
||||
tabIndex="0"
|
||||
className={cn(classes.acceptPreferences, classes.text)}
|
||||
onClick={closeCookiesBannerHandler}
|
||||
onKeyDown={closeCookiesBannerHandler}
|
||||
className={cn(classes.acceptPreferences, classes.text)}
|
||||
role="button"
|
||||
tabIndex="0"
|
||||
>
|
||||
Accept preferences >
|
||||
</span>
|
||||
|
@ -154,21 +155,21 @@ const CookiesBanner = () => {
|
|||
<div className={classes.formItem}>
|
||||
<FormControlLabel
|
||||
checked={localNecessary}
|
||||
control={<Checkbox disabled />}
|
||||
disabled
|
||||
label="Necessary"
|
||||
name="Necessary"
|
||||
onChange={() => setLocalNecessary(prev => !prev)}
|
||||
value={localNecessary}
|
||||
control={<Checkbox disabled />}
|
||||
/>
|
||||
</div>
|
||||
<div className={classes.formItem}>
|
||||
<FormControlLabel
|
||||
control={<Checkbox checked={localAnalytics} />}
|
||||
label="Analytics"
|
||||
name="Analytics"
|
||||
onChange={() => setLocalAnalytics(prev => !prev)}
|
||||
value={localAnalytics}
|
||||
control={<Checkbox checked={localAnalytics} />}
|
||||
/>
|
||||
</div>
|
||||
<div className={classes.formItem}>
|
||||
|
@ -176,8 +177,8 @@ const CookiesBanner = () => {
|
|||
color="primary"
|
||||
component={Link}
|
||||
minWidth={180}
|
||||
variant="outlined"
|
||||
onClick={() => acceptCookiesHandler()}
|
||||
variant="outlined"
|
||||
>
|
||||
Accept All
|
||||
</Button>
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
// @flow
|
||||
import React, { useState } from 'react'
|
||||
import Tooltip from '@material-ui/core/Tooltip'
|
||||
import { makeStyles } from '@material-ui/core/styles'
|
||||
import cn from 'classnames'
|
||||
import Img from '~/components/layout/Img'
|
||||
import { copyToClipboard } from '~/utils/clipboard'
|
||||
import { xs } from '~/theme/variables'
|
||||
import React, { useState } from 'react'
|
||||
|
||||
import CopyIcon from './copy.svg'
|
||||
|
||||
import Img from '~/components/layout/Img'
|
||||
import { xs } from '~/theme/variables'
|
||||
import { copyToClipboard } from '~/utils/clipboard'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
container: {
|
||||
display: 'flex',
|
||||
|
@ -39,8 +41,7 @@ const CopyBtn = ({ className, content, increaseZindex = false }: CopyBtnProps) =
|
|||
|
||||
return (
|
||||
<Tooltip
|
||||
title={clicked ? 'Copied' : 'Copy to clipboard'}
|
||||
placement="top"
|
||||
classes={customClasses}
|
||||
onClose={() => {
|
||||
// this is fired before tooltip is closed
|
||||
// added setTimeout so the user doesn't see the text changing/jumping
|
||||
|
@ -50,17 +51,18 @@ const CopyBtn = ({ className, content, increaseZindex = false }: CopyBtnProps) =
|
|||
}
|
||||
}, 300)
|
||||
}}
|
||||
classes={customClasses}
|
||||
placement="top"
|
||||
title={clicked ? 'Copied' : 'Copy to clipboard'}
|
||||
>
|
||||
<div className={cn(classes.container, className)}>
|
||||
<Img
|
||||
src={CopyIcon}
|
||||
height={20}
|
||||
alt="Copy to clipboard"
|
||||
height={20}
|
||||
onClick={() => {
|
||||
copyToClipboard(content)
|
||||
setClicked(true)
|
||||
}}
|
||||
src={CopyIcon}
|
||||
/>
|
||||
</div>
|
||||
</Tooltip>
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
// @flow
|
||||
import React from 'react'
|
||||
import Tooltip from '@material-ui/core/Tooltip'
|
||||
import { makeStyles } from '@material-ui/core/styles'
|
||||
import cn from 'classnames'
|
||||
import Img from '~/components/layout/Img'
|
||||
import React from 'react'
|
||||
|
||||
import EtherscanOpenIcon from './img/etherscan-open.svg'
|
||||
|
||||
import Img from '~/components/layout/Img'
|
||||
import { getEtherScanLink } from '~/logic/wallets/getWeb3'
|
||||
import { xs } from '~/theme/variables'
|
||||
|
||||
|
@ -33,12 +35,12 @@ type EtherscanBtnProps = {
|
|||
value: string,
|
||||
}
|
||||
|
||||
const EtherscanBtn = ({ type, value, className, increaseZindex = false }: EtherscanBtnProps) => {
|
||||
const EtherscanBtn = ({ className, increaseZindex = false, type, value }: EtherscanBtnProps) => {
|
||||
const classes = useStyles()
|
||||
const customClasses = increaseZindex ? { popper: classes.increasedPopperZindex } : {}
|
||||
|
||||
return (
|
||||
<Tooltip title="Show details on Etherscan" placement="top" classes={customClasses}>
|
||||
<Tooltip classes={customClasses} placement="top" title="Show details on Etherscan">
|
||||
<a
|
||||
aria-label="Show details on Etherscan"
|
||||
className={cn(classes.container, className)}
|
||||
|
@ -46,7 +48,7 @@ const EtherscanBtn = ({ type, value, className, increaseZindex = false }: Ethers
|
|||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<Img src={EtherscanOpenIcon} height={20} alt="Show on Etherscan" />
|
||||
<Img alt="Show on Etherscan" height={20} src={EtherscanOpenIcon} />
|
||||
</a>
|
||||
</Tooltip>
|
||||
)
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
// @flow
|
||||
import React from 'react'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import cn from 'classnames'
|
||||
import Block from '~/components/layout/Block'
|
||||
import React from 'react'
|
||||
|
||||
import { styles } from './style.js'
|
||||
|
||||
import CopyBtn from '~/components/CopyBtn'
|
||||
import EtherscanBtn from '~/components/EtherscanBtn'
|
||||
import { shortVersionOf } from '~/logic/wallets/ethAddresses'
|
||||
import { styles } from './style.js'
|
||||
import EllipsisTransactionDetails from '~/routes/safe/components/AddressBook/EllipsisTransactionDetails'
|
||||
import Block from '~/components/layout/Block'
|
||||
import Span from '~/components/layout/Span'
|
||||
import { shortVersionOf } from '~/logic/wallets/ethAddresses'
|
||||
import EllipsisTransactionDetails from '~/routes/safe/components/AddressBook/EllipsisTransactionDetails'
|
||||
|
||||
type EtherscanLinkProps = {
|
||||
classes: Object,
|
||||
|
@ -18,14 +20,14 @@ type EtherscanLinkProps = {
|
|||
value: string,
|
||||
}
|
||||
|
||||
const EtherscanLink = ({ type, value, cut, classes, knownAddress }: EtherscanLinkProps) => (
|
||||
const EtherscanLink = ({ classes, cut, knownAddress, type, value }: EtherscanLinkProps) => (
|
||||
<Block className={classes.etherscanLink}>
|
||||
<Span className={cn(knownAddress && classes.addressParagraph, classes.address)} size="md">
|
||||
{cut ? shortVersionOf(value, cut) : value}
|
||||
</Span>
|
||||
<CopyBtn className={cn(classes.button, classes.firstButton)} content={value} />
|
||||
<EtherscanBtn className={classes.button} type={type} value={value} />
|
||||
{knownAddress !== undefined ? <EllipsisTransactionDetails knownAddress={knownAddress} address={value} /> : null}
|
||||
{knownAddress !== undefined ? <EllipsisTransactionDetails address={value} knownAddress={knownAddress} /> : null}
|
||||
</Block>
|
||||
)
|
||||
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import { makeStyles } from '@material-ui/core/styles'
|
||||
import { useDispatch } from 'react-redux'
|
||||
import cn from 'classnames'
|
||||
import Link from '~/components/layout/Link'
|
||||
import { secondary, screenSm, sm } from '~/theme/variables'
|
||||
import { openCookieBanner } from '~/logic/cookies/store/actions/openCookieBanner'
|
||||
import * as React from 'react'
|
||||
import { useDispatch } from 'react-redux'
|
||||
|
||||
import GnoButtonLink from '~/components/layout/ButtonLink'
|
||||
import Link from '~/components/layout/Link'
|
||||
import { openCookieBanner } from '~/logic/cookies/store/actions/openCookieBanner'
|
||||
import { screenSm, secondary, sm } from '~/theme/variables'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
footer: {
|
||||
|
@ -57,23 +58,23 @@ const Footer = () => {
|
|||
<footer className={classes.footer}>
|
||||
<span className={classes.item}>©{date.getFullYear()} Gnosis</span>
|
||||
<span className={classes.sep}>|</span>
|
||||
<Link className={cn(classes.item, classes.link)} to="https://safe.gnosis.io/terms" target="_blank">
|
||||
<Link className={cn(classes.item, classes.link)} target="_blank" to="https://safe.gnosis.io/terms">
|
||||
Terms
|
||||
</Link>
|
||||
<span className={classes.sep}>|</span>
|
||||
<Link className={cn(classes.item, classes.link)} to="https://safe.gnosis.io/privacy" target="_blank">
|
||||
<Link className={cn(classes.item, classes.link)} target="_blank" to="https://safe.gnosis.io/privacy">
|
||||
Privacy
|
||||
</Link>
|
||||
<span className={classes.sep}>|</span>
|
||||
<Link className={cn(classes.item, classes.link)} to="https://safe.gnosis.io/licenses" target="_blank">
|
||||
<Link className={cn(classes.item, classes.link)} target="_blank" to="https://safe.gnosis.io/licenses">
|
||||
Licenses
|
||||
</Link>
|
||||
<span className={classes.sep}>|</span>
|
||||
<Link className={cn(classes.item, classes.link)} to="https://safe.gnosis.io/imprint" target="_blank">
|
||||
<Link className={cn(classes.item, classes.link)} target="_blank" to="https://safe.gnosis.io/imprint">
|
||||
Imprint
|
||||
</Link>
|
||||
<span className={classes.sep}>|</span>
|
||||
<Link className={cn(classes.item, classes.link)} to="https://safe.gnosis.io/cookie" target="_blank">
|
||||
<Link className={cn(classes.item, classes.link)} target="_blank" to="https://safe.gnosis.io/cookie">
|
||||
Cookie Policy
|
||||
</Link>
|
||||
<span className={classes.sep}>-</span>
|
||||
|
@ -83,8 +84,8 @@ const Footer = () => {
|
|||
<span className={classes.sep}>|</span>
|
||||
<Link
|
||||
className={cn(classes.item, classes.link)}
|
||||
to="https://github.com/gnosis/safe-react/releases"
|
||||
target="_blank"
|
||||
to="https://github.com/gnosis/safe-react/releases"
|
||||
>
|
||||
{appVersion}
|
||||
</Link>
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import Dot from '@material-ui/icons/FiberManualRecord'
|
||||
import * as React from 'react'
|
||||
|
||||
import Block from '~/components/layout/Block'
|
||||
import Img from '~/components/layout/Img'
|
||||
import { fancy, border, warning, screenSm } from '~/theme/variables'
|
||||
import { border, fancy, screenSm, warning } from '~/theme/variables'
|
||||
|
||||
const key = require('../assets/key.svg')
|
||||
const triangle = require('../assets/triangle.svg')
|
||||
|
@ -64,15 +65,15 @@ const buildDotStyleFrom = (size: number, top: number, right: number, mode: Mode)
|
|||
})
|
||||
|
||||
const KeyRing = ({
|
||||
classes,
|
||||
center = false,
|
||||
circleSize,
|
||||
keySize,
|
||||
classes,
|
||||
dotRight,
|
||||
dotSize,
|
||||
dotTop,
|
||||
dotRight,
|
||||
mode,
|
||||
center = false,
|
||||
hideDot = false,
|
||||
keySize,
|
||||
mode,
|
||||
}: Props) => {
|
||||
const keyStyle = buildKeyStyleFrom(circleSize, center, dotSize)
|
||||
const dotStyle = buildDotStyleFrom(dotSize, dotTop, dotRight, mode)
|
||||
|
@ -84,11 +85,11 @@ const KeyRing = ({
|
|||
<Block className={classes.root}>
|
||||
<Block className={classes.key} style={keyStyle}>
|
||||
<Img
|
||||
src={img}
|
||||
height={keySize}
|
||||
width={isWarning ? keySize + 2 : keySize}
|
||||
alt="Status connection"
|
||||
className={isWarning ? classes.warning : undefined}
|
||||
height={keySize}
|
||||
src={img}
|
||||
width={isWarning ? keySize + 2 : keySize}
|
||||
/>
|
||||
</Block>
|
||||
{!hideDot && <Dot className={classes.dot} style={dotStyle} />}
|
||||
|
|
|
@ -1,21 +1,23 @@
|
|||
// @flow
|
||||
import ClickAwayListener from '@material-ui/core/ClickAwayListener'
|
||||
import Grow from '@material-ui/core/Grow'
|
||||
import List from '@material-ui/core/List'
|
||||
import Popper from '@material-ui/core/Popper'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import * as React from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import Grow from '@material-ui/core/Grow'
|
||||
import ClickAwayListener from '@material-ui/core/ClickAwayListener'
|
||||
import Popper from '@material-ui/core/Popper'
|
||||
import List from '@material-ui/core/List'
|
||||
import Divider from '~/components/layout/Divider'
|
||||
|
||||
import NetworkLabel from './NetworkLabel'
|
||||
import Provider from './Provider'
|
||||
import SafeListHeader from './SafeListHeader'
|
||||
|
||||
import Spacer from '~/components/Spacer'
|
||||
import openHoc, { type Open } from '~/components/hoc/OpenHoc'
|
||||
import Col from '~/components/layout/Col'
|
||||
import Divider from '~/components/layout/Divider'
|
||||
import Img from '~/components/layout/Img'
|
||||
import Row from '~/components/layout/Row'
|
||||
import Spacer from '~/components/Spacer'
|
||||
import { border, sm, md, headerHeight, screenSm } from '~/theme/variables'
|
||||
import Provider from './Provider'
|
||||
import NetworkLabel from './NetworkLabel'
|
||||
import SafeListHeader from './SafeListHeader'
|
||||
import { border, headerHeight, md, screenSm, sm } from '~/theme/variables'
|
||||
|
||||
const logo = require('../assets/gnosis-safe-multisig-logo.svg')
|
||||
|
||||
|
@ -62,11 +64,11 @@ const styles = () => ({
|
|||
},
|
||||
})
|
||||
|
||||
const Layout = openHoc(({ open, toggle, clickAway, classes, providerInfo, providerDetails }: Props) => (
|
||||
const Layout = openHoc(({ classes, clickAway, open, providerDetails, providerInfo, toggle }: Props) => (
|
||||
<Row className={classes.summary}>
|
||||
<Col start="xs" middle="xs" className={classes.logo}>
|
||||
<Col className={classes.logo} middle="xs" start="xs">
|
||||
<Link to="/">
|
||||
<Img src={logo} height={32} alt="Gnosis Team Safe" />
|
||||
<Img alt="Gnosis Team Safe" height={32} src={logo} />
|
||||
</Link>
|
||||
</Col>
|
||||
<Divider />
|
||||
|
@ -74,7 +76,7 @@ const Layout = openHoc(({ open, toggle, clickAway, classes, providerInfo, provid
|
|||
<Divider />
|
||||
<NetworkLabel />
|
||||
<Spacer />
|
||||
<Provider open={open} toggle={toggle} info={providerInfo}>
|
||||
<Provider info={providerInfo} open={open} toggle={toggle}>
|
||||
{providerRef => (
|
||||
<Popper
|
||||
anchorEl={providerRef.current}
|
||||
|
@ -86,7 +88,7 @@ const Layout = openHoc(({ open, toggle, clickAway, classes, providerInfo, provid
|
|||
{({ TransitionProps }) => (
|
||||
<Grow {...TransitionProps}>
|
||||
<>
|
||||
<ClickAwayListener onClickAway={clickAway} mouseEvent="onClick" touchEvent={false}>
|
||||
<ClickAwayListener mouseEvent="onClick" onClickAway={clickAway} touchEvent={false}>
|
||||
<List className={classes.root} component="div">
|
||||
{providerDetails}
|
||||
</List>
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import { makeStyles } from '@material-ui/core/styles'
|
||||
import { getNetwork } from '~/config'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import * as React from 'react'
|
||||
|
||||
import Col from '~/components/layout/Col'
|
||||
import { xs, sm, md, border, screenSm } from '~/theme/variables'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import { getNetwork } from '~/config'
|
||||
import { border, md, screenSm, sm, xs } from '~/theme/variables'
|
||||
|
||||
const network = getNetwork()
|
||||
const formattedNetwork = network[0].toUpperCase() + network.substring(1).toLowerCase()
|
||||
|
@ -35,8 +36,8 @@ const EarlyAccessLabel = () => {
|
|||
const classes = useStyles()
|
||||
|
||||
return (
|
||||
<Col start="xs" middle="xs" className={classes.container}>
|
||||
<Paragraph size="xs" className={classes.text}>
|
||||
<Col className={classes.container} middle="xs" start="xs">
|
||||
<Paragraph className={classes.text} size="xs">
|
||||
{formattedNetwork}
|
||||
</Paragraph>
|
||||
</Col>
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import IconButton from '@material-ui/core/IconButton'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import ExpandLess from '@material-ui/icons/ExpandLess'
|
||||
import ExpandMore from '@material-ui/icons/ExpandMore'
|
||||
import * as React from 'react'
|
||||
|
||||
import { type Open } from '~/components/hoc/OpenHoc'
|
||||
import Col from '~/components/layout/Col'
|
||||
import Divider from '~/components/layout/Divider'
|
||||
import { type Open } from '~/components/hoc/OpenHoc'
|
||||
import { sm, md, screenSm } from '~/theme/variables'
|
||||
import { md, screenSm, sm } from '~/theme/variables'
|
||||
|
||||
type Props = Open & {
|
||||
classes: Object,
|
||||
|
@ -56,15 +57,15 @@ class Provider extends React.Component<Props> {
|
|||
}
|
||||
|
||||
render() {
|
||||
const { open, toggle, children, classes, info } = this.props
|
||||
const { children, classes, info, open, toggle } = this.props
|
||||
|
||||
return (
|
||||
<>
|
||||
<div ref={this.myRef} className={classes.root}>
|
||||
<div className={classes.root} ref={this.myRef}>
|
||||
<Divider />
|
||||
<Col end="sm" middle="xs" className={classes.provider} onClick={toggle}>
|
||||
<Col className={classes.provider} end="sm" middle="xs" onClick={toggle}>
|
||||
{info}
|
||||
<IconButton disableRipple className={classes.expand}>
|
||||
<IconButton className={classes.expand} disableRipple>
|
||||
{open ? <ExpandLess /> : <ExpandMore />}
|
||||
</IconButton>
|
||||
</Col>
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import * as React from 'react'
|
||||
|
||||
import ConnectButton from '~/components/ConnectButton'
|
||||
import Row from '~/components/layout/Row'
|
||||
import Block from '~/components/layout/Block'
|
||||
import { md, lg } from '~/theme/variables'
|
||||
import CircleDot from '~/components/Header/components/CircleDot'
|
||||
import Block from '~/components/layout/Block'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import Row from '~/components/layout/Row'
|
||||
import { lg, md } from '~/theme/variables'
|
||||
|
||||
type Props = {
|
||||
classes: Object,
|
||||
|
@ -39,14 +40,14 @@ const styles = () => ({
|
|||
const ConnectDetails = ({ classes }: Props) => (
|
||||
<>
|
||||
<div className={classes.container}>
|
||||
<Row margin="lg" align="center">
|
||||
<Paragraph className={classes.text} size="lg" noMargin weight="bolder">
|
||||
<Row align="center" margin="lg">
|
||||
<Paragraph className={classes.text} noMargin size="lg" weight="bolder">
|
||||
Connect a Wallet
|
||||
</Paragraph>
|
||||
</Row>
|
||||
</div>
|
||||
<Row className={classes.logo} margin="lg">
|
||||
<CircleDot keySize={32} circleSize={75} dotSize={25} dotTop={50} dotRight={25} center mode="error" />
|
||||
<CircleDot center circleSize={75} dotRight={25} dotSize={25} dotTop={50} keySize={32} mode="error" />
|
||||
</Row>
|
||||
<Block className={classes.connect}>
|
||||
<ConnectButton />
|
||||
|
|
|
@ -1,25 +1,26 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import classNames from 'classnames'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import Dot from '@material-ui/icons/FiberManualRecord'
|
||||
import EtherscanBtn from '~/components/EtherscanBtn'
|
||||
import classNames from 'classnames'
|
||||
import * as React from 'react'
|
||||
|
||||
import CopyBtn from '~/components/CopyBtn'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import Button from '~/components/layout/Button'
|
||||
import EtherscanBtn from '~/components/EtherscanBtn'
|
||||
import CircleDot from '~/components/Header/components/CircleDot'
|
||||
import Identicon from '~/components/Identicon'
|
||||
import Spacer from '~/components/Spacer'
|
||||
import Block from '~/components/layout/Block'
|
||||
import Button from '~/components/layout/Button'
|
||||
import Hairline from '~/components/layout/Hairline'
|
||||
import Img from '~/components/layout/Img'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import Row from '~/components/layout/Row'
|
||||
import Block from '~/components/layout/Block'
|
||||
import Spacer from '~/components/Spacer'
|
||||
import { xs, sm, md, lg, background, warning, connected as connectedBg } from '~/theme/variables'
|
||||
import { upperFirst } from '~/utils/css'
|
||||
import { shortVersionOf } from '~/logic/wallets/ethAddresses'
|
||||
import CircleDot from '~/components/Header/components/CircleDot'
|
||||
import { background, connected as connectedBg, lg, md, sm, warning, xs } from '~/theme/variables'
|
||||
import { upperFirst } from '~/utils/css'
|
||||
|
||||
const walletIcon = require('../../assets/wallet.svg')
|
||||
const dot = require('../../assets/dotRinkeby.svg')
|
||||
const walletIcon = require('../../assets/wallet.svg')
|
||||
|
||||
type Props = {
|
||||
provider: string,
|
||||
|
@ -91,7 +92,7 @@ const styles = () => ({
|
|||
},
|
||||
})
|
||||
|
||||
const UserDetails = ({ provider, connected, network, userAddress, classes, onDisconnect }: Props) => {
|
||||
const UserDetails = ({ classes, connected, network, onDisconnect, provider, userAddress }: Props) => {
|
||||
const status = connected ? 'Connected' : 'Connection error'
|
||||
const address = userAddress ? shortVersionOf(userAddress, 4) : 'Address not available'
|
||||
const identiconAddress = userAddress || 'random'
|
||||
|
@ -100,62 +101,62 @@ const UserDetails = ({ provider, connected, network, userAddress, classes, onDis
|
|||
return (
|
||||
<>
|
||||
<Block className={classes.container}>
|
||||
<Row className={classes.identicon} margin="md" align="center">
|
||||
<Row align="center" className={classes.identicon} margin="md">
|
||||
{connected ? (
|
||||
<Identicon address={identiconAddress} diameter={60} />
|
||||
) : (
|
||||
<CircleDot keySize={30} circleSize={75} dotSize={25} dotTop={50} dotRight={25} mode="warning" hideDot />
|
||||
<CircleDot circleSize={75} dotRight={25} dotSize={25} dotTop={50} hideDot keySize={30} mode="warning" />
|
||||
)}
|
||||
</Row>
|
||||
<Block justify="center" className={classes.user}>
|
||||
<Paragraph className={classes.address} size="sm" noMargin>
|
||||
<Block className={classes.user} justify="center">
|
||||
<Paragraph className={classes.address} noMargin size="sm">
|
||||
{address}
|
||||
</Paragraph>
|
||||
{userAddress && (
|
||||
<>
|
||||
<CopyBtn content={userAddress} increaseZindex />
|
||||
<EtherscanBtn type="address" value={userAddress} increaseZindex />
|
||||
<EtherscanBtn increaseZindex type="address" value={userAddress} />
|
||||
</>
|
||||
)}
|
||||
</Block>
|
||||
</Block>
|
||||
<Hairline margin="xs" />
|
||||
<Row className={classes.details}>
|
||||
<Paragraph noMargin align="right" className={classes.labels}>
|
||||
<Paragraph align="right" className={classes.labels} noMargin>
|
||||
Status
|
||||
</Paragraph>
|
||||
<Spacer />
|
||||
<Dot className={classNames(classes.dot, connected ? classes.connected : classes.warning)} />
|
||||
<Paragraph noMargin align="right" color={color} weight="bolder" className={classes.labels}>
|
||||
<Paragraph align="right" className={classes.labels} color={color} noMargin weight="bolder">
|
||||
{status}
|
||||
</Paragraph>
|
||||
</Row>
|
||||
<Hairline margin="xs" />
|
||||
<Row className={classes.details}>
|
||||
<Paragraph noMargin align="right" className={classes.labels}>
|
||||
<Paragraph align="right" className={classes.labels} noMargin>
|
||||
Wallet
|
||||
</Paragraph>
|
||||
<Spacer />
|
||||
<Img className={classes.logo} src={walletIcon} height={14} alt="Wallet icon" />
|
||||
<Paragraph noMargin align="right" weight="bolder" className={classes.labels}>
|
||||
<Img alt="Wallet icon" className={classes.logo} height={14} src={walletIcon} />
|
||||
<Paragraph align="right" className={classes.labels} noMargin weight="bolder">
|
||||
{upperFirst(provider)}
|
||||
</Paragraph>
|
||||
</Row>
|
||||
<Hairline margin="xs" />
|
||||
<Row className={classes.details}>
|
||||
<Paragraph noMargin align="right" className={classes.labels}>
|
||||
<Paragraph align="right" className={classes.labels} noMargin>
|
||||
Network
|
||||
</Paragraph>
|
||||
<Spacer />
|
||||
<Img className={classes.logo} src={dot} height={14} alt="Network" />
|
||||
<Paragraph noMargin align="right" weight="bolder" className={classes.labels}>
|
||||
<Img alt="Network" className={classes.logo} height={14} src={dot} />
|
||||
<Paragraph align="right" className={classes.labels} noMargin weight="bolder">
|
||||
{upperFirst(network)}
|
||||
</Paragraph>
|
||||
</Row>
|
||||
<Hairline margin="xs" />
|
||||
<Row className={classes.disconnect}>
|
||||
<Button onClick={onDisconnect} size="medium" variant="contained" color="primary" fullWidth>
|
||||
<Paragraph className={classes.disconnectText} size="md" color="white" noMargin>
|
||||
<Button color="primary" fullWidth onClick={onDisconnect} size="medium" variant="contained">
|
||||
<Paragraph className={classes.disconnectText} color="white" noMargin size="md">
|
||||
Disconnect
|
||||
</Paragraph>
|
||||
</Button>
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import Dot from '@material-ui/icons/FiberManualRecord'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import Col from '~/components/layout/Col'
|
||||
import { screenSm, connected as connectedBg, sm } from '~/theme/variables'
|
||||
import Identicon from '~/components/Identicon'
|
||||
import { shortVersionOf } from '~/logic/wallets/ethAddresses'
|
||||
import * as React from 'react'
|
||||
|
||||
import CircleDot from '~/components/Header/components/CircleDot'
|
||||
import Identicon from '~/components/Identicon'
|
||||
import Col from '~/components/layout/Col'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import { shortVersionOf } from '~/logic/wallets/ethAddresses'
|
||||
import { connected as connectedBg, screenSm, sm } from '~/theme/variables'
|
||||
|
||||
type Props = {
|
||||
provider: string,
|
||||
|
@ -54,7 +55,7 @@ const styles = () => ({
|
|||
},
|
||||
})
|
||||
|
||||
const ProviderInfo = ({ provider, network, userAddress, connected, classes }: Props) => {
|
||||
const ProviderInfo = ({ classes, connected, network, provider, userAddress }: Props) => {
|
||||
const providerText = `${provider} [${network}]`
|
||||
const cutAddress = connected ? shortVersionOf(userAddress, 4) : 'Connection Error'
|
||||
const color = connected ? 'primary' : 'warning'
|
||||
|
@ -64,16 +65,16 @@ const ProviderInfo = ({ provider, network, userAddress, connected, classes }: Pr
|
|||
<>
|
||||
{connected && (
|
||||
<>
|
||||
<Identicon className={classes.identicon} address={identiconAddress} diameter={30} />
|
||||
<Identicon address={identiconAddress} className={classes.identicon} diameter={30} />
|
||||
<Dot className={classes.dot} />
|
||||
</>
|
||||
)}
|
||||
{!connected && <CircleDot keySize={14} circleSize={35} dotSize={16} dotTop={24} dotRight={11} mode="warning" />}
|
||||
<Col start="sm" layout="column" className={classes.account}>
|
||||
<Paragraph size="xs" transform="capitalize" className={classes.network} noMargin weight="bolder">
|
||||
{!connected && <CircleDot circleSize={35} dotRight={11} dotSize={16} dotTop={24} keySize={14} mode="warning" />}
|
||||
<Col className={classes.account} layout="column" start="sm">
|
||||
<Paragraph className={classes.network} noMargin size="xs" transform="capitalize" weight="bolder">
|
||||
{providerText}
|
||||
</Paragraph>
|
||||
<Paragraph size="xs" className={classes.address} noMargin color={color}>
|
||||
<Paragraph className={classes.address} color={color} noMargin size="xs">
|
||||
{cutAddress}
|
||||
</Paragraph>
|
||||
</Col>
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import Col from '~/components/layout/Col'
|
||||
import { type Open } from '~/components/hoc/OpenHoc'
|
||||
import { sm } from '~/theme/variables'
|
||||
import * as React from 'react'
|
||||
|
||||
import CircleDot from '~/components/Header/components/CircleDot'
|
||||
import { type Open } from '~/components/hoc/OpenHoc'
|
||||
import Col from '~/components/layout/Col'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import { sm } from '~/theme/variables'
|
||||
|
||||
type Props = Open & {
|
||||
classes: Object,
|
||||
|
@ -32,12 +33,12 @@ const styles = () => ({
|
|||
|
||||
const ProviderDisconnected = ({ classes }: Props) => (
|
||||
<>
|
||||
<CircleDot keySize={17} circleSize={35} dotSize={16} dotTop={24} dotRight={11} mode="error" />
|
||||
<Col end="sm" middle="xs" layout="column" className={classes.account}>
|
||||
<Paragraph size="sm" transform="capitalize" className={classes.network} noMargin weight="bold">
|
||||
<CircleDot circleSize={35} dotRight={11} dotSize={16} dotTop={24} keySize={17} mode="error" />
|
||||
<Col className={classes.account} end="sm" layout="column" middle="xs">
|
||||
<Paragraph className={classes.network} noMargin size="sm" transform="capitalize" weight="bold">
|
||||
Not Connected
|
||||
</Paragraph>
|
||||
<Paragraph size="sm" color="fancy" className={classes.connect} noMargin>
|
||||
<Paragraph className={classes.connect} color="fancy" noMargin size="sm">
|
||||
Connect Wallet
|
||||
</Paragraph>
|
||||
</Col>
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
// @flow
|
||||
import IconButton from '@material-ui/core/IconButton'
|
||||
import { makeStyles } from '@material-ui/core/styles'
|
||||
import ExpandLessIcon from '@material-ui/icons/ExpandLess'
|
||||
import ExpandMoreIcon from '@material-ui/icons/ExpandMore'
|
||||
import * as React from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import { makeStyles } from '@material-ui/core/styles'
|
||||
import IconButton from '@material-ui/core/IconButton'
|
||||
import ExpandMoreIcon from '@material-ui/icons/ExpandMore'
|
||||
import ExpandLessIcon from '@material-ui/icons/ExpandLess'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import Col from '~/components/layout/Col'
|
||||
import { xs, sm, md, border, screenSm } from '~/theme/variables'
|
||||
import { safesCountSelector } from '~/routes/safe/store/selectors'
|
||||
|
||||
import { SidebarContext } from '~/components/Sidebar'
|
||||
import Col from '~/components/layout/Col'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import { safesCountSelector } from '~/routes/safe/store/selectors'
|
||||
import { border, md, screenSm, sm, xs } from '~/theme/variables'
|
||||
|
||||
export const TOGGLE_SIDEBAR_BTN_TESTID = 'TOGGLE_SIDEBAR_BTN'
|
||||
|
||||
|
@ -42,19 +43,19 @@ const { useContext } = React
|
|||
|
||||
const SafeListHeader = ({ safesCount }: Props) => {
|
||||
const classes = useStyles()
|
||||
const { toggleSidebar, isOpen } = useContext(SidebarContext)
|
||||
const { isOpen, toggleSidebar } = useContext(SidebarContext)
|
||||
|
||||
return (
|
||||
<Col start="xs" middle="xs" className={classes.container}>
|
||||
<Col className={classes.container} middle="xs" start="xs">
|
||||
Safes
|
||||
<Paragraph size="xs" className={classes.counter}>
|
||||
<Paragraph className={classes.counter} size="xs">
|
||||
{safesCount}
|
||||
</Paragraph>
|
||||
<IconButton
|
||||
onClick={toggleSidebar}
|
||||
className={classes.icon}
|
||||
aria-label="Expand Safe List"
|
||||
className={classes.icon}
|
||||
data-testid={TOGGLE_SIDEBAR_BTN_TESTID}
|
||||
onClick={toggleSidebar}
|
||||
>
|
||||
{isOpen ? <ExpandLessIcon /> : <ExpandMoreIcon color="secondary" />}
|
||||
</IconButton>
|
||||
|
|
|
@ -1,19 +1,21 @@
|
|||
// @flow
|
||||
import { withSnackbar } from 'notistack'
|
||||
import * as React from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import { withSnackbar } from 'notistack'
|
||||
import { logComponentStack, type Info } from '~/utils/logBoundaries'
|
||||
|
||||
import actions, { type Actions } from './actions'
|
||||
import Layout from './components/Layout'
|
||||
import ConnectDetails from './components/ProviderDetails/ConnectDetails'
|
||||
import UserDetails from './components/ProviderDetails/UserDetails'
|
||||
import ProviderAccessible from './components/ProviderInfo/ProviderAccessible'
|
||||
import ProviderDisconnected from './components/ProviderInfo/ProviderDisconnected'
|
||||
import selector, { type SelectorProps } from './selector'
|
||||
|
||||
import { onboard } from '~/components/ConnectButton'
|
||||
import { NOTIFICATIONS, showSnackbar } from '~/logic/notifications'
|
||||
import { web3Connect } from '~/components/ConnectButton'
|
||||
import { INJECTED_PROVIDERS } from '~/logic/wallets/getWeb3'
|
||||
import { loadLastUsedProvider } from '~/logic/wallets/store/middlewares/providerWatcher'
|
||||
import ProviderAccessible from './components/ProviderInfo/ProviderAccessible'
|
||||
import UserDetails from './components/ProviderDetails/UserDetails'
|
||||
import ProviderDisconnected from './components/ProviderInfo/ProviderDisconnected'
|
||||
import ConnectDetails from './components/ProviderDetails/ConnectDetails'
|
||||
import Layout from './components/Layout'
|
||||
import actions, { type Actions } from './actions'
|
||||
import selector, { type SelectorProps } from './selector'
|
||||
import { type Info, logComponentStack } from '~/utils/logBoundaries'
|
||||
|
||||
type Props = Actions &
|
||||
SelectorProps & {
|
||||
|
@ -36,13 +38,16 @@ class HeaderComponent extends React.PureComponent<Props, State> {
|
|||
|
||||
async componentDidMount() {
|
||||
const lastUsedProvider = await loadLastUsedProvider()
|
||||
if (INJECTED_PROVIDERS.includes(lastUsedProvider) || process.env.NODE_ENV === 'test') {
|
||||
web3Connect.connectToInjected()
|
||||
if (INJECTED_PROVIDERS.includes(lastUsedProvider.toUpperCase()) || process.env.NODE_ENV === 'test') {
|
||||
const hasSelectedWallet = await onboard.walletSelect(lastUsedProvider)
|
||||
if (hasSelectedWallet) {
|
||||
await onboard.walletCheck()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
componentDidCatch(error: Error, info: Info) {
|
||||
const { enqueueSnackbar, closeSnackbar } = this.props
|
||||
const { closeSnackbar, enqueueSnackbar } = this.props
|
||||
|
||||
this.setState({ hasError: true })
|
||||
showSnackbar(NOTIFICATIONS.CONNECT_WALLET_ERROR_MSG, enqueueSnackbar, closeSnackbar)
|
||||
|
@ -51,25 +56,25 @@ class HeaderComponent extends React.PureComponent<Props, State> {
|
|||
}
|
||||
|
||||
onDisconnect = () => {
|
||||
const { removeProvider, enqueueSnackbar, closeSnackbar } = this.props
|
||||
const { closeSnackbar, enqueueSnackbar, removeProvider } = this.props
|
||||
|
||||
removeProvider(enqueueSnackbar, closeSnackbar)
|
||||
}
|
||||
|
||||
getProviderInfoBased = () => {
|
||||
const { hasError } = this.state
|
||||
const { loaded, available, provider, network, userAddress } = this.props
|
||||
const { available, loaded, network, provider, userAddress } = this.props
|
||||
|
||||
if (hasError || !loaded) {
|
||||
return <ProviderDisconnected />
|
||||
}
|
||||
|
||||
return <ProviderAccessible provider={provider} network={network} userAddress={userAddress} connected={available} />
|
||||
return <ProviderAccessible connected={available} network={network} provider={provider} userAddress={userAddress} />
|
||||
}
|
||||
|
||||
getProviderDetailsBased = () => {
|
||||
const { hasError } = this.state
|
||||
const { loaded, available, provider, network, userAddress } = this.props
|
||||
const { available, loaded, network, provider, userAddress } = this.props
|
||||
|
||||
if (hasError || !loaded) {
|
||||
return <ConnectDetails />
|
||||
|
@ -90,7 +95,7 @@ class HeaderComponent extends React.PureComponent<Props, State> {
|
|||
const info = this.getProviderInfoBased()
|
||||
const details = this.getProviderDetailsBased()
|
||||
|
||||
return <Layout providerInfo={info} providerDetails={details} />
|
||||
return <Layout providerDetails={details} providerInfo={info} />
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
// @flow
|
||||
import { createStructuredSelector } from 'reselect'
|
||||
|
||||
import {
|
||||
providerNameSelector,
|
||||
userAccountSelector,
|
||||
networkSelector,
|
||||
availableSelector,
|
||||
loadedSelector,
|
||||
networkSelector,
|
||||
providerNameSelector,
|
||||
userAccountSelector,
|
||||
} from '~/logic/wallets/store/selectors'
|
||||
|
||||
export type SelectorProps = {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
|
||||
import { toDataUrl } from './blockies'
|
||||
|
||||
type Props = {
|
||||
|
@ -63,9 +64,9 @@ export default class Identicon extends React.PureComponent<Props> {
|
|||
}
|
||||
|
||||
render() {
|
||||
const { diameter, className } = this.props
|
||||
const { className, diameter } = this.props
|
||||
const style = this.getStyleFrom(diameter)
|
||||
|
||||
return <div className={className} style={style} ref={this.identicon} />
|
||||
return <div className={className} ref={this.identicon} style={style} />
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import MuiListItemText from '@material-ui/core/ListItemText'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import * as React from 'react'
|
||||
|
||||
import { type WithStyles } from '~/theme/mui'
|
||||
|
||||
type Props = WithStyles & {
|
||||
|
@ -20,7 +21,7 @@ const styles = {
|
|||
|
||||
class ListItemText extends React.PureComponent<Props> {
|
||||
render() {
|
||||
const { primary, secondary, classes, cut = false } = this.props
|
||||
const { classes, cut = false, primary, secondary } = this.props
|
||||
|
||||
const cutStyle = cut
|
||||
? {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import CircularProgress from '@material-ui/core/CircularProgress'
|
||||
import * as React from 'react'
|
||||
|
||||
import Page from '~/components/layout/Page'
|
||||
|
||||
const centerStyle = {
|
||||
|
@ -9,7 +10,7 @@ const centerStyle = {
|
|||
|
||||
const Loader = () => (
|
||||
<Page align="center">
|
||||
<CircularProgress style={centerStyle} size={60} />
|
||||
<CircularProgress size={60} style={centerStyle} />
|
||||
</Page>
|
||||
)
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import cn from 'classnames'
|
||||
import Modal from '@material-ui/core/Modal'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import cn from 'classnames'
|
||||
import * as React from 'react'
|
||||
|
||||
import { sm } from '~/theme/variables'
|
||||
|
||||
type Props = {
|
||||
|
@ -40,21 +41,21 @@ const styles = () => ({
|
|||
})
|
||||
|
||||
const GnoModal = ({
|
||||
title,
|
||||
description,
|
||||
open,
|
||||
children,
|
||||
classes,
|
||||
description,
|
||||
handleClose,
|
||||
modalClassName,
|
||||
classes,
|
||||
open,
|
||||
paperClassName,
|
||||
title,
|
||||
}: Props) => (
|
||||
<Modal
|
||||
aria-labelledby={title}
|
||||
aria-describedby={description}
|
||||
open={open}
|
||||
onClose={handleClose}
|
||||
aria-labelledby={title}
|
||||
className={cn(classes.root, modalClassName)}
|
||||
onClose={handleClose}
|
||||
open={open}
|
||||
>
|
||||
<div className={cn(classes.paper, paperClassName)}>{children}</div>
|
||||
</Modal>
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
|
||||
import Bold from '~/components/layout/Bold'
|
||||
import Col from '~/components/layout/Col'
|
||||
import Row from '~/components/layout/Row'
|
||||
import Paragraph from '~/components/layout/Paragraph/index'
|
||||
import Row from '~/components/layout/Row'
|
||||
import { CreateSafe } from '~/routes/welcome/components/Layout'
|
||||
|
||||
type Props = {
|
||||
|
@ -11,14 +12,14 @@ type Props = {
|
|||
provider: string,
|
||||
}
|
||||
|
||||
const NoSafe = ({ text, provider }: Props) => (
|
||||
const NoSafe = ({ provider, text }: Props) => (
|
||||
<Row>
|
||||
<Col xs={12} center="xs" sm={10} smOffset={2} start="sm" margin="md">
|
||||
<Col center="xs" margin="md" sm={10} smOffset={2} start="sm" xs={12}>
|
||||
<Paragraph size="lg">
|
||||
<Bold>{text}</Bold>
|
||||
</Paragraph>
|
||||
</Col>
|
||||
<Col xs={12} center="xs" sm={10} smOffset={2} start="sm" margin="md">
|
||||
<Col center="xs" margin="md" sm={10} smOffset={2} start="sm" xs={12}>
|
||||
<CreateSafe provider={provider} />
|
||||
</Col>
|
||||
</Row>
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
// @flow
|
||||
import { Component } from 'react'
|
||||
import { List } from 'immutable'
|
||||
import { connect } from 'react-redux'
|
||||
import { withSnackbar } from 'notistack'
|
||||
import { type Notification } from '~/logic/notifications/store/models/notification'
|
||||
import { Component } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
import actions, { type Actions } from './actions'
|
||||
import selector from './selector'
|
||||
|
||||
import { type Notification } from '~/logic/notifications/store/models/notification'
|
||||
|
||||
type Props = Actions & {
|
||||
notifications: List<Notification>,
|
||||
closeSnackbar: Function,
|
||||
|
@ -17,7 +19,7 @@ class Notifier extends Component<Props> {
|
|||
displayed = []
|
||||
|
||||
shouldComponentUpdate({ notifications: newSnacks = List() }) {
|
||||
const { notifications: currentSnacks, closeSnackbar, removeSnackbar } = this.props
|
||||
const { closeSnackbar, notifications: currentSnacks, removeSnackbar } = this.props
|
||||
|
||||
if (!newSnacks.size) {
|
||||
this.displayed = []
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
import { createStructuredSelector } from 'reselect'
|
||||
|
||||
import { notificationsListSelector } from '~/logic/notifications/store/selectors'
|
||||
|
||||
export default createStructuredSelector<Object, *>({
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
/* Onboard.js custom styles */
|
||||
|
||||
:global(.bn-onboard-custom.bn-onboard-modal) {
|
||||
font-family: "Averta";
|
||||
z-index: 2001;
|
||||
}
|
|
@ -2,17 +2,20 @@
|
|||
import 'babel-polyfill'
|
||||
|
||||
import { MuiThemeProvider } from '@material-ui/core/styles'
|
||||
import React, { Suspense } from 'react'
|
||||
import { Provider } from 'react-redux'
|
||||
import { ConnectedRouter } from 'connected-react-router'
|
||||
import React, { Suspense } from 'react'
|
||||
import { hot } from 'react-hot-loader/root'
|
||||
import PageFrame from '../layout/PageFrame'
|
||||
import { Provider } from 'react-redux'
|
||||
|
||||
import Loader from '../Loader'
|
||||
import PageFrame from '../layout/PageFrame'
|
||||
|
||||
import AppRoutes from '~/routes'
|
||||
import { history, store } from '~/store'
|
||||
import theme from '~/theme/mui'
|
||||
import AppRoutes from '~/routes'
|
||||
|
||||
import './index.scss'
|
||||
import './OnboardCustom.scss'
|
||||
|
||||
const Root = () => (
|
||||
<Provider store={store}>
|
||||
|
|
|
@ -42,4 +42,4 @@ body {
|
|||
body > div:first-child {
|
||||
display: flex;
|
||||
min-height: 100%;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,21 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import QrReader from 'react-qr-reader'
|
||||
import CircularProgress from '@material-ui/core/CircularProgress'
|
||||
import IconButton from '@material-ui/core/IconButton'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import Close from '@material-ui/icons/Close'
|
||||
import IconButton from '@material-ui/core/IconButton'
|
||||
import CircularProgress from '@material-ui/core/CircularProgress'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import Button from '~/components/layout/Button'
|
||||
import Block from '~/components/layout/Block'
|
||||
import Row from '~/components/layout/Row'
|
||||
import Hairline from '~/components/layout/Hairline'
|
||||
import Col from '~/components/layout/Col'
|
||||
import Modal from '~/components/Modal'
|
||||
import { checkWebcam } from './utils'
|
||||
import * as React from 'react'
|
||||
import QrReader from 'react-qr-reader'
|
||||
|
||||
import { styles } from './style'
|
||||
import { checkWebcam } from './utils'
|
||||
|
||||
import Modal from '~/components/Modal'
|
||||
import Block from '~/components/layout/Block'
|
||||
import Button from '~/components/layout/Button'
|
||||
import Col from '~/components/layout/Col'
|
||||
import Hairline from '~/components/layout/Hairline'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import Row from '~/components/layout/Row'
|
||||
|
||||
const { useEffect, useState } = React
|
||||
|
||||
|
@ -24,7 +26,7 @@ type Props = {
|
|||
isOpen: boolean,
|
||||
}
|
||||
|
||||
const ScanQRModal = ({ classes, onClose, isOpen, onScan }: Props) => {
|
||||
const ScanQRModal = ({ classes, isOpen, onClose, onScan }: Props) => {
|
||||
const [hasWebcam, setHasWebcam] = useState(null)
|
||||
const scannerRef: Object = React.createRef()
|
||||
const openImageDialog = () => {
|
||||
|
@ -52,43 +54,43 @@ const ScanQRModal = ({ classes, onClose, isOpen, onScan }: Props) => {
|
|||
}, [hasWebcam])
|
||||
|
||||
return (
|
||||
<Modal title="Receive Tokens" description="Receive Tokens Form" handleClose={onClose} open={isOpen}>
|
||||
<Row align="center" grow className={classes.heading}>
|
||||
<Paragraph size="xl" noMargin>
|
||||
<Modal description="Receive Tokens Form" handleClose={onClose} open={isOpen} title="Receive Tokens">
|
||||
<Row align="center" className={classes.heading} grow>
|
||||
<Paragraph noMargin size="xl">
|
||||
Scan QR
|
||||
</Paragraph>
|
||||
<IconButton onClick={onClose} disableRipple>
|
||||
<IconButton disableRipple onClick={onClose}>
|
||||
<Close className={classes.close} />
|
||||
</IconButton>
|
||||
</Row>
|
||||
<Hairline />
|
||||
<Col layout="column" middle="xs" className={classes.detailsContainer}>
|
||||
<Col className={classes.detailsContainer} layout="column" middle="xs">
|
||||
{hasWebcam === null ? (
|
||||
<Block justify="center" className={classes.loaderContainer}>
|
||||
<Block className={classes.loaderContainer} justify="center">
|
||||
<CircularProgress />
|
||||
</Block>
|
||||
) : (
|
||||
<QrReader
|
||||
ref={scannerRef}
|
||||
legacyMode={!hasWebcam}
|
||||
onScan={data => {
|
||||
if (data) onScan(data)
|
||||
}}
|
||||
onError={err => {
|
||||
console.error(err)
|
||||
}}
|
||||
onScan={data => {
|
||||
if (data) onScan(data)
|
||||
}}
|
||||
ref={scannerRef}
|
||||
style={{ width: '400px', height: '400px' }}
|
||||
/>
|
||||
)}
|
||||
</Col>
|
||||
<Hairline />
|
||||
<Row align="center" className={classes.buttonRow}>
|
||||
<Button color="secondary" className={classes.button} minWidth={154} onClick={onClose}>
|
||||
<Button className={classes.button} color="secondary" minWidth={154} onClick={onClose}>
|
||||
Close
|
||||
</Button>
|
||||
<Button
|
||||
color="primary"
|
||||
className={classes.button}
|
||||
color="primary"
|
||||
minWidth={154}
|
||||
onClick={() => {
|
||||
if (hasWebcam) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// @flow
|
||||
import { lg, sm, background, secondaryText } from '~/theme/variables'
|
||||
import { background, lg, secondaryText, sm } from '~/theme/variables'
|
||||
|
||||
export const styles = () => ({
|
||||
heading: {
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import { makeStyles } from '@material-ui/core/styles'
|
||||
import Img from '~/components/layout/Img'
|
||||
import Block from '~/components/layout/Block'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import { primary, secondaryBackground, md } from '~/theme/variables'
|
||||
import * as React from 'react'
|
||||
|
||||
import HomeIcon from '~/assets/icons/shape.svg'
|
||||
import Block from '~/components/layout/Block'
|
||||
import Img from '~/components/layout/Img'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import { md, primary, secondaryBackground } from '~/theme/variables'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
container: {
|
||||
|
@ -27,9 +28,9 @@ const DefaultBadge = () => {
|
|||
const classes = useStyles()
|
||||
|
||||
return (
|
||||
<Block justify="left" className={classes.container}>
|
||||
<Img src={HomeIcon} alt="Home Icon" />
|
||||
<Paragraph noMargin size="xs" className={classes.defaultText}>
|
||||
<Block className={classes.container} justify="left">
|
||||
<Img alt="Home Icon" src={HomeIcon} />
|
||||
<Paragraph className={classes.defaultText} noMargin size="xs">
|
||||
Default
|
||||
</Paragraph>
|
||||
</Block>
|
||||
|
|
|
@ -1,24 +1,26 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import { makeStyles } from '@material-ui/core/styles'
|
||||
import { List } from 'immutable'
|
||||
import MuiList from '@material-ui/core/List'
|
||||
import ListItem from '@material-ui/core/ListItem'
|
||||
import ListItemIcon from '@material-ui/core/ListItemIcon'
|
||||
import ListItemText from '@material-ui/core/ListItemText'
|
||||
import Link from '~/components/layout/Link'
|
||||
import Hairline from '~/components/layout/Hairline'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import ButtonLink from '~/components/layout/ButtonLink'
|
||||
import Identicon from '~/components/Identicon'
|
||||
import { mediumFontSize, sm, primary, disabled, md } from '~/theme/variables'
|
||||
import { formatAmount } from '~/logic/tokens/utils/formatAmount'
|
||||
import { shortVersionOf, sameAddress } from '~/logic/wallets/ethAddresses'
|
||||
import { type Safe } from '~/routes/safe/store/models/safe'
|
||||
import { SAFELIST_ADDRESS } from '~/routes/routes'
|
||||
import { makeStyles } from '@material-ui/core/styles'
|
||||
import { List } from 'immutable'
|
||||
import * as React from 'react'
|
||||
|
||||
import DefaultBadge from './DefaultBadge'
|
||||
import Img from '~/components/layout/Img'
|
||||
|
||||
import check from '~/assets/icons/check.svg'
|
||||
import Identicon from '~/components/Identicon'
|
||||
import ButtonLink from '~/components/layout/ButtonLink'
|
||||
import Hairline from '~/components/layout/Hairline'
|
||||
import Img from '~/components/layout/Img'
|
||||
import Link from '~/components/layout/Link'
|
||||
import Paragraph from '~/components/layout/Paragraph'
|
||||
import { formatAmount } from '~/logic/tokens/utils/formatAmount'
|
||||
import { sameAddress, shortVersionOf } from '~/logic/wallets/ethAddresses'
|
||||
import { SAFELIST_ADDRESS } from '~/routes/routes'
|
||||
import { type Safe } from '~/routes/safe/store/models/safe'
|
||||
import { disabled, md, mediumFontSize, primary, sm } from '~/theme/variables'
|
||||
|
||||
export const SIDEBAR_SAFELIST_ROW_TESTID = 'SIDEBAR_SAFELIST_ROW_TESTID'
|
||||
|
||||
|
@ -38,10 +40,10 @@ const useStyles = makeStyles({
|
|||
marginRight: '10px',
|
||||
},
|
||||
list: {
|
||||
overflow: 'hidden',
|
||||
overflowY: 'hidden',
|
||||
padding: 0,
|
||||
height: '100%',
|
||||
overflowX: 'hidden',
|
||||
overflowY: 'auto',
|
||||
padding: 0,
|
||||
},
|
||||
listItemRoot: {
|
||||
paddingTop: 0,
|
||||
|
@ -72,7 +74,7 @@ const useStyles = makeStyles({
|
|||
},
|
||||
})
|
||||
|
||||
const SafeList = ({ safes, onSafeClick, setDefaultSafe, defaultSafe, currentSafe }: SafeListProps) => {
|
||||
const SafeList = ({ currentSafe, defaultSafe, onSafeClick, safes, setDefaultSafe }: SafeListProps) => {
|
||||
const classes = useStyles()
|
||||
|
||||
return (
|
||||
|
@ -80,30 +82,30 @@ const SafeList = ({ safes, onSafeClick, setDefaultSafe, defaultSafe, currentSafe
|
|||
{safes.map(safe => (
|
||||
<React.Fragment key={safe.address}>
|
||||
<Link
|
||||
to={`${SAFELIST_ADDRESS}/${safe.address}/balances`}
|
||||
onClick={onSafeClick}
|
||||
data-testid={SIDEBAR_SAFELIST_ROW_TESTID}
|
||||
onClick={onSafeClick}
|
||||
to={`${SAFELIST_ADDRESS}/${safe.address}/balances`}
|
||||
>
|
||||
<ListItem classes={{ root: classes.listItemRoot }}>
|
||||
{sameAddress(currentSafe, safe.address) ? (
|
||||
<ListItemIcon>
|
||||
<Img src={check} alt="check" className={classes.checkIcon} />
|
||||
<Img alt="check" className={classes.checkIcon} src={check} />
|
||||
</ListItemIcon>
|
||||
) : (
|
||||
<div className={classes.noIcon}>placeholder</div>
|
||||
)}
|
||||
<ListItemIcon>
|
||||
<Identicon address={safe.address} diameter={32} className={classes.icon} />
|
||||
<Identicon address={safe.address} className={classes.icon} diameter={32} />
|
||||
</ListItemIcon>
|
||||
<ListItemText
|
||||
primary={safe.name}
|
||||
secondary={shortVersionOf(safe.address, 4)}
|
||||
classes={{
|
||||
primary: classes.safeName,
|
||||
secondary: classes.safeAddress,
|
||||
}}
|
||||
primary={safe.name}
|
||||
secondary={shortVersionOf(safe.address, 4)}
|
||||
/>
|
||||
<Paragraph size="lg" color="primary">
|
||||
<Paragraph color="primary" size="lg">
|
||||
{`${formatAmount(safe.ethBalance)} ETH`}
|
||||
</Paragraph>
|
||||
{sameAddress(defaultSafe, safe.address) ? (
|
||||
|
@ -111,13 +113,13 @@ const SafeList = ({ safes, onSafeClick, setDefaultSafe, defaultSafe, currentSafe
|
|||
) : (
|
||||
<ButtonLink
|
||||
className={classes.makeDefaultBtn}
|
||||
size="sm"
|
||||
onClick={e => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
|
||||
setDefaultSafe(safe.address)
|
||||
}}
|
||||
size="sm"
|
||||
>
|
||||
Make default
|
||||
</ButtonLink>
|
||||
|
|
|
@ -1,26 +1,28 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import { List } from 'immutable'
|
||||
import SearchBar from 'material-ui-search-bar'
|
||||
import { connect } from 'react-redux'
|
||||
import ClickAwayListener from '@material-ui/core/ClickAwayListener'
|
||||
import Drawer from '@material-ui/core/Drawer'
|
||||
import SearchIcon from '@material-ui/icons/Search'
|
||||
import Divider from '~/components/layout/Divider'
|
||||
import Button from '~/components/layout/Button'
|
||||
import Link from '~/components/layout/Link'
|
||||
import Spacer from '~/components/Spacer'
|
||||
import Hairline from '~/components/layout/Hairline'
|
||||
import Row from '~/components/layout/Row'
|
||||
import { WELCOME_ADDRESS } from '~/routes/routes'
|
||||
import { type Safe } from '~/routes/safe/store/models/safe'
|
||||
import { defaultSafeSelector, safeParamAddressFromStateSelector } from '~/routes/safe/store/selectors'
|
||||
import setDefaultSafe from '~/routes/safe/store/actions/setDefaultSafe'
|
||||
import { sortedSafeListSelector } from './selectors'
|
||||
import { List } from 'immutable'
|
||||
import SearchBar from 'material-ui-search-bar'
|
||||
import * as React from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
import SafeList from './SafeList'
|
||||
import { sortedSafeListSelector } from './selectors'
|
||||
import useSidebarStyles from './style'
|
||||
|
||||
const { useState, useEffect, useMemo } = React
|
||||
import Spacer from '~/components/Spacer'
|
||||
import Button from '~/components/layout/Button'
|
||||
import Divider from '~/components/layout/Divider'
|
||||
import Hairline from '~/components/layout/Hairline'
|
||||
import Link from '~/components/layout/Link'
|
||||
import Row from '~/components/layout/Row'
|
||||
import { WELCOME_ADDRESS } from '~/routes/routes'
|
||||
import setDefaultSafe from '~/routes/safe/store/actions/setDefaultSafe'
|
||||
import { type Safe } from '~/routes/safe/store/models/safe'
|
||||
import { defaultSafeSelector, safeParamAddressFromStateSelector } from '~/routes/safe/store/selectors'
|
||||
|
||||
const { useEffect, useMemo, useState } = React
|
||||
|
||||
type TSidebarContext = {
|
||||
isOpen: boolean,
|
||||
|
@ -48,7 +50,7 @@ const filterBy = (filter: string, safes: List<Safe>): List<Safe> =>
|
|||
safe.name.toLowerCase().includes(filter.toLowerCase()),
|
||||
)
|
||||
|
||||
const Sidebar = ({ children, safes, setDefaultSafeAction, defaultSafe, currentSafe }: SidebarProps) => {
|
||||
const Sidebar = ({ children, currentSafe, defaultSafe, safes, setDefaultSafeAction }: SidebarProps) => {
|
||||
const [isOpen, setIsOpen] = useState<boolean>(false)
|
||||
const [filter, setFilter] = useState<string>('')
|
||||
const classes = useSidebarStyles()
|
||||
|
@ -90,14 +92,14 @@ const Sidebar = ({ children, safes, setDefaultSafeAction, defaultSafe, currentSa
|
|||
<SidebarContext.Provider value={{ isOpen, toggleSidebar }}>
|
||||
<ClickAwayListener onClickAway={toggleSidebar}>
|
||||
<Drawer
|
||||
ModalProps={{ onBackdropClick: toggleSidebar }}
|
||||
className={classes.sidebar}
|
||||
classes={{ paper: classes.sidebarPaper }}
|
||||
className={classes.sidebar}
|
||||
ModalProps={{ onBackdropClick: toggleSidebar }}
|
||||
onKeyDown={handleEsc}
|
||||
open={isOpen}
|
||||
>
|
||||
<Row className={classes.topComponents} align="center">
|
||||
<Row className={classes.searchWrapper} align="center">
|
||||
<Row align="center" className={classes.topComponents}>
|
||||
<Row align="center" className={classes.searchWrapper}>
|
||||
<SearchIcon className={classes.searchIcon} />
|
||||
<SearchBar
|
||||
classes={searchClasses}
|
||||
|
@ -125,11 +127,11 @@ const Sidebar = ({ children, safes, setDefaultSafeAction, defaultSafe, currentSa
|
|||
</Row>
|
||||
<Hairline />
|
||||
<SafeList
|
||||
safes={filteredSafes}
|
||||
onSafeClick={toggleSidebar}
|
||||
setDefaultSafe={setDefaultSafeAction}
|
||||
defaultSafe={defaultSafe}
|
||||
currentSafe={currentSafe}
|
||||
defaultSafe={defaultSafe}
|
||||
onSafeClick={toggleSidebar}
|
||||
safes={filteredSafes}
|
||||
setDefaultSafe={setDefaultSafeAction}
|
||||
/>
|
||||
</Drawer>
|
||||
</ClickAwayListener>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// @flow
|
||||
import { List } from 'immutable'
|
||||
import { createSelector, type Selector } from 'reselect'
|
||||
import { type Selector, createSelector } from 'reselect'
|
||||
|
||||
import { type Safe } from '~/routes/safe/store/models/safe'
|
||||
import { safesListSelector } from '~/routes/safe/store/selectors'
|
||||
import { type GlobalState } from '~/store/index'
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// @flow
|
||||
import { makeStyles } from '@material-ui/core/styles'
|
||||
import { xs, mediumFontSize, secondaryText, md, headerHeight, screenSm } from '~/theme/variables'
|
||||
|
||||
import { headerHeight, md, mediumFontSize, screenSm, secondaryText, xs } from '~/theme/variables'
|
||||
|
||||
const sidebarWidth = '400px'
|
||||
const sidebarMarginLeft = '12px'
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
|
||||
import Button from '~/components/layout/Button'
|
||||
import Col from '~/components/layout/Col'
|
||||
import Row from '~/components/layout/Row'
|
||||
import { sm, boldFont } from '~/theme/variables'
|
||||
import { boldFont, sm } from '~/theme/variables'
|
||||
|
||||
const controlStyle = {
|
||||
backgroundColor: 'white',
|
||||
|
@ -30,7 +31,7 @@ type Props = {
|
|||
buttonLabels?: Array<string>,
|
||||
}
|
||||
|
||||
const Controls = ({ onPrevious, firstPage, penultimate, lastPage, disabled, currentStep, buttonLabels }: Props) => {
|
||||
const Controls = ({ buttonLabels, currentStep, disabled, firstPage, lastPage, onPrevious, penultimate }: Props) => {
|
||||
const back = firstPage ? 'Cancel' : 'Back'
|
||||
|
||||
let next
|
||||
|
@ -43,18 +44,18 @@ const Controls = ({ onPrevious, firstPage, penultimate, lastPage, disabled, curr
|
|||
}
|
||||
|
||||
return (
|
||||
<Row style={controlStyle} align="end" grow>
|
||||
<Col xs={12} end="xs">
|
||||
<Button style={firstButtonStyle} type="button" onClick={onPrevious} size="small">
|
||||
<Row align="end" grow style={controlStyle}>
|
||||
<Col end="xs" xs={12}>
|
||||
<Button onClick={onPrevious} size="small" style={firstButtonStyle} type="button">
|
||||
{back}
|
||||
</Button>
|
||||
<Button
|
||||
style={secondButtonStyle}
|
||||
size="small"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
type="submit"
|
||||
disabled={disabled}
|
||||
size="small"
|
||||
style={secondButtonStyle}
|
||||
type="submit"
|
||||
variant="contained"
|
||||
>
|
||||
{next}
|
||||
</Button>
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import Paper from '@material-ui/core/Paper'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import * as React from 'react'
|
||||
|
||||
import Block from '~/components/layout/Block'
|
||||
import { lg } from '~/theme/variables'
|
||||
|
||||
|
@ -23,7 +24,7 @@ type Props = {
|
|||
padding?: boolean,
|
||||
}
|
||||
|
||||
const OpenPaper = ({ classes, children, controls, padding = true }: Props) => (
|
||||
const OpenPaper = ({ children, classes, controls, padding = true }: Props) => (
|
||||
<Paper className={classes.root} elevation={1}>
|
||||
<Block className={padding ? classes.padding : ''}>{children}</Block>
|
||||
{controls}
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import Stepper from '@material-ui/core/Stepper'
|
||||
import FormStep from '@material-ui/core/Step'
|
||||
import StepLabel from '@material-ui/core/StepLabel'
|
||||
import StepContent from '@material-ui/core/StepContent'
|
||||
import StepLabel from '@material-ui/core/StepLabel'
|
||||
import Stepper from '@material-ui/core/Stepper'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import * as React from 'react'
|
||||
|
||||
import Controls from './Controls'
|
||||
|
||||
import GnoForm from '~/components/forms/GnoForm'
|
||||
import Hairline from '~/components/layout/Hairline'
|
||||
import { history } from '~/store'
|
||||
import Controls from './Controls'
|
||||
|
||||
const { useState, useEffect } = React
|
||||
const { useEffect, useState } = React
|
||||
|
||||
export { default as Step } from './Step'
|
||||
|
||||
|
@ -110,7 +112,7 @@ const GnoStepper = (props: Props) => {
|
|||
return pageNumber === steps.length - 1
|
||||
}
|
||||
|
||||
const { steps, children, classes, disabledWhenValidating = false, testId, mutators, buttonLabels } = props
|
||||
const { buttonLabels, children, classes, disabledWhenValidating = false, mutators, steps, testId } = props
|
||||
const activePage = getActivePageFrom(children)
|
||||
|
||||
const lastPage = isLastPage(page)
|
||||
|
@ -119,11 +121,11 @@ const GnoStepper = (props: Props) => {
|
|||
return (
|
||||
<>
|
||||
<GnoForm
|
||||
onSubmit={handleSubmit}
|
||||
initialValues={values}
|
||||
validation={validate}
|
||||
testId={testId}
|
||||
formMutators={mutators}
|
||||
initialValues={values}
|
||||
onSubmit={handleSubmit}
|
||||
testId={testId}
|
||||
validation={validate}
|
||||
>
|
||||
{(submitting: boolean, validating: boolean, ...rest: any) => {
|
||||
const disabled = disabledWhenValidating ? submitting || validating : submitting
|
||||
|
@ -131,19 +133,19 @@ const GnoStepper = (props: Props) => {
|
|||
<>
|
||||
<Hairline />
|
||||
<Controls
|
||||
disabled={disabled}
|
||||
onPrevious={previous}
|
||||
firstPage={page === 0}
|
||||
lastPage={lastPage}
|
||||
penultimate={penultimate}
|
||||
buttonLabels={buttonLabels}
|
||||
currentStep={page}
|
||||
disabled={disabled}
|
||||
firstPage={page === 0}
|
||||
lastPage={lastPage}
|
||||
onPrevious={previous}
|
||||
penultimate={penultimate}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
|
||||
return (
|
||||
<Stepper classes={{ root: classes.root }} activeStep={page} orientation="vertical">
|
||||
<Stepper activeStep={page} classes={{ root: classes.root }} orientation="vertical">
|
||||
{steps.map((label, index) => {
|
||||
const labelProps = {}
|
||||
const isClickable = index < page
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import { List } from 'immutable'
|
||||
import TableCell from '@material-ui/core/TableCell'
|
||||
import TableHead from '@material-ui/core/TableHead'
|
||||
import TableRow from '@material-ui/core/TableRow'
|
||||
import TableSortLabel from '@material-ui/core/TableSortLabel'
|
||||
import { List } from 'immutable'
|
||||
import * as React from 'react'
|
||||
|
||||
import { type Order } from '~/components/Table/sorting'
|
||||
|
||||
export type Column = {
|
||||
|
@ -51,8 +52,8 @@ class GnoTableHead extends React.PureComponent<Props> {
|
|||
<TableRow>
|
||||
{columns.map((column: Column) => (
|
||||
<TableCell
|
||||
key={column.id}
|
||||
align={column.align}
|
||||
key={column.id}
|
||||
padding={column.disablePadding ? 'none' : 'default'}
|
||||
sortDirection={orderBy === column.id ? order : false}
|
||||
>
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import { List } from 'immutable'
|
||||
import CircularProgress from '@material-ui/core/CircularProgress'
|
||||
import Table from '@material-ui/core/Table'
|
||||
import TableBody from '@material-ui/core/TableBody'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import CircularProgress from '@material-ui/core/CircularProgress'
|
||||
import TablePagination from '@material-ui/core/TablePagination'
|
||||
import Row from '~/components/layout/Row'
|
||||
import { type Order, stableSort, getSorting } from '~/components/Table/sorting'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import { List } from 'immutable'
|
||||
import * as React from 'react'
|
||||
|
||||
import TableHead, { type Column } from '~/components/Table/TableHead'
|
||||
import { xxl, xl, sm } from '~/theme/variables'
|
||||
import { type Order, getSorting, stableSort } from '~/components/Table/sorting'
|
||||
import Row from '~/components/layout/Row'
|
||||
import { sm, xl, xxl } from '~/theme/variables'
|
||||
|
||||
type Props<K> = {
|
||||
label: string,
|
||||
|
@ -87,7 +88,7 @@ class GnoTable<K> extends React.Component<Props<K>, State> {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { defaultOrderBy, columns } = this.props
|
||||
const { columns, defaultOrderBy } = this.props
|
||||
|
||||
if (defaultOrderBy && columns) {
|
||||
const defaultOrderCol = columns.find(({ id }) => id === defaultOrderBy)
|
||||
|
@ -143,21 +144,21 @@ class GnoTable<K> extends React.Component<Props<K>, State> {
|
|||
|
||||
render() {
|
||||
const {
|
||||
data,
|
||||
label,
|
||||
columns,
|
||||
classes,
|
||||
children,
|
||||
size,
|
||||
disablePagination,
|
||||
defaultOrderBy,
|
||||
defaultOrder,
|
||||
classes,
|
||||
columns,
|
||||
data,
|
||||
defaultFixed,
|
||||
defaultOrder,
|
||||
defaultOrderBy,
|
||||
defaultRowsPerPage,
|
||||
noBorder,
|
||||
disableLoadingOnEmptyTable,
|
||||
disablePagination,
|
||||
label,
|
||||
noBorder,
|
||||
size,
|
||||
} = this.props
|
||||
const { order, orderBy, page, orderProp, rowsPerPage, fixed } = this.state
|
||||
const { fixed, order, orderBy, orderProp, page, rowsPerPage } = this.state
|
||||
const orderByParam = orderBy || defaultOrderBy
|
||||
const orderParam = order || defaultOrder
|
||||
const displayRows = rowsPerPage || defaultRowsPerPage
|
||||
|
@ -182,7 +183,7 @@ class GnoTable<K> extends React.Component<Props<K>, State> {
|
|||
<>
|
||||
{!isEmpty && (
|
||||
<Table aria-labelledby={label} className={noBorder ? '' : classes.root}>
|
||||
<TableHead columns={columns} order={order} orderBy={orderByParam} onSort={this.onSort} />
|
||||
<TableHead columns={columns} onSort={this.onSort} order={order} orderBy={orderByParam} />
|
||||
<TableBody>{children(sortedData)}</TableBody>
|
||||
</Table>
|
||||
)}
|
||||
|
@ -193,16 +194,16 @@ class GnoTable<K> extends React.Component<Props<K>, State> {
|
|||
)}
|
||||
{!disablePagination && (
|
||||
<TablePagination
|
||||
backIconButtonProps={backProps}
|
||||
classes={paginationClasses}
|
||||
component="div"
|
||||
count={size}
|
||||
rowsPerPage={displayRows}
|
||||
rowsPerPageOptions={[5, 10, 25, 50, 100]}
|
||||
page={page}
|
||||
backIconButtonProps={backProps}
|
||||
nextIconButtonProps={nextProps}
|
||||
onChangePage={this.handleChangePage}
|
||||
onChangeRowsPerPage={this.handleChangeRowsPerPage}
|
||||
classes={paginationClasses}
|
||||
page={page}
|
||||
rowsPerPage={displayRows}
|
||||
rowsPerPageOptions={[5, 10, 25, 50, 100]}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
import * as React from 'react'
|
||||
import { Field } from 'react-final-form'
|
||||
import { OnChange } from 'react-final-form-listeners'
|
||||
|
||||
import TextField from '~/components/forms/TextField'
|
||||
import { composeValidators, required, mustBeEthereumAddress } from '~/components/forms/validator'
|
||||
import { composeValidators, mustBeEthereumAddress, required } from '~/components/forms/validator'
|
||||
import { getAddressFromENS } from '~/logic/wallets/getWeb3'
|
||||
|
||||
type Props = {
|
||||
|
@ -38,17 +39,17 @@ const AddressInput = ({
|
|||
}: Props): React.Element<*> => (
|
||||
<>
|
||||
<Field
|
||||
name={name}
|
||||
component={TextField}
|
||||
type="text"
|
||||
validate={composeValidators(required, mustBeEthereumAddress, ...validators)}
|
||||
inputAdornment={inputAdornment}
|
||||
placeholder={placeholder}
|
||||
text={text}
|
||||
className={className}
|
||||
testId={testId}
|
||||
component={TextField}
|
||||
defaultValue={defaultValue}
|
||||
disabled={disabled}
|
||||
inputAdornment={inputAdornment}
|
||||
name={name}
|
||||
placeholder={placeholder}
|
||||
testId={testId}
|
||||
text={text}
|
||||
type="text"
|
||||
validate={composeValidators(required, mustBeEthereumAddress, ...validators)}
|
||||
/>
|
||||
<OnChange name={name}>
|
||||
{async value => {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// @flow
|
||||
import React from 'react'
|
||||
import Checkbox, { type CheckoxProps } from '@material-ui/core/Checkbox'
|
||||
import React from 'react'
|
||||
|
||||
class GnoCheckbox extends React.PureComponent<CheckoxProps> {
|
||||
render() {
|
||||
|
@ -9,7 +9,7 @@ class GnoCheckbox extends React.PureComponent<CheckoxProps> {
|
|||
...rest
|
||||
} = this.props
|
||||
|
||||
return <Checkbox {...rest} name={name} inputProps={restInput} onChange={onChange} checked={!!checked} />
|
||||
return <Checkbox {...rest} checked={!!checked} inputProps={restInput} name={name} onChange={onChange} />
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import { type FormApi } from 'final-form'
|
||||
import * as React from 'react'
|
||||
import { Form } from 'react-final-form'
|
||||
|
||||
export type OnSubmit = (
|
||||
|
@ -25,17 +25,17 @@ const stylesBasedOn = (padding: number): $Shape<CSSStyleDeclaration> => ({
|
|||
flex: '1 0 auto',
|
||||
})
|
||||
|
||||
const GnoForm = ({ onSubmit, validation, initialValues, children, padding = 0, formMutators, testId = '' }: Props) => (
|
||||
const GnoForm = ({ children, formMutators, initialValues, onSubmit, padding = 0, testId = '', validation }: Props) => (
|
||||
<Form
|
||||
validate={validation}
|
||||
onSubmit={onSubmit}
|
||||
initialValues={initialValues}
|
||||
mutators={formMutators}
|
||||
onSubmit={onSubmit}
|
||||
render={({ handleSubmit, ...rest }) => (
|
||||
<form onSubmit={handleSubmit} style={stylesBasedOn(padding)} data-testid={testId}>
|
||||
<form data-testid={testId} onSubmit={handleSubmit} style={stylesBasedOn(padding)}>
|
||||
{children(rest.submitting, rest.validating, rest, rest.form.mutators)}
|
||||
</form>
|
||||
)}
|
||||
validate={validation}
|
||||
/>
|
||||
)
|
||||
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
// @flow
|
||||
import React from 'react'
|
||||
import Select, { type SelectFieldProps } from '@material-ui/core/Select'
|
||||
import FormControl from '@material-ui/core/FormControl'
|
||||
import InputLabel from '@material-ui/core/InputLabel'
|
||||
import FormHelperText from '@material-ui/core/FormHelperText'
|
||||
import InputLabel from '@material-ui/core/InputLabel'
|
||||
import Select, { type SelectFieldProps } from '@material-ui/core/Select'
|
||||
import React from 'react'
|
||||
|
||||
const style = {
|
||||
minWidth: '100%',
|
||||
}
|
||||
|
||||
const SelectInput = ({
|
||||
input: { name, value, onChange, ...restInput },
|
||||
meta,
|
||||
label,
|
||||
formControlProps,
|
||||
classes,
|
||||
renderValue,
|
||||
disableError,
|
||||
formControlProps,
|
||||
input: { name, onChange, value, ...restInput },
|
||||
label,
|
||||
meta,
|
||||
renderValue,
|
||||
...rest
|
||||
}: SelectFieldProps) => {
|
||||
const showError = ((meta.submitError && !meta.dirtySinceLastSubmit) || meta.error) && meta.touched && !disableError
|
||||
|
@ -30,9 +30,9 @@ const SelectInput = ({
|
|||
<InputLabel htmlFor={name}>{label}</InputLabel>
|
||||
<Select
|
||||
classes={classes}
|
||||
inputProps={inputProps}
|
||||
onChange={onChange}
|
||||
renderValue={renderValue}
|
||||
inputProps={inputProps}
|
||||
value={value}
|
||||
{...rest}
|
||||
/>
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
// @flow
|
||||
import React from 'react'
|
||||
import MuiTextField, { TextFieldProps } from '@material-ui/core/TextField'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import React from 'react'
|
||||
|
||||
import { lg } from '~/theme/variables'
|
||||
|
||||
// Neded for solving a fix in Windows browsers
|
||||
|
@ -21,39 +22,49 @@ const styles = () => ({
|
|||
class TextField extends React.PureComponent<TextFieldProps> {
|
||||
render() {
|
||||
const {
|
||||
input: { name, onChange, value, ...restInput },
|
||||
meta,
|
||||
text,
|
||||
inputAdornment,
|
||||
classes,
|
||||
testId,
|
||||
rows,
|
||||
input: { name, onChange, value, ...restInput },
|
||||
inputAdornment,
|
||||
meta,
|
||||
multiline,
|
||||
rows,
|
||||
testId,
|
||||
text,
|
||||
...rest
|
||||
} = this.props
|
||||
const helperText = value ? text : undefined
|
||||
const showError = (meta.touched || !meta.pristine) && !meta.valid
|
||||
const underline = meta.active || (meta.visited && !meta.valid)
|
||||
const isInactiveAndPristineOrUntouched = !meta.active && (meta.pristine || !meta.touched)
|
||||
const isInvalidAndUntouched = typeof meta.error === 'undefined' ? true : !meta.touched
|
||||
|
||||
const inputRoot = helperText ? classes.root : undefined
|
||||
const inputProps = { ...restInput, autoComplete: 'off', 'data-testid': testId }
|
||||
const inputRootProps = { ...inputAdornment, disableUnderline: !underline, className: inputRoot }
|
||||
const disableUnderline = isInactiveAndPristineOrUntouched && isInvalidAndUntouched
|
||||
|
||||
const inputRoot = helperText ? classes.root : ''
|
||||
const statusClasses = meta.valid ? 'isValid' : meta.error && (meta.dirty || meta.touched) ? 'isInvalid' : ''
|
||||
const inputProps = {
|
||||
...restInput,
|
||||
autoComplete: 'off',
|
||||
'data-testid': testId,
|
||||
}
|
||||
const inputRootProps = {
|
||||
...inputAdornment,
|
||||
className: `${inputRoot} ${statusClasses}`,
|
||||
disableUnderline: disableUnderline,
|
||||
}
|
||||
|
||||
return (
|
||||
<MuiTextField
|
||||
style={overflowStyle}
|
||||
{...rest}
|
||||
name={name}
|
||||
helperText={showError ? meta.error : helperText || ' '} // blank in order to force to have helper text
|
||||
error={meta.error && (meta.touched || !meta.pristine)}
|
||||
helperText={showError ? meta.error : helperText || ' '}
|
||||
inputProps={inputProps} // blank in order to force to have helper text
|
||||
InputProps={inputRootProps}
|
||||
// eslint-disable-next-line
|
||||
inputProps={inputProps}
|
||||
onChange={onChange}
|
||||
value={value}
|
||||
// data-testid={testId}
|
||||
rows={rows}
|
||||
multiline={multiline}
|
||||
name={name}
|
||||
onChange={onChange}
|
||||
rows={rows}
|
||||
style={overflowStyle}
|
||||
value={value}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
// @flow
|
||||
import React from 'react'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import { TextFieldProps } from '@material-ui/core/TextField'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import React from 'react'
|
||||
|
||||
import Field from '~/components/forms/Field'
|
||||
import TextField from '~/components/forms/TextField'
|
||||
|
||||
|
@ -23,7 +24,7 @@ const styles = () => ({
|
|||
})
|
||||
|
||||
const TextareaField = ({ classes, ...props }: TextFieldProps) => (
|
||||
<Field {...props} component={TextField} multiline rows="5" className={classes.textarea} />
|
||||
<Field {...props} className={classes.textarea} component={TextField} multiline rows="5" />
|
||||
)
|
||||
|
||||
export default withStyles(styles)(TextareaField)
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
// @flow
|
||||
import { type FieldValidator } from 'final-form'
|
||||
import { List } from 'immutable'
|
||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||
|
||||
import { sameAddress } from '~/logic/wallets/ethAddresses'
|
||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||
|
||||
export const simpleMemoize = (fn: Function) => {
|
||||
let lastArg
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// @flow
|
||||
import React from 'react'
|
||||
import { makeStyles } from '@material-ui/core/styles'
|
||||
import ReactDOM from 'react-dom'
|
||||
import Backdrop from '@material-ui/core/Backdrop'
|
||||
import { makeStyles } from '@material-ui/core/styles'
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
root: {
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
// @flow
|
||||
import classNames from 'classnames/bind'
|
||||
import * as React from 'react'
|
||||
import { capitalize } from '~/utils/css'
|
||||
import { type Size } from '~/theme/size'
|
||||
|
||||
import styles from './index.scss'
|
||||
|
||||
import { type Size } from '~/theme/size'
|
||||
import { capitalize } from '~/utils/css'
|
||||
|
||||
const { PureComponent } = React
|
||||
|
||||
const cx = classNames.bind(styles)
|
||||
|
@ -19,7 +21,7 @@ type Props = {
|
|||
|
||||
class Block extends PureComponent<Props> {
|
||||
render() {
|
||||
const { margin, padding, justify, children, className, ...props } = this.props
|
||||
const { children, className, justify, margin, padding, ...props } = this.props
|
||||
|
||||
const paddingStyle = padding ? capitalize(padding, 'padding') : undefined
|
||||
return (
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import Button from '@material-ui/core/Button'
|
||||
import * as React from 'react'
|
||||
|
||||
type Props = {
|
||||
minWidth?: number,
|
||||
|
@ -17,7 +17,7 @@ const calculateStyleBased = (minWidth, minHeight) => ({
|
|||
const GnoButton = ({ minWidth, minHeight = 35, testId = '', style = {}, ...props }: Props) => {
|
||||
const calculatedStyle = calculateStyleBased(minWidth, minHeight)
|
||||
|
||||
return <Button style={{ ...calculatedStyle, ...style }} data-testid={testId} {...props} />
|
||||
return <Button data-testid={testId} style={{ ...calculatedStyle, ...style }} {...props} />
|
||||
}
|
||||
|
||||
export default GnoButton
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
// @flow
|
||||
/* eslint-disable react/button-has-type */
|
||||
import * as React from 'react'
|
||||
import cn from 'classnames/bind'
|
||||
import * as React from 'react'
|
||||
|
||||
import styles from './index.scss'
|
||||
|
||||
const cx = cn.bind(styles)
|
||||
|
@ -16,15 +17,15 @@ type Props = {
|
|||
}
|
||||
|
||||
const GnoButtonLink = ({
|
||||
type = 'button',
|
||||
size = 'md',
|
||||
weight = 'regular',
|
||||
color = 'secondary',
|
||||
testId = '',
|
||||
className = '',
|
||||
color = 'secondary',
|
||||
size = 'md',
|
||||
testId = '',
|
||||
type = 'button',
|
||||
weight = 'regular',
|
||||
...props
|
||||
}: Props) => (
|
||||
<button type={type} className={cx(styles.btnLink, size, color, weight, className)} data-testid={testId} {...props} />
|
||||
<button className={cx(styles.btnLink, size, color, weight, className)} data-testid={testId} type={type} {...props} />
|
||||
)
|
||||
|
||||
export default GnoButtonLink
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import classNames from 'classnames/bind'
|
||||
import { capitalize } from '~/utils/css'
|
||||
import * as React from 'react'
|
||||
|
||||
import styles from './index.scss'
|
||||
|
||||
import { capitalize } from '~/utils/css'
|
||||
|
||||
const cx = classNames.bind(styles)
|
||||
|
||||
type Props = {
|
||||
|
@ -31,27 +33,27 @@ type Props = {
|
|||
}
|
||||
|
||||
const Col = ({
|
||||
children,
|
||||
margin,
|
||||
layout = 'inherit',
|
||||
overflow,
|
||||
xs,
|
||||
sm,
|
||||
md,
|
||||
lg,
|
||||
start,
|
||||
center,
|
||||
end,
|
||||
top,
|
||||
middle,
|
||||
bottom,
|
||||
around,
|
||||
between,
|
||||
xsOffset,
|
||||
smOffset,
|
||||
mdOffset,
|
||||
lgOffset,
|
||||
bottom,
|
||||
center,
|
||||
children,
|
||||
className,
|
||||
end,
|
||||
layout = 'inherit',
|
||||
lg,
|
||||
lgOffset,
|
||||
margin,
|
||||
md,
|
||||
mdOffset,
|
||||
middle,
|
||||
overflow,
|
||||
sm,
|
||||
smOffset,
|
||||
start,
|
||||
top,
|
||||
xs,
|
||||
xsOffset,
|
||||
...props
|
||||
}: Props) => {
|
||||
const colClassNames = cx(
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
|
||||
import { border } from '~/theme/variables'
|
||||
|
||||
type Props = {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
|
||||
import { type Size, getSize } from '~/theme/size'
|
||||
import { border } from '~/theme/variables'
|
||||
|
||||
|
@ -18,11 +19,11 @@ type Props = {
|
|||
style?: Object,
|
||||
}
|
||||
|
||||
const Hairline = ({ margin, color, style, className }: Props) => {
|
||||
const Hairline = ({ className, color, margin, style }: Props) => {
|
||||
const calculatedStyles = calculateStyleFrom(color, margin)
|
||||
const mergedStyles = { ...calculatedStyles, ...(style || {}) }
|
||||
|
||||
return <div style={mergedStyles} className={className} />
|
||||
return <div className={className} style={mergedStyles} />
|
||||
}
|
||||
|
||||
export default Hairline
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import classNames from 'classnames/bind'
|
||||
import { capitalize } from '~/utils/css'
|
||||
import * as React from 'react'
|
||||
|
||||
import styles from './index.scss'
|
||||
|
||||
import { capitalize } from '~/utils/css'
|
||||
|
||||
const cx = classNames.bind(styles)
|
||||
|
||||
type HeadingTag = 'h1' | 'h2' | 'h3' | 'h4'
|
||||
|
@ -20,7 +22,7 @@ type Props = {
|
|||
}
|
||||
|
||||
const Heading = (props: Props) => {
|
||||
const { align, tag, truncate, margin, color, children, testId, className = '', ...rest } = props
|
||||
const { align, children, className = '', color, margin, tag, testId, truncate, ...rest } = props
|
||||
|
||||
const classes = cx(className, 'heading', align, tag, margin ? capitalize(margin, 'margin') : undefined, color, {
|
||||
truncate,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// @flow
|
||||
import React from 'react'
|
||||
import classNames from 'classnames/bind'
|
||||
import React from 'react'
|
||||
|
||||
import styles from './index.scss'
|
||||
|
||||
const cx = classNames.bind(styles)
|
||||
|
@ -14,10 +15,10 @@ type Props = {
|
|||
testId?: string,
|
||||
}
|
||||
|
||||
const Img = ({ fullwidth, alt, bordered, className, style, testId = '', ...props }: Props) => {
|
||||
const Img = ({ alt, bordered, className, fullwidth, style, testId = '', ...props }: Props) => {
|
||||
const classes = cx(styles.img, { fullwidth, bordered }, className)
|
||||
|
||||
return <img alt={alt} style={style} className={classes} data-testid={testId} {...props} />
|
||||
return <img alt={alt} className={classes} data-testid={testId} style={style} {...props} />
|
||||
}
|
||||
|
||||
export default Img
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import classNames from 'classnames/bind'
|
||||
import * as React from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { capitalize } from '~/utils/css'
|
||||
|
||||
import styles from './index.scss'
|
||||
|
||||
import { capitalize } from '~/utils/css'
|
||||
|
||||
const cx = classNames.bind(styles)
|
||||
|
||||
type Props = {
|
||||
|
@ -16,7 +18,7 @@ type Props = {
|
|||
innerRef?: React.ElementRef<any>,
|
||||
}
|
||||
|
||||
const GnosisLink = ({ to, children, color, className, padding, innerRef, ...props }: Props) => {
|
||||
const GnosisLink = ({ children, className, color, innerRef, padding, to, ...props }: Props) => {
|
||||
const internal = /^\/(?!\/)/.test(to)
|
||||
const classes = cx(styles.link, color || 'regular', padding ? capitalize(padding, 'padding') : undefined, className)
|
||||
const LinkElement = internal ? Link : 'a'
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// @flow
|
||||
import classNames from 'classnames/bind'
|
||||
import React from 'react'
|
||||
|
||||
import styles from './index.scss'
|
||||
|
||||
const cx = classNames.bind(styles)
|
||||
|
@ -11,7 +12,7 @@ type Props = {
|
|||
overflow?: boolean,
|
||||
}
|
||||
|
||||
const Page = ({ children, align, overflow }: Props) => (
|
||||
const Page = ({ align, children, overflow }: Props) => (
|
||||
<main className={cx(styles.page, align, { overflow })}>{children}</main>
|
||||
)
|
||||
|
||||
|
|
|
@ -1,24 +1,26 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import { SnackbarProvider } from 'notistack'
|
||||
import { connect } from 'react-redux'
|
||||
import { withStyles } from '@material-ui/core/styles'
|
||||
import Backdrop from '~/components/layout/Backdrop'
|
||||
import CookiesBanner from '~/components/CookiesBanner'
|
||||
import Header from '~/components/Header'
|
||||
import Footer from '~/components/Footer'
|
||||
import Img from '~/components/layout/Img'
|
||||
import Notifier from '~/components/Notifier'
|
||||
import SidebarProvider from '~/components/Sidebar'
|
||||
import { ETHEREUM_NETWORK } from '~/logic/wallets/getWeb3'
|
||||
import { getNetwork } from '~/config'
|
||||
import { networkSelector } from '~/logic/wallets/store/selectors'
|
||||
import { SnackbarProvider } from 'notistack'
|
||||
import * as React from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
import AlertIcon from './assets/alert.svg'
|
||||
import CheckIcon from './assets/check.svg'
|
||||
import ErrorIcon from './assets/error.svg'
|
||||
import InfoIcon from './assets/info.svg'
|
||||
import styles from './index.scss'
|
||||
|
||||
import CookiesBanner from '~/components/CookiesBanner'
|
||||
import Footer from '~/components/Footer'
|
||||
import Header from '~/components/Header'
|
||||
import Notifier from '~/components/Notifier'
|
||||
import SidebarProvider from '~/components/Sidebar'
|
||||
import Backdrop from '~/components/layout/Backdrop'
|
||||
import Img from '~/components/layout/Img'
|
||||
import { getNetwork } from '~/config'
|
||||
import { ETHEREUM_NETWORK } from '~/logic/wallets/getWeb3'
|
||||
import { networkSelector } from '~/logic/wallets/store/selectors'
|
||||
|
||||
const notificationStyles = {
|
||||
success: {
|
||||
background: '#fff',
|
||||
|
@ -49,7 +51,6 @@ const PageFrame = ({ children, classes, currentNetwork }: Props) => {
|
|||
<div className={styles.frame}>
|
||||
<Backdrop isOpen={isWrongNetwork} />
|
||||
<SnackbarProvider
|
||||
maxSnack={5}
|
||||
anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
|
||||
classes={{
|
||||
variantSuccess: classes.success,
|
||||
|
@ -58,11 +59,12 @@ const PageFrame = ({ children, classes, currentNetwork }: Props) => {
|
|||
variantInfo: classes.info,
|
||||
}}
|
||||
iconVariant={{
|
||||
error: <Img src={ErrorIcon} alt="Error" />,
|
||||
info: <Img src={InfoIcon} alt="Info" />,
|
||||
success: <Img src={CheckIcon} alt="Success" />,
|
||||
warning: <Img src={AlertIcon} alt="Warning" />,
|
||||
error: <Img alt="Error" src={ErrorIcon} />,
|
||||
info: <Img alt="Info" src={InfoIcon} />,
|
||||
success: <Img alt="Success" src={CheckIcon} />,
|
||||
warning: <Img alt="Warning" src={AlertIcon} />,
|
||||
}}
|
||||
maxSnack={5}
|
||||
>
|
||||
<Notifier />
|
||||
<SidebarProvider>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import classNames from 'classnames/bind'
|
||||
import * as React from 'react'
|
||||
|
||||
import styles from './index.scss'
|
||||
|
||||
const cx = classNames.bind(styles)
|
||||
|
@ -20,7 +21,7 @@ type Props = {
|
|||
|
||||
class Paragraph extends React.PureComponent<Props> {
|
||||
render() {
|
||||
const { weight, children, color, align, size, transform, noMargin, className, dot, ...props } = this.props
|
||||
const { align, children, className, color, dot, noMargin, size, transform, weight, ...props } = this.props
|
||||
|
||||
return (
|
||||
<p
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// @flow
|
||||
import classNames from 'classnames/bind'
|
||||
import * as React from 'react'
|
||||
|
||||
import styles from './index.scss'
|
||||
|
||||
const cx = classNames.bind(styles)
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
// @flow
|
||||
import classNames from 'classnames/bind'
|
||||
import * as React from 'react'
|
||||
import { capitalize } from '~/utils/css'
|
||||
|
||||
import styles from './index.scss'
|
||||
|
||||
import { capitalize } from '~/utils/css'
|
||||
|
||||
const cx = classNames.bind(styles)
|
||||
|
||||
type Props = {
|
||||
|
@ -15,7 +17,7 @@ type Props = {
|
|||
testId?: string,
|
||||
}
|
||||
|
||||
const Row = ({ children, className, margin, align, grow, testId = '', ...props }: Props) => {
|
||||
const Row = ({ align, children, className, grow, margin, testId = '', ...props }: Props) => {
|
||||
const rowClassNames = cx(
|
||||
styles.row,
|
||||
margin ? capitalize(margin, 'margin') : undefined,
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import Table from '@material-ui/core/Table'
|
||||
import TableBody from '@material-ui/core/TableBody'
|
||||
import TableCell from '@material-ui/core/TableCell'
|
||||
import TableHead from '@material-ui/core/TableHead'
|
||||
import TableRow from '@material-ui/core/TableRow'
|
||||
import * as React from 'react'
|
||||
|
||||
export { TableBody, TableCell, TableHead, TableRow }
|
||||
|
||||
|
@ -22,7 +22,7 @@ const overflowStyle = {
|
|||
}
|
||||
|
||||
// see: https://css-tricks.com/responsive-data-tables/
|
||||
const GnoTable = ({ size, children }: Props) => {
|
||||
const GnoTable = ({ children, size }: Props) => {
|
||||
const style = size ? buildWidthFrom(size) : undefined
|
||||
|
||||
return (
|
||||
|
|
|
@ -5,7 +5,7 @@ import { TX_SERVICE_HOST, RELAY_API_URL } from '~/config/names'
|
|||
const devMainnetConfig = {
|
||||
...devConfig,
|
||||
[TX_SERVICE_HOST]: 'https://safe-transaction.mainnet.staging.gnosisdev.com/api/v1/',
|
||||
[RELAY_API_URL]: 'https://safe-relay.gnosis.io/api/v1/',
|
||||
[RELAY_API_URL]: 'https://safe-relay.mainnet.staging.gnosisdev.com/api/v1/',
|
||||
}
|
||||
|
||||
export default devMainnetConfig
|
||||
|
|
|
@ -41,6 +41,9 @@ export const getNetwork = () =>
|
|||
? ETHEREUM_NETWORK.MAINNET
|
||||
: ETHEREUM_NETWORK.RINKEBY
|
||||
|
||||
export const getNetworkId = () =>
|
||||
process.env.REACT_APP_NETWORK === "mainnet" ? 1 : 4
|
||||
|
||||
const getConfig = ensureOnce(configuration)
|
||||
|
||||
export const getTxServiceHost = () => {
|
||||
|
@ -75,4 +78,4 @@ export const getIntercomId = () =>
|
|||
|
||||
export const getExchangeRatesUrl = () => 'https://api.exchangeratesapi.io/latest'
|
||||
|
||||
export const getSafeLastVersion = () => process.env.REACT_APP_LATEST_SAFE_VERSION || '1.1.1'
|
||||
export const getSafeLastVersion = () => process.env.REACT_APP_LATEST_SAFE_VERSION || '1.1.1'
|
||||
|
|
|
@ -4,7 +4,7 @@ import { TX_SERVICE_HOST, SIGNATURES_VIA_METAMASK, RELAY_API_URL } from '~/confi
|
|||
const prodConfig = {
|
||||
[TX_SERVICE_HOST]: 'https://safe-transaction.rinkeby.gnosis.io/api/v1/',
|
||||
[SIGNATURES_VIA_METAMASK]: false,
|
||||
[RELAY_API_URL]: 'https://safe-relay.staging.gnosisdev.com/api/v1/',
|
||||
[RELAY_API_URL]: 'https://safe-relay.rinkeby.gnosis.io/api/v1/',
|
||||
}
|
||||
|
||||
export default prodConfig
|
||||
|
|
|
@ -5,7 +5,7 @@ import { TX_SERVICE_HOST, RELAY_API_URL } from '~/config/names'
|
|||
const stagingMainnetConfig = {
|
||||
...stagingConfig,
|
||||
[TX_SERVICE_HOST]: 'https://safe-transaction.mainnet.staging.gnosisdev.com/api/v1/',
|
||||
[RELAY_API_URL]: 'https://safe-relay.gnosis.io/api/v1/',
|
||||
[RELAY_API_URL]: 'https://safe-relay.mainnet.staging.gnosisdev.com/api/v1/',
|
||||
}
|
||||
|
||||
export default stagingMainnetConfig
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
// @flow
|
||||
import 'babel-polyfill'
|
||||
import { BigNumber } from 'bignumber.js'
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import { BigNumber } from 'bignumber.js'
|
||||
|
||||
import Root from '~/components/Root'
|
||||
import loadCurrentSessionFromStorage from '~/logic/currentSession/store/actions/loadCurrentSessionFromStorage'
|
||||
import loadActiveTokens from '~/logic/tokens/store/actions/loadActiveTokens'
|
||||
import loadDefaultSafe from '~/routes/safe/store/actions/loadDefaultSafe'
|
||||
import loadSafesFromStorage from '~/routes/safe/store/actions/loadSafesFromStorage'
|
||||
import loadCurrentSessionFromStorage from '~/logic/currentSession/store/actions/loadCurrentSessionFromStorage'
|
||||
import { store } from '~/store'
|
||||
|
||||
BigNumber.set({ EXPONENTIAL_AT: [-7, 255] })
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
import { createAction } from 'redux-actions'
|
||||
|
||||
import type { AddressBook } from '~/logic/addressBook/model/addressBook'
|
||||
|
||||
export const ADD_ADDRESS_BOOK = 'ADD_ADDRESS_BOOK'
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
import { createAction } from 'redux-actions'
|
||||
|
||||
import type { AddressBookEntryType } from '~/logic/addressBook/model/addressBook'
|
||||
|
||||
export const ADD_ENTRY = 'ADD_ENTRY'
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
import { createAction } from 'redux-actions'
|
||||
|
||||
import type { AddressBook } from '~/logic/addressBook/model/addressBook'
|
||||
|
||||
export const LOAD_ADDRESS_BOOK = 'LOAD_ADDRESS_BOOK'
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
// @flow
|
||||
import { List, Map } from 'immutable'
|
||||
import type { Dispatch as ReduxDispatch } from 'redux'
|
||||
import { Map, List } from 'immutable'
|
||||
import { type GlobalState } from '~/store/index'
|
||||
import { getAddressBookFromStorage } from '~/logic/addressBook/utils'
|
||||
|
||||
import { loadAddressBook } from '~/logic/addressBook/store/actions/loadAddressBook'
|
||||
import { safesListSelector } from '~/routes/safe/store/selectors'
|
||||
import { buildAddressBook } from '~/logic/addressBook/store/reducer/addressBook'
|
||||
import { getAddressBookFromStorage } from '~/logic/addressBook/utils'
|
||||
import { safesListSelector } from '~/routes/safe/store/selectors'
|
||||
import { type GlobalState } from '~/store/index'
|
||||
|
||||
const loadAddressBookFromStorage = () => async (dispatch: ReduxDispatch<GlobalState>, getState: Function) => {
|
||||
try {
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
// @flow
|
||||
import type { Dispatch as ReduxDispatch } from 'redux'
|
||||
import { type GlobalState } from '~/store/index'
|
||||
import { saveAddressBook } from '~/logic/addressBook/utils'
|
||||
import { updateAddressBookEntry } from '~/logic/addressBook/store/actions/updateAddressBookEntry'
|
||||
|
||||
import type { AddressBook } from '~/logic/addressBook/model/addressBook'
|
||||
import { updateAddressBookEntry } from '~/logic/addressBook/store/actions/updateAddressBookEntry'
|
||||
import { saveAddressBook } from '~/logic/addressBook/utils'
|
||||
import { type GlobalState } from '~/store/index'
|
||||
|
||||
const saveAndUpdateAddressBook = (addressBook: AddressBook) => async (dispatch: ReduxDispatch<GlobalState>) => {
|
||||
try {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
import { createAction } from 'redux-actions'
|
||||
|
||||
import type { AddressBookEntry } from '~/logic/addressBook/model/addressBook'
|
||||
|
||||
export const UPDATE_ENTRY = 'UPDATE_ENTRY'
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
// @flow
|
||||
import type { AnyAction, Store } from 'redux'
|
||||
import { type GlobalState } from '~/store/'
|
||||
|
||||
import type { AddressBookProps } from '~/logic/addressBook/model/addressBook'
|
||||
import { ADD_ENTRY } from '~/logic/addressBook/store/actions/addAddressBookEntry'
|
||||
import { REMOVE_ENTRY } from '~/logic/addressBook/store/actions/removeAddressBookEntry'
|
||||
import { UPDATE_ENTRY } from '~/logic/addressBook/store/actions/updateAddressBookEntry'
|
||||
import { addressBookMapSelector } from '~/logic/addressBook/store/selectors'
|
||||
import { enhanceSnackbarForAction, getNotificationsFromTxType } from '~/logic/notifications'
|
||||
import { TX_NOTIFICATION_TYPES } from '~/logic/safe/transactions'
|
||||
import enqueueSnackbar from '~/logic/notifications/store/actions/enqueueSnackbar'
|
||||
import { saveAddressBook } from '~/logic/addressBook/utils'
|
||||
import type { AddressBookProps } from '~/logic/addressBook/model/addressBook'
|
||||
import { enhanceSnackbarForAction, getNotificationsFromTxType } from '~/logic/notifications'
|
||||
import enqueueSnackbar from '~/logic/notifications/store/actions/enqueueSnackbar'
|
||||
import { TX_NOTIFICATION_TYPES } from '~/logic/safe/transactions'
|
||||
import { type GlobalState } from '~/store/'
|
||||
|
||||
const watchedActions = [ADD_ENTRY, REMOVE_ENTRY, UPDATE_ENTRY]
|
||||
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
// @flow
|
||||
import { List, Map } from 'immutable'
|
||||
import { handleActions, type ActionType } from 'redux-actions'
|
||||
import { type ActionType, handleActions } from 'redux-actions'
|
||||
|
||||
import type { AddressBook, AddressBookEntry, AddressBookProps } from '~/logic/addressBook/model/addressBook'
|
||||
import { ADD_ENTRY } from '~/logic/addressBook/store/actions/addAddressBookEntry'
|
||||
import { UPDATE_ENTRY } from '~/logic/addressBook/store/actions/updateAddressBookEntry'
|
||||
import { REMOVE_ENTRY } from '~/logic/addressBook/store/actions/removeAddressBookEntry'
|
||||
import { ADD_ADDRESS_BOOK } from '~/logic/addressBook/store/actions/addAddressBook'
|
||||
import { ADD_ENTRY } from '~/logic/addressBook/store/actions/addAddressBookEntry'
|
||||
import { LOAD_ADDRESS_BOOK } from '~/logic/addressBook/store/actions/loadAddressBook'
|
||||
import { sameAddress } from '~/logic/wallets/ethAddresses'
|
||||
import { REMOVE_ENTRY } from '~/logic/addressBook/store/actions/removeAddressBookEntry'
|
||||
import { UPDATE_ENTRY } from '~/logic/addressBook/store/actions/updateAddressBookEntry'
|
||||
import { getAddressesListFromAdbk } from '~/logic/addressBook/utils'
|
||||
import { sameAddress } from '~/logic/wallets/ethAddresses'
|
||||
|
||||
export const ADDRESS_BOOK_REDUCER_ID = 'addressBook'
|
||||
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
/* eslint-disable import/named */
|
||||
// @flow
|
||||
import { List, Map } from 'immutable'
|
||||
import { createSelector, Selector } from 'reselect'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { ADDRESS_BOOK_REDUCER_ID } from '~/logic/addressBook/store/reducer/addressBook'
|
||||
import type { GlobalState } from '~/store'
|
||||
import { Selector, createSelector } from 'reselect'
|
||||
|
||||
import type { AddressBook } from '~/logic/addressBook/model/addressBook'
|
||||
import { ADDRESS_BOOK_REDUCER_ID } from '~/logic/addressBook/store/reducer/addressBook'
|
||||
import { safeParamAddressFromStateSelector } from '~/routes/safe/store/selectors'
|
||||
import type { GlobalState } from '~/store'
|
||||
|
||||
export const addressBookMapSelector = (state: GlobalState): Map<string, AddressBook> =>
|
||||
state[ADDRESS_BOOK_REDUCER_ID].get('addressBook')
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
// @flow
|
||||
import { useSelector } from 'react-redux'
|
||||
|
||||
import type { AddressBook, AddressBookProps } from '~/logic/addressBook/model/addressBook'
|
||||
import { loadFromStorage, saveToStorage } from '~/utils/storage'
|
||||
import { getAddressBook } from '~/logic/addressBook/store/selectors'
|
||||
import type { Owner } from '~/routes/safe/store/models/owner'
|
||||
import { loadFromStorage, saveToStorage } from '~/utils/storage'
|
||||
|
||||
const ADDRESS_BOOK_STORAGE_KEY = 'ADDRESS_BOOK_STORAGE_KEY'
|
||||
|
||||
|
|
|
@ -7,5 +7,5 @@ const proxyCodeV10 =
|
|||
const oldProxyCode =
|
||||
'0x60806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680634555d5c91461008b5780635c60da1b146100b6575b73ffffffffffffffffffffffffffffffffffffffff600054163660008037600080366000845af43d6000803e6000811415610086573d6000fd5b3d6000f35b34801561009757600080fd5b506100a061010d565b6040518082815260200191505060405180910390f35b3480156100c257600080fd5b506100cb610116565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60006002905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050905600'
|
||||
|
||||
export const isProxyCode = codeToCheck =>
|
||||
export const isProxyCode = (codeToCheck: string) =>
|
||||
codeToCheck === oldProxyCode || codeToCheck === proxyCodeV10
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// @flow
|
||||
import { Map } from 'immutable'
|
||||
import { handleActions, type ActionType } from 'redux-actions'
|
||||
import { type ActionType, handleActions } from 'redux-actions'
|
||||
|
||||
import type { Cookie } from '~/logic/cookies/model/cookie'
|
||||
import { OPEN_COOKIE_BANNER } from '~/logic/cookies/store/actions/openCookieBanner'
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// @flow
|
||||
import type { Provider } from '~/logic/wallets/store/model/provider'
|
||||
import { COOKIES_REDUCER_ID } from '~/logic/cookies/store/reducer/cookies'
|
||||
import type { Provider } from '~/logic/wallets/store/model/provider'
|
||||
|
||||
export const cookieBannerOpen = (state: any): Provider => state[COOKIES_REDUCER_ID].get('cookieBannerOpen')
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
import Cookies from 'js-cookie'
|
||||
|
||||
import { getNetwork } from '~/config'
|
||||
|
||||
const PREFIX = `v1_${getNetwork()}`
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
import axios from 'axios'
|
||||
|
||||
import { getExchangeRatesUrl } from '~/config'
|
||||
import { AVAILABLE_CURRENCIES } from '~/logic/currencyValues/store/model/currencyValues'
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
import axios from 'axios'
|
||||
|
||||
import { getTxServiceHost } from '~/config'
|
||||
|
||||
const fetchTokenCurrenciesBalances = (safeAddress: string) => {
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
// @flow
|
||||
import { Dispatch as ReduxDispatch } from 'redux'
|
||||
import { List } from 'immutable'
|
||||
import type { GlobalState } from '~/store'
|
||||
import { AVAILABLE_CURRENCIES } from '~/logic/currencyValues/store/model/currencyValues'
|
||||
import { Dispatch as ReduxDispatch } from 'redux'
|
||||
|
||||
import fetchCurrenciesRates from '~/logic/currencyValues/api/fetchCurrenciesRates'
|
||||
import { currencyValuesListSelector } from '~/logic/currencyValues/store/selectors'
|
||||
import { setCurrencyBalances } from '~/logic/currencyValues/store/actions/setCurrencyBalances'
|
||||
import { AVAILABLE_CURRENCIES } from '~/logic/currencyValues/store/model/currencyValues'
|
||||
import { currencyValuesListSelector } from '~/logic/currencyValues/store/selectors'
|
||||
import type { GlobalState } from '~/store'
|
||||
|
||||
// eslint-disable-next-line max-len
|
||||
const fetchCurrencySelectedValue = (currencyValueSelected: AVAILABLE_CURRENCIES) => async (
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
// @flow
|
||||
import type { Dispatch as ReduxDispatch } from 'redux'
|
||||
import { List } from 'immutable'
|
||||
import type { GlobalState } from '~/store'
|
||||
import { setCurrencyBalances } from '~/logic/currencyValues/store/actions/setCurrencyBalances'
|
||||
import { AVAILABLE_CURRENCIES, makeBalanceCurrency } from '~/logic/currencyValues/store/model/currencyValues'
|
||||
import { setCurrencySelected } from '~/logic/currencyValues/store/actions/setCurrencySelected'
|
||||
import type { Dispatch as ReduxDispatch } from 'redux'
|
||||
|
||||
import fetchTokenCurrenciesBalances from '~/logic/currencyValues/api/fetchTokenCurrenciesBalances'
|
||||
import { loadFromStorage } from '~/utils/storage'
|
||||
import fetchCurrencySelectedValue from '~/logic/currencyValues/store/actions/fetchCurrencySelectedValue'
|
||||
import { CURRENCY_SELECTED_KEY } from '~/logic/currencyValues/store/actions/saveCurrencySelected'
|
||||
import { setCurrencyBalances } from '~/logic/currencyValues/store/actions/setCurrencyBalances'
|
||||
import { setCurrencySelected } from '~/logic/currencyValues/store/actions/setCurrencySelected'
|
||||
import { AVAILABLE_CURRENCIES, makeBalanceCurrency } from '~/logic/currencyValues/store/model/currencyValues'
|
||||
import type { GlobalState } from '~/store'
|
||||
import { loadFromStorage } from '~/utils/storage'
|
||||
|
||||
export const fetchCurrencyValues = (safeAddress: string) => async (dispatch: ReduxDispatch<GlobalState>) => {
|
||||
try {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue