GUI to a separate repo (#859)
* GUI to a separate repo * correct repo name, codeql to just python * fetch-depth: 0 is indeed needed * remove debug ls's * Switch to a submodule * update blockchain gitignore * Return omitted cd to install-gui.sh
14
.github/dependabot.yml
vendored
@ -3,20 +3,6 @@
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
# Enable version updates for npm
|
||||
- package-ecosystem: "npm"
|
||||
# Look for `package.json` and `lock` files in the `root` directory
|
||||
directory: "electron-react "
|
||||
# Check the npm registry for updates every day (weekdays)
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
day: "tuesday"
|
||||
target-branch: "dev"
|
||||
pull-request-branch-name:
|
||||
# Separate sections of the branch name with a hyphen
|
||||
# for example, `dependabot-npm_and_yarn-next_js-acorn-6.4.1`
|
||||
separator: "-"
|
||||
|
||||
# Enable version updates for Python
|
||||
- package-ecosystem: "pip"
|
||||
# Look for a `Dockerfile` in the `root` directory
|
||||
|
11
.github/workflows/build-macos-installer.yml
vendored
@ -33,7 +33,7 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
# we need fetch-depth 0 so setuptools_scm can resolve tags
|
||||
submodules: recursive
|
||||
|
||||
- name: Setup Python environment
|
||||
uses: actions/setup-python@v2
|
||||
@ -84,6 +84,13 @@ jobs:
|
||||
p12-file-base64: ${{ secrets.APPLE_DEV_ID_APP }}
|
||||
p12-password: ${{ secrets.APPLE_DEV_ID_APP_PASS }}
|
||||
|
||||
- name: Checkout GUI
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: 'Chia-Network/chia-blockchain-gui'
|
||||
ref: 'main'
|
||||
path: './chia-blockchain-gui'
|
||||
|
||||
- name: Run install script
|
||||
env:
|
||||
INSTALL_PYTHON_VERSION: ${{ matrix.python-version }}
|
||||
@ -104,7 +111,7 @@ jobs:
|
||||
run: |
|
||||
. ./activate
|
||||
clang --version
|
||||
cd ./electron-react
|
||||
cd ./chia-blockchain-gui
|
||||
npm install
|
||||
npm audit fix
|
||||
cd ../build_scripts
|
||||
|
1
.github/workflows/build-test-macos-core.yml
vendored
@ -33,7 +33,6 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
# we need fetch-depth 0 so setuptools_scm can resolve tags
|
||||
|
||||
- name: Setup Python environment
|
||||
uses: actions/setup-python@v2
|
||||
|
@ -33,7 +33,6 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
# we need fetch-depth 0 so setuptools_scm can resolve tags
|
||||
|
||||
- name: Setup Python environment
|
||||
uses: actions/setup-python@v2
|
||||
|
1
.github/workflows/build-test-ubuntu-core.yml
vendored
@ -33,7 +33,6 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
# we need fetch-depth 0 so setuptools_scm can resolve tags
|
||||
|
||||
- name: Setup Python environment
|
||||
uses: actions/setup-python@v2
|
||||
|
@ -33,7 +33,6 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
# we need fetch-depth 0 so setuptools_scm can resolve tags
|
||||
|
||||
- name: Setup Python environment
|
||||
uses: actions/setup-python@v2
|
||||
|
146
.github/workflows/build-windows-installer.yml
vendored
@ -17,83 +17,91 @@ jobs:
|
||||
timeout-minutes: 30
|
||||
|
||||
steps:
|
||||
- name: Cancel previous runs on the same branch
|
||||
if: ${{ github.ref != 'refs/heads/dev' }}
|
||||
uses: styfle/cancel-workflow-action@0.7.0
|
||||
with:
|
||||
access_token: ${{ github.token }}
|
||||
- name: Cancel previous runs on the same branch
|
||||
if: ${{ github.ref != 'refs/heads/dev' }}
|
||||
uses: styfle/cancel-workflow-action@0.7.0
|
||||
with:
|
||||
access_token: ${{ github.token }}
|
||||
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
# we need fetch-depth 0 so setuptools_scm can resolve tags
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: recursive
|
||||
|
||||
- name: Get npm cache directory
|
||||
id: npm-cache
|
||||
run: |
|
||||
echo "::set-output name=dir::$(npm config get cache)"
|
||||
- name: Get npm cache directory
|
||||
id: npm-cache
|
||||
run: |
|
||||
echo "::set-output name=dir::$(npm config get cache)"
|
||||
|
||||
- name: Cache npm
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ steps.npm-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node-
|
||||
- name: Cache npm
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ steps.npm-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node-
|
||||
|
||||
- name: Get pip cache dir
|
||||
id: pip-cache
|
||||
run: |
|
||||
echo "::set-output name=dir::$(pip cache dir)"
|
||||
- name: Get pip cache dir
|
||||
id: pip-cache
|
||||
run: |
|
||||
echo "::set-output name=dir::$(pip cache dir)"
|
||||
|
||||
- name: Cache pip
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ steps.pip-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip-
|
||||
- name: Cache pip
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ steps.pip-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip-
|
||||
|
||||
- name: Test for secrets access
|
||||
id: check_secrets
|
||||
shell: bash
|
||||
run: |
|
||||
unset HAS_SECRET
|
||||
if [ -n "$SECRET" ]; then HAS_SECRET='true' ; fi
|
||||
echo ::set-output name=HAS_SECRET::${HAS_SECRET}
|
||||
env:
|
||||
SECRET: "${{ secrets.WIN_CODE_SIGN_CERT }}"
|
||||
# We can't upgrade to Python 3.8 until we have a miniupnpc binary
|
||||
- uses: actions/setup-python@v2
|
||||
name: Install Python 3.7
|
||||
with:
|
||||
python-version: "3.7"
|
||||
|
||||
- name: Decode code signing cert into an encrypted file
|
||||
if: steps.check_secrets.outputs.HAS_SECRET
|
||||
uses: kitek/decode-base64-into-file-action@1.0
|
||||
with:
|
||||
encoded-value: ${{ secrets.WIN_CODE_SIGN_CERT }}
|
||||
destination-file: .\electron-react\win_code_sign_cert.p12
|
||||
- name: Checkout GUI
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: 'Chia-Network/chia-blockchain-gui'
|
||||
ref: 'main'
|
||||
path: 'chia-blockchain-gui'
|
||||
|
||||
- uses: actions/setup-python@v2
|
||||
name: Install Python 3.7
|
||||
with:
|
||||
python-version: "3.7"
|
||||
- name: Test for secrets access
|
||||
id: check_secrets
|
||||
shell: bash
|
||||
run: |
|
||||
unset HAS_SECRET
|
||||
if [ -n "$SECRET" ]; then HAS_SECRET='true' ; fi
|
||||
echo ::set-output name=HAS_SECRET::${HAS_SECRET}
|
||||
env:
|
||||
SECRET: "${{ secrets.WIN_CODE_SIGN_CERT }}"
|
||||
|
||||
- name: Build Windows installer with build_scripts\build_windows.ps1
|
||||
env:
|
||||
WIN_CODE_SIGN_PASS: ${{ secrets.WIN_CODE_SIGN_PASS }}
|
||||
HAS_SECRET: ${{ steps.check_secrets.outputs.HAS_SECRET }}
|
||||
run: |
|
||||
$env:path="C:\Program` Files` (x86)\Microsoft` Visual` Studio\2019\Enterprise\SDK\ScopeCppSDK\vc15\VC\bin\;$env:path"
|
||||
$env:path="C:\Program` Files` (x86)\Windows` Kits\10\App` Certification` Kit;$env:path"
|
||||
.\build_scripts\build_windows.ps1
|
||||
- name: Decode code signing cert into an encrypted file
|
||||
if: steps.check_secrets.outputs.HAS_SECRET
|
||||
uses: kitek/decode-base64-into-file-action@1.0
|
||||
with:
|
||||
encoded-value: ${{ secrets.WIN_CODE_SIGN_CERT }}
|
||||
destination-file: .\chia-blockchain-gui\win_code_sign_cert.p12
|
||||
|
||||
- name: Upload Windows exe's to artifacts
|
||||
uses: actions/upload-artifact@v2.2.2
|
||||
with:
|
||||
name: Windows-Exe
|
||||
path: ${{ github.workspace }}\electron-react\Chia-win32-x64\
|
||||
- name: Build Windows installer with build_scripts\build_windows.ps1
|
||||
env:
|
||||
WIN_CODE_SIGN_PASS: ${{ secrets.WIN_CODE_SIGN_PASS }}
|
||||
HAS_SECRET: ${{ steps.check_secrets.outputs.HAS_SECRET }}
|
||||
run: |
|
||||
$env:path="C:\Program` Files` (x86)\Microsoft` Visual` Studio\2019\Enterprise\SDK\ScopeCppSDK\vc15\VC\bin\;$env:path"
|
||||
$env:path="C:\Program` Files` (x86)\Windows` Kits\10\App` Certification` Kit;$env:path"
|
||||
.\build_scripts\build_windows.ps1
|
||||
|
||||
- name: Upload Installer to artifacts
|
||||
uses: actions/upload-artifact@v2.2.2
|
||||
with:
|
||||
name: Windows-Installers
|
||||
path: ${{ github.workspace }}\electron-react\release-builds\
|
||||
- name: Upload Windows exe's to artifacts
|
||||
uses: actions/upload-artifact@v2.2.2
|
||||
with:
|
||||
name: Windows-Exe
|
||||
path: ${{ github.workspace }}\chia-blockchain-gui\Chia-win32-x64\
|
||||
|
||||
- name: Upload Installer to artifacts
|
||||
uses: actions/upload-artifact@v2.2.2
|
||||
with:
|
||||
name: Windows-Installers
|
||||
path: ${{ github.workspace }}\chia-blockchain-gui\release-builds\
|
||||
|
2
.github/workflows/codeql-analysis.yml
vendored
@ -28,7 +28,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'javascript', 'python' ]
|
||||
language: [ 'python' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
|
||||
# Learn more:
|
||||
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
|
||||
|
6
.github/workflows/super-linter.yml
vendored
@ -18,10 +18,10 @@ name: GithHub Super Linter
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'master'
|
||||
- 'main'
|
||||
pull_request:
|
||||
branches-ignore:
|
||||
- 'master'
|
||||
- 'main'
|
||||
|
||||
###############
|
||||
# Set the Job #
|
||||
@ -52,7 +52,7 @@ jobs:
|
||||
uses: docker://github/super-linter:v3.10.2
|
||||
env:
|
||||
VALIDATE_ALL_CODEBASE: true
|
||||
DEFAULT_BRANCH: master
|
||||
DEFAULT_BRANCH: main
|
||||
LINTER_RULES_PATH: .github/linters
|
||||
PYTHON_BLACK_CONFIG_FILE: .python-black
|
||||
VALIDATE_BASH: true
|
||||
|
1
.github/workflows/upload-pypi-source.yml
vendored
@ -27,7 +27,6 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
# we need fetch-depth 0 so setuptools_scm can resolve tags
|
||||
|
||||
- uses: actions/setup-python@v2
|
||||
name: Install Python
|
||||
|
8
.gitignore
vendored
@ -84,10 +84,10 @@ vdf_bench
|
||||
main.sym
|
||||
|
||||
# Dev config react
|
||||
electron-react/src/dev_config.js
|
||||
# chia-blockchain-gui/src/dev_config.js
|
||||
# React built app
|
||||
electron-react/.eslintcache
|
||||
electron-react/build
|
||||
chia-blockchain-gui/.eslintcache
|
||||
chia-blockchain-gui/build
|
||||
build_scripts/dist
|
||||
build_scripts/*.Dmg
|
||||
electron-react/src/locales/_build
|
||||
chia-blockchain-gui/src/locales/_build
|
||||
|
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "chia-blockchain-gui"]
|
||||
path = chia-blockchain-gui
|
||||
url = https://github.com/Chia-Network/chia-blockchain-gui.git
|
@ -19,6 +19,7 @@ for setuptools_scm/PEP 440 reasons.
|
||||
|
||||
### Changed
|
||||
|
||||
- The GUI is now in a seperate repository from chia-blockchain, [chia-blockchain-gui](https://github.com/Chia-Network/chia-blockchain-gui). The installers and install scripts have been updated and it continues to follow basically the same install steps. Note that the GUI directory will now be `chia-blockchain-gui`.
|
||||
|
||||
### Fixed
|
||||
- The GUI was incorrectly reporting the time frame that the netspace estimate it displays utilizes. It is technically 312.5 minutes, on average, over the trailing 1000 sub blocks.
|
||||
|
@ -17,9 +17,6 @@ strategy:
|
||||
matrix:
|
||||
Mojave DMG:
|
||||
python.version: "3.8"
|
||||
# Python38:
|
||||
# python.version: '3.8' # Disabled 3.8 because artifact names conflict
|
||||
# Also, installer can target one verison
|
||||
|
||||
variables:
|
||||
- group: Apple-Notarize-Variables
|
||||
@ -65,7 +62,8 @@ steps:
|
||||
|
||||
- script: |
|
||||
. ./activate
|
||||
cd ./electron-react
|
||||
git submodule update --init --recursive
|
||||
cd ./chia-blockchain-gui
|
||||
npm install
|
||||
npm audit fix
|
||||
npm run locale:extract
|
||||
|
@ -24,9 +24,9 @@ mkdir dist
|
||||
echo "Create executeables with pyinstaller"
|
||||
pip install pyinstaller==4.2
|
||||
sudo pyinstaller --log-level=INFO daemon.spec
|
||||
cp -r dist/daemon ../electron-react
|
||||
cp -r dist/daemon ../chia-blockchain-gui
|
||||
cd .. || exit
|
||||
cd electron-react || exit
|
||||
cd chia-blockchain-gui || exit
|
||||
|
||||
echo "npm build"
|
||||
npm install
|
||||
|
@ -67,10 +67,10 @@ Write-Output " ---"
|
||||
pyinstaller --log-level INFO daemon_windows.spec
|
||||
|
||||
Write-Output " ---"
|
||||
Write-Output "Copy chia executables to electron-react\"
|
||||
Write-Output "Copy chia executables to chia-blockchain-gui\"
|
||||
Write-Output " ---"
|
||||
Copy-Item "dist\daemon" -Destination "..\electron-react\" -Recurse
|
||||
Set-Location -Path "..\electron-react" -PassThru
|
||||
Copy-Item "dist\daemon" -Destination "..\chia-blockchain-gui\" -Recurse
|
||||
Set-Location -Path "..\chia-blockchain-gui" -PassThru
|
||||
|
||||
Write-Output " ---"
|
||||
Write-Output "Prepare Electron packager"
|
||||
|
1
chia-blockchain-gui
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 995a77f75b381d166657c3f8ab3659970924cf17
|
@ -1,10 +0,0 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
max_line_length = 80
|
@ -1,2 +0,0 @@
|
||||
DISABLE_NEW_JSX_TRANSFORM=true
|
||||
SKIP_PREFLIGHT_CHECK=true
|
@ -1,3 +0,0 @@
|
||||
node_modules
|
||||
src/**/*.js
|
||||
src/**/*.jsx
|
@ -1,85 +0,0 @@
|
||||
module.exports = {
|
||||
extends: [
|
||||
"airbnb-typescript",
|
||||
"airbnb/hooks",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:@typescript-eslint/recommended-requiring-type-checking",
|
||||
"plugin:eslint-comments/recommended",
|
||||
"plugin:jest/recommended",
|
||||
"plugin:promise/recommended",
|
||||
"plugin:unicorn/recommended",
|
||||
"prettier",
|
||||
"prettier/react",
|
||||
"prettier/@typescript-eslint",
|
||||
],
|
||||
plugins: [
|
||||
"@typescript-eslint",
|
||||
"eslint-comments",
|
||||
"jest",
|
||||
"promise",
|
||||
"unicorn",
|
||||
"react",
|
||||
"jsx-a11y",
|
||||
"import",
|
||||
"prettier",
|
||||
],
|
||||
env: {
|
||||
"browser": true,
|
||||
"es6": true,
|
||||
"jest": true,
|
||||
},
|
||||
parser: "@typescript-eslint/parser",
|
||||
parserOptions: {
|
||||
sourceType: "module",
|
||||
project: "./tsconfig.json",
|
||||
ecmaFeatures: {
|
||||
jsx: true,
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
"jsx-a11y/anchor-is-valid": "off",
|
||||
"consistent-return": "off",
|
||||
"react/no-danger": "off",
|
||||
"no-case-declarations": "off",
|
||||
"eslint-comments/no-unlimited-disable": "off",
|
||||
"@typescript-eslint/naming-convention": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/await-thenable": "off",
|
||||
"@typescript-eslint/no-unsafe-member-access": "off",
|
||||
"@typescript-eslint/no-unsafe-assignment": "off",
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/no-unsafe-call": "off",
|
||||
"@typescript-eslint/restrict-template-expressions": "off",
|
||||
"@typescript-eslint/ban-types": "off",
|
||||
"@typescript-eslint/no-shadow": "off",
|
||||
"@typescript-eslint/no-unsafe-return": "off",
|
||||
"@typescript-eslint/restrict-plus-operands": "off",
|
||||
"@typescript-eslint/unbound-method": "off",
|
||||
"@typescript-eslint/explicit-module-boundary-types": "off",
|
||||
"@typescript-eslint/no-floating-promises": "off",
|
||||
"react/jsx-props-no-spreading": "off",
|
||||
"react/destructuring-assignment": "off",
|
||||
"react/require-default-props": "off",
|
||||
"react/default-props-match-prop-types": "off",
|
||||
"unicorn/no-abusive-eslint-disable": "off",
|
||||
"unicorn/no-nested-ternary": "off",
|
||||
"unicorn/no-object-as-default-parameter": "off",
|
||||
"unicorn/explicit-length-check": "off",
|
||||
"unicorn/no-null": "off",
|
||||
"unicorn/no-reduce": "off",
|
||||
"unicorn/consistent-function-scoping": "off",
|
||||
"unicorn/prevent-abbreviations": "off",
|
||||
"unicorn/no-lonely-if": "off",
|
||||
"unicorn/no-array-reduce": "off",
|
||||
"unicorn/no-new-array": "off",
|
||||
"unicorn/no-array-for-each": "off",
|
||||
"unicorn/prefer-spread": "off",
|
||||
"unicorn/consistent-destructuring": "off",
|
||||
"unicorn/filename-case": ["error", {
|
||||
"cases": {
|
||||
"camelCase": true,
|
||||
"pascalCase": true,
|
||||
},
|
||||
}],
|
||||
},
|
||||
};
|
@ -1,13 +0,0 @@
|
||||
{
|
||||
"catalogs": [{
|
||||
"path": "<rootDir>/src/locales/{locale}/messages",
|
||||
"include": ["<rootDir>/src"],
|
||||
"exclude": ["**/node_modules/**"]
|
||||
}],
|
||||
"locales": ["en", "sk", "zh-CN"],
|
||||
"format": "po",
|
||||
"sourceLocale": "en",
|
||||
"fallbackLocales": {
|
||||
default: "en"
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
module.exports = {
|
||||
singleQuote: true,
|
||||
trailingComma: 'all',
|
||||
printWidth: 80
|
||||
};
|
@ -1,2 +0,0 @@
|
||||
react: npm start
|
||||
electron: node src/electron-wait-react
|
@ -1,12 +0,0 @@
|
||||
const CracoAlias = require("craco-alias");
|
||||
|
||||
module.exports = {
|
||||
plugins: [{
|
||||
plugin: CracoAlias,
|
||||
options: {
|
||||
source: "tsconfig",
|
||||
baseUrl: "./src",
|
||||
tsConfigPath: "./tsconfig.paths.json"
|
||||
},
|
||||
}],
|
||||
};
|
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
25687
electron-react/package-lock.json
generated
@ -1,123 +0,0 @@
|
||||
{
|
||||
"name": "chia-blockchain",
|
||||
"author": "Chia Network <hello@chia.net> (https://chia.net/)",
|
||||
"description": "GUI for Chia Blockchain",
|
||||
"productName": "Chia Blockchain",
|
||||
"private": true,
|
||||
"homepage": "./",
|
||||
"main": "src/electron-starter.js",
|
||||
"scripts": {
|
||||
"start": "craco start",
|
||||
"build": "craco build",
|
||||
"test": "craco test --env=jsdom",
|
||||
"eject": "react-scripts eject",
|
||||
"electron": "electron .",
|
||||
"dev": "cross-env NODE_ENV=development BROWSER=none nf start",
|
||||
"dev:testnet": "cross-env TESTNET=true NODE_ENV=development BROWSER=none nf start -p 3000",
|
||||
"styleguide": "styleguidist server",
|
||||
"styleguide:build": "styleguidist build",
|
||||
"locale:extract": "lingui extract --overwrite",
|
||||
"locale:compile": "lingui compile",
|
||||
"eslint": "eslint src/**/*.[t]s{,x}",
|
||||
"format": "prettier --write src/**/*.[jt]s{,x} && eslint --fix src/**/*.[jt]s{,x}",
|
||||
"lint": "tsc --noEmit && npm run eslint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@lingui/core": "^3.4.0",
|
||||
"@lingui/macro": "^3.4.0",
|
||||
"@lingui/react": "^3.4.0",
|
||||
"@material-ui/core": "^4.11.3",
|
||||
"@material-ui/icons": "^4.11.2",
|
||||
"@material-ui/lab": "4.0.0-alpha.57",
|
||||
"@material-ui/styles": "^4.11.3",
|
||||
"@rehooks/local-storage": "^2.4.0",
|
||||
"about-window": "^1.13.4",
|
||||
"byte-size": "^7.0.0",
|
||||
"bytes-iec": "^3.1.1",
|
||||
"connected-react-router": "^6.8.0",
|
||||
"framer-motion": "^3.2.1",
|
||||
"history": "^4.10.1",
|
||||
"is-electron": "^2.2.0",
|
||||
"lodash": "^4.17.20",
|
||||
"make-plural": "^6.2.2",
|
||||
"match-sorter": "^6.1.0",
|
||||
"moment": "^2.29.1",
|
||||
"npm-audit-resolver": "^2.2.1",
|
||||
"polished": "^4.1.0",
|
||||
"react": "^17.0.1",
|
||||
"react-dom": "^17.0.1",
|
||||
"react-dropzone": "^11.2.4",
|
||||
"react-hook-form": "^6.14.2",
|
||||
"react-redux": "^7.2.2",
|
||||
"react-router": "^5.2.0",
|
||||
"react-router-dom": "^5.2.0",
|
||||
"react-scroll-to-bottom": "^4.1.0",
|
||||
"react-teleporter": "^2.1.1",
|
||||
"react-use": "^15.3.8",
|
||||
"redux": "^4.0.5",
|
||||
"redux-thunk": "^2.3.0",
|
||||
"stringify": "^5.2.0",
|
||||
"styled-components": "^5.2.1",
|
||||
"tail": "^2.2.0",
|
||||
"use-dark-mode": "^2.3.1",
|
||||
"ws": "^7.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.10",
|
||||
"@lingui/cli": "^3.4.0",
|
||||
"@types/jest": "^26.0.20",
|
||||
"@types/lingui__macro": "^2.7.4",
|
||||
"@types/lingui__react": "^2.8.3",
|
||||
"@types/lodash": "^4.14.168",
|
||||
"@types/node": "^14.14.22",
|
||||
"@types/react": "^17.0.0",
|
||||
"@types/react-dom": "^17.0.0",
|
||||
"@types/react-redux": "^7.1.16",
|
||||
"@types/react-router-dom": "^5.1.7",
|
||||
"@types/styled-components": "^5.1.7",
|
||||
"@typescript-eslint/eslint-plugin": "4.14.0",
|
||||
"@typescript-eslint/parser": "4.14.0",
|
||||
"babel-core": "^7.0.0-bridge.0",
|
||||
"craco": "^0.0.3",
|
||||
"craco-alias": "^2.1.1",
|
||||
"cross-env": "^7.0.3",
|
||||
"cypress": "^6.3.0",
|
||||
"electron": "^9.4.2",
|
||||
"electron-osx-sign": "github:electron/electron-osx-sign#master",
|
||||
"electron-winstaller": "^4.0.1",
|
||||
"eslint": "^7.18.0",
|
||||
"eslint-config-airbnb-typescript": "^12.0.0",
|
||||
"eslint-config-prettier": "^6.15.0",
|
||||
"eslint-plugin-eslint-comments": "^3.2.0",
|
||||
"eslint-plugin-import": "^2.22.1",
|
||||
"eslint-plugin-jest": "^24.1.3",
|
||||
"eslint-plugin-jsx-a11y": "^6.4.1",
|
||||
"eslint-plugin-prettier": "^3.3.1",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-react": "^7.22.0",
|
||||
"eslint-plugin-react-hooks": "^4.2.0",
|
||||
"eslint-plugin-unicorn": "^27.0.0",
|
||||
"eslint-webpack-plugin": "^2.4.3",
|
||||
"foreman": "^3.0.1",
|
||||
"prettier-eslint": "^12.0.0",
|
||||
"prettier-eslint-cli": "^5.0.0",
|
||||
"react-scripts": "4.0.1",
|
||||
"react-styleguidist": "^11.1.5",
|
||||
"redux-devtools-extension": "^2.13.8",
|
||||
"terser-webpack-plugin": "^5.1.1",
|
||||
"tsconfig-paths-webpack-plugin": "^3.3.0",
|
||||
"typescript": "^4.1.3"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 26 KiB |
@ -1,33 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<base href="./">
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tag above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>Chia Blockchain</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start`.
|
||||
To create a production bundle, use `npm run build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
@ -1,19 +0,0 @@
|
||||
import React from "react";
|
||||
import { ThemeProvider } from "@material-ui/core/styles";
|
||||
import CssBaseline from "@material-ui/core/CssBaseline";
|
||||
|
||||
import RsgWrapper from "react-styleguidist/lib/client/rsg-components/Wrapper/Wrapper";
|
||||
|
||||
import muiTheme from "./muiTheme";
|
||||
import "./assets/css/App.css";
|
||||
|
||||
const RsgMuiWrapper = ({ children, ...rest }) => (
|
||||
<>
|
||||
<CssBaseline />
|
||||
<RsgWrapper {...rest}>
|
||||
<ThemeProvider theme={muiTheme}>{children}</ThemeProvider>
|
||||
</RsgWrapper>
|
||||
</>
|
||||
);
|
||||
|
||||
export default RsgMuiWrapper;
|
Before Width: | Height: | Size: 305 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 94 KiB |
@ -1,18 +0,0 @@
|
||||
<svg width="150px" height="58px" viewBox="0 0 150 58" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="Community" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g transform="translate(-189.000000, -1096.000000)" fill="#3AAC59" fill-rule="nonzero" id="footer">
|
||||
<g transform="translate(0.000000, 988.000000)">
|
||||
<g id="Group-14" transform="translate(189.000000, 108.000000)">
|
||||
<g id="chia-logo-(1)">
|
||||
<polygon id="Rectangle-path" points="90 19 103 19 103 57 90 57"></polygon>
|
||||
<g id="Group">
|
||||
<path d="M72.151257,16.1408116 C67.1530726,16.1408116 62.0421788,17.3373768 60.7696927,19.5644928 C60.752514,19.5926522 60.7357542,19.6187101 60.7194134,19.6477101 L60.7194134,3.70443478 L47.3715084,3.70443478 L47.3715084,28.9974783 L47.3715084,29.0407681 C48.6993017,29.6489275 50.0610335,30.3436667 51.4386872,31.1291884 C51.9046089,31.3964928 52.2988827,31.6297536 52.5896648,31.8045942 C52.7723464,31.9142899 52.9546089,32.0244058 53.1368715,32.1378841 C53.1557263,32.1496522 45.5074022,44.0594058 35.0916201,46.5601304 C28.9378492,48.0387101 21.6682961,46.2486957 20.1955307,40.0754783 C20.1339385,39.8195217 20.1,39.5627246 20.0601955,39.3063478 C21.0414804,38.7221449 22.0449721,38.1858551 23.0539106,37.6886522 C25.6030726,36.5778261 27.5484637,35.7452319 28.2846369,35.4627971 C28.349162,35.4388406 28.4145251,35.4140435 28.4786313,35.3905072 C28.4798883,35.3905072 28.4815642,35.390087 28.4824022,35.390087 C28.4832402,35.390087 28.4832402,35.3892464 28.4844972,35.3884058 C34.5620112,33.1844058 39.6632682,32.4236812 39.6632682,32.4236812 C35.0304469,32.0231449 31.052514,32.3459275 27.7236034,33.0053623 C27.7223464,33.0036812 27.7189944,33.0028406 27.7189944,33.0028406 C27.7189944,33.0028406 27.6938547,33.0087246 27.6490223,33.0204928 C24.6347765,33.624029 22.1551676,34.5020145 20.2298883,35.3778986 C21.302514,30.9287101 25.1740223,27.0633043 29.7557263,25.9621449 C30.1583799,25.8654783 30.5664804,25.7906667 30.975838,25.7267826 C31.0935754,25.7087101 31.2108939,25.6927391 31.3290503,25.6771884 C31.647067,25.6338986 31.9667598,25.6002754 32.2885475,25.5742174 C32.3912011,25.5662319 32.4946927,25.5553043 32.5977654,25.5498406 C33.0092179,25.5237826 33.4219274,25.5107536 33.8363128,25.5124348 C33.9175978,25.5128551 33.9988827,25.5174783 34.0801676,25.5178986 C34.423743,25.522942 34.7673184,25.5363913 35.1113128,25.5582464 C35.2328212,25.5658116 35.3539106,25.5737971 35.474581,25.5834638 C35.5952514,25.5931304 35.7159218,25.6044783 35.8361732,25.6158261 C37.8087989,25.8196667 40.2322626,26.3492319 42.9188547,27.2621014 L42.9188547,18.5183913 C41.622486,18.1174348 40.2469274,17.729087 38.8189944,17.3777246 C35.0547486,16.374913 28.5909218,15.3073768 21.521648,17.0293043 C10.1513966,19.8002754 6.92681564,28.2123768 6.92681564,38.4918261 C6.92681564,39.8014493 7.03072626,41.0270145 7.22053073,42.1798696 C4.75223464,43.8147971 2.32793296,45.6922319 0.124441341,47.8348696 C0.124441341,47.8348696 3.40391061,46.3722609 7.73547486,44.4477536 C10.6269553,54.3203623 20.7129888,57.6414928 28.3081006,57.6414928 C36.2287709,57.6414928 41.3136872,55.3803333 47.3715084,51.6006667 L47.3715084,56.3881884 L60.7194134,56.3881884 L60.7194134,32.6397101 C60.7357542,32.6086087 60.752514,32.5779275 60.7696927,32.5459855 L60.7696927,32.1425072 C62.0396648,28.7482464 64.199581,27.8723623 66.6,27.8723623 C69.7726257,27.8723623 71.7548883,30.1255362 71.7548883,33.7059855 L71.7548883,56.3881884 L85.1027933,56.3881884 L85.1027933,29.8615942 C85.1027933,21.5100145 79.8821229,16.1408116 72.151257,16.1408116" id="Shape"></path>
|
||||
<path d="M96.2878492,0.385405797 C92.2575419,0.385405797 89.4155028,3.2353913 89.4155028,7.27857971 C89.4155028,11.3217681 92.2575419,14.1713333 96.2878492,14.1713333 C100.318156,14.1713333 103.160615,11.3217681 103.160615,7.27857971 C103.160615,3.2353913 100.318156,0.385405797 96.2878492,0.385405797" id="Shape"></path>
|
||||
<path d="M147.390084,34.8672464 L147.406425,34.8672464 L147.392179,17.9400725 L134.028352,17.9400725 L133.955447,20.3462319 C121.065084,12.0413043 112.836034,20.5820145 112.836034,20.5820145 C108.900419,24.1864203 106.61648,29.8771449 106.61648,37.0224928 C106.61648,49.6904493 114.20824,57.2262464 124.077235,57.2262464 C127.776117,57.2262464 131.183799,56.3881884 134.126397,52.3084348 C134.467458,53.2595507 135.226676,55.5883768 135.770531,56.3881884 L149.676955,56.3881884 C147.293296,52.4631014 147.31257,38.8528551 147.390084,34.8672464 M127.193296,46.2516377 C122.865084,46.2516377 119.813128,42.4841594 119.813128,37.138913 C119.813128,31.7936667 122.865084,28.0253478 127.193296,28.0253478 C130.228492,28.0253478 132.634358,29.880087 133.801676,32.830942 L133.801676,41.4460435 C132.634777,44.3968986 130.228492,46.2516377 127.193296,46.2516377" id="Shape"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 15 KiB |
@ -1,3 +0,0 @@
|
||||
<svg width="32" height="37" viewBox="0 0 32 37" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M19.2165 14.2887C20.866 12.6392 23.5876 12.4742 24.8247 12.3918C24.8247 13.7113 24.4948 16.3505 22.7629 18C21.1134 19.6495 18.3918 19.8144 17.0722 19.8969C17.2371 18.6598 17.567 15.9381 19.2165 14.2887ZM7.01031 31.5258C4.37113 28.9691 4.04124 24.7629 4.04124 23.1134C5.69072 23.1134 9.97938 23.2783 12.5361 25.8351C15.1753 28.3918 15.5052 32.5979 15.5052 34.2474C13.8557 34.3299 9.64949 34.0825 7.01031 31.5258ZM15.5052 20.0619C14.1856 19.9794 11.5464 19.732 9.89691 18C8.24742 16.3505 8.08247 13.6289 8 12.3918C9.31959 12.3918 11.9588 12.7217 13.6082 14.4536C15.0103 15.9381 15.4227 18.1649 15.4227 19.567V20.0619H15.5052ZM14.5155 5.87629C14.5155 4.22681 15.5876 2.74227 16.2474 2C16.9897 2.74227 18.0619 4.22681 18.0619 5.79382C18.0619 7.4433 16.9897 8.92784 16.2474 9.6701C15.6701 8.92784 14.5155 7.4433 14.5155 5.87629ZM17.1546 34.2474C17.1546 32.5979 17.4845 28.3918 20.1237 25.8351C22.7629 23.2783 26.9691 23.1134 28.6186 23.1134C28.6186 24.8454 28.2887 29.0515 25.6495 31.5258C23.0928 34.0825 18.8866 34.3299 17.1546 34.2474ZM0 36.8041H32V35.1546H22.6804C24.1649 34.6598 25.6495 33.9175 26.8866 32.7629C30.7629 29.0515 30.3505 22.6186 30.3505 22.2887C30.3505 21.8763 30.0206 21.5464 29.6082 21.5464C29.3608 21.5464 22.9278 20.9691 19.0515 24.6804C18.3093 25.4227 17.732 26.2474 17.2371 27.1546V21.5464C18.7216 21.5464 21.9381 21.299 24.0825 19.2371C26.8866 16.5155 26.6392 11.8144 26.6392 11.6495C26.6392 11.2371 26.3093 10.9072 25.8969 10.9072C25.732 10.9072 21.0309 10.4948 18.2268 13.2165C17.8969 13.5464 17.567 13.9588 17.3196 14.2887V11.2371C17.9794 10.5773 19.9588 8.43299 19.9588 5.79382C19.9588 2.6598 17.0722 0.268041 16.9897 0.185567C16.6598 -0.0618557 16.2474 -0.0618557 15.9175 0.185567C15.8351 0.268041 13.0309 2.74227 13.0309 5.87629C13.0309 8.35052 14.8454 10.4124 15.6701 11.1546V14.0412C15.5052 13.7938 15.2577 13.4639 15.0103 13.2165C12.2887 10.4124 7.58763 10.6598 7.42268 10.6598C7.01031 10.6598 6.68041 10.9897 6.68041 11.4021C6.68041 11.567 6.26804 16.268 8.98969 19.0722C11.0515 21.2165 14.268 21.5464 15.7526 21.6289V27.0722C15.2577 26.1649 14.6804 25.3402 13.9381 24.5979C10.0619 20.8866 3.62887 21.4639 3.38144 21.4639C2.96907 21.5464 2.63918 21.7938 2.63918 22.2062C2.63918 22.4536 2.2268 28.9691 6.10309 32.6804C7.34021 33.8351 8.82474 34.5773 10.3093 35.0722H0V36.8041Z" fill="#66666B"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 2.4 KiB |
@ -1,3 +0,0 @@
|
||||
<svg width="32" height="33" viewBox="0 0 32 33" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M32 16.0045C32 7.12929 24.798 0 15.9955 0C11.7033 0 7.62947 1.74595 4.64681 4.80136C4.64681 4.80136 4.64681 4.80136 4.57406 4.80136V4.87411C-1.53676 11.0577 -1.53676 21.0969 4.64681 27.2804V27.3532H4.71956C10.9031 33.5368 20.8696 33.6095 27.1259 27.4987H27.1986C27.1986 27.4987 27.1986 27.4987 27.1986 27.4259C30.2541 24.3705 32 20.2966 32 16.0045ZM26.6894 25.8255L21.5243 20.6604C23.7795 17.9687 23.8522 14.0403 21.5971 11.3487L26.7622 6.18357C31.8545 11.8579 31.7818 20.3694 26.6894 25.8255ZM11.9216 20.1512C9.73916 17.8232 9.81191 14.1131 12.1398 11.9306C14.395 9.82096 17.8869 9.82096 20.1421 11.9306C22.3245 14.2586 22.2518 17.9687 19.9239 20.1512C17.6687 22.2608 14.104 22.2608 11.9216 20.1512ZM25.6709 5.23784L20.5058 10.4029C17.8142 8.22051 13.8858 8.22051 11.1941 10.4757L6.10177 5.31059C11.6306 0.218244 20.1421 0.145496 25.6709 5.23784ZM5.15604 6.40181L10.3211 11.5669C8.21145 14.2586 8.2842 18.0415 10.3939 20.6604L5.22879 25.8255C0.20919 20.2966 0.209191 11.9306 5.15604 6.40181ZM6.24726 26.7712L11.4124 21.6061C14.0313 23.7158 17.8142 23.7885 20.5058 21.6789L25.6709 26.844C20.0694 31.8636 11.7034 31.7908 6.24726 26.7712Z" fill="#66666B"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.2 KiB |
@ -1,3 +0,0 @@
|
||||
<svg width="32" height="31" viewBox="0 0 32 31" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.571739 15.7671C0.48874 15.6841 0.476861 15.528 0.54195 15.4353L0.571732 15.4055L0.571739 15.4055L15.0758 0.901373L15.0824 0.894828L15.0887 0.888045C15.5542 0.386712 16.3523 0.383294 16.8193 0.807326L16.8624 0.850481L16.8624 0.850491L31.4174 15.4055C31.5275 15.5156 31.5275 15.657 31.4174 15.7671C31.3344 15.8501 31.1783 15.862 31.0856 15.7969L31.0558 15.7671L29.3255 14.0368L28.4719 13.1832V14.3903V29.6069C28.4719 29.8906 28.2378 30.1248 27.9541 30.1248H3.52614C3.24247 30.1248 3.00831 29.8906 3.00831 29.6069V14.8993V13.6921L2.15475 14.5457L0.933356 15.7671C0.823269 15.8772 0.681826 15.8772 0.571739 15.7671ZM15.6183 1.11844L15.5457 1.15472L15.4884 1.2121L3.6815 13.019L3.53506 13.1654V13.3725V29.098V29.598H4.03506H11.1599H11.6599V29.098V18.9197C11.6599 18.636 11.894 18.4019 12.1777 18.4019H19.8115C20.0951 18.4019 20.3293 18.636 20.3293 18.9197V29.098V29.598H20.8293H27.4452H27.9452V29.098V12.8636V12.6565L27.7988 12.51L16.5517 1.26299C16.2637 0.97499 15.8657 0.994735 15.6183 1.11844ZM19.8025 19.4286V18.9286H19.3025H12.6866H12.1866V19.4286V29.098V29.598H12.6866H19.3025H19.8025V29.098V19.4286Z" fill="#66666B" stroke="#66666B"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 9.0 KiB |
@ -1,3 +0,0 @@
|
||||
<svg width="40" height="32" viewBox="0 0 40 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M39.84 21.04L34.16 1.36C33.88 0.56 33.12 0 32.28 0H7.72C6.84 0 6.08 0.56 5.8 1.4L0.12 21C0.04 21.32 0 21.64 0 21.96V28.8C0 30.56 1.44 32 3.2 32H36.8C38.56 32 40 30.56 40 28.8V21.96C40 21.64 39.96 21.32 39.84 21.04ZM7.36 1.88C7.4 1.72 7.56 1.6 7.72 1.6H32.28C32.44 1.6 32.56 1.68 32.64 1.84L37.72 19.36C37.4 19.24 37.12 19.2 36.8 19.2H3.2C2.88 19.2 2.6 19.24 2.28 19.36L7.36 1.88ZM38.4 28.8C38.4 29.68 37.68 30.4 36.8 30.4H3.2C2.32 30.4 1.6 29.68 1.6 28.8V22.4C1.6 21.52 2.32 20.8 3.2 20.8H36.8C37.68 20.8 38.4 21.52 38.4 22.4V28.8ZM8 25.6C8 26.48 7.28 27.2 6.4 27.2C5.52 27.2 4.8 26.48 4.8 25.6C4.8 24.72 5.52 24 6.4 24C7.28 24 8 24.72 8 25.6ZM12.8 25.6C12.8 26.48 12.08 27.2 11.2 27.2C10.32 27.2 9.6 26.48 9.6 25.6C9.6 24.72 10.32 24 11.2 24C12.08 24 12.8 24.72 12.8 25.6ZM17.6 25.6C17.6 26.48 16.88 27.2 16 27.2C15.12 27.2 14.4 26.48 14.4 25.6C14.4 24.72 15.12 24 16 24C16.88 24 17.6 24.72 17.6 25.6ZM20.8 24H35.2V25.6H20.8V24Z" fill="#66666B"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.0 KiB |
@ -1,3 +0,0 @@
|
||||
<svg width="34" height="34" viewBox="0 0 34 34" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M22.7182 0.863589L22.7173 0.863515C19.3565 0.591019 16.0386 1.77164 13.6739 4.1814C11.9775 5.87811 10.8517 8.10021 10.468 10.4609C8.10909 10.843 5.92902 11.9263 4.18793 13.6674C2.27942 15.5759 1.09804 18.1202 0.87072 20.8014C0.598129 23.8466 1.55295 26.8011 3.50666 29.1183C5.46024 31.4353 8.23279 32.8904 11.2789 33.1178C14.6394 33.3901 17.9571 32.2095 20.3216 29.7999C22.018 28.1032 23.1444 25.9236 23.5279 23.5204C25.8867 23.1381 28.0666 22.0549 29.8076 20.3139C31.716 18.4055 32.8973 15.8614 33.1247 13.1805C33.7154 6.95136 29.0327 1.40873 22.7182 0.863589ZM10.3486 11.899C10.267 14.7277 11.1772 17.4613 13.0378 19.6762L13.038 19.6765C14.9915 21.9934 17.764 23.4484 20.8099 23.6759C21.2798 23.7151 21.7166 23.7205 22.1773 23.6923C21.793 25.6729 20.8038 27.4802 19.447 28.837C17.4237 30.8603 14.5654 32.0036 11.4866 31.7398C5.9444 31.256 1.85401 26.4182 2.2934 20.8761C2.51359 18.4122 3.56911 16.2579 5.19613 14.6309C6.59747 13.2295 8.36737 12.2795 10.3486 11.899ZM20.9277 22.2531L20.9272 22.2531C15.4803 21.8173 11.4144 17.107 11.7257 11.6721C12.2028 11.6399 12.6798 11.6436 13.1569 11.6834C18.6051 12.1631 22.6699 16.8745 22.3594 22.2645C21.8822 22.2967 21.405 22.2929 20.9277 22.2531ZM28.8906 19.3487L28.8889 19.3504C27.4878 20.7515 25.7182 21.7015 23.7374 22.0821C23.9359 16.0407 19.3833 10.7996 13.2758 10.3054C12.8054 10.2662 12.3681 10.2607 11.9069 10.289C12.2903 8.27033 13.2795 6.50273 14.638 5.14427C16.6613 3.12093 19.5197 1.97764 22.5985 2.2415C28.1422 2.72553 32.2753 7.56451 31.7917 13.1046C31.5715 15.5702 30.5152 17.768 28.8906 19.3487Z" fill="#66666B" stroke="#66666B" stroke-width="0.35"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.7 KiB |
@ -1,3 +0,0 @@
|
||||
<svg width="32" height="39" viewBox="0 0 32 39" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M30.5735 13.9987H30.3807L29.6482 11.7625L25.9855 0.543235C25.9084 0.350464 25.7928 0.196248 25.6 0.0805849C25.4072 0.00347644 25.2145 -0.0350778 25.0217 0.0420307L5.16626 6.59625L1.69639 7.75287C1.31084 7.86854 1.07952 8.33119 1.19518 8.71673L2.93012 13.9987H1.42651C0.616867 13.9987 0 14.6541 0 15.4252V36.63C0 37.4396 0.655422 38.0565 1.42651 38.0565H30.5735C31.3831 38.0565 32 37.4011 32 36.63V15.4252C32 14.6541 31.3831 13.9987 30.5735 13.9987ZM30.4578 28.2252H22.9398V23.8685H30.4964L30.4578 28.2252ZM2.89157 8.83239L24.7518 1.66131L28.8771 13.9215L21.4747 13.9987C21.9373 12.7649 21.9759 11.4155 21.5518 10.1432C20.5494 7.09745 17.2337 5.40107 14.188 6.40348C12.7229 6.90468 11.4892 7.90709 10.7952 9.3336C10.1012 10.7601 9.98554 12.3023 10.4482 13.8059C10.4867 13.883 10.4867 13.9601 10.5253 14.0372H4.5494L2.89157 8.83239ZM19.0072 13.9987C19.2771 13.4975 19.3157 12.9191 19.1614 12.3408C18.9687 11.8011 18.6217 11.377 18.0819 11.1071C17.6578 10.9143 17.2337 10.8372 16.7711 10.9143C16.694 10.9143 16.6169 10.9143 16.5398 10.9529L16.4241 10.9914L16.0386 9.87336L16.1542 9.8348C16.5398 9.71914 16.7711 9.25649 16.6554 8.87095C16.5398 8.4854 16.0771 8.25408 15.6916 8.36974L15.5759 8.4083V8.25408C15.4988 8.02275 15.306 7.82998 15.0747 7.75287C16.0386 7.5601 17.041 7.67577 17.9277 8.09986C18.9687 8.60107 19.7012 9.48781 20.0867 10.6059C20.4723 11.724 20.3566 12.9577 19.7783 13.9987H19.0072ZM12.2217 13.9987C12.106 13.7673 11.9904 13.536 11.9133 13.3047C11.5663 12.2252 11.6434 11.03 12.1446 10.0276C12.6072 9.14083 13.3398 8.44685 14.2265 8.06131C14.0723 8.25408 14.0337 8.52396 14.1108 8.75528L14.1494 8.9095C13.6096 9.10227 13.1855 9.44926 12.9157 9.95047C12.6458 10.4517 12.6072 11.03 12.8 11.5697C12.9928 12.1095 13.3398 12.5336 13.8795 12.8035C14.188 12.9577 14.4964 13.0348 14.8434 13.0348C14.959 13.0348 15.0747 13.0348 15.2289 12.9962C15.306 12.9962 15.3446 12.9962 15.4217 12.9577L15.5373 12.9191L15.8843 13.9987H12.2217ZM14.3422 10.6444C14.4193 10.5288 14.5349 10.4131 14.6506 10.3746L14.9976 11.4926C14.8434 11.5312 14.6892 11.5312 14.5735 11.4541C14.4193 11.377 14.3422 11.2613 14.2651 11.1071C14.2651 10.9529 14.2651 10.7987 14.3422 10.6444ZM17.3494 13.5746L17.0024 12.4565C17.1566 12.4179 17.3108 12.4179 17.4265 12.495C17.5807 12.5722 17.6578 12.6878 17.7349 12.842C17.812 13.1505 17.6193 13.4589 17.3494 13.5746ZM1.54217 36.5529V15.5408H4.00964H11.759H20.2024C20.2024 15.5408 20.2024 15.5408 20.241 15.5408H26.4867H30.4964V22.3264H22.8241C22.0145 22.3264 21.3976 22.9818 21.3976 23.7529V28.3408C21.3976 29.1505 22.053 29.7673 22.8241 29.7673H30.4578V36.5529H1.54217Z" fill="#66666B"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 2.7 KiB |
@ -1,28 +0,0 @@
|
||||
html,
|
||||
body,
|
||||
#root {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#root {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Roboto;
|
||||
src: url("./fonts/Roboto-Medium.ttf");
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Roboto;
|
||||
src: url("./fonts/Roboto-Regular.ttf");
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Roboto;
|
||||
src: url("./fonts/Roboto-Light.ttf");
|
||||
font-weight: 300;
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
import { I18nProvider } from '@lingui/react';
|
||||
import { i18n } from "@lingui/core"
|
||||
import useDarkMode from 'use-dark-mode';
|
||||
import isElectron from 'is-electron';
|
||||
import { en, sk, zh } from 'make-plural/plurals';
|
||||
import { ConnectedRouter } from 'connected-react-router';
|
||||
import { ThemeProvider } from '@chia/core';
|
||||
import AppRouter from './AppRouter';
|
||||
import darkTheme from '../../theme/dark';
|
||||
import lightTheme from '../../theme/light';
|
||||
import WebSocketConnection from '../../hocs/WebsocketConnection';
|
||||
import { daemon_rpc_ws } from '../../util/config';
|
||||
import store, { history } from '../../modules/store';
|
||||
import { exit_and_close } from '../../modules/message';
|
||||
import catalogEn from '../../locales/en/messages';
|
||||
import catalogSk from '../../locales/sk/messages';
|
||||
import catalogZhCN from '../../locales/zh-CN/messages';
|
||||
import useLocale from '../../hooks/useLocale';
|
||||
import './App.css';
|
||||
import AppModalDialogs from './AppModalDialogs';
|
||||
import AppLoading from './AppLoading';
|
||||
|
||||
i18n.loadLocaleData('en', { plurals: en });
|
||||
i18n.loadLocaleData('sk', { plurals: sk });
|
||||
i18n.loadLocaleData('zh-CN', { plurals: zh });
|
||||
|
||||
// @ts-ignore
|
||||
i18n.load('en', catalogEn.messages);
|
||||
// @ts-ignore
|
||||
i18n.load('sk', catalogSk.messages);
|
||||
// @ts-ignore
|
||||
i18n.load('zh-CN', catalogZhCN.messages);
|
||||
i18n.activate('en');
|
||||
|
||||
export default function App() {
|
||||
const { value: darkMode } = useDarkMode();
|
||||
const [locale] = useLocale('en');
|
||||
|
||||
useEffect(() => {
|
||||
i18n.activate(locale);
|
||||
}, [locale]);
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener('load', () => {
|
||||
if (isElectron()) {
|
||||
// @ts-ignore
|
||||
window.ipcRenderer.on('exit-daemon', (event) => {
|
||||
store.dispatch(exit_and_close(event));
|
||||
});
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<ConnectedRouter history={history}>
|
||||
<I18nProvider i18n={i18n}>
|
||||
<WebSocketConnection host={daemon_rpc_ws}>
|
||||
<ThemeProvider theme={darkMode ? darkTheme : lightTheme}>
|
||||
<AppRouter />
|
||||
<AppModalDialogs />
|
||||
<AppLoading />
|
||||
</ThemeProvider>
|
||||
</WebSocketConnection>
|
||||
</I18nProvider>
|
||||
</ConnectedRouter>
|
||||
</Provider>
|
||||
);
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { Spinner } from '@chia/core';
|
||||
import { RootState } from '../../modules/rootReducer';
|
||||
|
||||
export default function AppLoading() {
|
||||
const showProgressIndicator = useSelector(
|
||||
(state: RootState) => state.progress.progress_indicator,
|
||||
);
|
||||
|
||||
return <Spinner show={showProgressIndicator} />;
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { ModalDialogs } from '@chia/core';
|
||||
import { RootState } from '../../modules/rootReducer';
|
||||
|
||||
export default function AppModalDialogs() {
|
||||
const dialogs = useSelector((state: RootState) => state.dialog_state.dialogs);
|
||||
|
||||
return <ModalDialogs dialogs={dialogs} />;
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Switch, Route, Redirect } from 'react-router-dom';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { PrivateRoute } from '@chia/core';
|
||||
import SelectKey from '../selectKey/SelectKey';
|
||||
import WalletAdd from '../wallet/WalletAdd';
|
||||
import WalletImport from '../wallet/WalletImport';
|
||||
import Dashboard from '../dashboard/Dashboard';
|
||||
import BackupRestore from '../backup/BackupRestore';
|
||||
import type { RootState } from '../../modules/rootReducer';
|
||||
import LayoutLoading from '../layout/LayoutLoading';
|
||||
|
||||
export default function AppRouter() {
|
||||
const loggedInReceived = useSelector(
|
||||
(state: RootState) => state.wallet_state.logged_in_received,
|
||||
);
|
||||
const walletConnected = useSelector(
|
||||
(state: RootState) => state.daemon_state.wallet_connected,
|
||||
);
|
||||
const exiting = useSelector((state: RootState) => state.daemon_state.exiting);
|
||||
|
||||
if (exiting) {
|
||||
return (
|
||||
<LayoutLoading>
|
||||
<Trans id="Application.closing">Closing down node and server</Trans>
|
||||
</LayoutLoading>
|
||||
);
|
||||
}
|
||||
if (!walletConnected) {
|
||||
return (
|
||||
<LayoutLoading>
|
||||
<Trans id="Application.connectingToWallet">Connecting to wallet</Trans>
|
||||
</LayoutLoading>
|
||||
);
|
||||
}
|
||||
if (!loggedInReceived) {
|
||||
return (
|
||||
<LayoutLoading>
|
||||
<Trans id="Application.loggingIn">Logging in</Trans>
|
||||
</LayoutLoading>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Switch>
|
||||
<Route path="/" exact>
|
||||
<SelectKey />
|
||||
</Route>
|
||||
<Route path="/wallet/add" exact>
|
||||
<WalletAdd />
|
||||
</Route>
|
||||
<Route path="/wallet/import" exact>
|
||||
<WalletImport />
|
||||
</Route>
|
||||
<Route path="/wallet/restore" exact>
|
||||
<BackupRestore />
|
||||
</Route>
|
||||
<PrivateRoute path="/dashboard">
|
||||
<Dashboard />
|
||||
</PrivateRoute>
|
||||
<Route path="*">
|
||||
<Redirect to="/" />
|
||||
</Route>
|
||||
</Switch>
|
||||
);
|
||||
}
|
Before Width: | Height: | Size: 305 KiB |
@ -1,80 +0,0 @@
|
||||
import React from 'react';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import Modal from '@material-ui/core/Modal';
|
||||
import { Button } from '@material-ui/core';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import type { RootState } from '../../modules/rootReducer';
|
||||
import { showCreateBackup, create_backup_action } from '../../modules/message';
|
||||
import useSelectFile from '../../hooks/useSelectFile';
|
||||
|
||||
function getModalStyle() {
|
||||
const top = 50;
|
||||
const left = 50;
|
||||
|
||||
return {
|
||||
top: `${top}%`,
|
||||
left: `${left}%`,
|
||||
transform: `translate(-${top}%, -${left}%)`,
|
||||
};
|
||||
}
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
paper: {
|
||||
position: 'absolute',
|
||||
width: 400,
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
border: '1px solid #000',
|
||||
borderRadius: '5px',
|
||||
boxShadow: theme.shadows[5],
|
||||
padding: theme.spacing(2, 4, 3),
|
||||
},
|
||||
}));
|
||||
|
||||
export default function BackupCreate() {
|
||||
const selectFile = useSelectFile();
|
||||
const showBackupModal = useSelector(
|
||||
(state: RootState) => state.wallet_state.show_create_backup,
|
||||
);
|
||||
const dispatch = useDispatch();
|
||||
const classes = useStyles();
|
||||
const modalStyle = getModalStyle();
|
||||
|
||||
function handleClose() {
|
||||
dispatch(showCreateBackup(false));
|
||||
}
|
||||
|
||||
async function handleCreateBackup() {
|
||||
const filePath = await selectFile();
|
||||
if (filePath) {
|
||||
dispatch(create_backup_action(filePath));
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal
|
||||
open={showBackupModal}
|
||||
onClose={handleClose}
|
||||
aria-labelledby="simple-modal-title"
|
||||
aria-describedby="simple-modal-description"
|
||||
>
|
||||
<div style={modalStyle} className={classes.paper}>
|
||||
<h2 id="simple-modal-title">Create a Backup</h2>
|
||||
<p id="simple-modal-description">
|
||||
Backup file is used to restore smart wallets.
|
||||
</p>
|
||||
<Button
|
||||
style={{
|
||||
float: 'right',
|
||||
width: '100px',
|
||||
height: '45px',
|
||||
backgroundColor: '#0000dd',
|
||||
color: 'white',
|
||||
}}
|
||||
onClick={handleCreateBackup}
|
||||
>
|
||||
Create
|
||||
</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
}
|
@ -1,357 +0,0 @@
|
||||
import React, { DragEvent } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Paper,
|
||||
Grid,
|
||||
Typography,
|
||||
Container,
|
||||
} from '@material-ui/core';
|
||||
import { ArrowBackIos as ArrowBackIosIcon } from '@material-ui/icons';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import { useHistory } from 'react-router';
|
||||
import { Flex, Link } from '@chia/core';
|
||||
import {
|
||||
add_new_key_action,
|
||||
add_and_restore_from_backup,
|
||||
login_and_skip_action,
|
||||
get_backup_info_action,
|
||||
log_in_and_import_backup_action,
|
||||
} from '../../modules/message';
|
||||
import {
|
||||
changeBackupView,
|
||||
presentMain,
|
||||
presentBackupInfo,
|
||||
setBackupInfo,
|
||||
selectFilePath,
|
||||
} from '../../modules/backup';
|
||||
import { unix_to_short_date } from '../../util/utils';
|
||||
import type { RootState } from '../../modules/rootReducer';
|
||||
import Wallet from '../../types/Wallet';
|
||||
import myStyle from '../../constants/style';
|
||||
import LayoutHero from '../layout/LayoutHero';
|
||||
|
||||
const StyledDropPaper = styled(Paper)`
|
||||
background-color: ${({ theme }) =>
|
||||
theme.palette.type === 'dark' ? '#424242' : '#F0F0F0'};
|
||||
height: 300px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
`;
|
||||
|
||||
function WalletHeader() {
|
||||
const classes = myStyle();
|
||||
|
||||
return (
|
||||
<Box display="flex" style={{ minWidth: '100%' }}>
|
||||
<Box className={classes.column_three} flexGrow={1}>
|
||||
<Typography variant="subtitle2"> id</Typography>
|
||||
</Box>
|
||||
<Box className={classes.column_three} flexGrow={1}>
|
||||
<div className={classes.align_center}>
|
||||
{' '}
|
||||
<Typography variant="subtitle2"> name</Typography>
|
||||
</div>
|
||||
</Box>
|
||||
<Box className={classes.column_three} flexGrow={1}>
|
||||
<div className={classes.align_right}>
|
||||
{' '}
|
||||
<Typography variant="subtitle2"> type</Typography>
|
||||
</div>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
type WalletRowProps = {
|
||||
wallet: Wallet;
|
||||
};
|
||||
|
||||
function WalletRow(props: WalletRowProps) {
|
||||
const {
|
||||
wallet: {
|
||||
id,
|
||||
name,
|
||||
// @ts-ignore
|
||||
type_name: type,
|
||||
},
|
||||
} = props;
|
||||
const classes = myStyle();
|
||||
|
||||
return (
|
||||
<Box display="flex" style={{ minWidth: '100%' }}>
|
||||
<Box className={classes.column_three} flexGrow={1}>
|
||||
{id}
|
||||
</Box>
|
||||
<Box className={classes.column_three} flexGrow={1}>
|
||||
<div className={classes.align_center}> {name}</div>
|
||||
</Box>
|
||||
<Box className={classes.column_three} flexGrow={1}>
|
||||
<div className={classes.align_right}> {type}</div>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
function UIPart() {
|
||||
const dispatch = useDispatch();
|
||||
const classes = myStyle();
|
||||
let words = useSelector(
|
||||
(state: RootState) => state.mnemonic_state.mnemonic_input,
|
||||
);
|
||||
const fingerprint = useSelector(
|
||||
(state: RootState) => state.wallet_state.selected_fingerprint,
|
||||
);
|
||||
|
||||
words.forEach((word) => {
|
||||
if (word === '') {
|
||||
// @ts-ignore
|
||||
words = null;
|
||||
}
|
||||
});
|
||||
|
||||
function handleSkip() {
|
||||
if (fingerprint !== null) {
|
||||
dispatch(login_and_skip_action(fingerprint));
|
||||
} else if (words !== null) {
|
||||
dispatch(add_new_key_action(words));
|
||||
}
|
||||
}
|
||||
|
||||
const handleDragEnter = (e: DragEvent<HTMLDivElement>) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
};
|
||||
const handleDragLeave = (e: DragEvent<HTMLDivElement>) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
};
|
||||
const handleDragOver = (e: DragEvent<HTMLDivElement>) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
};
|
||||
const handleDrop = (e: DragEvent<HTMLDivElement>) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
const file_path = e.dataTransfer.files[0].path;
|
||||
if (fingerprint !== null) {
|
||||
dispatch(get_backup_info_action(file_path, fingerprint, null));
|
||||
} else if (words !== null) {
|
||||
dispatch(get_backup_info_action(file_path, null, words));
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<LayoutHero
|
||||
header={
|
||||
<Link to="/">
|
||||
<ArrowBackIosIcon fontSize="large" color="secondary" />
|
||||
</Link>
|
||||
}
|
||||
>
|
||||
<Container maxWidth="lg">
|
||||
<Flex flexDirection="column" gap={3} alignItems="center">
|
||||
<Typography variant="h4" component="h1" gutterBottom>
|
||||
Restore Smart Wallets From Backup
|
||||
</Typography>
|
||||
|
||||
<StyledDropPaper
|
||||
onDrop={(e) => handleDrop(e)}
|
||||
onDragOver={(e) => handleDragOver(e)}
|
||||
onDragEnter={(e) => handleDragEnter(e)}
|
||||
onDragLeave={(e) => handleDragLeave(e)}
|
||||
>
|
||||
<Typography variant="subtitle1">
|
||||
Drag and drop your backup file
|
||||
</Typography>
|
||||
</StyledDropPaper>
|
||||
|
||||
<Container maxWidth="xs">
|
||||
<Button
|
||||
onClick={handleSkip}
|
||||
type="submit"
|
||||
fullWidth
|
||||
variant="contained"
|
||||
color="primary"
|
||||
className={classes.submit}
|
||||
>
|
||||
Skip
|
||||
</Button>
|
||||
</Container>
|
||||
</Flex>
|
||||
</Container>
|
||||
</LayoutHero>
|
||||
);
|
||||
}
|
||||
|
||||
function BackupDetails() {
|
||||
const history = useHistory();
|
||||
const classes = myStyle();
|
||||
const dispatch = useDispatch();
|
||||
const file_path = useSelector(
|
||||
(state: RootState) => state.backup_state.selected_file_path,
|
||||
);
|
||||
const backupInfo = useSelector(
|
||||
(state: RootState) => state.backup_state.backup_info,
|
||||
);
|
||||
const selected_file_path = useSelector(
|
||||
(state: RootState) => state.backup_state.selected_file_path,
|
||||
);
|
||||
|
||||
const {
|
||||
timestamp,
|
||||
version,
|
||||
wallets,
|
||||
downloaded,
|
||||
backup_host: host,
|
||||
fingerprint: backup_fingerprint,
|
||||
} = backupInfo;
|
||||
|
||||
const date = unix_to_short_date(timestamp);
|
||||
|
||||
let words = useSelector(
|
||||
(state: RootState) => state.mnemonic_state.mnemonic_input,
|
||||
);
|
||||
const fingerprint = useSelector(
|
||||
(state: RootState) => state.wallet_state.selected_fingerprint,
|
||||
);
|
||||
|
||||
words.forEach((word) => {
|
||||
if (word === '') {
|
||||
// @ts-ignore
|
||||
words = null;
|
||||
}
|
||||
});
|
||||
|
||||
function handleGoBack() {
|
||||
dispatch(changeBackupView(presentMain));
|
||||
history.push('/');
|
||||
}
|
||||
|
||||
function goBackBackup() {
|
||||
dispatch(changeBackupView(presentMain));
|
||||
dispatch(setBackupInfo({}));
|
||||
// @ts-ignore
|
||||
dispatch(selectFilePath(null));
|
||||
}
|
||||
|
||||
function next() {
|
||||
if (fingerprint !== null) {
|
||||
dispatch(log_in_and_import_backup_action(fingerprint, file_path));
|
||||
} else if (words !== null) {
|
||||
dispatch(add_and_restore_from_backup(words, file_path));
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<ArrowBackIosIcon onClick={handleGoBack} className={classes.navigator}>
|
||||
{' '}
|
||||
</ArrowBackIosIcon>
|
||||
<div className={classes.grid_wrap}>
|
||||
<Container className={classes.grid} maxWidth="lg">
|
||||
<Typography className={classes.title} component="h4" variant="h4">
|
||||
Restore From Backup
|
||||
</Typography>
|
||||
</Container>
|
||||
</div>
|
||||
<div className={classes.dragContainer}>
|
||||
<Paper
|
||||
className={classes.drag}
|
||||
style={{
|
||||
position: 'relative',
|
||||
width: '80%',
|
||||
margin: 'auto',
|
||||
padding: '20px',
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
display="flex"
|
||||
onClick={goBackBackup}
|
||||
style={{ cursor: 'pointer', minWidth: '100%' }}
|
||||
>
|
||||
<Box>
|
||||
{' '}
|
||||
<ArrowBackIosIcon
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={goBackBackup}
|
||||
/>
|
||||
</Box>
|
||||
<Box className={classes.align_left} flexGrow={1}>
|
||||
<Typography variant="subtitle2">Import Backup File</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
<Grid container spacing={3} style={{ marginBottom: 10 }}>
|
||||
<Grid item xs={6}>
|
||||
<Typography variant="subtitle1">Backup info:</Typography>
|
||||
<Box display="flex" style={{ minWidth: '100%' }}>
|
||||
<Box flexGrow={1}>Date: </Box>
|
||||
<Box className={classes.align_right} flexGrow={1}>
|
||||
{date}
|
||||
</Box>
|
||||
</Box>
|
||||
<Box display="flex" style={{ minWidth: '100%' }}>
|
||||
<Box flexGrow={1}>Version: </Box>
|
||||
<Box className={classes.align_right} flexGrow={1}>
|
||||
{version}
|
||||
</Box>
|
||||
</Box>
|
||||
<Box display="flex" style={{ minWidth: '100%' }}>
|
||||
<Box flexGrow={1}>Fingerprint: </Box>
|
||||
<Box className={classes.align_right} flexGrow={1}>
|
||||
{backup_fingerprint}
|
||||
</Box>
|
||||
</Box>
|
||||
</Grid>
|
||||
<Grid item xs={6}>
|
||||
<Box display="flex" style={{ minWidth: '100%' }}>
|
||||
<Box flexGrow={1}>Downloaded: </Box>
|
||||
<Box className={classes.align_right} flexGrow={1}>
|
||||
{`${downloaded}`}
|
||||
</Box>
|
||||
</Box>
|
||||
<Box display="flex" style={{ minWidth: '100%' }}>
|
||||
<Box flexGrow={1}>
|
||||
{downloaded ? 'Backup Host:' : 'File Path'}
|
||||
</Box>
|
||||
<Box className={classes.align_right} flexGrow={1}>
|
||||
{downloaded ? host : selected_file_path}
|
||||
</Box>
|
||||
</Box>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Typography variant="subtitle1">Smart wallets</Typography>
|
||||
<WalletHeader />
|
||||
{!!wallets &&
|
||||
wallets.map((wallet: Wallet) => <WalletRow wallet={wallet} />)}
|
||||
</Paper>
|
||||
</div>
|
||||
<Container component="main" maxWidth="xs">
|
||||
<div className={classes.paper}>
|
||||
<Button
|
||||
onClick={next}
|
||||
type="submit"
|
||||
fullWidth
|
||||
variant="contained"
|
||||
color="primary"
|
||||
className={classes.submit}
|
||||
>
|
||||
Continue
|
||||
</Button>
|
||||
</div>
|
||||
</Container>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function RestoreBackup() {
|
||||
const view = useSelector((state: RootState) => state.backup_state.view);
|
||||
if (view === presentBackupInfo) {
|
||||
return <BackupDetails />;
|
||||
}
|
||||
return <UIPart />;
|
||||
}
|
@ -1,387 +0,0 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Button, Paper, TableRow, Table, TableBody, TableCell, TableContainer } from '@material-ui/core';
|
||||
import { Alert } from '@material-ui/lab';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { ArrowBackIos as ArrowBackIosIcon } from '@material-ui/icons';
|
||||
import { useParams, useHistory } from 'react-router-dom';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { Card, Loading, TooltipIcon, Flex } from '@chia/core';
|
||||
import styled from 'styled-components';
|
||||
import {
|
||||
unix_to_short_date,
|
||||
hex_to_array,
|
||||
arr_to_hex,
|
||||
sha256,
|
||||
} from '../../util/utils';
|
||||
import {
|
||||
getSubBlockRecord,
|
||||
getSubBlock,
|
||||
} from '../../modules/fullnodeMessages';
|
||||
import { chia_formatter } from '../../util/chia';
|
||||
import { calculatePoolReward, calculateBaseFarmerReward } from '../../util/blockRewards';
|
||||
import LayoutMain from '../layout/LayoutMain';
|
||||
|
||||
/* global BigInt */
|
||||
|
||||
const BackIcon = styled(ArrowBackIosIcon)`
|
||||
font-size: 1.25rem;
|
||||
cursor: pointer;
|
||||
`;
|
||||
|
||||
async function computeNewPlotId(block) {
|
||||
const { pool_public_key, plot_public_key } = block.reward_chain_sub_block.proof_of_space;
|
||||
|
||||
let buf = hex_to_array(pool_public_key);
|
||||
buf = buf.concat(hex_to_array(plot_public_key));
|
||||
const bufHash = await sha256(buf);
|
||||
return arr_to_hex(bufHash);
|
||||
}
|
||||
|
||||
export default function Block() {
|
||||
const { headerHash } = useParams();
|
||||
const history = useHistory();
|
||||
const dispatch = useDispatch();
|
||||
const [block, setBlock] = useState();
|
||||
const [blockRecord, setBlockRecord] = useState();
|
||||
const [prevBlockRecord, setPrevBlockRecord] = useState();
|
||||
const [newPlotId, setNewPlotId] = useState();
|
||||
const [nextSubBlocks, setNextSubBlocks] = useState([]);
|
||||
|
||||
const [error, setError] = useState();
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
const hasPreviousSubBlock = !!blockRecord?.prev_hash;
|
||||
const hasNextSubBlock = !!nextSubBlocks.length;
|
||||
|
||||
async function prepareData(headerHash) {
|
||||
setLoading(true);
|
||||
|
||||
try {
|
||||
setBlock();
|
||||
setBlockRecord();
|
||||
setPrevBlockRecord();
|
||||
setNewPlotId();
|
||||
|
||||
const block = await dispatch(getSubBlock(headerHash));
|
||||
setBlock(block);
|
||||
|
||||
if (block) {
|
||||
setNewPlotId(await computeNewPlotId(block));
|
||||
}
|
||||
|
||||
const blockRecord = await dispatch(getSubBlockRecord(headerHash));
|
||||
setBlockRecord(blockRecord);
|
||||
|
||||
if (blockRecord?.prev_block_hash) {
|
||||
const prevBlockRecord = await dispatch(getSubBlockRecord(blockRecord?.prev_block_hash));
|
||||
setPrevBlockRecord(prevBlockRecord);
|
||||
}
|
||||
} catch (e) {
|
||||
setError(e);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
prepareData(headerHash);
|
||||
}, [headerHash]);
|
||||
|
||||
function handleShowPreviousSubBlock() {
|
||||
const prevHash = blockRecord?.prev_hash;
|
||||
if (prevHash) {
|
||||
// save current hash
|
||||
setNextSubBlocks([headerHash, ...nextSubBlocks]);
|
||||
|
||||
history.push(`/dashboard/block/${prevHash}`);
|
||||
}
|
||||
}
|
||||
|
||||
function handleShowNextSubBlock() {
|
||||
const [nextSubBlock, ...rest] = nextSubBlocks;
|
||||
if (nextSubBlock) {
|
||||
setNextSubBlocks(rest);
|
||||
|
||||
history.push(`/dashboard/block/${nextSubBlock}`);
|
||||
}
|
||||
}
|
||||
|
||||
function handleShowPreviousBlock() {
|
||||
const prevBlockHash = blockRecord?.prev_block_hash;
|
||||
if (prevBlockHash) {
|
||||
// save current hash
|
||||
setNextSubBlocks([headerHash, ...nextSubBlocks]);
|
||||
|
||||
history.push(`/dashboard/block/${prevBlockHash}`);
|
||||
}
|
||||
}
|
||||
|
||||
function handleGoBack() {
|
||||
history.push('/dashboard');
|
||||
}
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<LayoutMain
|
||||
title={<Trans id="Block.title">Block</Trans>}
|
||||
>
|
||||
<Flex justifyContent="center">
|
||||
<Loading />
|
||||
</Flex>
|
||||
</LayoutMain>
|
||||
);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<LayoutMain
|
||||
title={<Trans id="Block.title">Block</Trans>}
|
||||
>
|
||||
<Alert severity="error">
|
||||
{error.message}
|
||||
</Alert>
|
||||
</LayoutMain>
|
||||
);
|
||||
}
|
||||
|
||||
if (!block) {
|
||||
return (
|
||||
<LayoutMain
|
||||
title={<Trans id="Block.title">Block</Trans>}
|
||||
>
|
||||
<Alert severity="warning">
|
||||
<Trans id="Block.notFound">
|
||||
Block with hash {headerHash} does not exists.
|
||||
</Trans>
|
||||
</Alert>
|
||||
|
||||
</LayoutMain>
|
||||
);
|
||||
}
|
||||
|
||||
const difficulty = prevBlockRecord && blockRecord
|
||||
? blockRecord.weight - prevBlockRecord.weight
|
||||
: blockRecord?.weight ?? 0;
|
||||
|
||||
const poolReward = chia_formatter(
|
||||
Number.parseFloat(calculatePoolReward(blockRecord.height)),
|
||||
'mojo',
|
||||
).to('chia').toString();
|
||||
|
||||
const baseFarmerReward = chia_formatter(
|
||||
Number.parseFloat(calculateBaseFarmerReward(blockRecord.height)),
|
||||
'mojo',
|
||||
).to('chia').toString();
|
||||
|
||||
const chia_fees = blockRecord.fees
|
||||
? chia_formatter(
|
||||
Number.parseFloat(BigInt(blockRecord.fees)),
|
||||
'mojo',
|
||||
).to('chia').toString()
|
||||
: '';
|
||||
|
||||
const rows = [
|
||||
{
|
||||
name: <Trans id="Block.headerHash">Header hash</Trans>,
|
||||
value: blockRecord.header_hash,
|
||||
},
|
||||
{
|
||||
name: <Trans id="Block.timestamp">Timestamp</Trans>,
|
||||
value: blockRecord.timestamp ? unix_to_short_date(blockRecord.timestamp) : null,
|
||||
tooltip: (
|
||||
<Trans id="Block.timestampTooltip">
|
||||
This is the time the block was created by the farmer, which is before
|
||||
it is finalized with a proof of time
|
||||
</Trans>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: <Trans id="Block.subBlockHeight">Sub Block Height</Trans>,
|
||||
value: blockRecord.sub_block_height,
|
||||
},
|
||||
{
|
||||
name: <Trans id="Block.height">Height</Trans>,
|
||||
value: blockRecord.height,
|
||||
},
|
||||
{
|
||||
name: <Trans id="Block.weight">Weight</Trans>,
|
||||
value: BigInt(blockRecord.weight).toLocaleString(),
|
||||
tooltip: (
|
||||
<Trans id="Block.weightTooltip">
|
||||
Weight is the total added difficulty of all sub blocks up to and including
|
||||
this one
|
||||
</Trans>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: <Trans id="Block.previousSubBlockHash">Previous Sub Block Hash</Trans>,
|
||||
value: blockRecord.prev_hash,
|
||||
onClick: handleShowPreviousSubBlock,
|
||||
},
|
||||
{
|
||||
name: <Trans id="Block.previousBlockHash">Previous Block Hash</Trans>,
|
||||
value: blockRecord.prev_block_hash,
|
||||
onClick: handleShowPreviousBlock,
|
||||
},
|
||||
{
|
||||
name: <Trans id="Block.difficulty">Difficulty</Trans>,
|
||||
value: BigInt(difficulty).toLocaleString(),
|
||||
},
|
||||
{
|
||||
name: <Trans id="Block.totalVDFIterations">Total VDF Iterations</Trans>,
|
||||
value: BigInt(blockRecord.total_iters).toLocaleString(),
|
||||
tooltip: (
|
||||
<Trans id="Block.totalVDFIterationsTooltip">
|
||||
The total number of VDF (verifiable delay function) or proof of time
|
||||
iterations on the whole chain up to this sub block.
|
||||
</Trans>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: <Trans id="Block.blockVDFIterations">Block VDF Iterations</Trans>,
|
||||
value: BigInt(block.reward_chain_sub_block.challenge_chain_ip_vdf.number_of_iterations).toLocaleString(),
|
||||
tooltip: (
|
||||
<Trans id="Block.blockVDFIterationsTooltip">
|
||||
The total number of VDF (verifiable delay function) or proof of time
|
||||
iterations on this block.
|
||||
</Trans>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: <Trans id="Block.proofOfSpaceSize">Proof of Space Size</Trans>,
|
||||
value: block.reward_chain_sub_block.proof_of_space.size,
|
||||
},
|
||||
{
|
||||
name: <Trans id="Block.plotPublicKey">Plot Public Key</Trans>,
|
||||
value: block.reward_chain_sub_block.proof_of_space.plot_public_key,
|
||||
},
|
||||
{
|
||||
name: <Trans id="Block.poolPublicKey">Pool Public Key</Trans>,
|
||||
value: block.reward_chain_sub_block.proof_of_space.pool_public_key,
|
||||
},
|
||||
{
|
||||
name: <Trans id="Block.farmerPuzzleHash">Farmer Puzzle Hash</Trans>,
|
||||
value: blockRecord.farmer_puzzle_hash,
|
||||
},
|
||||
{
|
||||
name: <Trans id="Block.poolPuzzleHash">Pool Puzzle Hash</Trans>,
|
||||
value: blockRecord.pool_puzzle_hash,
|
||||
},
|
||||
{
|
||||
name: <Trans id="Block.plotId">Plot Id</Trans>,
|
||||
value: newPlotId,
|
||||
tooltip: (
|
||||
<Trans id="Block.plotIdTooltip">
|
||||
The seed used to create the plot.
|
||||
This depends on the pool pk and plot pk.
|
||||
</Trans>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: (
|
||||
<Trans id="Block.transactionsFilterHash">
|
||||
Transactions Filter Hash
|
||||
</Trans>
|
||||
),
|
||||
value: block.foliage_block?.filter_hash,
|
||||
},
|
||||
/*
|
||||
{
|
||||
name: <Trans id="Block.coinbaseAmount">Coinbase Amount</Trans>,
|
||||
value: `${chia_cb} TXCH`,
|
||||
tooltip: (
|
||||
<Trans id="Block.coinbaseAmountTooltip">
|
||||
This is the chia block reward which goes to the pool (or farmer if not pooling)
|
||||
</Trans>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: <Trans id="Block.coinbasePuzzleHash">Coinbase Puzzle Hash</Trans>,
|
||||
value: blockRecord.pool_puzzle_hash,
|
||||
},
|
||||
*/
|
||||
|
||||
{
|
||||
name: <Trans id="Block.poolRewardAmount">Pool Reward Amount</Trans>,
|
||||
value: `${poolReward} TXCH`,
|
||||
},
|
||||
{
|
||||
name: <Trans id="Block.baseFarmerRewardAmount">Base Farmer Reward Amount</Trans>,
|
||||
value: `${baseFarmerReward} TXCH`,
|
||||
},
|
||||
{
|
||||
name: <Trans id="Block.feesAmount">Fees Amount</Trans>,
|
||||
value: chia_fees ? `${chia_fees} TXCH` : '',
|
||||
tooltip: (
|
||||
<Trans id="Block.feesAmountTooltip">
|
||||
The total transactions fees in this block. Rewarded to the farmer.
|
||||
</Trans>
|
||||
),
|
||||
},
|
||||
{
|
||||
name: <Trans id="Block.feesPuzzleHash">Fees Puzzle Hash</Trans>,
|
||||
value: blockRecord.farmer_puzzle_hash,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<LayoutMain
|
||||
title={<Trans id="Block.title">Block</Trans>}
|
||||
>
|
||||
<Card
|
||||
title={(
|
||||
<Flex gap={1} alignItems="baseline">
|
||||
<BackIcon onClick={handleGoBack}>
|
||||
{' '}
|
||||
</BackIcon>
|
||||
<span>
|
||||
<Trans id="Block.descriptionSubBlock">
|
||||
Sub Block at height {blockRecord.sub_block_height} in the Chia
|
||||
blockchain
|
||||
</Trans>
|
||||
</span>
|
||||
</Flex>
|
||||
)}
|
||||
action={(
|
||||
<Flex gap={1}>
|
||||
<Button onClick={handleShowPreviousSubBlock} disabled={!hasPreviousSubBlock}>
|
||||
<Trans id="Block.previous">
|
||||
Previous
|
||||
</Trans>
|
||||
</Button>
|
||||
<Button onClick={handleShowNextSubBlock} disabled={!hasNextSubBlock}>
|
||||
<Trans id="Block.next">
|
||||
Next
|
||||
</Trans>
|
||||
</Button>
|
||||
</Flex>
|
||||
)}
|
||||
>
|
||||
<TableContainer component={Paper}>
|
||||
<Table>
|
||||
<TableBody>
|
||||
{rows.map((row, index) => (
|
||||
<TableRow key={index}>
|
||||
<TableCell component="th" scope="row">
|
||||
{row.name}{' '}
|
||||
{row.tooltip && (
|
||||
<TooltipIcon>
|
||||
{row.tooltip}
|
||||
</TooltipIcon>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
onClick={row.onClick}
|
||||
align="right"
|
||||
>
|
||||
{row.value}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</Card>
|
||||
</LayoutMain>
|
||||
);
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
import React, { ReactNode } from 'react';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
|
||||
type Props = {
|
||||
children?: ReactNode;
|
||||
expanded?: boolean;
|
||||
};
|
||||
|
||||
export default function Accordion(props: Props) {
|
||||
const { expanded, children } = props;
|
||||
|
||||
return (
|
||||
<AnimatePresence>
|
||||
{expanded && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
>
|
||||
{children}
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
);
|
||||
}
|
||||
|
||||
Accordion.defaultProps = {
|
||||
children: undefined,
|
||||
expanded: false,
|
||||
};
|
@ -1 +0,0 @@
|
||||
export { default } from './Accordion';
|
@ -1,65 +0,0 @@
|
||||
import React, { useState, ReactNode } from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { Typography } from '@material-ui/core';
|
||||
import styled from 'styled-components';
|
||||
import {
|
||||
KeyboardArrowUp as KeyboardArrowUpIcon,
|
||||
KeyboardArrowDown as KeyboardArrowDownIcon,
|
||||
} from '@material-ui/icons';
|
||||
import Flex from '../Flex';
|
||||
import Accordion from '../Accordion';
|
||||
|
||||
const StyledToggleAdvancedOptions = styled(({ expanded, ...rest }) => (
|
||||
<Typography {...rest} />
|
||||
))`
|
||||
cursor: pointer;
|
||||
`;
|
||||
|
||||
type Props = {
|
||||
children?: ReactNode,
|
||||
expanded: boolean,
|
||||
};
|
||||
|
||||
export default function AdvancedOptions(props: Props) {
|
||||
const { children, expanded: defaultExpanded } = props;
|
||||
const [isExpanded, setIsExpanded] = useState<boolean>(defaultExpanded);
|
||||
|
||||
function handleToggle() {
|
||||
setIsExpanded(!isExpanded);
|
||||
}
|
||||
|
||||
return (
|
||||
<Flex flexDirection="column" gap={1}>
|
||||
<StyledToggleAdvancedOptions
|
||||
variant="caption"
|
||||
expanded={isExpanded}
|
||||
onClick={handleToggle}
|
||||
>
|
||||
{isExpanded ? (
|
||||
<Flex alignItems="center">
|
||||
<KeyboardArrowUpIcon />
|
||||
<Trans id="AdvancedOptions.hideAdvancedOptions">
|
||||
Hide Advanced Options
|
||||
</Trans>
|
||||
</Flex>
|
||||
) : (
|
||||
<Flex alignItems="center">
|
||||
<KeyboardArrowDownIcon />
|
||||
<Trans id="AdvancedOptions.showAdvancedOptions">
|
||||
Show Advanced Options
|
||||
</Trans>
|
||||
</Flex>
|
||||
)}
|
||||
</StyledToggleAdvancedOptions>
|
||||
|
||||
<Accordion expanded={isExpanded}>
|
||||
{children}
|
||||
</Accordion>
|
||||
</Flex>
|
||||
)
|
||||
}
|
||||
|
||||
AdvancedOptions.defaultProps = {
|
||||
expanded: false,
|
||||
children: undefined,
|
||||
};
|
@ -1 +0,0 @@
|
||||
export { default } from './AdvancedOptions';
|
@ -1,60 +0,0 @@
|
||||
import React, { ReactNode } from 'react';
|
||||
import { Button, Dialog, DialogTitle, DialogContent, DialogActions, DialogContentText } from '@material-ui/core';
|
||||
|
||||
type Props = {
|
||||
title?: ReactNode,
|
||||
children?: ReactNode,
|
||||
open: boolean,
|
||||
onClose: (value?: any) => void,
|
||||
};
|
||||
|
||||
export default function AlertDialog(props: Props) {
|
||||
const { onClose, open, title, children } = props;
|
||||
|
||||
function handleClose() {
|
||||
if (onClose) {
|
||||
onClose(true);
|
||||
}
|
||||
}
|
||||
|
||||
function handleHide() {
|
||||
if (onClose) {
|
||||
onClose();
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
onClose={handleHide}
|
||||
aria-labelledby="alert-dialog-title"
|
||||
aria-describedby="alert-dialog-description"
|
||||
open={open}
|
||||
>
|
||||
{title && (
|
||||
<DialogTitle id="alert-dialog-title">
|
||||
{title}
|
||||
</DialogTitle>
|
||||
)}
|
||||
{children && (
|
||||
<DialogContent>
|
||||
<DialogContentText id="alert-dialog-description">
|
||||
{children}
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
)}
|
||||
|
||||
<DialogActions>
|
||||
<Button onClick={handleClose} autoFocus>
|
||||
Ok
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
AlertDialog.defaultProps = {
|
||||
open: false,
|
||||
title: undefined,
|
||||
children: undefined,
|
||||
onClose: () => {},
|
||||
};
|
@ -1 +0,0 @@
|
||||
export { default } from './AlertDialog';
|
@ -1,36 +0,0 @@
|
||||
import React, { ReactNode } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { Box } from '@material-ui/core';
|
||||
|
||||
const OuterWrapper = styled(({ ration, ...rest }) => <Box {...rest} />)`
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
padding-bottom: ${(props) => (1 / props.ratio) * 100}%;
|
||||
overflow: hidden;
|
||||
`;
|
||||
|
||||
export const InnerWrapper = styled(Box)`
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
`;
|
||||
|
||||
type Props = {
|
||||
ratio: number;
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
export default function AspectRatio(props: Props) {
|
||||
const { children, ratio } = props;
|
||||
|
||||
return (
|
||||
<OuterWrapper ratio={ratio}>
|
||||
<InnerWrapper>
|
||||
{children}
|
||||
</InnerWrapper>
|
||||
</OuterWrapper>
|
||||
);
|
||||
}
|
@ -1 +0,0 @@
|
||||
export { default } from './AspectRatio';
|
@ -1,33 +0,0 @@
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { darken } from 'polished';
|
||||
import { Button as BaseButton, ButtonProps } from '@material-ui/core';
|
||||
|
||||
const DangerButton = styled(BaseButton)`
|
||||
color: ${({ theme }) => theme.palette.danger.contrastText};
|
||||
background-color: ${({ theme }) => theme.palette.danger.main};
|
||||
|
||||
&:hover {
|
||||
color: ${({ theme }) => theme.palette.danger.contrastText};
|
||||
background-color: ${({ theme }) => darken(0.1, theme.palette.danger.main)};
|
||||
}
|
||||
`;
|
||||
|
||||
type Props = Omit<ButtonProps, 'color'> & {
|
||||
color?: 'primary' | 'danger' | 'secondary';
|
||||
};
|
||||
|
||||
export default function Button(props: Props) {
|
||||
const { color, ...rest } = props;
|
||||
|
||||
switch (color) {
|
||||
case 'danger':
|
||||
return <DangerButton {...rest} />;
|
||||
case 'primary':
|
||||
return <BaseButton color="primary" {...rest} />;
|
||||
case 'secondary':
|
||||
return <BaseButton color="secondary" {...rest} />;
|
||||
default:
|
||||
return <BaseButton {...rest} />;
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
export { default } from './Button';
|
@ -1,24 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Button, ButtonProps } from '@material-ui/core';
|
||||
import { Check as CheckIcon } from '@material-ui/icons';
|
||||
|
||||
type Props = ButtonProps & {
|
||||
selected?: boolean,
|
||||
};
|
||||
|
||||
export default function ButtonSelected(props: Props) {
|
||||
const { selected, children, ...rest } = props;
|
||||
const color = selected ? 'primary' : 'default';
|
||||
|
||||
return (
|
||||
<Button color={color} {...rest}>
|
||||
{selected ? (
|
||||
<>
|
||||
<CheckIcon />
|
||||
{' '}
|
||||
{children}
|
||||
</>
|
||||
) : children}
|
||||
</Button>
|
||||
);
|
||||
}
|
@ -1 +0,0 @@
|
||||
export { default } from './ButtonSelected';
|
@ -1,60 +0,0 @@
|
||||
import React, { ReactNode, ReactElement } from 'react';
|
||||
import { Box, Card as CardMaterial, CardContent, CardHeader, Grid } from '@material-ui/core';
|
||||
import Flex from '../Flex';
|
||||
import TooltipIcon from '../TooltipIcon';
|
||||
|
||||
type Props = {
|
||||
children?: ReactNode;
|
||||
title?: ReactNode;
|
||||
tooltip?: ReactElement<any>;
|
||||
actions?: ReactNode;
|
||||
gap?: number;
|
||||
interactive?: boolean;
|
||||
action?: ReactNode,
|
||||
};
|
||||
|
||||
export default function Card(props: Props) {
|
||||
const { children, title, tooltip, actions, gap, interactive, action } = props;
|
||||
|
||||
const headerTitle = tooltip ? (
|
||||
<Flex alignItems="center" gap={1}>
|
||||
<Box>
|
||||
{title}
|
||||
</Box>
|
||||
<TooltipIcon interactive={interactive}>
|
||||
{tooltip}
|
||||
</TooltipIcon>
|
||||
</Flex>
|
||||
) : title;
|
||||
|
||||
return (
|
||||
<CardMaterial>
|
||||
{title && (
|
||||
<CardHeader title={headerTitle} action={action} />
|
||||
)}
|
||||
<CardContent>
|
||||
<Flex flexDirection="column" gap={3}>
|
||||
<Flex flexDirection="column" gap={gap}>
|
||||
{children}
|
||||
</Flex>
|
||||
{actions && (
|
||||
<Grid xs={12} item>
|
||||
<Flex gap={2}>
|
||||
{actions}
|
||||
</Flex>
|
||||
</Grid>
|
||||
)}
|
||||
</Flex>
|
||||
</CardContent>
|
||||
</CardMaterial>
|
||||
);
|
||||
}
|
||||
|
||||
Card.defaultProps = {
|
||||
gap: 2,
|
||||
children: undefined,
|
||||
title: undefined,
|
||||
tooltip: undefined,
|
||||
actions: undefined,
|
||||
interactive: false,
|
||||
};
|
@ -1 +0,0 @@
|
||||
export { default } from './Card';
|
@ -1,30 +0,0 @@
|
||||
import React, { ReactNode } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { Card, CardContent } from '@material-ui/core';
|
||||
import { Flex } from '@chia/core';
|
||||
|
||||
const StyledContent = styled(CardContent)`
|
||||
padding: ${({ theme }) => `${theme.spacing(5)}px ${theme.spacing(4)}px !important`};
|
||||
`;
|
||||
|
||||
type Props = {
|
||||
children?: ReactNode,
|
||||
};
|
||||
|
||||
export default function CardHero(props: Props) {
|
||||
const { children } = props;
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<StyledContent>
|
||||
<Flex flexDirection="column" gap={3}>
|
||||
{children}
|
||||
</Flex>
|
||||
</StyledContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
CardHero.defaultProps = {
|
||||
children: undefined,
|
||||
};
|
@ -1 +0,0 @@
|
||||
export { default } from "./CardHero";
|
@ -1,50 +0,0 @@
|
||||
import React, { ReactNode } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { Avatar, Card, CardContent, CardHeader, Divider, Grid, Typography } from '@material-ui/core';
|
||||
import Flex from '../Flex';
|
||||
|
||||
const StyledCardContent = styled(CardContent)`
|
||||
padding-left: 72px;
|
||||
`;
|
||||
|
||||
const StyledStep = styled(Avatar)`
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
`;
|
||||
|
||||
type Props = {
|
||||
children: ReactNode,
|
||||
title: ReactNode,
|
||||
step: ReactNode,
|
||||
};
|
||||
|
||||
export default function CardStep(props: Props) {
|
||||
const { children, step, title } = props;
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader
|
||||
avatar={
|
||||
<StyledStep aria-label="step">
|
||||
{step}
|
||||
</StyledStep>
|
||||
}
|
||||
title={(
|
||||
<Typography variant="h6">
|
||||
{title}
|
||||
</Typography>
|
||||
)}
|
||||
/>
|
||||
<Divider />
|
||||
<StyledCardContent>
|
||||
<Grid container>
|
||||
<Grid md={10} lg={8} item>
|
||||
<Flex flexDirection="column" gap={2}>
|
||||
{children}
|
||||
</Flex>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</StyledCardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
@ -1 +0,0 @@
|
||||
export { default } from "./CardStep";
|
@ -1,46 +0,0 @@
|
||||
import React, { ChangeEvent, ReactNode } from 'react';
|
||||
import { Controller, useFormContext } from 'react-hook-form';
|
||||
import { Checkbox as MaterialCheckbox, CheckboxProps } from '@material-ui/core';
|
||||
|
||||
const ParseBoolean = (props: CheckboxProps) => {
|
||||
const { onChange, ...rest } = props;
|
||||
const { name } = rest;
|
||||
const { setValue } = useFormContext();
|
||||
|
||||
function handleChange(e: ChangeEvent<HTMLInputElement>) {
|
||||
const value = !!e.target.checked;
|
||||
// @ts-ignore
|
||||
onChange(e, value);
|
||||
|
||||
if (name) {
|
||||
setValue(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
return <MaterialCheckbox onChange={handleChange} {...rest} />;
|
||||
}
|
||||
|
||||
type Props = {
|
||||
name: string,
|
||||
label?: ReactNode,
|
||||
value?: any,
|
||||
};
|
||||
|
||||
export default function Checkbox(props: Props): JSX.Element {
|
||||
const { name, ...rest } = props;
|
||||
const { control } = useFormContext();
|
||||
|
||||
return (
|
||||
// @ts-ignore
|
||||
<Controller
|
||||
as={<ParseBoolean />}
|
||||
name={name}
|
||||
control={control}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Checkbox.defaultProps = {
|
||||
value: true,
|
||||
};
|
@ -1 +0,0 @@
|
||||
export { default } from './Checkbox';
|
@ -1,66 +0,0 @@
|
||||
import React, { ReactNode } from 'react';
|
||||
import { Button, ButtonProps, Dialog, DialogTitle, DialogContent, DialogActions, DialogContentText } from '@material-ui/core';
|
||||
|
||||
type Props = {
|
||||
title?: ReactNode,
|
||||
children?: ReactNode,
|
||||
open: boolean,
|
||||
onClose: (value: boolean) => void,
|
||||
confirmTitle: ReactNode,
|
||||
cancelTitle: ReactNode,
|
||||
confirmColor?: ButtonProps['color'],
|
||||
};
|
||||
|
||||
export default function ConfirmDialog(props: Props) {
|
||||
const { onClose, open, title, children, cancelTitle, confirmTitle, confirmColor, ...rest } = props;
|
||||
|
||||
function handleConfirm() {
|
||||
onClose(true);
|
||||
}
|
||||
|
||||
function handleCancel() {
|
||||
onClose(false);
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
onClose={handleCancel}
|
||||
aria-labelledby="alert-dialog-title"
|
||||
aria-describedby="alert-dialog-description"
|
||||
open={open}
|
||||
{...rest}
|
||||
>
|
||||
{title && (
|
||||
<DialogTitle id="alert-dialog-title">
|
||||
{title}
|
||||
</DialogTitle>
|
||||
)}
|
||||
{children && (
|
||||
<DialogContent>
|
||||
<DialogContentText id="alert-dialog-description">
|
||||
{children}
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
)}
|
||||
|
||||
<DialogActions>
|
||||
<Button onClick={handleCancel} color="secondary" autoFocus>
|
||||
{cancelTitle}
|
||||
</Button>
|
||||
<Button onClick={handleConfirm} color={confirmColor}>
|
||||
{confirmTitle}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
ConfirmDialog.defaultProps = {
|
||||
open: false,
|
||||
onClose: () => {},
|
||||
title: undefined,
|
||||
children: undefined,
|
||||
cancelTitle: 'Cancel',
|
||||
confirmTitle: 'Ok',
|
||||
confirmColor: 'default',
|
||||
};
|
@ -1 +0,0 @@
|
||||
export { default } from './ConfirmDialog';
|
@ -1,18 +0,0 @@
|
||||
import React from 'react';
|
||||
import useDarkMode from 'use-dark-mode';
|
||||
import { IconButton } from '@material-ui/core';
|
||||
import { Brightness4, Brightness7 } from '@material-ui/icons';
|
||||
|
||||
export default function DarkModeToggle() {
|
||||
const { toggle, value: darkMode } = useDarkMode();
|
||||
|
||||
function handleClick() {
|
||||
toggle();
|
||||
}
|
||||
|
||||
return (
|
||||
<IconButton color="inherit" onClick={handleClick}>
|
||||
{darkMode ? <Brightness7 /> : <Brightness4 />}
|
||||
</IconButton>
|
||||
);
|
||||
}
|
@ -1 +0,0 @@
|
||||
export { default } from './DarkModeToggle';
|
@ -1,64 +0,0 @@
|
||||
import React, { ReactNode } from 'react';
|
||||
import { Paper, CircularProgress } from '@material-ui/core';
|
||||
import styled from 'styled-components';
|
||||
import { useDropzone, DropzoneOptions } from 'react-dropzone';
|
||||
import AspectRatio from '../AspectRatio';
|
||||
import Flex from '../Flex';
|
||||
|
||||
const StyledPaper = styled(Paper)`
|
||||
background-color: #999999;
|
||||
padding: ${({ theme }) => `${theme.spacing(1)}px ${theme.spacing(2)}px`};
|
||||
`;
|
||||
|
||||
type ChildrenRender = (input: {
|
||||
isDragActive: boolean;
|
||||
}) => ReactNode
|
||||
|
||||
type Props = {
|
||||
children: ReactNode | ChildrenRender;
|
||||
onDrop: (acceptedFiles: File[]) => void;
|
||||
maxFiles?: number;
|
||||
accept?: string[]; // ['image/jpeg', 'image/png']
|
||||
ratio: number;
|
||||
processing?: boolean;
|
||||
};
|
||||
|
||||
export default function Dropzone(props: Props) {
|
||||
const { children, onDrop, maxFiles, accept, ratio, processing } = props;
|
||||
|
||||
const config: DropzoneOptions = {
|
||||
onDrop,
|
||||
maxFiles,
|
||||
};
|
||||
|
||||
if (accept) {
|
||||
config.accept = accept.join(', ');
|
||||
}
|
||||
|
||||
const { getRootProps, getInputProps, isDragActive } = useDropzone(config);
|
||||
const childrenContent = typeof children === 'function'
|
||||
? children({ isDragActive })
|
||||
: children;
|
||||
|
||||
return (
|
||||
<div {...getRootProps()}>
|
||||
<input {...getInputProps()} />
|
||||
<StyledPaper>
|
||||
<AspectRatio ratio={ratio}>
|
||||
<Flex alignItems="center" justifyContent="center" flexDirection="column" height="100%">
|
||||
{processing ? (
|
||||
<CircularProgress color="secondary" />
|
||||
) : childrenContent}
|
||||
</Flex>
|
||||
</AspectRatio>
|
||||
</StyledPaper>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Dropzone.defaultProps = {
|
||||
maxFiles: undefined,
|
||||
accept: undefined,
|
||||
ratio: 16/6,
|
||||
processing: false,
|
||||
};
|
@ -1 +0,0 @@
|
||||
export { default } from './Dropzone';
|
@ -1,69 +0,0 @@
|
||||
import React from 'react';
|
||||
import { Box, BoxProps, useTheme } from '@material-ui/core';
|
||||
import styled from 'styled-components';
|
||||
|
||||
type GAP_SIZE = number | string | 'small' | 'normal' | 'large';
|
||||
|
||||
function getGap(gap: GAP_SIZE, theme: any): string {
|
||||
if (typeof gap === 'number') {
|
||||
return `${theme.spacing(gap)}px`;
|
||||
}
|
||||
|
||||
switch (gap) {
|
||||
case 'small':
|
||||
return '0.5rem';
|
||||
case 'normal':
|
||||
return '1rem';
|
||||
case 'large':
|
||||
return '2rem';
|
||||
default:
|
||||
return String(gap);
|
||||
}
|
||||
}
|
||||
|
||||
const StyledGapBox = styled(({ rowGap, columnGap, ...rest }) => (
|
||||
<Box {...rest} />
|
||||
))`
|
||||
> * {
|
||||
margin-bottom: ${({ rowGap }) => rowGap};
|
||||
${({ columnGap }) => columnGap && `margin-right: ${columnGap}`};
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
${({ columnGap }) => columnGap && `margin-right: 0`};
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
type Props = BoxProps & {
|
||||
gap?: GAP_SIZE;
|
||||
rowGap?: GAP_SIZE;
|
||||
columnGap?: GAP_SIZE;
|
||||
};
|
||||
|
||||
export default function Flex(props: Props) {
|
||||
const {
|
||||
gap = '0px',
|
||||
flexDirection,
|
||||
rowGap = gap,
|
||||
columnGap = gap,
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
const theme = useTheme();
|
||||
|
||||
const rowGapValue = flexDirection === 'column' ? getGap(rowGap, theme) : 0;
|
||||
|
||||
const columnGapValue =
|
||||
flexDirection !== 'column' ? getGap(columnGap, theme) : 0;
|
||||
|
||||
return (
|
||||
<StyledGapBox
|
||||
flexDirection={flexDirection}
|
||||
display="flex"
|
||||
rowGap={rowGapValue}
|
||||
columnGap={columnGapValue}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
}
|
@ -1 +0,0 @@
|
||||
export { default } from './Flex';
|
@ -1,20 +0,0 @@
|
||||
import React, { ReactNode } from 'react';
|
||||
import { UseFormMethods, FormProvider, SubmitHandler } from "react-hook-form";
|
||||
|
||||
export default function Form<T>(props: {
|
||||
methods: UseFormMethods<T>,
|
||||
onSubmit: SubmitHandler<T>,
|
||||
children: ReactNode,
|
||||
}) {
|
||||
const { methods, onSubmit, ...rest } = props;
|
||||
const { handleSubmit } = methods;
|
||||
|
||||
return (
|
||||
<FormProvider {...methods}>
|
||||
<form
|
||||
onSubmit={handleSubmit(onSubmit)}
|
||||
{...rest}
|
||||
/>
|
||||
</FormProvider>
|
||||
);
|
||||
}
|
@ -1 +0,0 @@
|
||||
export { default } from "./Form";
|
@ -1,39 +0,0 @@
|
||||
import React from 'react';
|
||||
import bytes from 'bytes-iec';
|
||||
|
||||
type Props = {
|
||||
value: number;
|
||||
unit: FormatOptions['unit'];
|
||||
mode: FormatOptions['mode'];
|
||||
unitSeparator: string;
|
||||
precision?: number;
|
||||
removeUnit?: boolean;
|
||||
fixedDecimals?: boolean;
|
||||
};
|
||||
|
||||
export default function FormatBytes(props: Props) {
|
||||
const { value, mode, precision, unit, unitSeparator, removeUnit, fixedDecimals } = props;
|
||||
const humanValue = bytes(value, {
|
||||
unit,
|
||||
mode,
|
||||
decimalPlaces: precision,
|
||||
unitSeparator,
|
||||
fixedDecimals,
|
||||
});
|
||||
|
||||
if (humanValue && removeUnit && unitSeparator) {
|
||||
const [justValue] = humanValue.split(unitSeparator);
|
||||
return <>{justValue}</>;
|
||||
}
|
||||
|
||||
return <>{humanValue}</>;
|
||||
}
|
||||
|
||||
FormatBytes.defaultProps = {
|
||||
unit: undefined,
|
||||
mode: 'binary',
|
||||
precision: 1,
|
||||
unitSeparator: ' ',
|
||||
removeUnit: false,
|
||||
fixedDecimals: false,
|
||||
};
|