diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8442f310..64ab87f5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,6 +6,7 @@ on: branches: # this will run on the specified branch - master + - development env: REACT_APP_BLOCKNATIVE_KEY: ${{ secrets.REACT_APP_BLOCKNATIVE_KEY }} @@ -14,7 +15,7 @@ env: REACT_APP_INFURA_TOKEN: ${{ secrets.REACT_APP_INFURA_TOKEN }} REACT_APP_PORTIS_ID: ${{ secrets.REACT_APP_PORTIS_ID }} REACT_APP_GNOSIS_APPS_URL: ${{ secrets.REACT_APP_GNOSIS_APPS_URL }} - + REACT_APP_INTERCOM_ID: ${{ secrets.REACT_APP_INTERCOM_ID }} jobs: release: runs-on: ${{ matrix.os }} @@ -28,20 +29,18 @@ jobs: steps: - name: Check out Git repository uses: actions/checkout@v2 - + - name: Patch node gyp on windows to support Visual Studio 2019 if: startsWith(matrix.os, 'windows') shell: powershell run: | yarn global add --production windows-build-tools --vs2015 --msvs_version=2015 - - name: Install node-gyp if: startsWith(matrix.os, 'windows') shell: powershell run: | yarn global add node-gyp yarn config set node_gyp "$_\node_modules\node-gyp\bin\node-gyp.js" - - name: Install Node.js, NPM and Yarn uses: actions/setup-node@v1 with: @@ -70,3 +69,25 @@ jobs: # If the commit is tagged with a version (e.g. "v1.0.0"), # release the app after building release: ${{ startsWith(github.ref, 'refs/tags/v') }} + + - name: 'Upload Artifacts OSX' + if: contains(github.ref, 'development') && startsWith(matrix.os, 'macos') + uses: actions/upload-artifact@v2 + with: + name: Desktop OSX + path: ./dist/Safe[ ]Multisig*.dmg + + - name: 'Upload Artifacts Linux' + if: contains(github.ref, 'development') && startsWith(matrix.os, 'ubuntu') + uses: actions/upload-artifact@v2 + with: + name: Desktop Linux + path: ./dist/Safe[ ]Multisig*.AppImage + + - name: 'Upload Artifacts Windows' + if: contains(github.ref, 'development') && startsWith(matrix.os, 'windows') + uses: actions/upload-artifact@v2 + with: + name: Desktop Windows + path: ./dist/Safe[ ]Multisig*.exe + diff --git a/config/webpack.config.prod.js b/config/webpack.config.prod.js index 9d3f67c5..cae3bcff 100644 --- a/config/webpack.config.prod.js +++ b/config/webpack.config.prod.js @@ -52,7 +52,7 @@ function ensureSlash(path, needsSlash) { // single-page apps that may serve index.html for nested URLs like /todos/42. // We can't use a relative path in HTML because we don't want to load something // like /todos/42/static/js/bundle.7289d.js. We have to know the root. -const buildDesktop = process.env.BUILD_FOR_DESKTOP +const buildDesktop = process.env.REACT_APP_BUILD_FOR_DESKTOP const homepagePath = require(paths.appPackageJson).homepage // var homepagePathname = homepagePath ? url.parse(homepagePath).pathname : '/'; diff --git a/package.json b/package.json index 7b34c5c1..ca2de4f9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "safe-react", - "version": "2.0.0", + "version": "2.1.0", "description": "Allowing crypto users manage funds in a safer way", "homepage": "https://github.com/gnosis/safe-react#readme", "bugs": { @@ -25,7 +25,7 @@ "electron-dev": "concurrently \"BROWSER=none yarn start\" \"wait-on http://localhost:3000 && electron .\"", "preelectron-pack": "yarn build", "build-mainnet": "cross-env REACT_APP_NETWORK=mainnet yarn build", - "build-desktop": "cross-env BUILD_FOR_DESKTOP=true yarn build-mainnet", + "build-desktop": "cross-env REACT_APP_BUILD_FOR_DESKTOP=true yarn build-mainnet", "flow": "flow", "format:staged": "lint-staged", "lint:check": "eslint './src/**/*.{js,jsx}'", @@ -48,11 +48,11 @@ "prettier --write" ] }, - "productName": "Safe Electron", + "productName": "Safe Multisig", "build": { "appId": "io.gnosis.safe.macos", "afterSign": "scripts/notarize.js", - "productName": "Safe Electron", + "productName": "Safe Multisig", "asar": true, "publish": [ { @@ -136,27 +136,27 @@ }, "dependencies": { "@gnosis.pm/safe-contracts": "1.1.1-dev.2", - "@gnosis.pm/util-contracts": "2.0.6", - "@gnosis.pm/safe-react-components": "https://github.com/gnosis/safe-react-components.git#a057248", - "@ledgerhq/hw-transport-node-hid": "5.12.0", - "@material-ui/core": "4.9.10", + "@gnosis.pm/safe-react-components": "https://github.com/gnosis/safe-react-components.git#a057248", + "@gnosis.pm/util-contracts": "2.0.6", + "@ledgerhq/hw-transport-node-hid": "5.15.0", + "@material-ui/core": "4.9.14", "@material-ui/icons": "4.9.1", "@material-ui/lab": "4.0.0-alpha.39", - "@openzeppelin/contracts": "^2.5.0", - "@testing-library/jest-dom": "5.5.0", - "@welldone-software/why-did-you-render": "4.0.8", + "@openzeppelin/contracts": "3.0.1", + "@testing-library/jest-dom": "5.7.0", + "@welldone-software/why-did-you-render": "4.2.1", "async-sema": "^3.1.0", "axios": "0.19.2", "bignumber.js": "9.0.0", - "bnc-onboard": "1.7.6", + "bnc-onboard": "1.9.0", "connected-react-router": "6.8.0", "cross-env": "^7.0.2", - "currency-flags": "^2.1.1", - "date-fns": "2.12.0", + "currency-flags": "2.1.2", + "date-fns": "2.13.0", "dotenv": "^8.2.0", "electron-is-dev": "^1.1.0", - "electron-log": "^4.1.1", - "electron-updater": "4.2.0", + "electron-log": "4.1.2", + "electron-updater": "4.3.1", "ethereum-ens": "0.8.0", "express": "^4.17.1", "final-form": "4.19.1", @@ -165,13 +165,13 @@ "immutable": "^4.0.0-rc.9", "install": "^0.13.0", "js-cookie": "^2.2.1", - "lint-staged": "10.1.3", + "lint-staged": "10.2.2", "material-ui-search-bar": "^1.0.0-beta.13", "notistack": "https://github.com/gnosis/notistack.git#v0.9.4", - "npm": "^6.14.4", + "npm": "6.14.5", "open": "^7.0.3", "optimize-css-assets-webpack-plugin": "5.0.3", - "polished": "3.5.1", + "polished": "3.6.3", "qrcode.react": "1.0.0", "query-string": "6.12.1", "react": "16.13.1", @@ -180,10 +180,10 @@ "react-final-form": "6.4.0", "react-final-form-listeners": "^1.0.2", "react-ga": "^2.7.0", - "react-hot-loader": "4.12.20", + "react-hot-loader": "4.12.21", "react-qr-reader": "^2.2.1", "react-redux": "7.2.0", - "react-router-dom": "5.1.2", + "react-router-dom": "5.2.0", "react-window": "^1.8.5", "recompose": "^0.30.0", "redux": "4.0.5", @@ -192,8 +192,8 @@ "reselect": "^4.0.0", "semver": "7.3.2", "styled-components": "^5.0.1", - "wait-on": "^4.0.1", - "web3": "1.2.6" + "wait-on": "5.0.0", + "web3": "1.2.7" }, "devDependencies": { "@babel/cli": "7.8.4", @@ -220,13 +220,13 @@ "@babel/preset-env": "7.9.5", "@babel/preset-flow": "7.9.0", "@babel/preset-react": "7.9.4", - "@testing-library/react": "10.0.2", + "@testing-library/react": "10.0.3", "autoprefixer": "9.7.6", "babel-core": "^7.0.0-bridge.0", "babel-eslint": "10.1.0", - "babel-jest": "25.3.0", + "babel-jest": "25.4.0", "babel-loader": "8.1.0", - "babel-plugin-dynamic-import-node": "^2.3.0", + "babel-plugin-dynamic-import-node": "2.3.3", "babel-plugin-transform-es3-member-expression-literals": "^6.22.0", "babel-plugin-transform-es3-property-literals": "^6.22.0", "babel-polyfill": "^6.26.0", @@ -239,37 +239,37 @@ "electron-builder": "22.2.0", "electron-notarize": "^0.2.1", "eslint": "^6.8.0", - "eslint-config-prettier": "6.10.1", + "eslint-config-prettier": "6.11.0", "eslint-plugin-flowtype": "4.7.0", "eslint-plugin-import": "2.20.2", "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", + "eslint-plugin-sort-destructure-keys": "1.3.4", "ethereumjs-abi": "0.6.8", "extract-text-webpack-plugin": "^4.0.0-beta.0", "file-loader": "6.0.0", - "flow-bin": "0.122.0", + "flow-bin": "0.123.0", "fs-extra": "9.0.0", "html-loader": "1.1.0", "html-webpack-plugin": "4.2.0", "husky": "^4.2.2", - "jest": "25.3.0", + "jest": "25.4.0", "jest-dom": "4.0.0", "json-loader": "^0.5.7", "mini-css-extract-plugin": "0.9.0", "postcss-loader": "^3.0.0", "postcss-mixins": "6.2.3", "postcss-simple-vars": "^5.0.2", - "prettier": "2.0.4", + "prettier": "2.0.5", "run-with-testrpc": "0.3.1", "style-loader": "1.1.4", "terser-webpack-plugin": "2.3.5", - "truffle": "5.1.21", + "truffle": "5.1.23", "truffle-contract": "4.0.31", "truffle-solidity-loader": "0.1.32", "url-loader": "4.1.0", - "webpack": "4.42.1", + "webpack": "4.43.0", "webpack-bundle-analyzer": "3.7.0", "webpack-cli": "3.3.11", "webpack-dev-server": "3.10.3", diff --git a/public/electron.js b/public/electron.js index c0f1926c..0559083c 100644 --- a/public/electron.js +++ b/public/electron.js @@ -129,14 +129,18 @@ function createWindow() { autoUpdater.init(mainWindow); }); - mainWindow.webContents.on('crashed', () => { - log.info('App Crashed'); + mainWindow.webContents.on('crashed', (event) => { + log.info(`App Crashed: ${event}`); mainWindow.reload(); }); mainWindow.on("closed", () => (mainWindow = null)); } +process.on('uncaughtException',function(error){ + log.error(error); +}); + app.userAgentFallback = process.platform ==='win32' ? 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.100 Safari/537.36' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) old-airport-include/1.0.0 Chrome Electron/7.1.7 Safari/537.36'; @@ -144,7 +148,7 @@ app.userAgentFallback = process.platform ==='win32' ? app.commandLine.appendSwitch('ignore-certificate-errors'); app.on("ready", () =>{ // Hide the menu - //Menu.setApplicationMenu(null); + Menu.setApplicationMenu(null); if(!isDev) createServer(); createWindow(); }); diff --git a/scripts/preload.js b/scripts/preload.js index 322e2fa7..75069a22 100644 --- a/scripts/preload.js +++ b/scripts/preload.js @@ -2,11 +2,21 @@ // It has the same sandbox as a Chrome extension. const TransportNodeHid = require("@ledgerhq/hw-transport-node-hid").default; +const log = require('electron-log'); window.TransportNodeHid = TransportNodeHid; window.isDesktop = true; window.addEventListener('DOMContentLoaded', () => { + console.error = (...args) => { + log.error(...args) + } + console.warn = (...args) => { + log.warn(...args) + } + console.log = (...args) => { + log.info(...args) + } const replaceText = (selector, text) => { const element = document.getElementById(selector) if (element) element.innerText = text diff --git a/src/components-v2/layouts/ListContentLayout/Layout.jsx b/src/components-v2/layouts/ListContentLayout/Layout.jsx index 0228ed6d..bc748ae3 100644 --- a/src/components-v2/layouts/ListContentLayout/Layout.jsx +++ b/src/components-v2/layouts/ListContentLayout/Layout.jsx @@ -28,6 +28,22 @@ export const Menu = styled.div.attrs(() => ({ className: 'background' }))` border-top-left-radius: 8px; border-bottom-left-radius: 8px; background-color: white; + overflow-y: auto; + + ::-webkit-scrollbar { + width: 0.7em !important; + scroll-behavior: smooth !important; + } + + ::-webkit-scrollbar-track { + -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3) !important; + } + + ::-webkit-scrollbar-thumb { + background-color: darkgrey !important; + outline: 1px solid slategrey !important; + border-radius: 10px !important; + } ` export const Content = styled.div.attrs(() => ({ className: 'background' }))` diff --git a/src/components/CookiesBanner/index.jsx b/src/components/CookiesBanner/index.jsx index b8dcd88e..6b1edba3 100644 --- a/src/components/CookiesBanner/index.jsx +++ b/src/components/CookiesBanner/index.jsx @@ -17,6 +17,8 @@ import { mainFontFamily, md, primary, screenSm } from '~/theme/variables' import { loadGoogleAnalytics } from '~/utils/googleAnalytics' import { loadIntercom } from '~/utils/intercom' +const isDesktop = process.env.REACT_APP_BUILD_FOR_DESKTOP + const useStyles = makeStyles({ container: { backgroundColor: '#fff', @@ -111,14 +113,18 @@ const CookiesBanner = () => { fetchCookiesFromStorage() }, [showBanner]) + useEffect(() => { + if (isDesktop && showBanner) acceptCookiesHandler() + }, [isDesktop, showBanner]) + const acceptCookiesHandler = async () => { const newState = { acceptedNecessary: true, - acceptedAnalytics: true, + acceptedAnalytics: !isDesktop, } await saveCookie(COOKIES_KEY, newState, 365) dispatch(openCookieBanner(false)) - setShowAnalytics(true) + setShowAnalytics(!isDesktop) } const closeCookiesBannerHandler = async () => { @@ -193,8 +199,9 @@ const CookiesBanner = () => { loadIntercom() loadGoogleAnalytics() } + if (isDesktop) loadIntercom() - return showBanner ? cookieBannerContent : null + return showBanner && !isDesktop ? cookieBannerContent : null } export default CookiesBanner diff --git a/src/components/Header/components/ProviderDetails/UserDetails.jsx b/src/components/Header/components/ProviderDetails/UserDetails.jsx index 03933adc..c95618a8 100644 --- a/src/components/Header/components/ProviderDetails/UserDetails.jsx +++ b/src/components/Header/components/ProviderDetails/UserDetails.jsx @@ -29,6 +29,7 @@ type Props = { userAddress: string, classes: Object, onDisconnect: Function, + openDashboard?: Function, } const styles = () => ({ @@ -72,6 +73,15 @@ const styles = () => ({ }, disconnect: { padding: `${md} ${lg}`, + '& button': { + background: '#f02525', + }, + }, + dashboard: { + padding: `${md} ${lg} ${xs}`, + }, + dashboardText: { + letterSpacing: '1px', }, disconnectText: { letterSpacing: '1px', @@ -92,7 +102,7 @@ const styles = () => ({ }, }) -const UserDetails = ({ classes, connected, network, onDisconnect, provider, userAddress }: Props) => { +const UserDetails = ({ classes, connected, network, onDisconnect, openDashboard, provider, userAddress }: Props) => { const status = connected ? 'Connected' : 'Connection error' const address = userAddress ? shortVersionOf(userAddress, 4) : 'Address not available' const identiconAddress = userAddress || 'random' @@ -154,6 +164,15 @@ const UserDetails = ({ classes, connected, network, onDisconnect, provider, user + {openDashboard && ( + + + + )}