mirror of
https://github.com/kremalicious/blowfish.git
synced 2024-11-22 09:47:00 +01:00
commit
f4cb6dc52c
@ -5,14 +5,9 @@
|
|||||||
"prettier",
|
"prettier",
|
||||||
"prettier/react"
|
"prettier/react"
|
||||||
],
|
],
|
||||||
"parser": "babel-eslint",
|
|
||||||
"plugins": ["react"],
|
"plugins": ["react"],
|
||||||
"rules": {
|
|
||||||
"quotes": ["error", "single"],
|
|
||||||
"semi": ["error", "never"]
|
|
||||||
},
|
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaVersion": 2017,
|
"ecmaVersion": 2020,
|
||||||
"sourceType": "module",
|
"sourceType": "module",
|
||||||
"ecmaFeatures": {
|
"ecmaFeatures": {
|
||||||
"jsx": true
|
"jsx": true
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,7 +1,7 @@
|
|||||||
node_modules
|
node_modules
|
||||||
build
|
|
||||||
dist
|
dist
|
||||||
coverage
|
coverage
|
||||||
|
app
|
||||||
.next
|
.next
|
||||||
out
|
out
|
||||||
.env
|
.env
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"plugins": ["stylelint-prettier"],
|
|
||||||
"rules": {
|
|
||||||
"prettier/prettier": true
|
|
||||||
}
|
|
||||||
}
|
|
@ -23,7 +23,7 @@ before_script:
|
|||||||
script:
|
script:
|
||||||
- npm test || travis_terminate 1
|
- npm test || travis_terminate 1
|
||||||
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
||||||
- npm run dist
|
- npm run build
|
||||||
|
|
||||||
branches:
|
branches:
|
||||||
except:
|
except:
|
||||||
|
18
README.md
18
README.md
@ -91,20 +91,14 @@ When building the app yourself, you can configure more in the `src/config.js` fi
|
|||||||
## Build packages
|
## Build packages
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run dist
|
npm run build
|
||||||
```
|
```
|
||||||
|
|
||||||
Will build and package the app into platform specific packages for macOS, Windows & Linux.
|
Will build and package the app into platform specific packages for macOS, Windows & Linux.
|
||||||
|
|
||||||
On a Mac and Linux machine, packaging requires [`wine`](https://www.winehq.org) in your `PATH`. To install on macOS with [Homebrew](https://brew.sh):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
brew install wine
|
|
||||||
```
|
|
||||||
|
|
||||||
## Creating Releases
|
## Creating Releases
|
||||||
|
|
||||||
From a clean `main` branch, running any release task will do the following:
|
From a clean `main` branch, running the release task will do the following:
|
||||||
|
|
||||||
- bumps the project version
|
- bumps the project version
|
||||||
- creates a Git tag
|
- creates a Git tag
|
||||||
@ -112,11 +106,9 @@ From a clean `main` branch, running any release task will do the following:
|
|||||||
- creates a GitHub release with commit messages as description
|
- creates a GitHub release with commit messages as description
|
||||||
- adds freshly build binaries for macOS, Windows & Linux as assets to each GitHub release
|
- adds freshly build binaries for macOS, Windows & Linux as assets to each GitHub release
|
||||||
|
|
||||||
You can execute the script using {major|minor|patch} as first argument to bump the version accordingly:
|
```bash
|
||||||
|
npm run release
|
||||||
- To bump a patch version: `npm run release`
|
```
|
||||||
- To bump a minor version: `npm run release minor`
|
|
||||||
- To bump a major version: `npm run release major`
|
|
||||||
|
|
||||||
For the GitHub releases steps a GitHub personal access token, exported as `GITHUB_TOKEN` is required. [Setup](https://github.com/release-it/release-it#github-releases)
|
For the GitHub releases steps a GitHub personal access token, exported as `GITHUB_TOKEN` is required. [Setup](https://github.com/release-it/release-it#github-releases)
|
||||||
|
|
||||||
|
16
electron-builder.json
Normal file
16
electron-builder.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"appId": "com.kremalicious.blowfish",
|
||||||
|
"directories": { "buildResources": "./src/resources" },
|
||||||
|
"files": ["app", "package.json"],
|
||||||
|
"mac": {
|
||||||
|
"category": "public.app-category.finance",
|
||||||
|
"identity": null,
|
||||||
|
"darkModeSupport": true
|
||||||
|
},
|
||||||
|
"linux": {
|
||||||
|
"target": ["deb", "snap", "AppImage"],
|
||||||
|
"category": "Office",
|
||||||
|
"executableName": "Blowfish",
|
||||||
|
"artifactName": "${productName}-${version}.${ext}"
|
||||||
|
}
|
||||||
|
}
|
4
nextron.config.js
Normal file
4
nextron.config.js
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
module.exports = {
|
||||||
|
mainSrcDir: './src/main',
|
||||||
|
rendererSrcDir: './src/renderer'
|
||||||
|
}
|
6991
package-lock.json
generated
6991
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
76
package.json
76
package.json
@ -3,25 +3,21 @@
|
|||||||
"productName": "Blowfish",
|
"productName": "Blowfish",
|
||||||
"version": "1.5.2",
|
"version": "1.5.2",
|
||||||
"description": "🐡 Simple Electron-based desktop app to retrieve and display your total Ocean Token balances.",
|
"description": "🐡 Simple Electron-based desktop app to retrieve and display your total Ocean Token balances.",
|
||||||
"main": "./src/main/index.js",
|
"main": "app/background.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "electron .",
|
"start": "nextron",
|
||||||
|
"build": "nextron build --all",
|
||||||
|
"postinstall": "electron-builder install-app-deps",
|
||||||
"test": "npm run lint && npm run jest",
|
"test": "npm run lint && npm run jest",
|
||||||
"test:watch": "npm run jest -- --watch",
|
"test:watch": "npm run jest -- --watch",
|
||||||
"jest": "NODE_ENV=test jest -c tests/jest.config.js",
|
"jest": "NODE_ENV=test jest -c tests/jest.config.js",
|
||||||
"lint": "eslint --ignore-path .gitignore ./src/**/*.{js,jsx} && stylelint --ignore-path .gitignore ./src/**/*.{css,scss}",
|
"lint": "eslint --ignore-path .gitignore ./src/**/*.{js,jsx}",
|
||||||
"copy:icons": "copy 'src/renderer/images/icon*' build/",
|
"format": "prettier --write --ignore-path .gitignore 'src/**/*.{js,jsx,json,css,scss}'",
|
||||||
"build:react": "cross-env NODE_ENV=production next build src/renderer && next export src/renderer && npm run copy:icons",
|
"release": "release-it",
|
||||||
"build:electron:mac": "electron-builder build -m -p never",
|
"changelog": "auto-changelog -p"
|
||||||
"build:electron:linux": "electron-builder build -l -p never",
|
|
||||||
"build:electron:win": "electron-builder build -w -p never",
|
|
||||||
"dist": "./scripts/release-prepare.sh",
|
|
||||||
"release": "release-it --non-interactive",
|
|
||||||
"changelog": "auto-changelog -p",
|
|
||||||
"format": "prettier --write --ignore-path .gitignore 'src/**/*.{js,jsx,json,css,scss}'"
|
|
||||||
},
|
},
|
||||||
"repository": "https://github.com/kremalicious/blowfish.git",
|
"repository": "https://github.com/kremalicious/blowfish.git",
|
||||||
"homepage": "https://github.com/kremalicious/blowfish",
|
"homepage": "https://getblow.fish",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Matthias Kretschmann",
|
"name": "Matthias Kretschmann",
|
||||||
"email": "m@kretschmann.io",
|
"email": "m@kretschmann.io",
|
||||||
@ -29,12 +25,10 @@
|
|||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@coingecko/cryptoformat": "^0.4.1",
|
"@coingecko/cryptoformat": "^0.4.2",
|
||||||
"@oceanprotocol/contracts": "^0.5.3",
|
"@oceanprotocol/contracts": "^0.5.4",
|
||||||
"axios": "^0.20.0",
|
"axios": "^0.20.0",
|
||||||
"electron-is-dev": "^1.2.0",
|
"electron-store": "^6.0.1",
|
||||||
"electron-next": "^3.1.5",
|
|
||||||
"electron-store": "^6.0.0",
|
|
||||||
"ethereum-address": "^0.0.4",
|
"ethereum-address": "^0.0.4",
|
||||||
"ethereum-blockies": "github:MyEtherWallet/blockies",
|
"ethereum-blockies": "github:MyEtherWallet/blockies",
|
||||||
"ethjs": "^0.4.0",
|
"ethjs": "^0.4.0",
|
||||||
@ -43,61 +37,31 @@
|
|||||||
"swr": "^0.3.5"
|
"swr": "^0.3.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.11.6",
|
|
||||||
"@babel/preset-env": "^7.11.5",
|
|
||||||
"@jest-runner/electron": "^3.0.0",
|
"@jest-runner/electron": "^3.0.0",
|
||||||
"@react-mock/state": "^0.1.8",
|
"@react-mock/state": "^0.1.8",
|
||||||
"@svgr/webpack": "^5.4.0",
|
"@svgr/webpack": "^5.4.0",
|
||||||
"@testing-library/jest-dom": "^5.11.4",
|
"@testing-library/jest-dom": "^5.11.4",
|
||||||
"@testing-library/react": "^11.0.4",
|
"@testing-library/react": "^11.0.4",
|
||||||
"auto-changelog": "^2.2.1",
|
"auto-changelog": "^2.2.1",
|
||||||
"babel-eslint": "^10.1.0",
|
"babel-jest": "^26.5.2",
|
||||||
"babel-jest": "^26.3.0",
|
|
||||||
"copy": "^0.3.2",
|
|
||||||
"cross-env": "^7.0.2",
|
|
||||||
"dotenv": "^8.2.0",
|
"dotenv": "^8.2.0",
|
||||||
"electron": "^10.1.3",
|
"electron": "^10.1.3",
|
||||||
"electron-builder": "^22.8.1",
|
"electron-builder": "^22.8.1",
|
||||||
"electron-devtools-installer": "^3.1.1",
|
"electron-serve": "^1.0.0",
|
||||||
"eslint": "^7.10.0",
|
"eslint": "^7.11.0",
|
||||||
"eslint-config-prettier": "^6.12.0",
|
"eslint-config-prettier": "^6.12.0",
|
||||||
"eslint-plugin-react": "^7.21.3",
|
"eslint-plugin-react": "^7.21.4",
|
||||||
"identity-obj-proxy": "^3.0.0",
|
"identity-obj-proxy": "^3.0.0",
|
||||||
"jest": "^26.4.2",
|
"jest": "^26.5.2",
|
||||||
"next": "^9.5.3",
|
"next": "9.5.1",
|
||||||
|
"nextron": "^5.15.2",
|
||||||
"prettier": "^2.1.2",
|
"prettier": "^2.1.2",
|
||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
"react-dom": "^16.13.1",
|
"react-dom": "^16.13.1",
|
||||||
"react-pose": "^4.0.10",
|
"react-pose": "^4.0.10",
|
||||||
"release-it": "^14.0.3",
|
"release-it": "^14.0.4"
|
||||||
"stylelint": "^13.7.2",
|
|
||||||
"stylelint-prettier": "^1.1.2"
|
|
||||||
},
|
},
|
||||||
"browserslist": "electron >= 8.0",
|
"browserslist": "electron >= 8.0",
|
||||||
"build": {
|
|
||||||
"appId": "com.kremalicious.blowfish",
|
|
||||||
"files": [
|
|
||||||
"./src/main/**/*",
|
|
||||||
"./src/renderer/out/**/*",
|
|
||||||
"./src/*.js",
|
|
||||||
"package.json"
|
|
||||||
],
|
|
||||||
"mac": {
|
|
||||||
"category": "public.app-category.finance",
|
|
||||||
"identity": null,
|
|
||||||
"darkModeSupport": true
|
|
||||||
},
|
|
||||||
"linux": {
|
|
||||||
"target": [
|
|
||||||
"deb",
|
|
||||||
"snap",
|
|
||||||
"AppImage"
|
|
||||||
],
|
|
||||||
"category": "Office",
|
|
||||||
"executableName": "Blowfish",
|
|
||||||
"artifactName": "${productName}-${version}.${ext}"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"release-it": {
|
"release-it": {
|
||||||
"hooks": {
|
"hooks": {
|
||||||
"after:init": "npm test",
|
"after:init": "npm test",
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
rm -rf {dist,build,src/renderer/.next,src/renderer/out}/ && \
|
|
||||||
npm run build:react && \
|
|
||||||
npm run build:electron:mac && \
|
|
||||||
|
|
||||||
if [ -x "$(command -v docker)" ]; then
|
|
||||||
docker run --rm \
|
|
||||||
--env-file <(env | grep -iE 'DEBUG|NODE_|ELECTRON_|YARN_|NPM_|CI|CIRCLE|TRAVIS_TAG|TRAVIS|TRAVIS_REPO_|TRAVIS_BUILD_|TRAVIS_BRANCH|TRAVIS_PULL_REQUEST_|APPVEYOR_|CSC_|GH_|GITHUB_|BT_|AWS_|STRIP|BUILD_') \
|
|
||||||
--env ELECTRON_CACHE="/root/.cache/electron" \
|
|
||||||
--env ELECTRON_BUILDER_CACHE="/root/.cache/electron-builder" \
|
|
||||||
-v ${PWD}:/project \
|
|
||||||
-v ${PWD##*/}-node-modules:/project/node_modules \
|
|
||||||
-v ~/.cache/electron:/root/.cache/electron \
|
|
||||||
-v ~/.cache/electron-builder:/root/.cache/electron-builder \
|
|
||||||
electronuserland/builder:wine \
|
|
||||||
/bin/bash -c "npm i && npm run build:react && npm run build:electron:win"
|
|
||||||
|
|
||||||
docker run --rm \
|
|
||||||
--env-file <(env | grep -iE 'DEBUG|NODE_|ELECTRON_|YARN_|NPM_|CI|CIRCLE|TRAVIS_TAG|TRAVIS|TRAVIS_REPO_|TRAVIS_BUILD_|TRAVIS_BRANCH|TRAVIS_PULL_REQUEST_|APPVEYOR_|CSC_|GH_|GITHUB_|BT_|AWS_|STRIP|BUILD_') \
|
|
||||||
--env ELECTRON_CACHE="/root/.cache/electron" \
|
|
||||||
--env ELECTRON_BUILDER_CACHE="/root/.cache/electron-builder" \
|
|
||||||
-v ${PWD}:/project \
|
|
||||||
-v ${PWD##*/}-node-modules:/project/node_modules \
|
|
||||||
-v ~/.cache/electron:/root/.cache/electron \
|
|
||||||
-v ~/.cache/electron-builder:/root/.cache/electron-builder \
|
|
||||||
electronuserland/builder:12 \
|
|
||||||
/bin/bash -c "npm i && npm run build:react && npm run build:electron:linux"
|
|
||||||
fi
|
|
149
src/main/background.js
Normal file
149
src/main/background.js
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
import serve from 'electron-serve'
|
||||||
|
import { app, systemPreferences, nativeTheme, ipcMain } from 'electron'
|
||||||
|
import { productName } from '../../package.json'
|
||||||
|
import {
|
||||||
|
createWindow,
|
||||||
|
createWindowEvents,
|
||||||
|
buildMenu,
|
||||||
|
buildTouchbar,
|
||||||
|
updateTouchbar
|
||||||
|
} from './helpers'
|
||||||
|
import { rgbaToHex } from '../utils'
|
||||||
|
|
||||||
|
const isProd = process.env.NODE_ENV === 'production'
|
||||||
|
|
||||||
|
if (isProd) {
|
||||||
|
serve({ directory: 'app' })
|
||||||
|
} else {
|
||||||
|
app.setPath('userData', `${app.getPath('userData')} (development)`)
|
||||||
|
}
|
||||||
|
|
||||||
|
let mainWindow
|
||||||
|
|
||||||
|
const width = 640
|
||||||
|
const height = 450
|
||||||
|
|
||||||
|
;(async () => {
|
||||||
|
await app.whenReady()
|
||||||
|
|
||||||
|
const isDarkMode = nativeTheme.shouldUseDarkColors
|
||||||
|
|
||||||
|
mainWindow = createWindow('main', {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
minWidth: width,
|
||||||
|
minHeight: height,
|
||||||
|
acceptFirstMouse: true,
|
||||||
|
titleBarStyle: 'hiddenInset',
|
||||||
|
fullscreenWindowTitle: true,
|
||||||
|
backgroundColor: isDarkMode ? '#141414' : '#fff',
|
||||||
|
frame: process.platform === 'darwin' ? false : true,
|
||||||
|
show: false,
|
||||||
|
title: productName,
|
||||||
|
autoHideMenuBar: true,
|
||||||
|
webPreferences: {
|
||||||
|
nodeIntegration: true,
|
||||||
|
scrollBounce: true,
|
||||||
|
enableBlinkFeatures: 'OverlayScrollbars',
|
||||||
|
enableRemoteModule: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (isProd) {
|
||||||
|
await mainWindow.loadURL('app://./index.html')
|
||||||
|
} else {
|
||||||
|
const port = process.argv[2]
|
||||||
|
await mainWindow.loadURL(`http://localhost:${port}/`)
|
||||||
|
// mainWindow.webContents.openDevTools()
|
||||||
|
}
|
||||||
|
|
||||||
|
createWindowEvents(mainWindow)
|
||||||
|
|
||||||
|
mainWindow.once('ready-to-show', () => {
|
||||||
|
mainWindow.show()
|
||||||
|
mainWindow.focus()
|
||||||
|
})
|
||||||
|
|
||||||
|
// Load menu
|
||||||
|
buildMenu(mainWindow)
|
||||||
|
|
||||||
|
// Load touchbar
|
||||||
|
if (process.platform === 'darwin') {
|
||||||
|
const accentColor = getAccentColor()
|
||||||
|
buildTouchbar(mainWindow, accentColor)
|
||||||
|
|
||||||
|
ipcMain.on('prices-updated', (event, pricesNew) => {
|
||||||
|
updateTouchbar(pricesNew, mainWindow, accentColor)
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.on('currency-updated', (event, pricesNew, currentCurrency) => {
|
||||||
|
updateTouchbar(pricesNew, mainWindow, accentColor, currentCurrency)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
switchAccentColor()
|
||||||
|
switchTheme()
|
||||||
|
|
||||||
|
// add platform as class
|
||||||
|
mainWindow.webContents.executeJavaScript(
|
||||||
|
`document.getElementsByTagName('html')[0].classList.add('${process.platform}')`
|
||||||
|
)
|
||||||
|
})()
|
||||||
|
|
||||||
|
app.on('window-all-closed', () => {
|
||||||
|
if (process.platform !== 'darwin') {
|
||||||
|
app.quit()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//
|
||||||
|
// Accent color setting
|
||||||
|
// macOS & Windows
|
||||||
|
//
|
||||||
|
const getAccentColor = () => {
|
||||||
|
const systemAccentColor = systemPreferences.getAccentColor()
|
||||||
|
return rgbaToHex(systemAccentColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
const switchAccentColor = () => {
|
||||||
|
if (process.platform !== 'linux') {
|
||||||
|
const accentColor = getAccentColor()
|
||||||
|
mainWindow.webContents.send('accent-color', accentColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen for accent color changes in System Preferences
|
||||||
|
// macOS
|
||||||
|
if (process.platform === 'darwin') {
|
||||||
|
systemPreferences.subscribeNotification('AppleAquaColorVariantChanged', () =>
|
||||||
|
switchAccentColor()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Windows
|
||||||
|
if (process.platform === 'windows') {
|
||||||
|
systemPreferences.on('accent-color-changed', () => switchAccentColor())
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Appearance setting
|
||||||
|
//
|
||||||
|
const switchTheme = () => {
|
||||||
|
const isDarkMode = nativeTheme.shouldUseDarkColors
|
||||||
|
|
||||||
|
isDarkMode
|
||||||
|
? mainWindow.webContents.executeJavaScript(
|
||||||
|
'document.getElementsByTagName("html")[0].classList.add("dark")'
|
||||||
|
)
|
||||||
|
: mainWindow.webContents.executeJavaScript(
|
||||||
|
'document.getElementsByTagName("html")[0].classList.remove("dark")'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen for appearance changes in System Preferences
|
||||||
|
if (process.platform === 'darwin') {
|
||||||
|
systemPreferences.subscribeNotification(
|
||||||
|
'AppleInterfaceThemeChangedNotification',
|
||||||
|
() => switchTheme()
|
||||||
|
)
|
||||||
|
}
|
@ -1,8 +1,8 @@
|
|||||||
const { app, Menu } = require('electron')
|
import { app, Menu } from 'electron'
|
||||||
const { openUrl } = require('../utils')
|
import { openUrl } from '../../utils'
|
||||||
const { homepage } = require('../../package.json')
|
import { homepage } from '../../../package.json'
|
||||||
|
|
||||||
const buildMenu = (mainWindow) => {
|
export default function buildMenu(mainWindow) {
|
||||||
const template = [
|
const template = [
|
||||||
{
|
{
|
||||||
label: 'Edit',
|
label: 'Edit',
|
||||||
@ -179,5 +179,3 @@ const buildMenu = (mainWindow) => {
|
|||||||
const menu = Menu.buildFromTemplate(template)
|
const menu = Menu.buildFromTemplate(template)
|
||||||
Menu.setApplicationMenu(menu)
|
Menu.setApplicationMenu(menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = buildMenu
|
|
22
src/main/helpers/create-window-events.js
Normal file
22
src/main/helpers/create-window-events.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
export default function createWindowEvents(mainWindow) {
|
||||||
|
mainWindow.on('enter-full-screen', () =>
|
||||||
|
mainWindow.webContents.executeJavaScript(
|
||||||
|
'document.getElementsByTagName("html")[0].classList.add("fullscreen")'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
mainWindow.on('leave-full-screen', () =>
|
||||||
|
mainWindow.webContents.executeJavaScript(
|
||||||
|
'document.getElementsByTagName("html")[0].classList.remove("fullscreen")'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
mainWindow.on('blur', () =>
|
||||||
|
mainWindow.webContents.executeJavaScript(
|
||||||
|
'document.getElementsByTagName("html")[0].classList.add("blur")'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
mainWindow.on('focus', () =>
|
||||||
|
mainWindow.webContents.executeJavaScript(
|
||||||
|
'document.getElementsByTagName("html")[0].classList.remove("blur")'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
78
src/main/helpers/create-window.js
Normal file
78
src/main/helpers/create-window.js
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import { screen, BrowserWindow } from 'electron'
|
||||||
|
import * as Store from 'electron-store'
|
||||||
|
|
||||||
|
export default function createWindow(windowName, options) {
|
||||||
|
const key = 'window-state'
|
||||||
|
const name = `window-state-${windowName}`
|
||||||
|
const store = new Store({ name })
|
||||||
|
const defaultSize = {
|
||||||
|
width: options.width,
|
||||||
|
height: options.height
|
||||||
|
}
|
||||||
|
let state = {}
|
||||||
|
let win
|
||||||
|
|
||||||
|
const restore = () => store.get(key, defaultSize)
|
||||||
|
|
||||||
|
const getCurrentPosition = () => {
|
||||||
|
const position = win.getPosition()
|
||||||
|
const size = win.getSize()
|
||||||
|
return {
|
||||||
|
x: position[0],
|
||||||
|
y: position[1],
|
||||||
|
width: size[0],
|
||||||
|
height: size[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const windowWithinBounds = (windowState, bounds) => {
|
||||||
|
return (
|
||||||
|
windowState.x >= bounds.x &&
|
||||||
|
windowState.y >= bounds.y &&
|
||||||
|
windowState.x + windowState.width <= bounds.x + bounds.width &&
|
||||||
|
windowState.y + windowState.height <= bounds.y + bounds.height
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const resetToDefaults = () => {
|
||||||
|
const bounds = screen.getPrimaryDisplay().bounds
|
||||||
|
return Object.assign({}, defaultSize, {
|
||||||
|
x: (bounds.width - defaultSize.width) / 2,
|
||||||
|
y: (bounds.height - defaultSize.height) / 2
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const ensureVisibleOnSomeDisplay = (windowState) => {
|
||||||
|
const visible = screen.getAllDisplays().some((display) => {
|
||||||
|
return windowWithinBounds(windowState, display.bounds)
|
||||||
|
})
|
||||||
|
if (!visible) {
|
||||||
|
// Window is partially or fully not visible now.
|
||||||
|
// Reset it to safe defaults.
|
||||||
|
return resetToDefaults()
|
||||||
|
}
|
||||||
|
return windowState
|
||||||
|
}
|
||||||
|
|
||||||
|
const saveState = () => {
|
||||||
|
if (!win.isMinimized() && !win.isMaximized()) {
|
||||||
|
Object.assign(state, getCurrentPosition())
|
||||||
|
}
|
||||||
|
store.set(key, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
state = ensureVisibleOnSomeDisplay(restore())
|
||||||
|
|
||||||
|
win = new BrowserWindow({
|
||||||
|
...options,
|
||||||
|
...state,
|
||||||
|
webPreferences: {
|
||||||
|
nodeIntegration: true,
|
||||||
|
...options.webPreferences
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
win.on('close', saveState)
|
||||||
|
|
||||||
|
return win
|
||||||
|
}
|
12
src/main/helpers/index.js
Normal file
12
src/main/helpers/index.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import createWindow from './create-window'
|
||||||
|
import createWindowEvents from './create-window-events'
|
||||||
|
import buildMenu from './build-menu'
|
||||||
|
import { buildTouchbar, updateTouchbar } from './touchbar'
|
||||||
|
|
||||||
|
export {
|
||||||
|
createWindow,
|
||||||
|
createWindowEvents,
|
||||||
|
buildMenu,
|
||||||
|
buildTouchbar,
|
||||||
|
updateTouchbar
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
const { TouchBar } = require('electron')
|
import { TouchBar } from 'electron'
|
||||||
const { cryptoFormatter } = require('../utils')
|
import { cryptoFormatter } from '../../utils'
|
||||||
const { conversions } = require('../config')
|
import { conversions } from '../../config'
|
||||||
|
|
||||||
const { TouchBarButton } = TouchBar
|
const { TouchBarButton } = TouchBar
|
||||||
|
|
||||||
@ -51,4 +51,4 @@ const updateTouchbar = (
|
|||||||
mainWindow.setTouchBar(touchBar)
|
mainWindow.setTouchBar(touchBar)
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { buildTouchbar, updateTouchbar }
|
export { buildTouchbar, updateTouchbar }
|
@ -1,214 +0,0 @@
|
|||||||
const path = require('path')
|
|
||||||
const {
|
|
||||||
app,
|
|
||||||
BrowserWindow,
|
|
||||||
systemPreferences,
|
|
||||||
nativeTheme,
|
|
||||||
ipcMain
|
|
||||||
} = require('electron')
|
|
||||||
const prepareNext = require('electron-next')
|
|
||||||
const isDev = require('electron-is-dev')
|
|
||||||
const pkg = require('../../package.json')
|
|
||||||
const buildMenu = require('./menu')
|
|
||||||
const { buildTouchbar, updateTouchbar } = require('./touchbar')
|
|
||||||
const { rgbaToHex } = require('../utils')
|
|
||||||
|
|
||||||
let mainWindow
|
|
||||||
|
|
||||||
const width = 640
|
|
||||||
const height = 450
|
|
||||||
|
|
||||||
app.allowRendererProcessReuse = true
|
|
||||||
|
|
||||||
const createWindow = async () => {
|
|
||||||
const isDarkMode = nativeTheme.shouldUseDarkColors
|
|
||||||
|
|
||||||
mainWindow = new BrowserWindow({
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
minWidth: width,
|
|
||||||
minHeight: height,
|
|
||||||
acceptFirstMouse: true,
|
|
||||||
titleBarStyle: 'hiddenInset',
|
|
||||||
fullscreenWindowTitle: true,
|
|
||||||
backgroundColor: isDarkMode ? '#141414' : '#fff',
|
|
||||||
frame: process.platform === 'darwin' ? false : true,
|
|
||||||
show: false,
|
|
||||||
title: pkg.productName,
|
|
||||||
autoHideMenuBar: true,
|
|
||||||
webPreferences: {
|
|
||||||
nodeIntegration: true,
|
|
||||||
preload: path.join(__dirname, 'preload.js'),
|
|
||||||
scrollBounce: true,
|
|
||||||
enableBlinkFeatures: 'OverlayScrollbars',
|
|
||||||
enableRemoteModule: true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
mainWindow.loadURL(
|
|
||||||
isDev
|
|
||||||
? 'http://localhost:8000'
|
|
||||||
: `file://${path.join(__dirname, '../renderer/out/index.html')}`
|
|
||||||
)
|
|
||||||
|
|
||||||
createWindowEvents(mainWindow)
|
|
||||||
installDevTools(mainWindow)
|
|
||||||
|
|
||||||
mainWindow.once('ready-to-show', () => {
|
|
||||||
mainWindow.show()
|
|
||||||
mainWindow.focus()
|
|
||||||
})
|
|
||||||
|
|
||||||
mainWindow.on('closed', () => {
|
|
||||||
mainWindow = null
|
|
||||||
})
|
|
||||||
|
|
||||||
// Load menu
|
|
||||||
buildMenu(mainWindow)
|
|
||||||
|
|
||||||
// Load touchbar
|
|
||||||
if (process.platform === 'darwin') {
|
|
||||||
const accentColor = getAccentColor()
|
|
||||||
buildTouchbar(mainWindow, accentColor)
|
|
||||||
|
|
||||||
ipcMain.on('prices-updated', (event, pricesNew) => {
|
|
||||||
updateTouchbar(pricesNew, mainWindow, accentColor)
|
|
||||||
})
|
|
||||||
|
|
||||||
ipcMain.on('currency-updated', (event, pricesNew, currentCurrency) => {
|
|
||||||
updateTouchbar(pricesNew, mainWindow, accentColor, currentCurrency)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
app.on('ready', async () => {
|
|
||||||
await prepareNext('./src/renderer')
|
|
||||||
await createWindow()
|
|
||||||
|
|
||||||
mainWindow.webContents.on('dom-ready', () => {
|
|
||||||
switchTheme()
|
|
||||||
|
|
||||||
// add platform as class
|
|
||||||
mainWindow.webContents.executeJavaScript(
|
|
||||||
`document.getElementsByTagName('html')[0].classList.add('${process.platform}')`
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
mainWindow.webContents.on('did-finish-load', () => {
|
|
||||||
switchAccentColor()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// Quit when all windows are closed.
|
|
||||||
app.on('window-all-closed', () => {
|
|
||||||
if (process.platform !== 'darwin') {
|
|
||||||
app.quit()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
app.on('activate', () => {
|
|
||||||
if (mainWindow === null) {
|
|
||||||
createWindow()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const installDevTools = async (mainWindow) => {
|
|
||||||
if (isDev) {
|
|
||||||
const {
|
|
||||||
default: installExtension,
|
|
||||||
REACT_DEVELOPER_TOOLS
|
|
||||||
} = require('electron-devtools-installer')
|
|
||||||
|
|
||||||
try {
|
|
||||||
const name = await installExtension(REACT_DEVELOPER_TOOLS)
|
|
||||||
console.log(`Added Extension: ${name}`) // eslint-disable-line no-console
|
|
||||||
|
|
||||||
mainWindow.webContents.on('devtools-opened', () =>
|
|
||||||
mainWindow.setSize(1024, 420, true)
|
|
||||||
)
|
|
||||||
mainWindow.webContents.on('devtools-closed', () =>
|
|
||||||
mainWindow.setSize(width, height, true)
|
|
||||||
)
|
|
||||||
} catch (error) {
|
|
||||||
console.log('An error occurred: ', error) // eslint-disable-line no-console
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const createWindowEvents = (mainWindow) => {
|
|
||||||
mainWindow.on('enter-full-screen', () =>
|
|
||||||
mainWindow.webContents.executeJavaScript(
|
|
||||||
'document.getElementsByTagName("html")[0].classList.add("fullscreen")'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
mainWindow.on('leave-full-screen', () =>
|
|
||||||
mainWindow.webContents.executeJavaScript(
|
|
||||||
'document.getElementsByTagName("html")[0].classList.remove("fullscreen")'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
mainWindow.on('blur', () =>
|
|
||||||
mainWindow.webContents.executeJavaScript(
|
|
||||||
'document.getElementsByTagName("html")[0].classList.add("blur")'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
mainWindow.on('focus', () =>
|
|
||||||
mainWindow.webContents.executeJavaScript(
|
|
||||||
'document.getElementsByTagName("html")[0].classList.remove("blur")'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Accent color setting
|
|
||||||
// macOS & Windows
|
|
||||||
//
|
|
||||||
const getAccentColor = () => {
|
|
||||||
const systemAccentColor = systemPreferences.getAccentColor()
|
|
||||||
return rgbaToHex(systemAccentColor)
|
|
||||||
}
|
|
||||||
|
|
||||||
const switchAccentColor = () => {
|
|
||||||
if (process.platform !== 'linux') {
|
|
||||||
const accentColor = getAccentColor()
|
|
||||||
mainWindow.webContents.send('accent-color', accentColor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listen for accent color changes in System Preferences
|
|
||||||
// macOS
|
|
||||||
if (process.platform === 'darwin') {
|
|
||||||
systemPreferences.subscribeNotification('AppleAquaColorVariantChanged', () =>
|
|
||||||
switchAccentColor()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Windows
|
|
||||||
if (process.platform === 'windows') {
|
|
||||||
systemPreferences.on('accent-color-changed', () => switchAccentColor())
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Appearance setting
|
|
||||||
// macOS
|
|
||||||
//
|
|
||||||
const switchTheme = () => {
|
|
||||||
if (process.platform === 'darwin') {
|
|
||||||
const isDarkMode = nativeTheme.shouldUseDarkColors
|
|
||||||
|
|
||||||
isDarkMode
|
|
||||||
? mainWindow.webContents.executeJavaScript(
|
|
||||||
'document.getElementsByTagName("html")[0].classList.add("dark")'
|
|
||||||
)
|
|
||||||
: mainWindow.webContents.executeJavaScript(
|
|
||||||
'document.getElementsByTagName("html")[0].classList.remove("dark")'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listen for appearance changes in System Preferences
|
|
||||||
if (process.platform === 'darwin') {
|
|
||||||
systemPreferences.subscribeNotification(
|
|
||||||
'AppleInterfaceThemeChangedNotification',
|
|
||||||
() => switchTheme()
|
|
||||||
)
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
const { webFrame, ipcRenderer } = require('electron')
|
|
||||||
const Store = require('electron-store')
|
|
||||||
|
|
||||||
// Since we disabled nodeIntegration we can reintroduce
|
|
||||||
// needed node functionality here
|
|
||||||
process.once('loaded', () => {
|
|
||||||
const store = new Store()
|
|
||||||
|
|
||||||
global.ipcRenderer = ipcRenderer
|
|
||||||
global.webFrame = webFrame
|
|
||||||
global.store = store
|
|
||||||
})
|
|
@ -1,5 +1,6 @@
|
|||||||
import React, { PureComponent } from 'react'
|
import React, { PureComponent } from 'react'
|
||||||
import ethereum_address from 'ethereum-address'
|
import ethereum_address from 'ethereum-address'
|
||||||
|
import electron from 'electron'
|
||||||
import Store from 'electron-store'
|
import Store from 'electron-store'
|
||||||
import { AppContext } from '../../../store/createContext'
|
import { AppContext } from '../../../store/createContext'
|
||||||
import Saved from './Saved'
|
import Saved from './Saved'
|
||||||
@ -9,12 +10,12 @@ import styles from './index.module.css'
|
|||||||
export default class AccountsList extends PureComponent {
|
export default class AccountsList extends PureComponent {
|
||||||
static contextType = AppContext
|
static contextType = AppContext
|
||||||
|
|
||||||
store = process.env.NODE_ENV === 'test' ? new Store() : global.store
|
store = (electron.remote && new Store()) || false
|
||||||
|
|
||||||
state = { accounts: [], input: '', error: '' }
|
state = { accounts: [], input: '', error: '' }
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
if (this.store.has('accounts')) {
|
if (this.store && this.store.has('accounts')) {
|
||||||
this.setState({ accounts: this.store.get('accounts') })
|
this.setState({ accounts: this.store.get('accounts') })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -46,7 +47,7 @@ export default class AccountsList extends PureComponent {
|
|||||||
} else {
|
} else {
|
||||||
const joined = [...accounts, input]
|
const joined = [...accounts, input]
|
||||||
|
|
||||||
this.store.set('accounts', joined)
|
this.store && this.store.set('accounts', joined)
|
||||||
this.setState({ accounts: joined, input: '', error: '' })
|
this.setState({ accounts: joined, input: '', error: '' })
|
||||||
this.context.setBalances()
|
this.context.setBalances()
|
||||||
}
|
}
|
||||||
@ -63,7 +64,7 @@ export default class AccountsList extends PureComponent {
|
|||||||
array.splice(index, 1)
|
array.splice(index, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.store.set('accounts', array)
|
this.store && this.store.set('accounts', array)
|
||||||
this.setState({ accounts: array })
|
this.setState({ accounts: array })
|
||||||
this.context.setBalances()
|
this.context.setBalances()
|
||||||
}
|
}
|
||||||
|
@ -38,12 +38,6 @@ module.exports = withSvgr(
|
|||||||
env: {
|
env: {
|
||||||
ETHERSCAN_API_KEY: process.env.ETHERSCAN_API_KEY,
|
ETHERSCAN_API_KEY: process.env.ETHERSCAN_API_KEY,
|
||||||
INFURA_PROJECT_ID: process.env.INFURA_PROJECT_ID
|
INFURA_PROJECT_ID: process.env.INFURA_PROJECT_ID
|
||||||
},
|
|
||||||
exportPathMap() {
|
|
||||||
return {
|
|
||||||
'/': { page: '/' },
|
|
||||||
'/preferences': { page: '/preferences' }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
import React, { useEffect } from 'react'
|
import React, { useEffect } from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import Router from 'next/router'
|
import Router from 'next/router'
|
||||||
// import { ipcRenderer } from 'electron'
|
import electron from 'electron'
|
||||||
import AppProvider from '../store/AppProvider'
|
import AppProvider from '../store/AppProvider'
|
||||||
import PriceProvider from '../store/PriceProvider'
|
import PriceProvider from '../store/PriceProvider'
|
||||||
import Layout from '../Layout'
|
import Layout from '../Layout'
|
||||||
|
|
||||||
import '../global.css'
|
import '../global.css'
|
||||||
|
|
||||||
|
const ipcRenderer = electron.ipcRenderer || false
|
||||||
|
|
||||||
export default function App({ Component, pageProps }) {
|
export default function App({ Component, pageProps }) {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
global.ipcRenderer.on('goTo', (evt, route) => {
|
ipcRenderer &&
|
||||||
|
ipcRenderer.on('goTo', (evt, route) => {
|
||||||
Router.push(route)
|
Router.push(route)
|
||||||
})
|
})
|
||||||
}, [])
|
}, [])
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
import React, { useContext, useState, useEffect } from 'react'
|
import React, { useContext, useState, useEffect } from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import ms from 'ms'
|
import ms from 'ms'
|
||||||
// import { ipcRenderer } from 'electron'
|
import electron from 'electron'
|
||||||
import { AppContext, PriceContext } from './createContext'
|
import { AppContext, PriceContext } from './createContext'
|
||||||
import { refreshInterval, conversions } from '../../config'
|
import { refreshInterval, conversions } from '../../config'
|
||||||
import { getAccounts, getBalance } from './helpers'
|
import { getAccounts, getBalance } from './helpers'
|
||||||
|
|
||||||
|
const ipcRenderer = electron.ipcRenderer || false
|
||||||
|
|
||||||
export default function AppProvider({ children }) {
|
export default function AppProvider({ children }) {
|
||||||
const { prices } = useContext(PriceContext)
|
const { prices } = useContext(PriceContext)
|
||||||
const [isLoading, setIsLoading] = useState(true)
|
const [isLoading, setIsLoading] = useState(true)
|
||||||
@ -15,12 +17,25 @@ export default function AppProvider({ children }) {
|
|||||||
const [accentColor, setAccentColor] = useState('#f6388a')
|
const [accentColor, setAccentColor] = useState('#f6388a')
|
||||||
const [error, setError] = useState()
|
const [error, setError] = useState()
|
||||||
|
|
||||||
|
function toggleCurrencies(currency) {
|
||||||
|
setCurrency(currency)
|
||||||
|
const pricesNew = Array.from(prices)
|
||||||
|
ipcRenderer && ipcRenderer.send('currency-updated', pricesNew, currency)
|
||||||
|
}
|
||||||
|
|
||||||
|
// listener for accent color & touchbar
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// listener for accent color
|
if (!ipcRenderer) return
|
||||||
if (process.env.NODE_ENV !== 'test') {
|
|
||||||
global.ipcRenderer.on('accent-color', (evt, accentColor) => {
|
ipcRenderer.on('accent-color', (evt, accentColor) => {
|
||||||
setAccentColor(accentColor)
|
setAccentColor(accentColor)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ipcRenderer.on('setCurrency', (evt, currency) => toggleCurrencies(currency))
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
ipcRenderer.removeAllListeners('accent-color')
|
||||||
|
ipcRenderer.removeAllListeners('setCurrency')
|
||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
@ -36,11 +51,6 @@ export default function AppProvider({ children }) {
|
|||||||
console.error(error.message)
|
console.error(error.message)
|
||||||
setError(error.message)
|
setError(error.message)
|
||||||
}
|
}
|
||||||
|
|
||||||
// listener for touchbar
|
|
||||||
global.ipcRenderer.on('setCurrency', (evt, currency) =>
|
|
||||||
toggleCurrencies(currency)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init()
|
init()
|
||||||
@ -81,12 +91,6 @@ export default function AppProvider({ children }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleCurrencies(currency) {
|
|
||||||
setCurrency(currency)
|
|
||||||
const pricesNew = Array.from(prices)
|
|
||||||
global.ipcRenderer.send('currency-updated', pricesNew, currency)
|
|
||||||
}
|
|
||||||
|
|
||||||
const context = {
|
const context = {
|
||||||
isLoading,
|
isLoading,
|
||||||
accounts,
|
accounts,
|
||||||
|
@ -6,6 +6,9 @@ import { fetchData } from '../../utils'
|
|||||||
import { convertPrices } from './helpers'
|
import { convertPrices } from './helpers'
|
||||||
import useSWR from 'swr'
|
import useSWR from 'swr'
|
||||||
import ms from 'ms'
|
import ms from 'ms'
|
||||||
|
import electron from 'electron'
|
||||||
|
|
||||||
|
const ipcRenderer = electron.ipcRenderer || false
|
||||||
|
|
||||||
export default function PriceProvider({ children }) {
|
export default function PriceProvider({ children }) {
|
||||||
// construct initial prices Map to get consistent
|
// construct initial prices Map to get consistent
|
||||||
@ -40,7 +43,7 @@ export default function PriceProvider({ children }) {
|
|||||||
|
|
||||||
setPrices(newPrices)
|
setPrices(newPrices)
|
||||||
setPriceChanges(newPriceChanges)
|
setPriceChanges(newPriceChanges)
|
||||||
global.ipcRenderer.send('prices-updated', Array.from(newPrices)) // convert Map to array, ipc messages seem to kill it
|
ipcRenderer && ipcRenderer.send('prices-updated', Array.from(newPrices)) // convert Map to array, ipc messages seem to kill it
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import electron from 'electron'
|
||||||
import Store from 'electron-store'
|
import Store from 'electron-store'
|
||||||
import Eth from 'ethjs'
|
import Eth from 'ethjs'
|
||||||
import { oceanTokenContract, conversions } from '../../config'
|
import { oceanTokenContract, conversions } from '../../config'
|
||||||
@ -30,9 +31,10 @@ export async function getBalance(account) {
|
|||||||
export async function getAccounts() {
|
export async function getAccounts() {
|
||||||
let needsConfig
|
let needsConfig
|
||||||
let accountsPref
|
let accountsPref
|
||||||
const store = process.env.NODE_ENV === 'test' ? new Store() : global.store
|
|
||||||
|
|
||||||
if (store.has('accounts')) {
|
const store = (electron.remote && new Store()) || false
|
||||||
|
|
||||||
|
if (store && store.has('accounts')) {
|
||||||
accountsPref = store.get('accounts')
|
accountsPref = store.get('accounts')
|
||||||
needsConfig = !accountsPref.length
|
needsConfig = !accountsPref.length
|
||||||
} else {
|
} else {
|
||||||
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 145 KiB After Width: | Height: | Size: 145 KiB |
@ -1,6 +1,6 @@
|
|||||||
const { app, shell } = require('electron')
|
import { app, shell } from 'electron'
|
||||||
const { formatCurrency } = require('@coingecko/cryptoformat')
|
import { formatCurrency } from '@coingecko/cryptoformat'
|
||||||
const axios = require('axios')
|
import axios from 'axios'
|
||||||
|
|
||||||
const fetchData = async (url) => {
|
const fetchData = async (url) => {
|
||||||
try {
|
try {
|
||||||
@ -75,7 +75,7 @@ const cryptoFormatter = (value, currency) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
export {
|
||||||
openUrl,
|
openUrl,
|
||||||
rgbaToHex,
|
rgbaToHex,
|
||||||
locale,
|
locale,
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {
|
import { render, fireEvent, waitFor } from '@testing-library/react'
|
||||||
render,
|
|
||||||
waitForElementToBeRemoved,
|
|
||||||
fireEvent,
|
|
||||||
wait
|
|
||||||
} from '@testing-library/react'
|
|
||||||
import AppProvider from '../src/renderer/store/AppProvider'
|
import AppProvider from '../src/renderer/store/AppProvider'
|
||||||
import PriceProvider from '../src/renderer/store/PriceProvider'
|
import PriceProvider from '../src/renderer/store/PriceProvider'
|
||||||
import { PriceContext, AppContext } from '../src/renderer/store/createContext'
|
import { PriceContext, AppContext } from '../src/renderer/store/createContext'
|
||||||
@ -20,7 +15,6 @@ describe('Providers', () => {
|
|||||||
</PriceContext.Consumer>
|
</PriceContext.Consumer>
|
||||||
</PriceProvider>
|
</PriceProvider>
|
||||||
)
|
)
|
||||||
await waitForElementToBeRemoved(() => getByText(/"eur":0/))
|
|
||||||
expect(getByText(/eur/)).toBeInTheDocument()
|
expect(getByText(/eur/)).toBeInTheDocument()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -38,7 +32,7 @@ describe('Providers', () => {
|
|||||||
</AppProvider>
|
</AppProvider>
|
||||||
</PriceContext.Provider>
|
</PriceContext.Provider>
|
||||||
)
|
)
|
||||||
await wait(() => getByText('Click'))
|
await waitFor(() => getByText('Click'))
|
||||||
expect(getByText('Click')).toBeInTheDocument()
|
expect(getByText('Click')).toBeInTheDocument()
|
||||||
|
|
||||||
fireEvent.click(getByText('Click'))
|
fireEvent.click(getByText('Click'))
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
has: () => jest.fn()
|
has: () => jest.fn(),
|
||||||
|
get: () => jest.fn()
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ module.exports = {
|
|||||||
'<rootDir>/src/renderer/.next',
|
'<rootDir>/src/renderer/.next',
|
||||||
'<rootDir>/src/renderer/out',
|
'<rootDir>/src/renderer/out',
|
||||||
'<rootDir>/node_modules',
|
'<rootDir>/node_modules',
|
||||||
'<rootDir>/build',
|
'<rootDir>/app',
|
||||||
'<rootDir>/dist',
|
'<rootDir>/dist',
|
||||||
'<rootDir>/coverage'
|
'<rootDir>/coverage'
|
||||||
],
|
],
|
||||||
|
Loading…
Reference in New Issue
Block a user