Fixed conflicts
This commit is contained in:
commit
8473c648b0
89 changed files with 35960 additions and 25967 deletions
54
.eslintrc.json
Normal file
54
.eslintrc.json
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
{
|
||||
"root": true,
|
||||
"ignorePatterns": [
|
||||
"projects/**/*"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"*.ts"
|
||||
],
|
||||
"parserOptions": {
|
||||
"project": [
|
||||
"tsconfig.json",
|
||||
"e2e/tsconfig.json"
|
||||
],
|
||||
"createDefaultProgram": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:@angular-eslint/recommended",
|
||||
"plugin:@angular-eslint/template/process-inline-templates"
|
||||
],
|
||||
"rules": {
|
||||
"@angular-eslint/component-selector": [
|
||||
"error",
|
||||
{
|
||||
"prefix": "app",
|
||||
"style": "kebab-case",
|
||||
"type": "element"
|
||||
}
|
||||
],
|
||||
"@angular-eslint/directive-selector": [
|
||||
"error",
|
||||
{
|
||||
"prefix": "app",
|
||||
"style": "camelCase",
|
||||
"type": "attribute"
|
||||
}
|
||||
],
|
||||
"@angular-eslint/no-empty-lifecycle-method": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.html"
|
||||
],
|
||||
"extends": [
|
||||
"plugin:@angular-eslint/template/recommended"
|
||||
],
|
||||
"rules": {
|
||||
"@angular-eslint/template/eqeqeq": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
61
.github/workflows/electron_hash.yml
vendored
61
.github/workflows/electron_hash.yml
vendored
|
|
@ -7,7 +7,7 @@ on:
|
|||
jobs:
|
||||
# Release draft and share app version via package.json
|
||||
pre_build:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-20.04
|
||||
outputs:
|
||||
output1: ${{ steps.release_drafter.outputs.upload_url }}
|
||||
output2: ${{ steps.package-version.outputs.current-version }}
|
||||
|
|
@ -38,17 +38,17 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
- os: ubuntu-20.04
|
||||
artifact_name: checksums
|
||||
asset_name: checksums
|
||||
app_ext: AppImage
|
||||
app_os: linux
|
||||
- os: macos-latest
|
||||
- os: macos-11
|
||||
artifact_name: checksums
|
||||
asset_name: checksums
|
||||
app_ext: dmg
|
||||
app_os: mac
|
||||
- os: windows-latest
|
||||
- os: windows-2022
|
||||
artifact_name: checksums
|
||||
asset_name: checksums
|
||||
app_ext: exe
|
||||
|
|
@ -60,12 +60,13 @@ jobs:
|
|||
uses: actions/checkout@v1
|
||||
|
||||
- name: Install Node.js, NPM and Yarn
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 14
|
||||
node-version: 16
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install APT dependencies
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
if: matrix.os == 'ubuntu-20.04'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install build-essential git -y
|
||||
|
|
@ -74,35 +75,13 @@ jobs:
|
|||
|
||||
- name: Install and Build Desktop App
|
||||
run: |
|
||||
npm install -g @angular/cli
|
||||
npm install
|
||||
npm run desktop:build
|
||||
|
||||
- name: Temporarily fix electron-builder
|
||||
# https://github.com/electron-userland/electron-builder/issues/4176
|
||||
if: matrix.os != 'macos-latest'
|
||||
- name: Build Electron app
|
||||
run: |
|
||||
sed -i 's/\^\[\\w/\^\[.\\w/g' node_modules/builder-util/out/util.js
|
||||
shell: bash
|
||||
|
||||
- name: Temporarily fix electron-builder (MacOS)
|
||||
# https://github.com/electron-userland/electron-builder/issues/4176
|
||||
if: matrix.os == 'macos-latest'
|
||||
run: |
|
||||
sed -i '' 's/\^\[\\w/\^\[.\\w/g' node_modules/builder-util/out/util.js
|
||||
shell: bash
|
||||
|
||||
- name: Build/release Electron app
|
||||
uses: samuelmeuli/action-electron-builder@v1
|
||||
with:
|
||||
# GitHub token, automatically provided to the action
|
||||
# (No need to define this secret in the repo settings)
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# is already built
|
||||
skip_build: true
|
||||
|
||||
release: false
|
||||
args: "-p never" # Do not publish, done in the next step instead
|
||||
npm run desktop:local
|
||||
|
||||
- name: Create Hashes
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
|
|
@ -116,27 +95,27 @@ jobs:
|
|||
shell: bash
|
||||
|
||||
- name: Rename file paths in .yml (Linux)
|
||||
if: matrix.os == 'ubuntu-latest' && startsWith(github.ref, 'refs/tags/')
|
||||
if: matrix.os == 'ubuntu-20.04' && startsWith(github.ref, 'refs/tags/')
|
||||
run: |
|
||||
sed -i '/.AppImage/ s//-Linux.AppImage/g' desktop-app/build/latest-linux.yml | bash
|
||||
shell: bash
|
||||
|
||||
# Special sed command for mac
|
||||
- name: Rename file paths in .yml (Mac)
|
||||
if: matrix.os == 'macos-latest' && startsWith(github.ref, 'refs/tags/')
|
||||
if: matrix.os == 'macos-11' && startsWith(github.ref, 'refs/tags/')
|
||||
run: |
|
||||
sed -i '' '/.dmg/ s//-Mac.dmg/g' desktop-app/build/latest-mac.yml
|
||||
shell: bash
|
||||
|
||||
- name: Rename file paths in .yml (Windows)
|
||||
if: matrix.os == 'windows-latest' && startsWith(github.ref, 'refs/tags/')
|
||||
if: matrix.os == 'windows-2022' && startsWith(github.ref, 'refs/tags/')
|
||||
run: |
|
||||
sed -i '/.exe/ s//-Windows.exe/g' desktop-app/build/latest.yml | bash
|
||||
shell: bash
|
||||
|
||||
# Upload binaries separately for better control which release draft they go into
|
||||
- name: Upload Binaries Linux
|
||||
if: matrix.os == 'ubuntu-latest' && startsWith(github.ref, 'refs/tags/')
|
||||
if: matrix.os == 'ubuntu-20.04' && startsWith(github.ref, 'refs/tags/')
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
|
@ -147,7 +126,7 @@ jobs:
|
|||
asset_content_type: application/octet-stream
|
||||
|
||||
- name: Upload Binaries Mac
|
||||
if: matrix.os == 'macos-latest' && startsWith(github.ref, 'refs/tags/')
|
||||
if: matrix.os == 'macos-11' && startsWith(github.ref, 'refs/tags/')
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
|
@ -158,7 +137,7 @@ jobs:
|
|||
asset_content_type: application/octet-stream
|
||||
|
||||
- name: Upload Binaries Windows
|
||||
if: matrix.os == 'windows-latest' && startsWith(github.ref, 'refs/tags/')
|
||||
if: matrix.os == 'windows-2022' && startsWith(github.ref, 'refs/tags/')
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
|
@ -180,7 +159,7 @@ jobs:
|
|||
asset_content_type: application/octet-stream
|
||||
|
||||
- name: Upload yml Linux
|
||||
if: matrix.os == 'ubuntu-latest' && startsWith(github.ref, 'refs/tags/')
|
||||
if: matrix.os == 'ubuntu-20.04' && startsWith(github.ref, 'refs/tags/')
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
|
@ -191,7 +170,7 @@ jobs:
|
|||
asset_content_type: application/octet-stream
|
||||
|
||||
- name: Upload yml Mac
|
||||
if: matrix.os == 'macos-latest' && startsWith(github.ref, 'refs/tags/')
|
||||
if: matrix.os == 'macos-11' && startsWith(github.ref, 'refs/tags/')
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
|
@ -202,7 +181,7 @@ jobs:
|
|||
asset_content_type: application/octet-stream
|
||||
|
||||
- name: Upload yml Windows
|
||||
if: matrix.os == 'windows-latest' && startsWith(github.ref, 'refs/tags/')
|
||||
if: matrix.os == 'windows-2022' && startsWith(github.ref, 'refs/tags/')
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
|
|
|||
2
.github/workflows/ghpages.yml
vendored
2
.github/workflows/ghpages.yml
vendored
|
|
@ -16,7 +16,7 @@ jobs:
|
|||
- name: Setup NodeJS
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 14
|
||||
node-version: 16
|
||||
|
||||
- name: Install APT dependencies
|
||||
run: |
|
||||
|
|
|
|||
4
.github/workflows/linting.yml
vendored
4
.github/workflows/linting.yml
vendored
|
|
@ -12,9 +12,9 @@ jobs:
|
|||
uses: actions/checkout@v1
|
||||
|
||||
- name: Install Node.js, NPM and Yarn
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 14
|
||||
node-version: '16'
|
||||
|
||||
- name: Install APT dependencies
|
||||
run: |
|
||||
|
|
|
|||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -28,6 +28,7 @@
|
|||
!.vscode/extensions.json
|
||||
|
||||
# misc
|
||||
/.angular/cache
|
||||
/.sass-cache
|
||||
/connect.lock
|
||||
/coverage
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
- Communication with the network is done via nano RPC and Websocket protocols, private or public on any nano network.
|
||||
|
||||
## Development Prerequisites
|
||||
- [NodeJS](https://nodejs.org) v14.x + NPM v6.x
|
||||
- [NodeJS](https://nodejs.org) v16.x + NPM v8.x
|
||||
- Angular CLI: `npm install -g @angular/cli`
|
||||
|
||||
## Development Guide
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# build the angular app
|
||||
FROM node:14 AS build
|
||||
FROM node:16 AS build
|
||||
WORKDIR /usr/src/app
|
||||
RUN apt-get update && apt-get install -y \
|
||||
libudev-dev \
|
||||
|
|
|
|||
81
angular.json
81
angular.json
|
|
@ -11,7 +11,6 @@
|
|||
"build": {
|
||||
"builder": "@angular-devkit/build-angular:browser",
|
||||
"options": {
|
||||
"aot": true,
|
||||
"outputPath": "dist",
|
||||
"index": "src/index.html",
|
||||
"main": "src/main.ts",
|
||||
|
|
@ -28,27 +27,33 @@
|
|||
],
|
||||
"scripts": [],
|
||||
"allowedCommonJsDependencies": [
|
||||
"qrcode",
|
||||
"bip39",
|
||||
"@zxing/library",
|
||||
"bignumber.js",
|
||||
"nanocurrency",
|
||||
"hw-app-nano",
|
||||
"crypto-js",
|
||||
"blakejs",
|
||||
"nanocurrency-web",
|
||||
"bignumber.js",
|
||||
"u2f-api",
|
||||
"create-hash",
|
||||
"randombytes",
|
||||
"pbkdf2",
|
||||
"zxcvbn",
|
||||
"url",
|
||||
"punycode",
|
||||
"querystring",
|
||||
"hw-transport-webusb",
|
||||
"hw-transport-web-ble"
|
||||
]
|
||||
"qrcode",
|
||||
"bip39",
|
||||
"@zxing/library",
|
||||
"bignumber.js",
|
||||
"nanocurrency",
|
||||
"hw-app-nano",
|
||||
"crypto-js",
|
||||
"blakejs",
|
||||
"nanocurrency-web",
|
||||
"bignumber.js",
|
||||
"u2f-api",
|
||||
"create-hash",
|
||||
"randombytes",
|
||||
"pbkdf2",
|
||||
"zxcvbn",
|
||||
"url",
|
||||
"punycode",
|
||||
"querystring",
|
||||
"hw-transport-webusb",
|
||||
"hw-transport-web-ble"
|
||||
],
|
||||
"vendorChunk": true,
|
||||
"extractLicenses": false,
|
||||
"buildOptimizer": false,
|
||||
"sourceMap": true,
|
||||
"optimization": false,
|
||||
"namedChunks": true
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
|
|
@ -61,9 +66,7 @@
|
|||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"extractCss": true,
|
||||
"namedChunks": false,
|
||||
"aot": true,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"buildOptimizer": true,
|
||||
|
|
@ -86,9 +89,7 @@
|
|||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"extractCss": true,
|
||||
"namedChunks": false,
|
||||
"aot": true,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"buildOptimizer": true,
|
||||
|
|
@ -99,7 +100,8 @@
|
|||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultConfiguration": ""
|
||||
},
|
||||
"serve": {
|
||||
"builder": "@angular-devkit/build-angular:dev-server",
|
||||
|
|
@ -140,14 +142,11 @@
|
|||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"builder": "@angular-eslint/builder:lint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"src/tsconfig.app.json",
|
||||
"src/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
"lintFilePatterns": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.html"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -164,17 +163,6 @@
|
|||
"protractorConfig": "./protractor.conf.js",
|
||||
"devServerTarget": "nault:serve"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"e2e/tsconfig.e2e.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -188,5 +176,8 @@
|
|||
"@schematics/angular:directive": {
|
||||
"prefix": "app"
|
||||
}
|
||||
},
|
||||
"cli": {
|
||||
"defaultCollection": "@angular-eslint/schematics"
|
||||
}
|
||||
}
|
||||
|
|
@ -6,15 +6,16 @@
|
|||
"declaration": false,
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"target": "es5",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"target": "es2017",
|
||||
"module": "commonjs",
|
||||
"baseUrl": ".",
|
||||
"typeRoots": [
|
||||
"../node_modules/@types"
|
||||
],
|
||||
"lib": [
|
||||
"es2017",
|
||||
"es2020",
|
||||
"dom"
|
||||
]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "../tsconfig.base.json",
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/e2e",
|
||||
"baseUrl": "./",
|
||||
|
|
|
|||
37059
package-lock.json
generated
37059
package-lock.json
generated
File diff suppressed because it is too large
Load diff
90
package.json
90
package.json
|
|
@ -16,44 +16,43 @@
|
|||
"release": "npm run desktop:build && electron-builder",
|
||||
"wallet:dev": "ng serve --open",
|
||||
"wallet:dev-ssl": "ng serve --ssl --open",
|
||||
"wallet:build": "ng build --prod",
|
||||
"wallet:build": "ng build --configuration production",
|
||||
"wallet:build-desktop": "ng build --configuration=desktop --base-href ",
|
||||
"desktop:compile": "cd desktop-app && tsc && cd ..",
|
||||
"desktop:build": "npm run wallet:build-desktop && npm run desktop:compile",
|
||||
"desktop:build-local": "npm run desktop:build && npm run desktop:local",
|
||||
"desktop:dev": "npm run desktop:compile && electron desktop-app/dist/desktop-app.js",
|
||||
"desktop:local": "electron-builder",
|
||||
"desktop:full": "electron-builder -wml --x64",
|
||||
"desktop:publish": "electron-builder -wml --x64 -p always"
|
||||
"desktop:local": "electron-builder -p never"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular-devkit/core": "10.0.5",
|
||||
"@angular/animations": "^10.0.7",
|
||||
"@angular/common": "^10.0.7",
|
||||
"@angular/compiler": "^10.0.7",
|
||||
"@angular/core": "^10.0.7",
|
||||
"@angular/forms": "^10.0.7",
|
||||
"@angular/localize": "^10.0.7",
|
||||
"@angular/platform-browser": "^10.0.7",
|
||||
"@angular/platform-browser-dynamic": "^10.0.7",
|
||||
"@angular/router": "^10.0.7",
|
||||
"@angular/service-worker": "^10.2.5",
|
||||
"@ledgerhq/hw-transport": "^5.51.1",
|
||||
"@ledgerhq/hw-transport-node-ble": "^6.20.0",
|
||||
"@ledgerhq/hw-transport-node-hid": "^6.20.0",
|
||||
"@angular-devkit/core": "13.1.2",
|
||||
"@angular/animations": "^13.1.1",
|
||||
"@angular/common": "^13.1.1",
|
||||
"@angular/compiler": "^13.1.1",
|
||||
"@angular/core": "^13.1.1",
|
||||
"@angular/forms": "^13.1.1",
|
||||
"@angular/localize": "^13.1.1",
|
||||
"@angular/platform-browser": "^13.1.1",
|
||||
"@angular/platform-browser-dynamic": "^13.1.1",
|
||||
"@angular/router": "^13.1.1",
|
||||
"@angular/service-worker": "^13.1.1",
|
||||
"@ledgerhq/hw-transport": "^6.27.1",
|
||||
"@ledgerhq/hw-transport-node-ble": "^6.27.1",
|
||||
"@ledgerhq/hw-transport-node-hid": "^6.27.1",
|
||||
"@ledgerhq/hw-transport-u2f": "^5.34.0",
|
||||
"@ledgerhq/hw-transport-web-ble": "^5.51.1",
|
||||
"@ledgerhq/hw-transport-webhid": "^5.51.1",
|
||||
"@ledgerhq/hw-transport-webusb": "^5.53.1",
|
||||
"@ledgerhq/logs": "^5.50.0",
|
||||
"@ng-bootstrap/ng-bootstrap": "^7.0.0",
|
||||
"@ngneat/transloco": "^2.22.0",
|
||||
"@ledgerhq/hw-transport-web-ble": "^6.27.1",
|
||||
"@ledgerhq/hw-transport-webhid": "^6.27.1",
|
||||
"@ledgerhq/hw-transport-webusb": "^6.27.1",
|
||||
"@ledgerhq/logs": "^6.10.0",
|
||||
"@ng-bootstrap/ng-bootstrap": "^11.0.0",
|
||||
"@ngneat/transloco": "^3.1.1",
|
||||
"@types/crypto-js": "^3.1.38",
|
||||
"@types/w3c-web-hid": "^1.0.2",
|
||||
"@types/w3c-web-usb": "^1.0.5",
|
||||
"@zxing/ngx-scanner": "^3.0.0",
|
||||
"angular-password-strength-meter": "^3.0.0",
|
||||
"@zxing/browser": "^0.0.10",
|
||||
"@zxing/library": "^0.18.6",
|
||||
"@zxing/ngx-scanner": "^3.4.0",
|
||||
"babel-polyfill": "^6.26.0",
|
||||
"babel-runtime": "^6.26.0",
|
||||
"bignumber.js": "^5.0.0",
|
||||
|
|
@ -77,37 +76,44 @@
|
|||
"safe-buffer": "^5.2.1",
|
||||
"tslib": "^2.0.0",
|
||||
"tweetnacl": "^1.0.0",
|
||||
"zone.js": "~0.10.3"
|
||||
"url": "^0.11.0",
|
||||
"usb": "^2.0.3",
|
||||
"zone.js": "~0.11.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "^0.1000.5",
|
||||
"@angular/cli": "^10.0.5",
|
||||
"@angular/compiler-cli": "^10.0.7",
|
||||
"@angular/language-service": "^10.0.7",
|
||||
"@angular-devkit/build-angular": "^13.1.2",
|
||||
"@angular-eslint/builder": "13.2.1",
|
||||
"@angular-eslint/eslint-plugin": "13.2.1",
|
||||
"@angular-eslint/eslint-plugin-template": "13.2.1",
|
||||
"@angular-eslint/schematics": "13.2.1",
|
||||
"@angular-eslint/template-parser": "13.2.1",
|
||||
"@angular/cli": "^13.1.2",
|
||||
"@angular/compiler-cli": "^13.1.1",
|
||||
"@angular/language-service": "^13.1.1",
|
||||
"@types/bip39": "^2.4.0",
|
||||
"@types/jasmine": "~2.5.53",
|
||||
"@types/jasmine": "~3.6.0",
|
||||
"@types/jasminewd2": "~2.0.2",
|
||||
"@types/ledgerhq__hw-transport": "^4.21.3",
|
||||
"@types/node": "^12.20.39",
|
||||
"@types/qrcode": "^0.8.1",
|
||||
"codelyzer": "^6.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "5.17.0",
|
||||
"@typescript-eslint/parser": "5.17.0",
|
||||
"electron": "^9.4.0",
|
||||
"electron-builder": "^22.7.0",
|
||||
"jasmine-core": "~3.5.0",
|
||||
"electron-builder": "^22.14.5",
|
||||
"eslint": "^8.12.0",
|
||||
"jasmine-core": "~3.6.0",
|
||||
"jasmine-spec-reporter": "~5.0.0",
|
||||
"karma": "~5.0.0",
|
||||
"karma": "~6.3.9",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-cli": "~2.0.0",
|
||||
"karma-coverage-istanbul-reporter": "~3.0.2",
|
||||
"karma-jasmine": "~3.3.0",
|
||||
"karma-jasmine": "~4.0.0",
|
||||
"karma-jasmine-html-reporter": "^1.5.0",
|
||||
"protractor": "~7.0.0",
|
||||
"ts-node": "~3.2.0",
|
||||
"tslint": "~6.1.3",
|
||||
"typescript": "~3.9.7",
|
||||
"uikit": "^3.0.0-beta.40",
|
||||
"worker-loader": "^2.0.0",
|
||||
"zxcvbn3": "^0.1.1"
|
||||
"typescript": "~4.5.4",
|
||||
"uikit": "^3.9.4",
|
||||
"worker-loader": "^3.0.8"
|
||||
},
|
||||
"build": {
|
||||
"appId": "cc.nault",
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ const routes: Routes = [
|
|||
@NgModule({
|
||||
imports: [
|
||||
// On the desktop apps, use hashes so it works properly using only index.html
|
||||
RouterModule.forRoot(routes, { useHash: environment.desktop }),
|
||||
RouterModule.forRoot(routes, { useHash: environment.desktop, relativeLinkResolution: 'legacy' }),
|
||||
],
|
||||
declarations: [],
|
||||
exports: [RouterModule]
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
import { TestBed, async } from '@angular/core/testing';
|
||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
||||
import { AppComponent } from './app.component';
|
||||
describe('AppComponent', () => {
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
}).compileComponents();
|
||||
}));
|
||||
it('should create the app', async(() => {
|
||||
it('should create the app', waitForAsync(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.debugElement.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
}));
|
||||
it(`should have as title 'app'`, async(() => {
|
||||
it(`should have as title 'app'`, waitForAsync(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.debugElement.componentInstance;
|
||||
expect(app.title).toEqual('app');
|
||||
}));
|
||||
it('should render title in a h1 tag', async(() => {
|
||||
it('should render title in a h1 tag', waitForAsync(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.debugElement.nativeElement;
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@ import { InstallWidgetComponent } from './components/install-widget/install-widg
|
|||
import { QrModalComponent } from './components/qr-modal/qr-modal.component';
|
||||
import { QrModalService } from './services/qr-modal.service';
|
||||
import { NgbModule, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { PasswordStrengthMeterModule } from 'angular-password-strength-meter';
|
||||
import {MusigService} from './services/musig.service';
|
||||
|
||||
// QR code module
|
||||
|
|
@ -71,6 +70,7 @@ import { MultisigComponent } from './components/multisig/multisig.component';
|
|||
import { KeygeneratorComponent } from './components/keygenerator/keygenerator.component';
|
||||
import { NanoTransactionMobileComponent } from './components/helpers/nano-transaction-mobile/nano-transaction-mobile.component';
|
||||
import { TranslocoRootModule } from './transloco/transloco-root.module';
|
||||
import { NoPaddingZerosPipe } from './pipes/no-padding-zeros.pipe';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
|
|
@ -111,6 +111,7 @@ import { TranslocoRootModule } from './transloco/transloco-root.module';
|
|||
MultisigComponent,
|
||||
KeygeneratorComponent,
|
||||
NanoTransactionMobileComponent,
|
||||
NoPaddingZerosPipe
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
|
|
@ -121,7 +122,6 @@ import { TranslocoRootModule } from './transloco/transloco-root.module';
|
|||
ClipboardModule,
|
||||
ZXingScannerModule,
|
||||
NgbModule,
|
||||
PasswordStrengthMeterModule,
|
||||
ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production && !environment.desktop }),
|
||||
TranslocoRootModule,
|
||||
],
|
||||
|
|
@ -148,6 +148,7 @@ import { TranslocoRootModule } from './transloco/transloco-root.module';
|
|||
QrModalService,
|
||||
DeeplinkService,
|
||||
MusigService,
|
||||
NoPaddingZerosPipe
|
||||
],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -519,7 +519,7 @@
|
|||
</div>
|
||||
|
||||
<!-- Modal for remote receive incoming -->
|
||||
<div id="receive-modal" uk-modal>
|
||||
<div class="modal-position-bottom" id="receive-modal" uk-modal>
|
||||
<div class="uk-modal-dialog uk-modal-body modal-qr">
|
||||
<button class="uk-modal-close-default" type="button" uk-close></button>
|
||||
<div class="uk-modal-header">
|
||||
|
|
@ -547,7 +547,7 @@
|
|||
</div>
|
||||
|
||||
<!-- Modal for creating send and change block for remote signing-->
|
||||
<div id="block-modal" uk-modal>
|
||||
<div class="modal-position-bottom" id="block-modal" uk-modal>
|
||||
<div class="uk-modal-dialog uk-modal-body modal-block">
|
||||
<button class="uk-modal-close-default" type="button" uk-close></button>
|
||||
<div class="uk-modal-header">
|
||||
|
|
@ -678,7 +678,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div id="qr-code-modal" uk-modal>
|
||||
<div class="modal-position-bottom" id="qr-code-modal" uk-modal>
|
||||
<div class="uk-modal-dialog uk-margin-auto-vertical">
|
||||
<button class="uk-modal-close-default" type="button" uk-close></button>
|
||||
<div class="uk-modal-body">
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { AccountDetailsComponent } from './account-details.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('AccountDetailsComponent', () => {
|
|||
let component: AccountDetailsComponent;
|
||||
let fixture: ComponentFixture<AccountDetailsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ AccountDetailsComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { AccountsComponent } from './accounts.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('AccountsComponent', () => {
|
|||
let component: AccountsComponent;
|
||||
let fixture: ComponentFixture<AccountsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ AccountsComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -184,8 +184,8 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="uk-card-footer uk-text-right@s nlt-button-group">
|
||||
<button class="uk-button uk-button-danger" (click)="cancelNewAddress()">{{ 'general.cancel' | transloco }}</button>
|
||||
<button class="uk-button uk-button-primary" (click)="saveNewAddress()">{{ 'general.save' | transloco }}</button>
|
||||
<button class="uk-button uk-button-danger uk-width-1-1@s uk-width-auto@m" (click)="cancelNewAddress()">{{ 'general.cancel' | transloco }}</button>
|
||||
<button class="uk-button uk-button-primary uk-width-1-1@s uk-width-auto@m" (click)="saveNewAddress()">{{ 'general.save' | transloco }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -231,9 +231,9 @@
|
|||
<span *ngIf="!addressBookShowQRExport">{{ 'address-book.you-can-still-import-your-address-book-by-using-the-url' | transloco }}</span>
|
||||
<br><br>
|
||||
<input type="text" class="uk-input" style="max-width: 750px;" value="{{ addressBookQRExportUrl }}"><br>
|
||||
<div class="nlt-button-group uk-margin-small-top">
|
||||
<button ngxClipboard [cbContent]="addressBookQRExportUrl" (cbOnSuccess)="notificationService.sendSuccess('Address book export copied to clipboard!')" class="uk-button uk-button-secondary" style="margin-left: 0;">{{ 'general.copy-to-clipboard' | transloco }}</button>
|
||||
<button (click)="exportAddressBookToFile()" class="uk-button uk-button-primary">{{ 'address-book.export-as-file' | transloco }}</button>
|
||||
<div class="nlt-button-group">
|
||||
<button ngxClipboard [cbContent]="addressBookQRExportUrl" (cbOnSuccess)="notificationService.sendSuccess('Address book export copied to clipboard!')" class="uk-button uk-button-secondary uk-width-1-1@s uk-width-auto@m uk-margin-small-top" style="margin-left: 0;">{{ 'general.copy-to-clipboard' | transloco }}</button>
|
||||
<button (click)="exportAddressBookToFile()" class="uk-button uk-button-primary uk-width-1-1@s uk-width-auto@m uk-margin-small-top">{{ 'address-book.export-as-file' | transloco }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { AddressBookComponent } from './address-book.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('AddressBookComponent', () => {
|
|||
let component: AddressBookComponent;
|
||||
let fixture: ComponentFixture<AddressBookComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ AddressBookComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -423,24 +423,20 @@ export class AddressBookComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
// Check for iOS, which is weird with saving files
|
||||
const iOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
|
||||
|
||||
if (window.navigator.msSaveOrOpenBlob) {
|
||||
window.navigator.msSaveBlob(blob, fileName);
|
||||
const elem = window.document.createElement('a');
|
||||
const objUrl = window.URL.createObjectURL(blob);
|
||||
if (iOS) {
|
||||
elem.href = `data:attachment/file,${JSON.stringify(exportData)}`;
|
||||
} else {
|
||||
const elem = window.document.createElement('a');
|
||||
const objUrl = window.URL.createObjectURL(blob);
|
||||
if (iOS) {
|
||||
elem.href = `data:attachment/file,${JSON.stringify(exportData)}`;
|
||||
} else {
|
||||
elem.href = objUrl;
|
||||
}
|
||||
elem.download = fileName;
|
||||
document.body.appendChild(elem);
|
||||
elem.click();
|
||||
setTimeout(function() {
|
||||
document.body.removeChild(elem);
|
||||
window.URL.revokeObjectURL(objUrl);
|
||||
}, 200);
|
||||
elem.href = objUrl;
|
||||
}
|
||||
elem.download = fileName;
|
||||
document.body.appendChild(elem);
|
||||
elem.click();
|
||||
setTimeout(function() {
|
||||
document.body.removeChild(elem);
|
||||
window.URL.revokeObjectURL(objUrl);
|
||||
}, 200);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { ChangeRepWidgetComponent } from './change-rep-widget.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('ChangeRepWidgetComponent', () => {
|
|||
let component: ChangeRepWidgetComponent;
|
||||
let fixture: ComponentFixture<ChangeRepWidgetComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ChangeRepWidgetComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { ConfigureAppComponent } from './configure-app.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('ConfigureAppComponent', () => {
|
|||
let component: ConfigureAppComponent;
|
||||
let fixture: ComponentFixture<ConfigureAppComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ConfigureAppComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -348,7 +348,13 @@ export class ConfigureAppComponent implements OnInit {
|
|||
if (resaveWallet && newStorage === this.storageOptions[1].value) {
|
||||
const UIkit = window['UIkit'];
|
||||
try {
|
||||
await UIkit.modal.confirm('<p class="uk-alert uk-alert-danger"><br><span class="uk-flex"><span uk-icon="icon: warning; ratio: 3;" class="uk-align-center"></span></span><span style="font-size: 18px;">' + this.translocoService.translate('configure-app.you-are-about-to-disable-storage-of-all-wallet-data-which') + '</span><br><br><b style="font-size: 18px;">' + this.translocoService.translate('reset-wallet.before-continuing-make-sure-you-have-saved-the-nano-seed') + '</b><br><br><span style="font-size: 18px;"><b>' + this.translocoService.translate('reset-wallet.you-will-not-be-able-to-recover-the-funds-without-a-backup') + '</b></span></p><br>');
|
||||
await UIkit.modal.confirm(
|
||||
`<p class="uk-alert uk-alert-danger"><br><span class="uk-flex"><span uk-icon="icon: warning; ratio: 3;" class="uk-align-center"></span></span>
|
||||
<span style="font-size: 18px;">
|
||||
${ this.translocoService.translate('configure-app.you-are-about-to-disable-storage-of-all-wallet-data-which') }
|
||||
</span><br>
|
||||
${ this.walletService.isConfigured() ? '<br><b style="font-size: 18px;">' + this.translocoService.translate('reset-wallet.before-continuing-make-sure-you-have-saved-the-nano-seed') + '</b><br><br><span style="font-size: 18px;"><b>' + this.translocoService.translate('reset-wallet.you-will-not-be-able-to-recover-the-funds-without-a-backup') + '</b></span></p><br>' : '' }`
|
||||
);
|
||||
} catch (err) {
|
||||
// pressing cancel, reset storage setting and interrupt
|
||||
this.selectedStorage = this.storageOptions[0].value;
|
||||
|
|
|
|||
|
|
@ -508,7 +508,7 @@
|
|||
<div uk-grid>
|
||||
<div class="uk-width-1-2@m">
|
||||
<input type="password" class="uk-input" [(ngModel)]="walletPasswordModel" placeholder="New Wallet Password">
|
||||
<password-strength-meter *ngIf="walletPasswordModel.length > 0" [password]="walletPasswordModel" [enableFeedback]="true" [minPasswordLength]="6"></password-strength-meter>
|
||||
<!-- <password-strength-meter *ngIf="walletPasswordModel.length > 0" [password]="walletPasswordModel" [enableFeedback]="true" [minPasswordLength]="6"></password-strength-meter> -->
|
||||
<span class="password-helper" *ngIf="walletPasswordModel.length > 0 && walletPasswordModel.length < 6">{{ 'configure-wallet.set-wallet-password.errors.password-must-be-at-least-x-characters-long' | transloco: { minCharacters: 6 } }}</span>
|
||||
<span class="password-helper" *ngIf="walletPasswordConfirmModel.length >= 6 && walletPasswordModel !== walletPasswordConfirmModel">{{ 'configure-wallet.set-wallet-password.errors.passwords-do-not-match' | transloco }}</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { ConfigureWalletComponent } from './configure-wallet.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('ConfigureWalletComponent', () => {
|
|||
let component: ConfigureWalletComponent;
|
||||
let fixture: ComponentFixture<ConfigureWalletComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ConfigureWalletComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { ConverterComponent } from './converter.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('ConverterComponent', () => {
|
|||
let component: ConverterComponent;
|
||||
let fixture: ComponentFixture<ConverterComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ConverterComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { NanoAccountIdComponent } from './nano-account-id.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('NanoAccountIdComponent', () => {
|
|||
let component: NanoAccountIdComponent;
|
||||
let fixture: ComponentFixture<NanoAccountIdComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ NanoAccountIdComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { NanoIdenticonComponent } from './nano-identicon.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('NanoIdenticonComponent', () => {
|
|||
let component: NanoIdenticonComponent;
|
||||
let fixture: ComponentFixture<NanoIdenticonComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ NanoIdenticonComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { NanoTransactionMobileComponent } from './nano-transaction-mobile.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('NanoTransactionMobileComponent', () => {
|
|||
let component: NanoTransactionMobileComponent;
|
||||
let fixture: ComponentFixture<NanoTransactionMobileComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ NanoTransactionMobileComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -65,8 +65,8 @@
|
|||
<div class="uk-card-footer">
|
||||
<div uk-grid>
|
||||
<div class="nlt-button-group uk-width-1-1 uk-text-right">
|
||||
<button routerLink="/address-book" class="uk-button uk-button-danger">Cancel</button>
|
||||
<button (click)="confirmImport()" class="uk-button uk-button-primary">Import Entries</button>
|
||||
<button routerLink="/address-book" class="uk-button uk-button-danger uk-width-1-1@s uk-width-auto@m">Cancel</button>
|
||||
<button (click)="confirmImport()" class="uk-button uk-button-primary uk-width-1-1@s uk-width-auto@m">Import Entries</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { ImportAddressBookComponent } from './import-address-book.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('ImportAddressBookComponent', () => {
|
|||
let component: ImportAddressBookComponent;
|
||||
let fixture: ComponentFixture<ImportAddressBookComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ImportAddressBookComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { ImportWalletComponent } from './import-wallet.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('ImportWalletComponent', () => {
|
|||
let component: ImportWalletComponent;
|
||||
let fixture: ComponentFixture<ImportWalletComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ImportWalletComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { InstallWidgetComponent } from './install-widget.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('InstallWidgetComponent', () => {
|
|||
let component: InstallWidgetComponent;
|
||||
let fixture: ComponentFixture<InstallWidgetComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ InstallWidgetComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { KeygeneratorComponent } from './keygenerator.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('KeygeneratorComponent', () => {
|
|||
let component: KeygeneratorComponent;
|
||||
let fixture: ComponentFixture<KeygeneratorComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ KeygeneratorComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {NotificationService} from '../../services/notification.service';
|
|||
@Component({
|
||||
selector: 'app-keygenerator',
|
||||
templateUrl: './keygenerator.component.html',
|
||||
styleUrls: ['./keygenerator.component.less']
|
||||
styleUrls: ['./keygenerator.component.css']
|
||||
})
|
||||
export class KeygeneratorComponent implements OnInit {
|
||||
seed = '';
|
||||
|
|
|
|||
|
|
@ -116,8 +116,8 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="uk-card-footer uk-text-right@s nlt-button-group">
|
||||
<button class="uk-button uk-button-danger" (click)="cancelNewRep()">Cancel</button>
|
||||
<button class="uk-button uk-button-primary" (click)="saveNewRepresentative()">Save</button>
|
||||
<button class="uk-button uk-button-danger uk-width-1-1@s uk-width-auto@m" (click)="cancelNewRep()">Cancel</button>
|
||||
<button class="uk-button uk-button-primary uk-width-1-1@s uk-width-auto@m" (click)="saveNewRepresentative()">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { ManageRepresentativesComponent } from './manage-representatives.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('ManageRepresentativesComponent', () => {
|
|||
let component: ManageRepresentativesComponent;
|
||||
let fixture: ComponentFixture<ManageRepresentativesComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ManageRepresentativesComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
<div uk-grid>
|
||||
<div class="uk-width-1-2@s">
|
||||
<input class="uk-input" [(ngModel)]="newPassword" placeholder="New Password" type="password">
|
||||
<password-strength-meter *ngIf="newPassword.length > 0" [password]="newPassword" [enableFeedback]="true" [minPasswordLength]="6"></password-strength-meter>
|
||||
<!-- <password-strength-meter *ngIf="newPassword.length > 0" [password]="newPassword" [enableFeedback]="true" [minPasswordLength]="6"></password-strength-meter> -->
|
||||
<span class="password-helper" *ngIf="newPassword.length > 0 && newPassword.length < 6">Password must be at least 6 characters long</span>
|
||||
<span class="password-helper" *ngIf="confirmPassword.length >= 6 && newPassword !== confirmPassword">Passwords do not match!</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { ManageWalletComponent } from './manage-wallet.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('ManageWalletComponent', () => {
|
|||
let component: ManageWalletComponent;
|
||||
let fixture: ComponentFixture<ManageWalletComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ManageWalletComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -155,31 +155,27 @@ export class ManageWalletComponent implements OnInit {
|
|||
// Check for iOS, which is weird with saving files
|
||||
const iOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
|
||||
|
||||
if (window.navigator.msSaveOrOpenBlob) {
|
||||
window.navigator.msSaveBlob(blob, fileName);
|
||||
} else {
|
||||
const elem = window.document.createElement('a');
|
||||
const objUrl = window.URL.createObjectURL(blob);
|
||||
if (iOS) {
|
||||
switch (type) {
|
||||
case 'json':
|
||||
elem.href = `data:attachment/file,${JSON.stringify(exportData)}`;
|
||||
break;
|
||||
case 'csv':
|
||||
elem.href = `data:attachment/file,${csvFile}`;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
elem.href = objUrl;
|
||||
const elem = window.document.createElement('a');
|
||||
const objUrl = window.URL.createObjectURL(blob);
|
||||
if (iOS) {
|
||||
switch (type) {
|
||||
case 'json':
|
||||
elem.href = `data:attachment/file,${JSON.stringify(exportData)}`;
|
||||
break;
|
||||
case 'csv':
|
||||
elem.href = `data:attachment/file,${csvFile}`;
|
||||
break;
|
||||
}
|
||||
elem.download = fileName;
|
||||
document.body.appendChild(elem);
|
||||
elem.click();
|
||||
setTimeout(function() {
|
||||
document.body.removeChild(elem);
|
||||
window.URL.revokeObjectURL(objUrl);
|
||||
}, 200);
|
||||
} else {
|
||||
elem.href = objUrl;
|
||||
}
|
||||
elem.download = fileName;
|
||||
document.body.appendChild(elem);
|
||||
elem.click();
|
||||
setTimeout(function() {
|
||||
document.body.removeChild(elem);
|
||||
window.URL.revokeObjectURL(objUrl);
|
||||
}, 200);
|
||||
}
|
||||
|
||||
async exportToFile() {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { MultisigComponent } from './multisig.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('MultisigComponent', () => {
|
|||
let component: MultisigComponent;
|
||||
let fixture: ComponentFixture<MultisigComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ MultisigComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import { MusigService } from '../../services/musig.service';
|
|||
@Component({
|
||||
selector: 'app-multisig',
|
||||
templateUrl: './multisig.component.html',
|
||||
styleUrls: ['./multisig.component.less']
|
||||
styleUrls: ['./multisig.component.css']
|
||||
})
|
||||
export class MultisigComponent implements OnInit {
|
||||
accountAdd = '';
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { NotificationsComponent } from './notifications.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('NotificationsComponent', () => {
|
|||
let component: NotificationsComponent;
|
||||
let fixture: ComponentFixture<NotificationsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ NotificationsComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { QrGeneratorComponent } from './qr-generator.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('QrGeneratorComponent', () => {
|
|||
let component: QrGeneratorComponent;
|
||||
let fixture: ComponentFixture<QrGeneratorComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ QrGeneratorComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { QrModalComponent } from './qr-modal.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('QrModalComponent', () => {
|
|||
let component: QrModalComponent;
|
||||
let fixture: ComponentFixture<QrModalComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ QrModalComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { QrScanComponent } from './qr-scan.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('AddressBookComponent', () => {
|
|||
let component: QrScanComponent;
|
||||
let fixture: ComponentFixture<QrScanComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ QrScanComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,3 +1,18 @@
|
|||
.merchant-mode-text-full {
|
||||
display: none;
|
||||
}
|
||||
.merchant-mode-text-short {
|
||||
display: inline-block;
|
||||
}
|
||||
@media (min-width: 460px) {
|
||||
.merchant-mode-text-full {
|
||||
display: inline-block;
|
||||
}
|
||||
.merchant-mode-text-short {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.label-block {
|
||||
margin-left: 10px;
|
||||
margin-bottom: 10px;
|
||||
|
|
@ -63,9 +78,6 @@
|
|||
max-width: 280px;
|
||||
margin: 25px auto 0 auto;
|
||||
}
|
||||
.copy-address-button {
|
||||
margin-top: 25px;
|
||||
}
|
||||
@media (max-width: 959px) {
|
||||
.qr-code {
|
||||
max-width: 250px;
|
||||
|
|
@ -162,3 +174,116 @@
|
|||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.merchant-mode-overlay {
|
||||
background-color: #FFF;
|
||||
z-index: 1050; /* above notifications */
|
||||
padding: 15px !important;
|
||||
}
|
||||
|
||||
.merchant-mode-contents {
|
||||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
padding: 20px;
|
||||
}
|
||||
@media (max-width: 699px) {
|
||||
.merchant-mode-contents {
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.merchant-mode-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-left: 25px;
|
||||
}
|
||||
@media (max-width: 699px) {
|
||||
.merchant-mode-header {
|
||||
flex-direction: column;
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
.merchant-mode-header {
|
||||
position: fixed;
|
||||
width: calc(100% - 86px);
|
||||
}
|
||||
}
|
||||
|
||||
.merchant-mode-exit .label {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.merchant-mode-logo {
|
||||
width: 200px;
|
||||
height: 85px;
|
||||
background: url('../../../assets/img/nault-logo.svg');
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.merchant-mode-exit {
|
||||
cursor: pointer;
|
||||
padding: 6px 23px 8px 20px;
|
||||
border: 2px solid transparent;
|
||||
border-radius: 50px;
|
||||
transition: border-color 100ms ease-in-out;
|
||||
}
|
||||
.merchant-mode-exit:hover {
|
||||
border-color: #676686AA;
|
||||
}
|
||||
|
||||
.merchant-centered-container {
|
||||
padding-bottom: 170px;
|
||||
max-width: 500px;
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
.merchant-centered-container {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.merchant-mode-icon-qr-code {
|
||||
width: 19px;
|
||||
height: 19px;
|
||||
margin-right: 10px;
|
||||
background-color: currentcolor;
|
||||
-webkit-mask-image: url('assets/img/qr-code.svg');
|
||||
mask-image: url('assets/img/qr-code.svg');
|
||||
}
|
||||
|
||||
.merchant-mode-qr-code {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
width: 290px;
|
||||
height: 290px;
|
||||
border-radius: 20px;
|
||||
border: 2px solid #19191B;
|
||||
background-color: #FFF;
|
||||
}
|
||||
|
||||
.merchant-mode-amount-integer,
|
||||
.merchant-mode-amount-fractional,
|
||||
.merchant-mode-currency-name {
|
||||
font-family: 'Montserrat', Arial, Helvetica, sans-serif;
|
||||
font-size: 34px;
|
||||
}
|
||||
|
||||
.merchant-mode-amount-integer {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.merchant-mode-amount-fractional {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.merchant-mode-currency-name {
|
||||
font-weight: 400;
|
||||
}
|
||||
.merchant-mode-currency-margin {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,24 @@
|
|||
<div class="uk-animation-slide-left-small" uk-grid>
|
||||
<div class="uk-width-1-1">
|
||||
|
||||
<h2 class="uk-heading-divider">Receive Nano</h2>
|
||||
<ng-template #switchToMerchantModeButton>
|
||||
<button
|
||||
class="uk-width-1-1 uk-width-auto@s uk-button uk-button-primary uk-text-center nlt-icon-button nlt-button-green"
|
||||
type="button"
|
||||
(click)="merchantModeEnable()"
|
||||
>
|
||||
<span class="nlt-icon" uk-icon="icon: cart;"></span>
|
||||
<span class="merchant-mode-text-full">Switch to Merchant Mode</span>
|
||||
<span class="merchant-mode-text-short">Merchant Mode</span>
|
||||
</button>
|
||||
</ng-template>
|
||||
|
||||
<div class="uk-margin-bottom uk-flex uk-flex-between">
|
||||
<h2 class="uk-flex-1 uk-heading-divider uk-margin-remove">Receive Nano</h2>
|
||||
<div class="uk-flex-none uk-visible@s uk-flex uk-flex-top uk-margin-medium-left">
|
||||
<ng-container *ngTemplateOutlet="switchToMerchantModeButton"></ng-container>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="uk-card uk-card-default uk-margin">
|
||||
<div class="uk-card-body">
|
||||
|
|
@ -53,14 +70,15 @@
|
|||
<div style="padding-top: 100%"></div>
|
||||
</div>
|
||||
</ng-template>
|
||||
<div *ngIf="(pendingAccountModel !== '0')">
|
||||
<div class="uk-flex uk-flex-center uk-flex-middle uk-text-center qr-address">
|
||||
<div>
|
||||
<div class="uk-flex uk-flex-center uk-flex-middle uk-text-center qr-address" *ngIf="(pendingAccountModel !== '0')">
|
||||
<app-nano-account-id [accountID]="pendingAccountModel" middle="break" class="nano-address-monospace uk-width-auto" style="max-width: 90%;"></app-nano-account-id>
|
||||
<a class="span-icon hide-on-small-viewports" ngxClipboard [cbContent]="pendingAccountModel" (cbOnSuccess)="copied()" uk-icon="icon: copy" title="Copy Account Address" uk-tooltip></a>
|
||||
</div>
|
||||
<div class="only-on-small-viewports uk-text-center">
|
||||
<div class="uk-margin-medium-top only-on-small-viewports nlt-button-group uk-flex uk-flex-column uk-flex-middle">
|
||||
<button
|
||||
class="copy-address-button uk-width-1-1 uk-width-4-5@s uk-button uk-button-primary uk-text-center"
|
||||
*ngIf="(pendingAccountModel !== '0')"
|
||||
class="uk-width-1-1 uk-width-4-5@s uk-button uk-button-primary uk-text-center nlt-icon-button"
|
||||
[class.nlt-button-success]="recentlyCopiedAccountAddress"
|
||||
[class.uk-disabled]="recentlyCopiedAccountAddress"
|
||||
type="button"
|
||||
|
|
@ -68,8 +86,12 @@
|
|||
[cbContent]="pendingAccountModel"
|
||||
(cbOnSuccess)="copiedAccountAddress()"
|
||||
>
|
||||
<span class="nlt-icon" uk-icon="icon: copy;"></span>
|
||||
{{ recentlyCopiedAccountAddress ? 'Copied!' : 'Copy address' }}
|
||||
</button>
|
||||
<div class="uk-hidden@s uk-width-1-1 uk-flex">
|
||||
<ng-container *ngTemplateOutlet="switchToMerchantModeButton"></ng-container>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -281,3 +303,264 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="merchant-mode-overlay" id="merchant-mode-modal" uk-modal>
|
||||
<div class="merchant-mode-contents uk-flex uk-flex-column uk-flex-middle">
|
||||
<div
|
||||
class="uk-width-1-1 merchant-mode-header"
|
||||
[class.uk-margin-medium-bottom]="inMerchantModeQR === false"
|
||||
[class.uk-margin-bottom]="inMerchantModeQR === true"
|
||||
>
|
||||
<div class="merchant-mode-logo"></div>
|
||||
<div
|
||||
class="merchant-mode-exit uk-flex uk-flex-middle"
|
||||
[class.uk-visible@s]="(inMerchantModeQR === true)"
|
||||
(click)="inMerchantModeQR ? merchantModeHideQR() : merchantModeDisable()"
|
||||
>
|
||||
<span uk-icon="icon: close; ratio: 1.4;" class="uk-margin-small-right" style="margin-top: 2px;"></span>
|
||||
<span class="label">{{ inMerchantModeQR ? 'Cancel Payment' : 'Exit Merchant Mode' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="merchant-centered-container uk-flex-1 uk-width-1-1 uk-flex uk-flex-column uk-flex-center uk-flex-middle uk-text-center">
|
||||
<ng-container *ngIf="(inMerchantModePaymentComplete === false) && (inMerchantModeQR === false) && (pendingAccountModel === '0')">
|
||||
<div class="uk-width-1-1 uk-card uk-card-default uk-margin-bottom">
|
||||
<div class="uk-card-body">
|
||||
<p class="uk-text-large">Select the <span class="uk-text-primary">destination account</span></p>
|
||||
<select id="form-horizontal-select" class="uk-select" [(ngModel)]="pendingAccountModel" (change)="onSelectedAccountChange(pendingAccountModel)">
|
||||
<option [value]="0">–</option>
|
||||
<option *ngFor="let account of accounts" [value]="account.id">{{account.addressBookName ? account.addressBookName + ' - ' : '#' + account.index + ' - ' }} {{ account.id | squeeze }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="(inMerchantModePaymentComplete === false) && (inMerchantModeQR === false) && (pendingAccountModel !== '0')">
|
||||
<div class="identicon-name-row uk-text-truncate">
|
||||
<app-nano-identicon scale="6" [accountID]="pendingAccountModel" [settingIdenticonsStyle]="settings.settings.identiconsStyle" class="nano-identicon" *ngIf="(settings.settings.identiconsStyle !== 'none')"></app-nano-identicon>
|
||||
<div class="account-label uk-text-truncate">{{ selectedAccountAddressBookName }}</div>
|
||||
</div>
|
||||
<app-nano-account-id [accountID]="pendingAccountModel" middle="off" class="nano-address-monospace uk-width-auto"></app-nano-account-id>
|
||||
<button
|
||||
class="uk-width-auto uk-button uk-button-secondary uk-text-center nlt-icon-button uk-margin-small-top"
|
||||
type="button"
|
||||
(click)="unsetSelectedAccount()"
|
||||
>
|
||||
<span class="nlt-icon" uk-icon="icon: pencil;"></span>
|
||||
Change account
|
||||
</button>
|
||||
|
||||
<div
|
||||
class="uk-width-1-1 uk-card uk-card-default uk-margin-bottom"
|
||||
style="margin-top: 60px;"
|
||||
>
|
||||
<div class="uk-card-body">
|
||||
<p class="uk-text-large">Enter the <span class="uk-text-primary">requested amount</span></p>
|
||||
<div class="form-amount">
|
||||
<div class="uk-width-1-1 uk-inline">
|
||||
<label class="uk-form-icon uk-link-reset uk-link-muted xno-symbol" for="form-horizontal-amount"></label>
|
||||
<input [(ngModel)]="amountNano" [ngClass]="{ 'uk-form-danger': !validNano }" [attr.disabled]="pendingAccountModel == '0' || null" autocomplete="off" class="uk-input" id="form-horizontal-amount" (input)="nanoAmountChange()" style="padding-left: 52px !important;" type="number" step="any" placeholder="Amount of XNO" maxlength="40">
|
||||
</div>
|
||||
<div style="margin-top: 10px;" *ngIf="settings.settings.displayCurrency">
|
||||
<p class="text-half-muted" style="margin: 0 0 14px 0;">or</p>
|
||||
<div class="uk-width-1-1 uk-inline">
|
||||
<a class="uk-form-icon uk-link-reset uk-link-muted fiat-currency-ticker" uk-tooltip title="Last Price: {{ price.price.lastPrice | fiat: settings.settings.displayCurrency }} / XNO">{{ settings.settings.displayCurrency | currencySymbol }}</a>
|
||||
<input [(ngModel)]="amountFiat" [ngClass]="{ 'uk-form-danger': !validFiat }" [attr.disabled]="pendingAccountModel == '0' || null" autocomplete="off" (input)="fiatAmountChange()" style="padding-left: 52px !important;" class="uk-input" id="form-horizontal-text-fiat" type="number" step="any" placeholder="Amount of {{ settings.settings.displayCurrency }}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="uk-width-1-1 uk-button uk-button-primary uk-text-center nlt-icon-button uk-margin-medium-top"
|
||||
type="button"
|
||||
(click)="merchantModeShowQR()"
|
||||
>
|
||||
<span class="merchant-mode-icon-qr-code"></span>
|
||||
Create QR code
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="(inMerchantModeQR === true)">
|
||||
<p class="uk-text-large uk-margin-remove-bottom">Send</p>
|
||||
<p class="uk-text-large uk-text-primary uk-margin-remove-top" *ngIf="(amountNano === '')">
|
||||
<span class="merchant-mode-currency-name">XNO</span>
|
||||
</p>
|
||||
<p class="uk-text-large uk-text-primary uk-margin-remove-top" *ngIf="(amountNano !== '')">
|
||||
<span
|
||||
class="merchant-mode-amount-integer"
|
||||
>{{ merchantModeRawRequestedQR | rai: 'mnano,true' | amountsplit: 0 }}</span>
|
||||
<span
|
||||
class="merchant-mode-amount-fractional"
|
||||
>{{ merchantModeRawRequestedQR | rai: 'mnano,true' | amountsplit: 1 }}</span>
|
||||
<span class="merchant-mode-currency-name merchant-mode-currency-margin">XNO</span>
|
||||
</p>
|
||||
<p class="text-half-muted" style="margin: -16px 0 10px 0;">to</p>
|
||||
<app-nano-account-id
|
||||
[accountID]="pendingAccountModel" middle="break"
|
||||
class="nano-address-monospace uk-width-auto"
|
||||
style="display: inline-block; max-width: 325px;"
|
||||
></app-nano-account-id>
|
||||
<div
|
||||
class="uk-width-1-1 uk-flex uk-flex-center uk-margin-top"
|
||||
style="margin-bottom: 40px;"
|
||||
>
|
||||
<img class="merchant-mode-qr-code" [src]="qrCodeImage" alt="QR code" *ngIf="qrCodeImage">
|
||||
<div class="merchant-mode-qr-code" *ngIf="!qrCodeImage"><div uk-spinner="ratio: 2;"></div></div>
|
||||
</div>
|
||||
<div
|
||||
class="uk-width-1-1 uk-card uk-card-default uk-margin-bottom"
|
||||
*ngFor="let prompt of merchantModePrompts; let promptIdx = index"
|
||||
>
|
||||
<div class="uk-card-body">
|
||||
<p
|
||||
*ngIf="(amountNano === '')"
|
||||
class="uk-text-large text-half-muted uk-margin-remove-bottom"
|
||||
>
|
||||
Received
|
||||
</p>
|
||||
<p
|
||||
*ngIf="(amountNano !== '') && prompt.moreThanRequested"
|
||||
class="uk-text-large text-half-muted uk-margin-remove-bottom"
|
||||
>
|
||||
Received <span class="uk-text-success">more</span> than requested
|
||||
</p>
|
||||
<p
|
||||
*ngIf="(amountNano !== '') && prompt.lessThanRequested"
|
||||
class="uk-text-large text-half-muted uk-margin-remove-bottom"
|
||||
>
|
||||
Received <span class="uk-text-warning">less</span> than requested
|
||||
</p>
|
||||
<p
|
||||
class="uk-text-large uk-margin-remove-top"
|
||||
[class.uk-text-success]="prompt.moreThanRequested"
|
||||
[class.uk-text-warning]="prompt.lessThanRequested"
|
||||
>
|
||||
<span
|
||||
class="merchant-mode-amount-integer"
|
||||
>{{ prompt.amountRaw | rai: 'mnano,true' | amountsplit: 0 }}</span>
|
||||
<span
|
||||
class="merchant-mode-amount-fractional"
|
||||
>{{ prompt.amountRaw | rai: 'mnano,true' | amountsplit: 1 }}</span>
|
||||
<span class="merchant-mode-currency-name merchant-mode-currency-margin">XNO</span>
|
||||
</p>
|
||||
<div
|
||||
*ngIf="prompt.amountHiddenRaw.gt(0)"
|
||||
class="uk-text-small text-half-muted block-hash-monospace"
|
||||
style="margin: -22px 0 28px 0;"
|
||||
>
|
||||
+{{ prompt.amountHiddenRaw.toString(10) }} raw
|
||||
</div>
|
||||
<button
|
||||
*ngIf="prompt.moreThanRequested"
|
||||
class="uk-width-1-1 uk-button uk-button-primary uk-text-center nlt-icon-button uk-margin-bottom nlt-button-green"
|
||||
type="button"
|
||||
(click)="merchantModeMarkCompleteFromPrompt(prompt)"
|
||||
>
|
||||
<span class="nlt-icon" uk-icon="icon: check;" style="margin-top: -2px;"></span>
|
||||
Mark Payment Complete
|
||||
</button>
|
||||
<button
|
||||
*ngIf="prompt.lessThanRequested"
|
||||
class="uk-width-1-1 uk-button uk-button-primary uk-text-center nlt-icon-button uk-margin-bottom"
|
||||
type="button"
|
||||
(click)="merchantModeSubtractAmountFromPrompt(prompt, promptIdx)"
|
||||
>
|
||||
<span class="nlt-icon" uk-icon="icon: pencil;" style="margin-top: -2px;"></span>
|
||||
Subtract From Amount
|
||||
</button>
|
||||
<button
|
||||
class="uk-width-1-1 uk-button uk-button-secondary uk-text-danger uk-text-center nlt-icon-button"
|
||||
type="button"
|
||||
(click)="merchantModeDiscardPrompt(promptIdx)"
|
||||
>
|
||||
<span class="nlt-icon" uk-icon="icon: close;" style="margin-top: -2px;"></span>
|
||||
Discard As Unrelated
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<ng-container *ngIf="merchantModePrompts.length === 0">
|
||||
<p class="uk-text-large uk-margin-top text-half-muted">Awaiting payment...</p>
|
||||
<button
|
||||
class="uk-width-auto uk-button uk-text-center nlt-icon-button"
|
||||
[class.uk-button-primary]="!loadingIncomingTxList"
|
||||
[class.uk-button-secondary]="loadingIncomingTxList"
|
||||
[class.uk-disabled]="loadingIncomingTxList"
|
||||
type="button"
|
||||
(click)="!loadingIncomingTxList && getPending()"
|
||||
>
|
||||
<span class="nlt-icon" uk-icon="icon: refresh;" style="margin-top: -2px;" *ngIf="!loadingIncomingTxList"></span>
|
||||
<span class="spinner" uk-spinner="ratio: 0.5;" *ngIf="loadingIncomingTxList"></span>
|
||||
{{ loadingIncomingTxList ? 'Checking Payment...' : 'Check Payment' }}
|
||||
</button>
|
||||
</ng-container>
|
||||
<div
|
||||
class="merchant-mode-exit uk-flex uk-flex-middle uk-hidden@s"
|
||||
style="margin-top: 70px;"
|
||||
(click)="merchantModeHideQR()"
|
||||
>
|
||||
<span uk-icon="icon: close; ratio: 1.4;" class="uk-margin-small-right" style="margin-top: 2px;"></span>
|
||||
<span class="label">Cancel Payment</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="(inMerchantModePaymentComplete === true)">
|
||||
<p class="uk-text-large uk-margin-remove-bottom uk-text-success">Received</p>
|
||||
<p class="uk-text-large uk-text-success uk-margin-remove-top">
|
||||
<span
|
||||
class="merchant-mode-amount-integer"
|
||||
>{{ merchantModeRawReceivedTotal | rai: 'mnano,true' | amountsplit: 0 }}</span>
|
||||
<span
|
||||
class="merchant-mode-amount-fractional"
|
||||
>{{ merchantModeRawReceivedTotal | rai: 'mnano,true' | amountsplit: 1 }}</span>
|
||||
<span class="merchant-mode-currency-name merchant-mode-currency-margin">XNO</span>
|
||||
</p>
|
||||
<div
|
||||
*ngIf="merchantModeRawReceivedTotalHiddenRaw.gt(0)"
|
||||
class="uk-text-small text-half-muted block-hash-monospace"
|
||||
style="margin: -22px 0 28px 0;"
|
||||
>
|
||||
+{{ merchantModeRawReceivedTotalHiddenRaw.toString(10) }} raw
|
||||
</div>
|
||||
<img style="width: 50%; margin-top: -40px;" src="data:image/svg+xml,%3Csvg width='200mm' height='200mm' viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='m157.05 40.584c-2.5562-2e-6 -5.1127 0.97964-7.0714 2.9383l-65.687 65.687-34.266-34.266c-3.9174-3.9174-10.225-3.9174-14.142 1e-6l-12.915 12.915c-3.9174 3.9174-3.9174 10.225-1e-6 14.142l39.526 39.526c0.4262 0.72955 0.95143 1.4181 1.5782 2.0448l12.915 12.915c3.9174 3.9174 10.225 3.9174 14.142 0l85.906-85.907c3.9174-3.9174 3.9174-10.224 0-14.142l-12.915-12.915c-1.9587-1.9587-4.5147-2.9383-7.0709-2.9383z' fill='none' stop-color='%23000000' stroke='%2332d296' stroke-linejoin='round' stroke-width='2' style='paint-order:stroke fill markers'/%3E%3C/svg%3E" />
|
||||
<p class="uk-flex uk-flex-center uk-flex-middle text-half-muted uk-margin-remove-bottom">
|
||||
<button
|
||||
class="uk-button uk-button-secondary uk-text-center nlt-icon-button"
|
||||
type="button"
|
||||
ngxClipboard
|
||||
[cbContent]="(
|
||||
'Amount Requested: '
|
||||
+ ( merchantModeRawRequestedTotal | rai: 'mnano,true' | amountsplit: 0 )
|
||||
+ ( merchantModeRawRequestedTotal | rai: 'mnano,true' | amountsplit: 1 )
|
||||
+ ' XNO'
|
||||
+ '\n\n'
|
||||
+ 'Amount Paid: '
|
||||
+ ( merchantModeRawReceivedTotal | rai: 'mnano,true' | amountsplit: 0 )
|
||||
+ ( merchantModeRawReceivedTotal | rai: 'mnano,true' | amountsplit: 1 )
|
||||
+ ' XNO'
|
||||
+ '\n\n'
|
||||
+ 'Transaction ID\'s:'
|
||||
+ '\n- '
|
||||
+ merchantModeTransactionHashes.join('\n- ')
|
||||
)"
|
||||
>
|
||||
<span class="nlt-icon" uk-icon="icon: copy;"></span>
|
||||
Copy Payment Information
|
||||
</button>
|
||||
</p>
|
||||
<ul class="uk-width-1-1">
|
||||
<li
|
||||
*ngFor="let hash of merchantModeTransactionHashes"
|
||||
class="uk-text-left text-half-muted block-hash-monospace"
|
||||
style="word-wrap: anywhere;"
|
||||
>
|
||||
{{ hash }}
|
||||
</li>
|
||||
</ul>
|
||||
<div
|
||||
class="merchant-mode-exit uk-flex uk-flex-middle"
|
||||
style="margin-top: 70px;"
|
||||
(click)="merchantModeResetState()"
|
||||
>
|
||||
<span uk-icon="icon: plus-circle; ratio: 1.4;" class="uk-margin-small-right" style="margin-top: 2px;"></span>
|
||||
<span class="label">New Payment</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { ReceiveComponent } from './receive.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('ReceiveComponent', () => {
|
|||
let component: ReceiveComponent;
|
||||
let fixture: ComponentFixture<ReceiveComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ ReceiveComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ export class ReceiveComponent implements OnInit, OnDestroy {
|
|||
|
||||
timeoutIdClearingRecentlyCopiedState: any = null;
|
||||
mobileTransactionMenuModal: any = null;
|
||||
merchantModeModal: any = null;
|
||||
mobileTransactionData: any = null;
|
||||
|
||||
selectedAccountAddressBookName = '';
|
||||
|
|
@ -48,6 +49,17 @@ export class ReceiveComponent implements OnInit, OnDestroy {
|
|||
validFiat = true;
|
||||
qrSuccessClass = '';
|
||||
|
||||
inMerchantMode = false;
|
||||
inMerchantModeQR = false;
|
||||
inMerchantModePaymentComplete = false;
|
||||
merchantModeRawRequestedQR: BigNumber = null;
|
||||
merchantModeRawRequestedTotal: BigNumber = null;
|
||||
merchantModeRawReceivedTotal: BigNumber = null;
|
||||
merchantModeRawReceivedTotalHiddenRaw: BigNumber = null;
|
||||
merchantModeSeenBlockHashes = {};
|
||||
merchantModePrompts = [];
|
||||
merchantModeTransactionHashes = [];
|
||||
|
||||
routerSub = null;
|
||||
|
||||
constructor(
|
||||
|
|
@ -67,12 +79,17 @@ export class ReceiveComponent implements OnInit, OnDestroy {
|
|||
|
||||
async ngOnInit() {
|
||||
const UIkit = window['UIkit'];
|
||||
|
||||
const mobileTransactionMenuModal = UIkit.modal('#mobile-transaction-menu-modal');
|
||||
this.mobileTransactionMenuModal = mobileTransactionMenuModal;
|
||||
|
||||
const merchantModeModal = UIkit.modal('#merchant-mode-modal');
|
||||
this.merchantModeModal = merchantModeModal;
|
||||
|
||||
this.routerSub = this.route.events.subscribe(event => {
|
||||
if (event instanceof ChildActivationEnd) {
|
||||
this.mobileTransactionMenuModal.hide();
|
||||
this.merchantModeModal.hide();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -110,12 +127,16 @@ export class ReceiveComponent implements OnInit, OnDestroy {
|
|||
this.showQrConfirmation();
|
||||
setTimeout(() => this.resetAmount(), 500);
|
||||
}
|
||||
if ( (this.inMerchantModeQR === true) && (transaction.block.link_as_account === this.qrAccount) ) {
|
||||
this.onMerchantModeReceiveTransaction(transaction);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.mobileTransactionMenuModal.hide();
|
||||
this.merchantModeModal.hide();
|
||||
if (this.routerSub) {
|
||||
this.routerSub.unsubscribe();
|
||||
}
|
||||
|
|
@ -164,6 +185,14 @@ export class ReceiveComponent implements OnInit, OnDestroy {
|
|||
// Blocks for selected account
|
||||
this.pendingBlocksForSelectedAccount =
|
||||
this.pendingBlocks.filter(block => (block.destination === selectedAccountID));
|
||||
|
||||
if (this.inMerchantModeQR === true) {
|
||||
this.pendingBlocksForSelectedAccount.forEach(
|
||||
(pendingBlock) => {
|
||||
this.onMerchantModeReceiveTransaction(pendingBlock);
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
showMobileMenuForTransaction(transaction) {
|
||||
|
|
@ -364,4 +393,140 @@ export class ReceiveComponent implements OnInit, OnDestroy {
|
|||
return new BigNumber(value);
|
||||
}
|
||||
|
||||
unsetSelectedAccount() {
|
||||
this.pendingAccountModel = '0';
|
||||
this.onSelectedAccountChange(this.pendingAccountModel);
|
||||
}
|
||||
|
||||
getRawAmountWithoutTinyRaws(rawAmountWithTinyRaws) {
|
||||
const tinyRaws =
|
||||
rawAmountWithTinyRaws.mod(this.nano);
|
||||
|
||||
return rawAmountWithTinyRaws.minus(tinyRaws);
|
||||
}
|
||||
|
||||
merchantModeResetState() {
|
||||
this.unsetSelectedAccount();
|
||||
this.resetAmount();
|
||||
|
||||
this.inMerchantModeQR = false;
|
||||
this.inMerchantModePaymentComplete = false;
|
||||
}
|
||||
|
||||
merchantModeEnable() {
|
||||
this.merchantModeResetState();
|
||||
|
||||
this.inMerchantMode = true;
|
||||
this.merchantModeModal.show();
|
||||
}
|
||||
|
||||
merchantModeDisable() {
|
||||
this.inMerchantMode = false;
|
||||
this.inMerchantModeQR = false;
|
||||
this.inMerchantModePaymentComplete = false;
|
||||
this.merchantModeModal.hide();
|
||||
}
|
||||
|
||||
merchantModeShowQR() {
|
||||
const isRequestingAnyAmount = (this.validNano === false || Number(this.amountNano) === 0);
|
||||
|
||||
if(isRequestingAnyAmount === true) {
|
||||
this.resetAmount();
|
||||
}
|
||||
|
||||
this.merchantModeRawRequestedTotal =
|
||||
(isRequestingAnyAmount === true)
|
||||
? new BigNumber(0)
|
||||
: this.util.nano.mnanoToRaw(this.amountNano);
|
||||
|
||||
this.merchantModeRawRequestedQR =
|
||||
(isRequestingAnyAmount === true)
|
||||
? new BigNumber(0)
|
||||
: this.util.nano.mnanoToRaw(this.amountNano);
|
||||
|
||||
this.merchantModeSeenBlockHashes =
|
||||
this.pendingBlocksForSelectedAccount.reduce(
|
||||
(seenHashes, receivableBlock) => {
|
||||
seenHashes[receivableBlock.hash] = true
|
||||
return seenHashes
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
this.merchantModeTransactionHashes = [];
|
||||
|
||||
this.inMerchantModeQR = true;
|
||||
}
|
||||
|
||||
merchantModeHideQR() {
|
||||
this.inMerchantModeQR = false;
|
||||
}
|
||||
|
||||
onMerchantModeReceiveTransaction(transaction) {
|
||||
if( this.merchantModeSeenBlockHashes[transaction.hash] != null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.merchantModeSeenBlockHashes[transaction.hash] = true;
|
||||
|
||||
const receivedAmountWithTinyRaws = new BigNumber(transaction.amount);
|
||||
|
||||
const receivedAmount =
|
||||
this.getRawAmountWithoutTinyRaws(receivedAmountWithTinyRaws);
|
||||
|
||||
const requestedAmount =
|
||||
this.getRawAmountWithoutTinyRaws(this.merchantModeRawRequestedQR);
|
||||
|
||||
if( receivedAmount.eq(requestedAmount) ) {
|
||||
this.merchantModeTransactionHashes.push(transaction.hash);
|
||||
|
||||
this.merchantModeMarkCompleteWithAmount(this.merchantModeRawRequestedTotal);
|
||||
} else {
|
||||
const transactionPrompt = {
|
||||
moreThanRequested: receivedAmount.gt(requestedAmount),
|
||||
lessThanRequested: receivedAmount.lt(requestedAmount),
|
||||
amountRaw: receivedAmountWithTinyRaws,
|
||||
amountHiddenRaw: receivedAmountWithTinyRaws.mod(this.nano),
|
||||
transactionHash: transaction.hash,
|
||||
}
|
||||
|
||||
this.merchantModePrompts.push(transactionPrompt);
|
||||
}
|
||||
}
|
||||
|
||||
merchantModeSubtractAmountFromPrompt(prompt, promptIdx) {
|
||||
const subtractedRawWithTinyRaws = prompt.amountRaw;
|
||||
|
||||
const subtractedRaw =
|
||||
this.getRawAmountWithoutTinyRaws(subtractedRawWithTinyRaws);
|
||||
|
||||
const newAmountRaw =
|
||||
this.merchantModeRawRequestedQR.minus(subtractedRaw);
|
||||
|
||||
this.merchantModeRawRequestedQR = newAmountRaw;
|
||||
this.changeQRAmount(newAmountRaw.toFixed());
|
||||
|
||||
this.merchantModeTransactionHashes.push(prompt.transactionHash);
|
||||
|
||||
this.merchantModePrompts.splice(promptIdx, 1);
|
||||
}
|
||||
|
||||
merchantModeMarkCompleteFromPrompt(prompt) {
|
||||
this.merchantModeTransactionHashes.push(prompt.transactionHash);
|
||||
|
||||
this.merchantModeMarkCompleteWithAmount(prompt.amountRaw);
|
||||
}
|
||||
|
||||
merchantModeDiscardPrompt(promptIdx) {
|
||||
this.merchantModePrompts.splice(promptIdx, 1);
|
||||
}
|
||||
|
||||
merchantModeMarkCompleteWithAmount(amountRaw) {
|
||||
this.merchantModeRawReceivedTotal = amountRaw;
|
||||
this.merchantModeRawReceivedTotalHiddenRaw = amountRaw.mod(this.nano);
|
||||
|
||||
this.inMerchantModePaymentComplete = true;
|
||||
this.inMerchantModeQR = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { RemoteSigningComponent } from './remote-signing.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('RemoteSigningComponent', () => {
|
|||
let component: RemoteSigningComponent;
|
||||
let fixture: ComponentFixture<RemoteSigningComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ RemoteSigningComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="uk-card-footer">
|
||||
<button class="uk-button uk-button-primary uk-width-1-1" type="button" (click)="changeRepresentatives()" *ngIf="!changingRepresentatives">Update Representatives</button>
|
||||
<button class="uk-button uk-button-primary uk-width-1-1@s uk-width-auto@m uk-float-right" type="button" (click)="changeRepresentatives()" *ngIf="!changingRepresentatives">Update Representatives</button>
|
||||
<button class="uk-button uk-button-secondary uk-width-1-1 uk-disabled nlt-icon-button" type="button" *ngIf="changingRepresentatives"><span class="spinner" uk-spinner="ratio: 0.5;"></span> Updating Representatives</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { RepresentativesComponent } from './representatives.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('RepresentativesComponent', () => {
|
|||
let component: RepresentativesComponent;
|
||||
let fixture: ComponentFixture<RepresentativesComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ RepresentativesComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { SendComponent } from './send.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('SendComponent', () => {
|
|||
let component: SendComponent;
|
||||
let fixture: ComponentFixture<SendComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ SendComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -334,15 +334,13 @@
|
|||
<a *ngIf="processedHash" [routerLink]="'/account/' + signatureAccount" [queryParams]="{ sign: 1 }" class="uk-button uk-button-primary uk-width-auto" title="Account detail view" uk-tooltip>Account Detail View</a>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!processedHash" uk-grid>
|
||||
<div class="uk-width-1-2@s">
|
||||
<a class="uk-button uk-button-danger uk-width-1-1" (click)="cancel()">Cancel</a>
|
||||
</div>
|
||||
<div class="uk-width-1-2@s">
|
||||
<button *ngIf="!confirmingTransaction && shouldSign && signTypeSelected !== signTypes[3]" class="uk-button uk-button-primary uk-width-1-1" (click)="confirmTransaction()">Confirm & Sign</button>
|
||||
<button *ngIf="!confirmingTransaction && shouldSign && signTypeSelected === signTypes[3]" class="uk-button uk-button-primary uk-width-1-1" (click)="startMultisig()" [disabled]="!this.validPrivkey || !this.validParticipants || finalSignature || (this.activeStep > 1 && !this.isInputAddDisabled)">{{this.activeStep !== 4 ? (this.activeStep === 1 ? 'Start Multi-signing' : 'Step '+ (this.activeStep - 1) + '/3 | Next') : 'Step '+ (this.activeStep - 1) + '/3 | Final Step'}}</button>
|
||||
<div *ngIf="!processedHash">
|
||||
<div class="nlt-button-group uk-width-1-1 uk-text-right">
|
||||
<button class="uk-button uk-button-danger uk-width-1-1@s uk-width-auto@m" (click)="cancel()">Cancel</button>
|
||||
<button *ngIf="!confirmingTransaction && shouldSign && signTypeSelected !== signTypes[3]" class="uk-button uk-button-primary uk-width-1-1@s uk-width-auto@m" (click)="confirmTransaction()">Confirm & Sign</button>
|
||||
<button *ngIf="!confirmingTransaction && shouldSign && signTypeSelected === signTypes[3]" class="uk-button uk-button-primary uk-width-1-1@s uk-width-auto@m" (click)="startMultisig()" [disabled]="!this.validPrivkey || !this.validParticipants || finalSignature || (this.activeStep > 1 && !this.isInputAddDisabled)">{{this.activeStep !== 4 ? (this.activeStep === 1 ? 'Start Multi-signing' : 'Step '+ (this.activeStep - 1) + '/3 | Next') : 'Step '+ (this.activeStep - 1) + '/3 | Final Step'}}</button>
|
||||
<button *ngIf="confirmingTransaction && shouldSign" class="uk-button uk-button-primary uk-disabled uk-width-1-1"><span class="uk-margin-right" uk-spinner></span> Loading</button>
|
||||
<button *ngIf="!confirmingTransaction && !shouldSign" class="uk-button uk-button-primary uk-width-1-1" (click)="confirmBlock()">Confirm & Process</button>
|
||||
<button *ngIf="!confirmingTransaction && !shouldSign" class="uk-button uk-button-primary uk-width-1-1@s uk-width-auto@m" (click)="confirmBlock()">Confirm & Process</button>
|
||||
<button *ngIf="confirmingTransaction && !shouldSign" class="uk-button uk-button-primary uk-disabled uk-width-1-1"><span class="uk-margin-right" uk-spinner></span> Loading</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -362,7 +360,7 @@
|
|||
</div>
|
||||
|
||||
<!-- Modal for result QR -->
|
||||
<div id="signed-modal" uk-modal>
|
||||
<div class="modal-position-bottom" id="signed-modal" uk-modal>
|
||||
<div class="uk-modal-dialog uk-modal-body modal-qr">
|
||||
<button class="uk-modal-close-default" type="button" uk-close></button>
|
||||
<div class="uk-modal-header">
|
||||
|
|
@ -390,7 +388,7 @@
|
|||
</div>
|
||||
|
||||
<!-- Modal for output data QR -->
|
||||
<div id="qr-code-modal" uk-modal>
|
||||
<div class="modal-position-bottom" id="qr-code-modal" uk-modal>
|
||||
<div class="uk-modal-dialog uk-margin-auto-vertical">
|
||||
<button class="uk-modal-close-default" type="button" uk-close></button>
|
||||
<div class="uk-modal-body">
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { SignComponent } from './sign.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('SignComponent', () => {
|
|||
let component: SignComponent;
|
||||
let fixture: ComponentFixture<SignComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ SignComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { SweeperComponent } from './sweeper.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('SweeperComponent', () => {
|
|||
let component: SweeperComponent;
|
||||
let fixture: ComponentFixture<SweeperComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ SweeperComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -191,6 +191,29 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="uk-margin" *ngIf="successorHash">
|
||||
<label class="uk-form-label">Successor:</label>
|
||||
<div class="uk-form-controls uk-text-truncate">
|
||||
<div uk-grid class="uk-flex-nowrap uk-text-truncate">
|
||||
<a
|
||||
class="uk-width-auto uk-text-truncate block-hash-monospace block-hash-clickable"
|
||||
[routerLink]="'/transaction/' + successorHash"
|
||||
style="max-width: calc(100% - 35px);"
|
||||
title="View Block Details"
|
||||
uk-tooltip
|
||||
>{{ successorHash }}</a>
|
||||
<div class="uk-width-auto block-hash-actions">
|
||||
<ul class="uk-iconnav">
|
||||
<li><a ngxClipboard [cbContent]="successorHash" (cbOnSuccess)="copied()" uk-icon="icon: copy" title="Copy Successor Block Hash" uk-tooltip></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="uk-margin" *ngIf="blockHeight != -1">
|
||||
<label class="uk-form-label">Height:</label>
|
||||
<div class="uk-form-controls uk-text-truncate">{{ blockHeight | number:'':'en-US' }}</div>
|
||||
</div>
|
||||
<div class="uk-margin" *ngIf="(transaction?.contents?.link || transaction?.contents?.source) && (blockType == 'open' || blockType == 'receive')">
|
||||
<label class="uk-form-label">Link (Source):</label>
|
||||
<div class="uk-form-controls uk-text-truncate">
|
||||
|
|
@ -220,10 +243,6 @@
|
|||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="uk-margin" *ngIf="blockHeight != -1">
|
||||
<label class="uk-form-label">Height:</label>
|
||||
<div class="uk-form-controls uk-text-truncate">{{ blockHeight | number:'':'en-US' }}</div>
|
||||
</div>
|
||||
<div class="uk-margin" *ngIf="transaction?.contents?.work">
|
||||
<label class="uk-form-label">Work:</label>
|
||||
<div class="uk-form-controls uk-text-truncate">
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { TransactionDetailsComponent } from './transaction-details.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('TransactionDetailsComponent', () => {
|
|||
let component: TransactionDetailsComponent;
|
||||
let fixture: ComponentFixture<TransactionDetailsComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ TransactionDetailsComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ export class TransactionDetailsComponent implements OnInit {
|
|||
showBlockData = false;
|
||||
|
||||
amountRaw = new BigNumber(0);
|
||||
successorHash = '';
|
||||
|
||||
constructor(
|
||||
private walletService: WalletService,
|
||||
|
|
@ -69,6 +70,7 @@ export class TransactionDetailsComponent implements OnInit {
|
|||
let legacyFromAccount = '';
|
||||
this.blockType = '';
|
||||
this.amountRaw = new BigNumber(0);
|
||||
this.successorHash = '';
|
||||
const hash = this.route.snapshot.params.transaction;
|
||||
this.hashID = hash;
|
||||
|
||||
|
|
@ -90,9 +92,11 @@ export class TransactionDetailsComponent implements OnInit {
|
|||
this.isUnconfirmedBlock = (hashData.confirmed === 'false') ? true : false;
|
||||
this.blockHeight = hashData.height;
|
||||
|
||||
const HASH_ONLY_ZEROES = '0000000000000000000000000000000000000000000000000000000000000000';
|
||||
|
||||
const blockType = hashData.contents.type;
|
||||
if (blockType === 'state') {
|
||||
const isOpen = hashData.contents.previous === '0000000000000000000000000000000000000000000000000000000000000000';
|
||||
const isOpen = (hashData.contents.previous === HASH_ONLY_ZEROES);
|
||||
|
||||
if (isOpen) {
|
||||
this.blockType = 'open';
|
||||
|
|
@ -126,6 +130,13 @@ export class TransactionDetailsComponent implements OnInit {
|
|||
this.amountRaw = new BigNumber(hashData.amount).mod(this.nano);
|
||||
}
|
||||
|
||||
if (
|
||||
(hashData.successor != null)
|
||||
&& (hashData.successor !== HASH_ONLY_ZEROES)
|
||||
) {
|
||||
this.successorHash = hashData.successor;
|
||||
}
|
||||
|
||||
this.transaction = hashData;
|
||||
|
||||
let fromAccount = '';
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { WalletWidgetComponent } from './wallet-widget.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('WalletWidgetComponent', () => {
|
|||
let component: WalletWidgetComponent;
|
||||
let fixture: ComponentFixture<WalletWidgetComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ WalletWidgetComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ export class WalletWidgetComponent implements OnInit {
|
|||
this.notificationService.sendSuccess(`Wallet unlocked`);
|
||||
this.modal.hide();
|
||||
if (this.unlockPassword.length < 6) {
|
||||
// tslint:disable-next-line: max-line-length
|
||||
// eslint-disable-next-line max-len
|
||||
this.notificationService.sendWarning(`You are using an insecure password and encouraged to change it from settings > manage wallet`);
|
||||
}
|
||||
|
||||
|
|
|
|||
19
src/app/pipes/no-padding-zeros.pipe.ts
Normal file
19
src/app/pipes/no-padding-zeros.pipe.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
|
||||
@Pipe({
|
||||
name: 'noPaddingZeros'
|
||||
})
|
||||
export class NoPaddingZerosPipe implements PipeTransform {
|
||||
transform(input: string): string {
|
||||
const sig = input.split('.')[0];
|
||||
const frac = input.split('.')[1].replace(/0+$/g, '');
|
||||
|
||||
// 1.000000 XNO >> 1 XNO
|
||||
if (!frac) {
|
||||
return sig;
|
||||
}
|
||||
|
||||
// 0.002200 >> 0.0022 XNO
|
||||
return `${sig}.${frac}`;
|
||||
}
|
||||
}
|
||||
|
|
@ -22,14 +22,21 @@ export class ApiService {
|
|||
this.node.setLoading();
|
||||
}
|
||||
}
|
||||
let header;
|
||||
let options: any = {
|
||||
responseType: 'json',
|
||||
};
|
||||
if (this.appSettings.settings.serverAuth != null && this.appSettings.settings.serverAuth !== '') {
|
||||
header = {
|
||||
headers: new HttpHeaders()
|
||||
.set('Authorization', this.appSettings.settings.serverAuth)
|
||||
};
|
||||
options =
|
||||
Object.assign(
|
||||
{},
|
||||
options,
|
||||
{
|
||||
headers: new HttpHeaders()
|
||||
.set('Authorization', this.appSettings.settings.serverAuth)
|
||||
}
|
||||
);
|
||||
}
|
||||
return await this.http.post(apiUrl, data, header).toPromise()
|
||||
return await this.http.post(apiUrl, data, options).toPromise()
|
||||
.then(res => {
|
||||
this.node.setOnline();
|
||||
return res;
|
||||
|
|
|
|||
|
|
@ -64,17 +64,35 @@ export class NinjaService {
|
|||
|
||||
// false - does not exist, null - any other error
|
||||
async getAccount(account: string): Promise<any> {
|
||||
return await this.http.get(this.ninjaUrl + 'accounts/' + account).toPromise()
|
||||
.then(res => {
|
||||
return res;
|
||||
})
|
||||
.catch(err => {
|
||||
if (err.status === 404) {
|
||||
return false;
|
||||
}
|
||||
const REQUEST_TIMEOUT_MS = 10000;
|
||||
|
||||
return null;
|
||||
const successPromise =
|
||||
this.http.get(this.ninjaUrl + 'accounts/' + account).toPromise()
|
||||
.then(res => {
|
||||
return res;
|
||||
})
|
||||
.catch(err => {
|
||||
if (err.status === 404) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
const timeoutPromise =
|
||||
new Promise(resolve => {
|
||||
setTimeout(
|
||||
() => {
|
||||
resolve(null);
|
||||
},
|
||||
REQUEST_TIMEOUT_MS
|
||||
);
|
||||
});
|
||||
|
||||
return await Promise.race([
|
||||
successPromise,
|
||||
timeoutPromise
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -453,11 +453,11 @@ export class RepresentativeService {
|
|||
}
|
||||
|
||||
// Default representatives list
|
||||
// tslint:disable-next-line:member-ordering
|
||||
// eslint-disable-next-line @typescript-eslint/member-ordering
|
||||
defaultRepresentatives = [];
|
||||
|
||||
// Bad representatives hardcoded to be avoided. Not visible in the user rep list
|
||||
// tslint:disable-next-line:member-ordering
|
||||
// eslint-disable-next-line @typescript-eslint/member-ordering
|
||||
nfReps = [
|
||||
{
|
||||
id: 'nano_3arg3asgtigae3xckabaaewkx3bzsh7nwz7jkmjos79ihyaxwphhm6qgjps4',
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ function hexToUint4(hexValue) {
|
|||
return uint4;
|
||||
}
|
||||
function hexToUint8(hexValue) {
|
||||
// tslint:disable-next-line:no-bitwise
|
||||
// eslint-disable-next-line no-bitwise
|
||||
const length = (hexValue.length / 2) | 0;
|
||||
const uint8 = new Uint8Array(length);
|
||||
for (let i = 0; i < length; i++) uint8[i] = parseInt(hexValue.substr(i * 2, 2), 16);
|
||||
|
|
@ -124,7 +124,7 @@ function uint4ToUint8(uintValue) {
|
|||
return uint8;
|
||||
}
|
||||
|
||||
// tslint:disable:no-bitwise
|
||||
/* eslint-disable no-bitwise */
|
||||
function uint4ToUint5(uintValue) {
|
||||
const length = uintValue.length / 5 * 4;
|
||||
const uint5 = new Uint8Array(length);
|
||||
|
|
@ -140,7 +140,7 @@ function uint4ToUint5(uintValue) {
|
|||
}
|
||||
return uint5;
|
||||
}
|
||||
// tslint:enable:no-bitwise
|
||||
/* eslint-enable no-bitwise */
|
||||
|
||||
function uint4ToHex(uint4) {
|
||||
let hex = '';
|
||||
|
|
@ -158,7 +158,7 @@ function uint5ToString(uint5) {
|
|||
return string;
|
||||
}
|
||||
|
||||
// tslint:disable:no-bitwise
|
||||
/* eslint-disable no-bitwise */
|
||||
function uint5ToUint4(uint5) {
|
||||
const length = uint5.length / 4 * 5;
|
||||
const uint4 = new Uint8Array(length);
|
||||
|
|
@ -172,7 +172,7 @@ function uint5ToUint4(uint5) {
|
|||
}
|
||||
return uint4;
|
||||
}
|
||||
// tslint:enable:no-bitwise
|
||||
/* eslint-enable no-bitwise */
|
||||
|
||||
|
||||
/** Uint8 Functions **/
|
||||
|
|
@ -191,7 +191,7 @@ function uint8ToHex(uintValue) {
|
|||
return(hex);
|
||||
}
|
||||
|
||||
// tslint:disable:no-bitwise
|
||||
/* eslint-disable no-bitwise */
|
||||
function uint8ToUint4(uintValue) {
|
||||
const uint4 = new Uint8Array(uintValue.length * 2);
|
||||
for (let i = 0; i < uintValue.length; i++) {
|
||||
|
|
@ -201,12 +201,12 @@ function uint8ToUint4(uintValue) {
|
|||
|
||||
return uint4;
|
||||
}
|
||||
// tslint:enable:no-bitwise
|
||||
/* eslint-enable no-bitwise */
|
||||
|
||||
|
||||
/** Dec Functions **/
|
||||
function decToHex(decValue, bytes = null) {
|
||||
// tslint:disable-next-line:prefer-const
|
||||
// eslint-disable-next-line prefer-const
|
||||
let dec = decValue.toString().split(''), sum = [], hex = '', hexArray = [], i, s;
|
||||
while (dec.length) {
|
||||
s = 1 * dec.shift();
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import {NotificationService} from './notification.service';
|
|||
import {AppSettingsService} from './app-settings.service';
|
||||
import {PriceService} from './price.service';
|
||||
import {LedgerService} from './ledger.service';
|
||||
import { NoPaddingZerosPipe } from 'app/pipes/no-padding-zeros.pipe';
|
||||
|
||||
export type WalletType = 'seed' | 'ledger' | 'privateKey' | 'expandedKey';
|
||||
|
||||
|
|
@ -136,6 +137,7 @@ export class WalletService {
|
|||
private websocket: WebsocketService,
|
||||
private nanoBlock: NanoBlockService,
|
||||
private ledgerService: LedgerService,
|
||||
private noZerosPipe: NoPaddingZerosPipe,
|
||||
private notifications: NotificationService) {
|
||||
this.websocket.newTransactions$.subscribe(async (transaction) => {
|
||||
if (!transaction) return; // Not really a new transaction
|
||||
|
|
@ -853,7 +855,7 @@ export class WalletService {
|
|||
this.wallet.balanceFiat = this.util.nano.rawToMnano(walletBalance).times(fiatPrice).toNumber();
|
||||
this.wallet.pendingFiat = this.util.nano.rawToMnano(walletPendingAboveThresholdConfirmed).times(fiatPrice).toNumber();
|
||||
|
||||
// tslint:disable-next-line
|
||||
// eslint-disable-next-line
|
||||
this.wallet.hasPending = walletPendingAboveThresholdConfirmed.gt(0);
|
||||
|
||||
this.wallet.updatingBalance = false;
|
||||
|
|
@ -1018,7 +1020,7 @@ export class WalletService {
|
|||
|
||||
const receiveAmount = this.util.nano.rawToMnano(nextBlock.amount);
|
||||
this.notifications.removeNotification('success-receive');
|
||||
this.notifications.sendSuccess(`Successfully received ${receiveAmount.isZero() ? '' : receiveAmount.toFixed(6)} XNO!`, { identifier: 'success-receive' });
|
||||
this.notifications.sendSuccess(`Successfully received ${receiveAmount.isZero() ? '' : this.noZerosPipe.transform(receiveAmount.toFixed(6)) } XNO!`, { identifier: 'success-receive' });
|
||||
|
||||
// remove after processing
|
||||
// list also updated with reloadBalances but not if called too fast
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { WelcomeComponent } from './welcome.component';
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ describe('WelcomeComponent', () => {
|
|||
let component: WelcomeComponent;
|
||||
let fixture: ComponentFixture<WelcomeComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ WelcomeComponent ]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
/*! UIkit 3.5.4 | https://www.getuikit.com | (c) 2014 - 2020 YOOtheme | MIT License */
|
||||
/*! UIkit 3.9.4 | https://www.getuikit.com | (c) 2014 - 2021 YOOtheme | MIT License */
|
||||
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||
typeof define === 'function' && define.amd ? define('uikiticons', factory) :
|
||||
(global = global || self, global.UIkitIcons = factory());
|
||||
}(this, (function () { 'use strict';
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.UIkitIcons = factory());
|
||||
})(this, (function () { 'use strict';
|
||||
|
||||
function plugin(UIkit) {
|
||||
|
||||
|
|
@ -19,6 +19,7 @@
|
|||
"arrow-left": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polyline fill=\"none\" stroke=\"#000\" points=\"10 14 5 9.5 10 5\"/><line fill=\"none\" stroke=\"#000\" x1=\"16\" y1=\"9.5\" x2=\"5\" y2=\"9.52\"/></svg>",
|
||||
"arrow-right": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polyline fill=\"none\" stroke=\"#000\" points=\"10 5 15 9.5 10 14\"/><line fill=\"none\" stroke=\"#000\" x1=\"4\" y1=\"9.5\" x2=\"15\" y2=\"9.5\"/></svg>",
|
||||
"arrow-up": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"10.5,4 15.37,9.4 14.63,10.08 10.5,5.49 6.37,10.08 5.63,9.4\"/><line fill=\"none\" stroke=\"#000\" x1=\"10.5\" y1=\"16\" x2=\"10.5\" y2=\"5\"/></svg>",
|
||||
"bag": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"none\" stroke=\"#000\" d=\"M7.5,7.5V4A2.48,2.48,0,0,1,10,1.5,2.54,2.54,0,0,1,12.5,4V7.5\"/><polygon fill=\"none\" stroke=\"#000\" points=\"16.5 7.5 3.5 7.5 2.5 18.5 17.5 18.5 16.5 7.5\"/></svg>",
|
||||
"ban": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><circle fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" cx=\"10\" cy=\"10\" r=\"9\"/><line fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" x1=\"4\" y1=\"3.5\" x2=\"16\" y2=\"16.5\"/></svg>",
|
||||
"behance": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M9.5,10.6c-0.4-0.5-0.9-0.9-1.6-1.1c1.7-1,2.2-3.2,0.7-4.7C7.8,4,6.3,4,5.2,4C3.5,4,1.7,4,0,4v12c1.7,0,3.4,0,5.2,0 c1,0,2.1,0,3.1-0.5C10.2,14.6,10.5,12.3,9.5,10.6L9.5,10.6z M5.6,6.1c1.8,0,1.8,2.7-0.1,2.7c-1,0-2,0-2.9,0V6.1H5.6z M2.6,13.8v-3.1 c1.1,0,2.1,0,3.2,0c2.1,0,2.1,3.2,0.1,3.2L2.6,13.8z\"/><path d=\"M19.9,10.9C19.7,9.2,18.7,7.6,17,7c-4.2-1.3-7.3,3.4-5.3,7.1c0.9,1.7,2.8,2.3,4.7,2.1c1.7-0.2,2.9-1.3,3.4-2.9h-2.2 c-0.4,1.3-2.4,1.5-3.5,0.6c-0.4-0.4-0.6-1.1-0.6-1.7H20C20,11.7,19.9,10.9,19.9,10.9z M13.5,10.6c0-1.6,2.3-2.7,3.5-1.4 c0.4,0.4,0.5,0.9,0.6,1.4H13.5L13.5,10.6z\"/><rect x=\"13\" y=\"4\" width=\"5\" height=\"1.4\"/></svg>",
|
||||
"bell": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M17,15.5 L3,15.5 C2.99,14.61 3.79,13.34 4.1,12.51 C4.58,11.3 4.72,10.35 5.19,7.01 C5.54,4.53 5.89,3.2 7.28,2.16 C8.13,1.56 9.37,1.5 9.81,1.5 L9.96,1.5 C9.96,1.5 11.62,1.41 12.67,2.17 C14.08,3.2 14.42,4.54 14.77,7.02 C15.26,10.35 15.4,11.31 15.87,12.52 C16.2,13.34 17.01,14.61 17,15.5 L17,15.5 Z\"/><path fill=\"none\" stroke=\"#000\" d=\"M12.39,16 C12.39,17.37 11.35,18.43 9.91,18.43 C8.48,18.43 7.42,17.37 7.42,16\"/></svg>",
|
||||
|
|
@ -48,6 +49,7 @@
|
|||
"credit-card": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect fill=\"none\" stroke=\"#000\" x=\"1.5\" y=\"4.5\" width=\"17\" height=\"12\"/><rect x=\"1\" y=\"7\" width=\"18\" height=\"3\"/></svg>",
|
||||
"database": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><ellipse fill=\"none\" stroke=\"#000\" cx=\"10\" cy=\"4.64\" rx=\"7.5\" ry=\"3.14\"/><path fill=\"none\" stroke=\"#000\" d=\"M17.5,8.11 C17.5,9.85 14.14,11.25 10,11.25 C5.86,11.25 2.5,9.84 2.5,8.11\"/><path fill=\"none\" stroke=\"#000\" d=\"M17.5,11.25 C17.5,12.99 14.14,14.39 10,14.39 C5.86,14.39 2.5,12.98 2.5,11.25\"/><path fill=\"none\" stroke=\"#000\" d=\"M17.49,4.64 L17.5,14.36 C17.5,16.1 14.14,17.5 10,17.5 C5.86,17.5 2.5,16.09 2.5,14.36 L2.5,4.64\"/></svg>",
|
||||
"desktop": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"8\" y=\"15\" width=\"1\" height=\"2\"/><rect x=\"11\" y=\"15\" width=\"1\" height=\"2\"/><rect x=\"5\" y=\"16\" width=\"10\" height=\"1\"/><rect fill=\"none\" stroke=\"#000\" x=\"1.5\" y=\"3.5\" width=\"17\" height=\"11\"/></svg>",
|
||||
"discord": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\"><path d=\"M16.074,4.361a14.243,14.243,0,0,0-3.61-1.134,10.61,10.61,0,0,0-.463.96,13.219,13.219,0,0,0-4,0,10.138,10.138,0,0,0-.468-.96A14.206,14.206,0,0,0,3.919,4.364,15.146,15.146,0,0,0,1.324,14.5a14.435,14.435,0,0,0,4.428,2.269A10.982,10.982,0,0,0,6.7,15.21a9.294,9.294,0,0,1-1.494-.727c.125-.093.248-.19.366-.289a10.212,10.212,0,0,0,8.854,0c.119.1.242.2.366.289a9.274,9.274,0,0,1-1.5.728,10.8,10.8,0,0,0,.948,1.562,14.419,14.419,0,0,0,4.431-2.27A15.128,15.128,0,0,0,16.074,4.361Zm-8.981,8.1a1.7,1.7,0,0,1-1.573-1.79A1.689,1.689,0,0,1,7.093,8.881a1.679,1.679,0,0,1,1.573,1.791A1.687,1.687,0,0,1,7.093,12.462Zm5.814,0a1.7,1.7,0,0,1-1.573-1.79,1.689,1.689,0,0,1,1.573-1.791,1.679,1.679,0,0,1,1.573,1.791A1.688,1.688,0,0,1,12.907,12.462Z\"/></svg>",
|
||||
"download": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polyline fill=\"none\" stroke=\"#000\" points=\"14,10 9.5,14.5 5,10\"/><rect x=\"3\" y=\"17\" width=\"13\" height=\"1\"/><line fill=\"none\" stroke=\"#000\" x1=\"9.5\" y1=\"13.91\" x2=\"9.5\" y2=\"3\"/></svg>",
|
||||
"dribbble": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.4\" d=\"M1.3,8.9c0,0,5,0.1,8.6-1c1.4-0.4,2.6-0.9,4-1.9 c1.4-1.1,2.5-2.5,2.5-2.5\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.4\" d=\"M3.9,16.6c0,0,1.7-2.8,3.5-4.2 c1.8-1.3,4-2,5.7-2.2C16,10,19,10.6,19,10.6\"/><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.4\" d=\"M6.9,1.6c0,0,3.3,4.6,4.2,6.8 c0.4,0.9,1.3,3.1,1.9,5.2c0.6,2,0.9,4.4,0.9,4.4\"/><circle fill=\"none\" stroke=\"#000\" stroke-width=\"1.4\" cx=\"10\" cy=\"10\" r=\"9\"/></svg>",
|
||||
"etsy": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\"><path d=\"M8,4.26C8,4.07,8,4,8.31,4h4.46c.79,0,1.22.67,1.53,1.91l.25,1h.76c.14-2.82.26-4,.26-4S13.65,3,12.52,3H6.81L3.75,2.92v.84l1,.2c.73.11.9.27,1,1,0,0,.06,2,.06,5.17s-.06,5.14-.06,5.14c0,.59-.23.81-1,.94l-1,.2v.84l3.06-.1h5.11c1.15,0,3.82.1,3.82.1,0-.7.45-3.88.51-4.22h-.73l-.76,1.69a2.25,2.25,0,0,1-2.45,1.47H9.4c-1,0-1.44-.4-1.44-1.24V10.44s2.16,0,2.86.06c.55,0,.85.19,1.06,1l.23,1H13L12.9,9.94,13,7.41h-.85l-.28,1.13c-.16.74-.28.84-1,1-1,.1-2.89.09-2.89.09Z\"/></svg>",
|
||||
|
|
@ -67,7 +69,6 @@
|
|||
"github-alt": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10,0.5 C4.75,0.5 0.5,4.76 0.5,10.01 C0.5,15.26 4.75,19.51 10,19.51 C15.24,19.51 19.5,15.26 19.5,10.01 C19.5,4.76 15.25,0.5 10,0.5 L10,0.5 Z M12.81,17.69 C12.81,17.69 12.81,17.7 12.79,17.69 C12.47,17.75 12.35,17.59 12.35,17.36 L12.35,16.17 C12.35,15.45 12.09,14.92 11.58,14.56 C12.2,14.51 12.77,14.39 13.26,14.21 C13.87,13.98 14.36,13.69 14.74,13.29 C15.42,12.59 15.76,11.55 15.76,10.17 C15.76,9.25 15.45,8.46 14.83,7.8 C15.1,7.08 15.07,6.29 14.75,5.44 L14.51,5.42 C14.34,5.4 14.06,5.46 13.67,5.61 C13.25,5.78 12.79,6.03 12.31,6.35 C11.55,6.16 10.81,6.05 10.09,6.05 C9.36,6.05 8.61,6.15 7.88,6.35 C7.28,5.96 6.75,5.68 6.26,5.54 C6.07,5.47 5.9,5.44 5.78,5.44 L5.42,5.44 C5.06,6.29 5.04,7.08 5.32,7.8 C4.7,8.46 4.4,9.25 4.4,10.17 C4.4,11.94 4.96,13.16 6.08,13.84 C6.53,14.13 7.05,14.32 7.69,14.43 C8.03,14.5 8.32,14.54 8.55,14.55 C8.07,14.89 7.82,15.42 7.82,16.16 L7.82,17.51 C7.8,17.69 7.7,17.8 7.51,17.8 C4.21,16.74 1.82,13.65 1.82,10.01 C1.82,5.5 5.49,1.83 10,1.83 C14.5,1.83 18.17,5.5 18.17,10.01 C18.18,13.53 15.94,16.54 12.81,17.69 L12.81,17.69 Z\"/></svg>",
|
||||
"github": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10,1 C5.03,1 1,5.03 1,10 C1,13.98 3.58,17.35 7.16,18.54 C7.61,18.62 7.77,18.34 7.77,18.11 C7.77,17.9 7.76,17.33 7.76,16.58 C5.26,17.12 4.73,15.37 4.73,15.37 C4.32,14.33 3.73,14.05 3.73,14.05 C2.91,13.5 3.79,13.5 3.79,13.5 C4.69,13.56 5.17,14.43 5.17,14.43 C5.97,15.8 7.28,15.41 7.79,15.18 C7.87,14.6 8.1,14.2 8.36,13.98 C6.36,13.75 4.26,12.98 4.26,9.53 C4.26,8.55 4.61,7.74 5.19,7.11 C5.1,6.88 4.79,5.97 5.28,4.73 C5.28,4.73 6.04,4.49 7.75,5.65 C8.47,5.45 9.24,5.35 10,5.35 C10.76,5.35 11.53,5.45 12.25,5.65 C13.97,4.48 14.72,4.73 14.72,4.73 C15.21,5.97 14.9,6.88 14.81,7.11 C15.39,7.74 15.73,8.54 15.73,9.53 C15.73,12.99 13.63,13.75 11.62,13.97 C11.94,14.25 12.23,14.8 12.23,15.64 C12.23,16.84 12.22,17.81 12.22,18.11 C12.22,18.35 12.38,18.63 12.84,18.54 C16.42,17.35 19,13.98 19,10 C19,5.03 14.97,1 10,1 L10,1 Z\"/></svg>",
|
||||
"gitter": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"3.5\" y=\"1\" width=\"1.531\" height=\"11.471\"/><rect x=\"7.324\" y=\"4.059\" width=\"1.529\" height=\"15.294\"/><rect x=\"11.148\" y=\"4.059\" width=\"1.527\" height=\"15.294\"/><rect x=\"14.971\" y=\"4.059\" width=\"1.529\" height=\"8.412\"/></svg>",
|
||||
"google-plus": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M12.9,9c0,2.7-0.6,5-3.2,6.3c-3.7,1.8-8.1,0.2-9.4-3.6C-1.1,7.6,1.9,3.3,6.1,3c1.7-0.1,3.2,0.3,4.6,1.3 c0.1,0.1,0.3,0.2,0.4,0.4c-0.5,0.5-1.2,1-1.7,1.6c-1-0.8-2.1-1.1-3.5-0.9C5,5.6,4.2,6,3.6,6.7c-1.3,1.3-1.5,3.4-0.5,5 c1,1.7,2.6,2.3,4.6,1.9c1.4-0.3,2.4-1.2,2.6-2.6H6.9V9H12.9z\"/><polygon points=\"20,9 20,11 18,11 18,13 16,13 16,11 14,11 14,9 16,9 16,7 18,7 18,9\"/></svg>",
|
||||
"google": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M17.86,9.09 C18.46,12.12 17.14,16.05 13.81,17.56 C9.45,19.53 4.13,17.68 2.47,12.87 C0.68,7.68 4.22,2.42 9.5,2.03 C11.57,1.88 13.42,2.37 15.05,3.65 C15.22,3.78 15.37,3.93 15.61,4.14 C14.9,4.81 14.23,5.45 13.5,6.14 C12.27,5.08 10.84,4.72 9.28,4.98 C8.12,5.17 7.16,5.76 6.37,6.63 C4.88,8.27 4.62,10.86 5.76,12.82 C6.95,14.87 9.17,15.8 11.57,15.25 C13.27,14.87 14.76,13.33 14.89,11.75 L10.51,11.75 L10.51,9.09 L17.86,9.09 L17.86,9.09 Z\"/></svg>",
|
||||
"grid": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"2\" y=\"2\" width=\"3\" height=\"3\"/><rect x=\"8\" y=\"2\" width=\"3\" height=\"3\"/><rect x=\"14\" y=\"2\" width=\"3\" height=\"3\"/><rect x=\"2\" y=\"8\" width=\"3\" height=\"3\"/><rect x=\"8\" y=\"8\" width=\"3\" height=\"3\"/><rect x=\"14\" y=\"8\" width=\"3\" height=\"3\"/><rect x=\"2\" y=\"14\" width=\"3\" height=\"3\"/><rect x=\"8\" y=\"14\" width=\"3\" height=\"3\"/><rect x=\"14\" y=\"14\" width=\"3\" height=\"3\"/></svg>",
|
||||
"happy": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"13\" cy=\"7\" r=\"1\"/><circle cx=\"7\" cy=\"7\" r=\"1\"/><circle fill=\"none\" stroke=\"#000\" cx=\"10\" cy=\"10\" r=\"8.5\"/><path fill=\"none\" stroke=\"#000\" d=\"M14.6,11.4 C13.9,13.3 12.1,14.5 10,14.5 C7.9,14.5 6.1,13.3 5.4,11.4\"/></svg>",
|
||||
|
|
@ -131,6 +132,7 @@
|
|||
"tablet": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"none\" stroke=\"#000\" d=\"M5,18.5 C4.2,18.5 3.5,17.8 3.5,17 L3.5,3 C3.5,2.2 4.2,1.5 5,1.5 L16,1.5 C16.8,1.5 17.5,2.2 17.5,3 L17.5,17 C17.5,17.8 16.8,18.5 16,18.5 L5,18.5 L5,18.5 L5,18.5 Z\"/><circle cx=\"10.5\" cy=\"16.3\" r=\".8\"/></svg>",
|
||||
"tag": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path fill=\"none\" stroke=\"#000\" stroke-width=\"1.1\" d=\"M17.5,3.71 L17.5,7.72 C17.5,7.96 17.4,8.2 17.21,8.39 L8.39,17.2 C7.99,17.6 7.33,17.6 6.93,17.2 L2.8,13.07 C2.4,12.67 2.4,12.01 2.8,11.61 L11.61,2.8 C11.81,2.6 12.08,2.5 12.34,2.5 L16.19,2.5 C16.52,2.5 16.86,2.63 17.11,2.88 C17.35,3.11 17.48,3.4 17.5,3.71 L17.5,3.71 Z\"/><circle cx=\"14\" cy=\"6\" r=\"1\"/></svg>",
|
||||
"thumbnails": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect fill=\"none\" stroke=\"#000\" x=\"3.5\" y=\"3.5\" width=\"5\" height=\"5\"/><rect fill=\"none\" stroke=\"#000\" x=\"11.5\" y=\"3.5\" width=\"5\" height=\"5\"/><rect fill=\"none\" stroke=\"#000\" x=\"11.5\" y=\"11.5\" width=\"5\" height=\"5\"/><rect fill=\"none\" stroke=\"#000\" x=\"3.5\" y=\"11.5\" width=\"5\" height=\"5\"/></svg>",
|
||||
"tiktok": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M17.24,6V8.82a6.79,6.79,0,0,1-4-1.28v5.81A5.26,5.26,0,1,1,8,8.1a4.36,4.36,0,0,1,.72.05v2.9A2.57,2.57,0,0,0,7.64,11a2.4,2.4,0,1,0,2.77,2.38V2h2.86a4,4,0,0,0,1.84,3.38A4,4,0,0,0,17.24,6Z\"/></svg>",
|
||||
"trash": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polyline fill=\"none\" stroke=\"#000\" points=\"6.5 3 6.5 1.5 13.5 1.5 13.5 3\"/><polyline fill=\"none\" stroke=\"#000\" points=\"4.5 4 4.5 18.5 15.5 18.5 15.5 4\"/><rect x=\"8\" y=\"7\" width=\"1\" height=\"9\"/><rect x=\"11\" y=\"7\" width=\"1\" height=\"9\"/><rect x=\"2\" y=\"3\" width=\"16\" height=\"1\"/></svg>",
|
||||
"triangle-down": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"5 7 15 7 10 12\"/></svg>",
|
||||
"triangle-left": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"12 5 7 10 12 15\"/></svg>",
|
||||
|
|
@ -139,6 +141,7 @@
|
|||
"tripadvisor": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M19.021,7.866C19.256,6.862,20,5.854,20,5.854h-3.346C14.781,4.641,12.504,4,9.98,4C7.363,4,4.999,4.651,3.135,5.876H0\tc0,0,0.738,0.987,0.976,1.988c-0.611,0.837-0.973,1.852-0.973,2.964c0,2.763,2.249,5.009,5.011,5.009\tc1.576,0,2.976-0.737,3.901-1.879l1.063,1.599l1.075-1.615c0.475,0.611,1.1,1.111,1.838,1.451c1.213,0.547,2.574,0.612,3.825,0.15\tc2.589-0.963,3.913-3.852,2.964-6.439c-0.175-0.463-0.4-0.876-0.675-1.238H19.021z M16.38,14.594\tc-1.002,0.371-2.088,0.328-3.06-0.119c-0.688-0.317-1.252-0.817-1.657-1.438c-0.164-0.25-0.313-0.52-0.417-0.811\tc-0.124-0.328-0.186-0.668-0.217-1.014c-0.063-0.689,0.037-1.396,0.339-2.043c0.448-0.971,1.251-1.71,2.25-2.079\tc2.075-0.765,4.375,0.3,5.14,2.366c0.762,2.066-0.301,4.37-2.363,5.134L16.38,14.594L16.38,14.594z M8.322,13.066\tc-0.72,1.059-1.935,1.76-3.309,1.76c-2.207,0-4.001-1.797-4.001-3.996c0-2.203,1.795-4.002,4.001-4.002\tc2.204,0,3.999,1.8,3.999,4.002c0,0.137-0.024,0.261-0.04,0.396c-0.067,0.678-0.284,1.313-0.648,1.853v-0.013H8.322z M2.472,10.775\tc0,1.367,1.112,2.479,2.476,2.479c1.363,0,2.472-1.11,2.472-2.479c0-1.359-1.11-2.468-2.472-2.468\tC3.584,8.306,2.473,9.416,2.472,10.775L2.472,10.775z M12.514,10.775c0,1.367,1.104,2.479,2.471,2.479\tc1.363,0,2.474-1.108,2.474-2.479c0-1.359-1.11-2.468-2.474-2.468c-1.364,0-2.477,1.109-2.477,2.468H12.514z M3.324,10.775\tc0-0.893,0.726-1.618,1.614-1.618c0.889,0,1.625,0.727,1.625,1.618c0,0.898-0.725,1.627-1.625,1.627\tc-0.901,0-1.625-0.729-1.625-1.627H3.324z M13.354,10.775c0-0.893,0.726-1.618,1.627-1.618c0.886,0,1.61,0.727,1.61,1.618\tc0,0.898-0.726,1.627-1.626,1.627s-1.625-0.729-1.625-1.627H13.354z M9.977,4.875c1.798,0,3.425,0.324,4.849,0.968\tc-0.535,0.015-1.061,0.108-1.586,0.3c-1.264,0.463-2.264,1.388-2.815,2.604c-0.262,0.551-0.398,1.133-0.448,1.72\tC9.79,7.905,7.677,5.873,5.076,5.82C6.501,5.208,8.153,4.875,9.94,4.875H9.977z\"/></svg>",
|
||||
"tumblr": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6.885,8.598c0,0,0,3.393,0,4.996c0,0.282,0,0.66,0.094,0.942c0.377,1.509,1.131,2.545,2.545,3.11 c1.319,0.472,2.356,0.472,3.676,0c0.565-0.188,1.132-0.659,1.132-0.659l-0.849-2.263c0,0-1.036,0.378-1.603,0.283 c-0.565-0.094-1.226-0.66-1.226-1.508c0-1.603,0-4.902,0-4.902h2.828V5.771h-2.828V2H8.205c0,0-0.094,0.66-0.188,0.942 C7.828,3.791,7.262,4.733,6.603,5.394C5.848,6.147,5,6.43,5,6.43v2.168H6.885z\"/></svg>",
|
||||
"tv": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"7\" y=\"16\" width=\"6\" height=\"1\"/><rect fill=\"none\" stroke=\"#000\" x=\".5\" y=\"3.5\" width=\"19\" height=\"11\"/></svg>",
|
||||
"twitch": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M5.23,1,2,4.23V15.85H5.88v3.23L9.1,15.85h2.59L17.5,10V1Zm11,8.4L13.62,12H11L8.78,14.24V12H5.88V2.29H16.21Z\"/><rect x=\"12.98\" y=\"4.55\" width=\"1.29\" height=\"3.88\"/><rect x=\"9.43\" y=\"4.55\" width=\"1.29\" height=\"3.88\"/></svg>",
|
||||
"twitter": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M19,4.74 C18.339,5.029 17.626,5.229 16.881,5.32 C17.644,4.86 18.227,4.139 18.503,3.28 C17.79,3.7 17.001,4.009 16.159,4.17 C15.485,3.45 14.526,3 13.464,3 C11.423,3 9.771,4.66 9.771,6.7 C9.771,6.99 9.804,7.269 9.868,7.539 C6.795,7.38 4.076,5.919 2.254,3.679 C1.936,4.219 1.754,4.86 1.754,5.539 C1.754,6.82 2.405,7.95 3.397,8.61 C2.79,8.589 2.22,8.429 1.723,8.149 L1.723,8.189 C1.723,9.978 2.997,11.478 4.686,11.82 C4.376,11.899 4.049,11.939 3.713,11.939 C3.475,11.939 3.245,11.919 3.018,11.88 C3.49,13.349 4.852,14.419 6.469,14.449 C5.205,15.429 3.612,16.019 1.882,16.019 C1.583,16.019 1.29,16.009 1,15.969 C2.635,17.019 4.576,17.629 6.662,17.629 C13.454,17.629 17.17,12 17.17,7.129 C17.17,6.969 17.166,6.809 17.157,6.649 C17.879,6.129 18.504,5.478 19,4.74\"/></svg>",
|
||||
"uikit": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><polygon points=\"14.4,3.1 11.3,5.1 15,7.3 15,12.9 10,15.7 5,12.9 5,8.5 2,6.8 2,14.8 9.9,19.5 18,14.8 18,5.3\"/><polygon points=\"9.8,4.2 6.7,2.4 9.8,0.4 12.9,2.3\"/></svg>",
|
||||
"unlock": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" xmlns=\"http://www.w3.org/2000/svg\"><rect fill=\"none\" stroke=\"#000\" x=\"3.5\" y=\"8.5\" width=\"13\" height=\"10\"/><path fill=\"none\" stroke=\"#000\" d=\"M6.5,8.5 L6.5,4.9 C6.5,3 8.1,1.5 10,1.5 C11.9,1.5 13.5,3 13.5,4.9\"/></svg>",
|
||||
|
|
@ -164,4 +167,4 @@
|
|||
|
||||
return plugin;
|
||||
|
||||
})));
|
||||
}));
|
||||
|
|
|
|||
4
src/assets/lib/base/uikit-icons.min.js
vendored
4
src/assets/lib/base/uikit-icons.min.js
vendored
File diff suppressed because one or more lines are too long
12170
src/assets/lib/base/uikit-rtl.css
Normal file
12170
src/assets/lib/base/uikit-rtl.css
Normal file
File diff suppressed because it is too large
Load diff
1
src/assets/lib/base/uikit-rtl.min.css
vendored
Normal file
1
src/assets/lib/base/uikit-rtl.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
2
src/assets/lib/base/uikit.min.css
vendored
2
src/assets/lib/base/uikit.min.css
vendored
File diff suppressed because one or more lines are too long
4
src/assets/lib/base/uikit.min.js
vendored
4
src/assets/lib/base/uikit.min.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -186,6 +186,10 @@
|
|||
border-bottom-color: @dark-mode-background-1;
|
||||
}
|
||||
|
||||
.uk-table-striped > tr:nth-of-type(2n):last-child, .uk-table-striped tbody tr:nth-of-type(2n):last-child {
|
||||
border-bottom: 1px solid @dark-mode-background-2;
|
||||
}
|
||||
|
||||
// General (List)
|
||||
.uk-list {
|
||||
background: @dark-mode-background-2;
|
||||
|
|
@ -449,6 +453,16 @@
|
|||
background: @dark-mode-background-2 !important;
|
||||
}
|
||||
|
||||
.merchant-mode-overlay {
|
||||
background: @dark-mode-background-1 !important;
|
||||
|
||||
.merchant-mode-logo {
|
||||
background: url('../../assets/img/nault-logo-night-mode.svg');
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
}
|
||||
|
||||
// Representatives page
|
||||
.delegating-account-row, .representative-row {
|
||||
background: @dark-mode-background-3 !important;
|
||||
|
|
|
|||
|
|
@ -575,6 +575,10 @@
|
|||
border-left-color: @global-primary-background;
|
||||
color: @global-primary-background;
|
||||
}
|
||||
|
||||
> .uk-grid-stack {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.label-new {
|
||||
|
|
@ -582,8 +586,10 @@
|
|||
margin: -10px 0px -10px -9px;
|
||||
|
||||
> .uk-badge {
|
||||
display: flex;
|
||||
height: 22px;
|
||||
font-size: 16px;
|
||||
padding-bottom: 2px;
|
||||
padding: 1px 0 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ h1, h2, h3, h4, h5, .uk-text-lead, .uk-button, .uk-alert, .uk-description-list d
|
|||
|
||||
@media (max-width: 939px) {
|
||||
.nlt-button-group button {
|
||||
margin-bottom: @nlt-intro-margin / 2 !important;
|
||||
margin-bottom: 20px !important;
|
||||
}
|
||||
|
||||
h2:not(.uk-card-title):not(.uk-modal-title) {
|
||||
|
|
@ -1336,6 +1336,30 @@ input[type=number] {
|
|||
}
|
||||
}
|
||||
|
||||
// Receive page
|
||||
.merchant-centered-container {
|
||||
.identicon-name-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
height: 28px;
|
||||
padding-bottom: 8px;
|
||||
|
||||
.nano-identicon {
|
||||
display: inline-block;
|
||||
width: 27px;
|
||||
height: 27px;
|
||||
margin-right: 12px;
|
||||
margin-left: 1px;
|
||||
flex-shrink: 0;
|
||||
|
||||
.canvas-container canvas {
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Representatives page
|
||||
.delegating-account-row {
|
||||
border-top: none !important;
|
||||
|
|
@ -1527,6 +1551,14 @@ input[type=number] {
|
|||
background-color: #16A670 !important;
|
||||
}
|
||||
|
||||
.nlt-button-green {
|
||||
background-color: #16A670 !important;
|
||||
|
||||
&:hover {
|
||||
background-color: #069660 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.nlt-page-intro {
|
||||
margin-bottom: @nlt-intro-margin;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,18 +13,12 @@ import '@angular/localize/init';
|
|||
// (window as any).global = window;
|
||||
global.Buffer = global.Buffer || require('buffer').Buffer;
|
||||
|
||||
/**
|
||||
* Required to support Web Animations `@angular/platform-browser/animations`.
|
||||
* Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
|
||||
**/
|
||||
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
|
||||
|
||||
|
||||
|
||||
/***************************************************************************************************
|
||||
* Zone JS is required by default for Angular itself.
|
||||
*/
|
||||
import 'zone.js/dist/zone'; // Included with Angular CLI.
|
||||
import 'zone.js'; // Included with Angular CLI.
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,9 @@ __karma__.loaded = function () {};
|
|||
// First, initialize the Angular testing environment.
|
||||
getTestBed().initTestEnvironment(
|
||||
BrowserDynamicTestingModule,
|
||||
platformBrowserDynamicTesting()
|
||||
platformBrowserDynamicTesting(), {
|
||||
teardown: { destroyAfterEach: false }
|
||||
}
|
||||
);
|
||||
// Then we find all the tests.
|
||||
const context = require.context('./', true, /\.spec\.ts$/);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "../tsconfig.base.json",
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/app",
|
||||
"baseUrl": "./",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"extends": "../tsconfig.base.json",
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../out-tsc/spec",
|
||||
"baseUrl": "./",
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
{
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
"downlevelIteration": true,
|
||||
"importHelpers": true,
|
||||
"outDir": "./dist/out-tsc",
|
||||
"sourceMap": true,
|
||||
"declaration": false,
|
||||
"moduleResolution": "node",
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"target": "es2015",
|
||||
"typeRoots": [
|
||||
"node_modules/@types",
|
||||
"./src/typings"
|
||||
],
|
||||
"lib": [
|
||||
"es2017",
|
||||
"dom"
|
||||
],
|
||||
"module": "es2020",
|
||||
"baseUrl": "./",
|
||||
"paths": {
|
||||
"stream": ["../node_modules/readable-stream/readable.js"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +1,27 @@
|
|||
/*
|
||||
This is a "Solution Style" tsconfig.json file, and is used by editors and TypeScript’s language server to improve development experience.
|
||||
It is not intended to be used to perform a compilation.
|
||||
|
||||
To learn more about this file see: https://angular.io/config/solution-tsconfig.
|
||||
*/
|
||||
{
|
||||
"files": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./src/tsconfig.app.json"
|
||||
},
|
||||
{
|
||||
"path": "./src/tsconfig.spec.json"
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
"downlevelIteration": true,
|
||||
"importHelpers": true,
|
||||
"outDir": "./dist/out-tsc",
|
||||
"sourceMap": true,
|
||||
"declaration": false,
|
||||
"moduleResolution": "node",
|
||||
"experimentalDecorators": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"target": "es2017",
|
||||
"typeRoots": [
|
||||
"node_modules/@types",
|
||||
"./src/typings"
|
||||
],
|
||||
"lib": [
|
||||
"es2020",
|
||||
"dom"
|
||||
],
|
||||
"module": "es2020",
|
||||
"baseUrl": "./",
|
||||
"paths": {
|
||||
"stream": ["../node_modules/readable-stream/readable.js"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,6 @@
|
|||
"sourceMap": true,
|
||||
"declaration": false,
|
||||
"moduleResolution": "node",
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"target": "es2015",
|
||||
"typeRoots": [
|
||||
|
|
|
|||
141
tslint.json
141
tslint.json
|
|
@ -1,141 +0,0 @@
|
|||
{
|
||||
"rulesDirectory": [
|
||||
"node_modules/codelyzer"
|
||||
],
|
||||
"rules": {
|
||||
"arrow-return-shorthand": true,
|
||||
"callable-types": true,
|
||||
"class-name": true,
|
||||
"comment-format": [
|
||||
true,
|
||||
"check-space"
|
||||
],
|
||||
"curly": [true, "ignore-same-line"],
|
||||
"deprecation": {
|
||||
"severity": "warn"
|
||||
},
|
||||
"eofline": true,
|
||||
"forin": true,
|
||||
"import-blacklist": [
|
||||
true,
|
||||
"rxjs/Rx"
|
||||
],
|
||||
"import-spacing": true,
|
||||
"indent": [
|
||||
true,
|
||||
"spaces"
|
||||
],
|
||||
"interface-over-type-literal": true,
|
||||
"label-position": true,
|
||||
"max-line-length": [
|
||||
true,
|
||||
140
|
||||
],
|
||||
"member-access": false,
|
||||
"member-ordering": [
|
||||
true,
|
||||
{
|
||||
"order": [
|
||||
"static-field",
|
||||
"instance-field",
|
||||
"static-method",
|
||||
"instance-method"
|
||||
]
|
||||
}
|
||||
],
|
||||
"no-arg": true,
|
||||
"no-bitwise": true,
|
||||
"no-console": [
|
||||
true,
|
||||
"debug",
|
||||
"info",
|
||||
"time",
|
||||
"timeEnd",
|
||||
"trace"
|
||||
],
|
||||
"no-construct": true,
|
||||
"no-debugger": true,
|
||||
"no-duplicate-super": true,
|
||||
"no-empty": false,
|
||||
"no-empty-interface": true,
|
||||
"no-eval": true,
|
||||
"no-inferrable-types": [
|
||||
true,
|
||||
"ignore-params"
|
||||
],
|
||||
"no-misused-new": true,
|
||||
"no-non-null-assertion": true,
|
||||
"no-shadowed-variable": true,
|
||||
"no-string-literal": false,
|
||||
"no-string-throw": true,
|
||||
"no-switch-case-fall-through": true,
|
||||
"no-trailing-whitespace": true,
|
||||
"no-unnecessary-initializer": true,
|
||||
"no-unused-expression": true,
|
||||
"no-var-keyword": true,
|
||||
"object-literal-sort-keys": false,
|
||||
"one-line": [
|
||||
true,
|
||||
"check-open-brace",
|
||||
"check-catch",
|
||||
"check-else",
|
||||
"check-whitespace"
|
||||
],
|
||||
"prefer-const": true,
|
||||
"quotemark": [
|
||||
true,
|
||||
"single"
|
||||
],
|
||||
"radix": true,
|
||||
"semicolon": [
|
||||
true,
|
||||
"always"
|
||||
],
|
||||
"triple-equals": [
|
||||
true,
|
||||
"allow-null-check"
|
||||
],
|
||||
"typedef-whitespace": [
|
||||
true,
|
||||
{
|
||||
"call-signature": "nospace",
|
||||
"index-signature": "nospace",
|
||||
"parameter": "nospace",
|
||||
"property-declaration": "nospace",
|
||||
"variable-declaration": "nospace"
|
||||
}
|
||||
],
|
||||
"unified-signatures": true,
|
||||
"variable-name": false,
|
||||
"whitespace": [
|
||||
true,
|
||||
"check-branch",
|
||||
"check-decl",
|
||||
"check-operator",
|
||||
"check-separator",
|
||||
"check-type"
|
||||
],
|
||||
"directive-selector": [
|
||||
true,
|
||||
"attribute",
|
||||
"app",
|
||||
"camelCase"
|
||||
],
|
||||
"component-selector": [
|
||||
true,
|
||||
"element",
|
||||
"app",
|
||||
"kebab-case"
|
||||
],
|
||||
"no-output-on-prefix": true,
|
||||
"no-inputs-metadata-property": true,
|
||||
"no-outputs-metadata-property": true,
|
||||
"no-host-metadata-property": true,
|
||||
"no-input-rename": true,
|
||||
"no-output-rename": true,
|
||||
"use-lifecycle-interface": true,
|
||||
"use-pipe-transform-interface": true,
|
||||
"component-class-suffix": true,
|
||||
"directive-class-suffix": true
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue