From 0d3ff9097783d8d5695f0c955cce0f286831efdb Mon Sep 17 00:00:00 2001 From: ShahanaFarooqui Date: Mon, 18 Mar 2019 20:13:01 -0400 Subject: [PATCH] Merging Angular pre-build code Merging Angular pre-build code --- .editorconfig | 13 + .gitignore | 103 +- angular.json | 125 ++ e2e/protractor.conf.js | 28 + e2e/src/app.e2e-spec.ts | 14 + e2e/src/app.po.ts | 11 + e2e/tsconfig.e2e.json | 13 + prebuild.js | 12 + product management/Channels Details.png | Bin 0 -> 85962 bytes product management/Channels Lookup.png | Bin 0 -> 52505 bytes product management/Channels.png | Bin 0 -> 97815 bytes product management/Home Page.png | Bin 0 -> 63267 bytes product management/Node Lookup.png | Bin 0 -> 54417 bytes product management/Peers.png | Bin 0 -> 71691 bytes product management/Start.png | Bin 0 -> 39428 bytes product management/Unlock Wallet.png | Bin 0 -> 42776 bytes product management/roadmap.md | 44 + protractor.conf.js | 28 + src/app/app.component.html | 78 ++ src/app/app.component.scss | 4 + src/app/app.component.ts | 166 +++ src/app/app.module.ts | 103 ++ src/app/app.routing.ts | 46 + .../channel-closed.component.html | 64 + .../channel-closed.component.scss | 25 + .../channel-closed.component.spec.ts | 25 + .../channel-closed.component.ts | 104 ++ .../channel-manage.component.html | 131 ++ .../channel-manage.component.scss | 50 + .../channel-manage.component.spec.ts | 25 + .../channel-manage.component.ts | 251 ++++ .../channel-pending.component.html | 252 ++++ .../channel-pending.component.scss | 6 + .../channel-pending.component.spec.ts | 25 + .../channel-pending.component.ts | 241 ++++ src/app/pages/help/help.component.html | 20 + src/app/pages/help/help.component.scss | 3 + src/app/pages/help/help.component.ts | 29 + src/app/pages/home/home.component.html | 237 ++++ src/app/pages/home/home.component.scss | 12 + src/app/pages/home/home.component.spec.ts | 25 + src/app/pages/home/home.component.ts | 148 +++ .../pages/invoices/invoices.component.html | 77 ++ .../pages/invoices/invoices.component.scss | 23 + src/app/pages/invoices/invoices.component.ts | 141 +++ .../channel-lookup.component.css | 3 + .../channel-lookup.component.html | 109 ++ .../channel-lookup.component.spec.ts | 25 + .../channel-lookup.component.ts | 40 + src/app/pages/lookups/lookups.component.html | 47 + src/app/pages/lookups/lookups.component.scss | 14 + .../pages/lookups/lookups.component.spec.ts | 25 + src/app/pages/lookups/lookups.component.ts | 94 ++ .../node-lookup/node-lookup.component.css | 7 + .../node-lookup/node-lookup.component.html | 56 + .../node-lookup/node-lookup.component.spec.ts | 25 + .../node-lookup/node-lookup.component.ts | 24 + .../horizontal-navigation.component.html | 19 + .../horizontal-navigation.component.scss | 19 + .../horizontal-navigation.component.spec.ts | 25 + .../horizontal-navigation.component.ts | 69 ++ .../side-navigation.component.html | 65 + .../side-navigation.component.scss | 0 .../side-navigation.component.spec.ts | 25 + .../side-navigation.component.ts | 153 +++ .../top-menu/top-menu.component.html | 22 + .../top-menu/top-menu.component.scss | 26 + .../top-menu/top-menu.component.spec.ts | 25 + .../navigation/top-menu/top-menu.component.ts | 93 ++ .../pages/payments/payments.component.html | 81 ++ .../pages/payments/payments.component.scss | 43 + src/app/pages/payments/payments.component.ts | 192 +++ src/app/pages/peers/peers.component.html | 87 ++ src/app/pages/peers/peers.component.scss | 30 + src/app/pages/peers/peers.component.spec.ts | 25 + src/app/pages/peers/peers.component.ts | 157 +++ .../server-config.component.html | 37 + .../server-config.component.scss | 3 + .../server-config/server-config.component.ts | 72 ++ src/app/pages/signin/signin.component.html | 22 + src/app/pages/signin/signin.component.scss | 0 src/app/pages/signin/signin.component.ts | 59 + .../switch/forwarding-history.component.html | 87 ++ .../switch/forwarding-history.component.scss | 21 + .../forwarding-history.component.spec.ts | 25 + .../switch/forwarding-history.component.ts | 123 ++ .../list-transactions.component.html | 57 + .../list-transactions.component.scss | 31 + .../list-transactions.component.spec.ts | 25 + .../list-transactions.component.ts | 110 ++ .../send-receive-trans.component.html | 163 +++ .../send-receive-trans.component.scss | 0 .../send-receive-trans.component.ts | 175 +++ .../unlock-lnd/unlock-lnd.component.html | 21 + .../unlock-lnd/unlock-lnd.component.scss | 0 .../pages/unlock-lnd/unlock-lnd.component.ts | 41 + src/app/shared/animation/row-animation.ts | 10 + .../alert-message.component.html | 35 + .../alert-message.component.scss | 40 + .../alert-message/alert-message.component.ts | 106 ++ .../confirmation-message.component.html | 39 + .../confirmation-message.component.scss | 16 + .../confirmation-message.component.ts | 107 ++ .../not-found/not-found.component.html | 16 + .../not-found/not-found.component.ts | 16 + .../settings-nav/settings-nav.component.html | 74 ++ .../settings-nav/settings-nav.component.scss | 0 .../settings-nav.component.spec.ts | 25 + .../settings-nav/settings-nav.component.ts | 80 ++ .../spinner-dialog.component.html | 6 + .../spinner-dialog.component.scss | 4 + .../spinner-dialog.component.ts | 16 + .../sso-failed/sso-failed.component.html | 15 + .../sso-failed/sso-failed.component.ts | 14 + .../directive/clipboard.directive.spec.ts | 8 + .../shared/directive/clipboard.directive.ts | 28 + src/app/shared/models/RTLconfig.ts | 31 + src/app/shared/models/alertData.ts | 15 + src/app/shared/models/errorPayload.ts | 7 + src/app/shared/models/lndModels.ts | 340 ++++++ src/app/shared/models/navMenu.ts | 39 + src/app/shared/services/auth.guard.ts | 29 + src/app/shared/services/auth.interceptor.ts | 21 + src/app/shared/services/logger.service.ts | 50 + src/app/shared/shared.module.ts | 105 ++ src/app/shared/store/rtl.actions.ts | 405 +++++++ src/app/shared/store/rtl.effects.ts | 1064 +++++++++++++++++ src/app/shared/store/rtl.reducers.ts | 265 ++++ .../theme/overlay-container/theme-overlay.ts | 12 + .../shared/theme/skins/bluegray-amber.scss | 50 + .../theme/skins/bluegray-deeppurple.scss | 50 + .../theme/skins/bluegray-lightgreen.scss | 50 + src/app/shared/theme/skins/dark-blue.scss | 5 + src/app/shared/theme/skins/dark-green.scss | 5 + src/app/shared/theme/skins/dark-pink.scss | 5 + src/app/shared/theme/skins/gray-blue.scss | 50 + src/app/shared/theme/skins/gray-lime.scss | 50 + src/app/shared/theme/skins/gray-purple.scss | 50 + src/app/shared/theme/skins/light-blue.scss | 50 + src/app/shared/theme/skins/light-red.scss | 50 + src/app/shared/theme/skins/light-teal.scss | 50 + src/app/shared/theme/skins/self-blue.scss | 83 ++ src/app/shared/theme/skins/self-brown.scss | 83 ++ src/app/shared/theme/skins/self-gray.scss | 50 + src/app/shared/theme/skins/self-green.scss | 83 ++ src/app/shared/theme/skins/self-pink.scss | 83 ++ src/app/shared/theme/skins/self-yellow.scss | 83 ++ src/app/shared/theme/styles/change-theme.scss | 63 + src/app/shared/theme/styles/constants.scss | 11 + .../theme/styles/perfect-scrollbar.scss | 100 ++ src/app/shared/theme/styles/root.scss | 782 ++++++++++++ src/app/shared/theme/styles/styles.scss | 6 + src/app/shared/theme/styles/theme.scss | 96 ++ src/assets/.gitkeep | 0 src/assets/images/RTL1.jpg | Bin 0 -> 7747 bytes src/assets/images/RTL2.jpg | Bin 0 -> 9587 bytes src/assets/images/favicon.ico | Bin 0 -> 6829 bytes src/browserslist | 11 + src/environments/environment.prod.ts | 24 + src/environments/environment.ts | 24 + src/environments/version.ts | 1 + src/index.html | 13 + src/karma.conf.js | 31 + src/main.ts | 12 + src/polyfills.ts | 80 ++ src/test.ts | 20 + src/tsconfig.app.json | 11 + src/tsconfig.spec.json | 18 + src/tslint.json | 17 + tsconfig.json | 20 + tslint.json | 141 +++ 171 files changed, 10788 insertions(+), 60 deletions(-) create mode 100644 .editorconfig create mode 100644 angular.json create mode 100644 e2e/protractor.conf.js create mode 100644 e2e/src/app.e2e-spec.ts create mode 100644 e2e/src/app.po.ts create mode 100644 e2e/tsconfig.e2e.json create mode 100644 prebuild.js create mode 100644 product management/Channels Details.png create mode 100644 product management/Channels Lookup.png create mode 100644 product management/Channels.png create mode 100644 product management/Home Page.png create mode 100644 product management/Node Lookup.png create mode 100644 product management/Peers.png create mode 100644 product management/Start.png create mode 100644 product management/Unlock Wallet.png create mode 100644 product management/roadmap.md create mode 100644 protractor.conf.js create mode 100644 src/app/app.component.html create mode 100644 src/app/app.component.scss create mode 100644 src/app/app.component.ts create mode 100644 src/app/app.module.ts create mode 100644 src/app/app.routing.ts create mode 100644 src/app/pages/channels/channel-closed/channel-closed.component.html create mode 100644 src/app/pages/channels/channel-closed/channel-closed.component.scss create mode 100644 src/app/pages/channels/channel-closed/channel-closed.component.spec.ts create mode 100644 src/app/pages/channels/channel-closed/channel-closed.component.ts create mode 100644 src/app/pages/channels/channel-manage/channel-manage.component.html create mode 100644 src/app/pages/channels/channel-manage/channel-manage.component.scss create mode 100644 src/app/pages/channels/channel-manage/channel-manage.component.spec.ts create mode 100644 src/app/pages/channels/channel-manage/channel-manage.component.ts create mode 100644 src/app/pages/channels/channel-pending/channel-pending.component.html create mode 100644 src/app/pages/channels/channel-pending/channel-pending.component.scss create mode 100644 src/app/pages/channels/channel-pending/channel-pending.component.spec.ts create mode 100644 src/app/pages/channels/channel-pending/channel-pending.component.ts create mode 100644 src/app/pages/help/help.component.html create mode 100644 src/app/pages/help/help.component.scss create mode 100644 src/app/pages/help/help.component.ts create mode 100644 src/app/pages/home/home.component.html create mode 100644 src/app/pages/home/home.component.scss create mode 100644 src/app/pages/home/home.component.spec.ts create mode 100644 src/app/pages/home/home.component.ts create mode 100644 src/app/pages/invoices/invoices.component.html create mode 100644 src/app/pages/invoices/invoices.component.scss create mode 100644 src/app/pages/invoices/invoices.component.ts create mode 100644 src/app/pages/lookups/channel-lookup/channel-lookup.component.css create mode 100644 src/app/pages/lookups/channel-lookup/channel-lookup.component.html create mode 100644 src/app/pages/lookups/channel-lookup/channel-lookup.component.spec.ts create mode 100644 src/app/pages/lookups/channel-lookup/channel-lookup.component.ts create mode 100644 src/app/pages/lookups/lookups.component.html create mode 100644 src/app/pages/lookups/lookups.component.scss create mode 100644 src/app/pages/lookups/lookups.component.spec.ts create mode 100644 src/app/pages/lookups/lookups.component.ts create mode 100644 src/app/pages/lookups/node-lookup/node-lookup.component.css create mode 100644 src/app/pages/lookups/node-lookup/node-lookup.component.html create mode 100644 src/app/pages/lookups/node-lookup/node-lookup.component.spec.ts create mode 100644 src/app/pages/lookups/node-lookup/node-lookup.component.ts create mode 100644 src/app/pages/navigation/horizontal-navigation/horizontal-navigation.component.html create mode 100644 src/app/pages/navigation/horizontal-navigation/horizontal-navigation.component.scss create mode 100644 src/app/pages/navigation/horizontal-navigation/horizontal-navigation.component.spec.ts create mode 100644 src/app/pages/navigation/horizontal-navigation/horizontal-navigation.component.ts create mode 100644 src/app/pages/navigation/side-navigation/side-navigation.component.html create mode 100644 src/app/pages/navigation/side-navigation/side-navigation.component.scss create mode 100644 src/app/pages/navigation/side-navigation/side-navigation.component.spec.ts create mode 100644 src/app/pages/navigation/side-navigation/side-navigation.component.ts create mode 100644 src/app/pages/navigation/top-menu/top-menu.component.html create mode 100644 src/app/pages/navigation/top-menu/top-menu.component.scss create mode 100644 src/app/pages/navigation/top-menu/top-menu.component.spec.ts create mode 100644 src/app/pages/navigation/top-menu/top-menu.component.ts create mode 100644 src/app/pages/payments/payments.component.html create mode 100644 src/app/pages/payments/payments.component.scss create mode 100644 src/app/pages/payments/payments.component.ts create mode 100644 src/app/pages/peers/peers.component.html create mode 100644 src/app/pages/peers/peers.component.scss create mode 100644 src/app/pages/peers/peers.component.spec.ts create mode 100644 src/app/pages/peers/peers.component.ts create mode 100644 src/app/pages/server-config/server-config.component.html create mode 100644 src/app/pages/server-config/server-config.component.scss create mode 100644 src/app/pages/server-config/server-config.component.ts create mode 100644 src/app/pages/signin/signin.component.html create mode 100644 src/app/pages/signin/signin.component.scss create mode 100644 src/app/pages/signin/signin.component.ts create mode 100644 src/app/pages/switch/forwarding-history.component.html create mode 100644 src/app/pages/switch/forwarding-history.component.scss create mode 100644 src/app/pages/switch/forwarding-history.component.spec.ts create mode 100644 src/app/pages/switch/forwarding-history.component.ts create mode 100644 src/app/pages/transactions/list-transactions/list-transactions.component.html create mode 100644 src/app/pages/transactions/list-transactions/list-transactions.component.scss create mode 100644 src/app/pages/transactions/list-transactions/list-transactions.component.spec.ts create mode 100644 src/app/pages/transactions/list-transactions/list-transactions.component.ts create mode 100644 src/app/pages/transactions/send-receive/send-receive-trans.component.html create mode 100644 src/app/pages/transactions/send-receive/send-receive-trans.component.scss create mode 100644 src/app/pages/transactions/send-receive/send-receive-trans.component.ts create mode 100644 src/app/pages/unlock-lnd/unlock-lnd.component.html create mode 100644 src/app/pages/unlock-lnd/unlock-lnd.component.scss create mode 100644 src/app/pages/unlock-lnd/unlock-lnd.component.ts create mode 100644 src/app/shared/animation/row-animation.ts create mode 100644 src/app/shared/components/alert-message/alert-message.component.html create mode 100644 src/app/shared/components/alert-message/alert-message.component.scss create mode 100644 src/app/shared/components/alert-message/alert-message.component.ts create mode 100644 src/app/shared/components/confirmation-message/confirmation-message.component.html create mode 100644 src/app/shared/components/confirmation-message/confirmation-message.component.scss create mode 100644 src/app/shared/components/confirmation-message/confirmation-message.component.ts create mode 100644 src/app/shared/components/not-found/not-found.component.html create mode 100644 src/app/shared/components/not-found/not-found.component.ts create mode 100644 src/app/shared/components/settings-nav/settings-nav.component.html create mode 100644 src/app/shared/components/settings-nav/settings-nav.component.scss create mode 100644 src/app/shared/components/settings-nav/settings-nav.component.spec.ts create mode 100644 src/app/shared/components/settings-nav/settings-nav.component.ts create mode 100644 src/app/shared/components/spinner-dialog/spinner-dialog.component.html create mode 100644 src/app/shared/components/spinner-dialog/spinner-dialog.component.scss create mode 100644 src/app/shared/components/spinner-dialog/spinner-dialog.component.ts create mode 100644 src/app/shared/components/sso-failed/sso-failed.component.html create mode 100644 src/app/shared/components/sso-failed/sso-failed.component.ts create mode 100644 src/app/shared/directive/clipboard.directive.spec.ts create mode 100644 src/app/shared/directive/clipboard.directive.ts create mode 100644 src/app/shared/models/RTLconfig.ts create mode 100644 src/app/shared/models/alertData.ts create mode 100644 src/app/shared/models/errorPayload.ts create mode 100644 src/app/shared/models/lndModels.ts create mode 100644 src/app/shared/models/navMenu.ts create mode 100644 src/app/shared/services/auth.guard.ts create mode 100644 src/app/shared/services/auth.interceptor.ts create mode 100644 src/app/shared/services/logger.service.ts create mode 100644 src/app/shared/shared.module.ts create mode 100644 src/app/shared/store/rtl.actions.ts create mode 100644 src/app/shared/store/rtl.effects.ts create mode 100644 src/app/shared/store/rtl.reducers.ts create mode 100644 src/app/shared/theme/overlay-container/theme-overlay.ts create mode 100644 src/app/shared/theme/skins/bluegray-amber.scss create mode 100644 src/app/shared/theme/skins/bluegray-deeppurple.scss create mode 100644 src/app/shared/theme/skins/bluegray-lightgreen.scss create mode 100644 src/app/shared/theme/skins/dark-blue.scss create mode 100644 src/app/shared/theme/skins/dark-green.scss create mode 100644 src/app/shared/theme/skins/dark-pink.scss create mode 100644 src/app/shared/theme/skins/gray-blue.scss create mode 100644 src/app/shared/theme/skins/gray-lime.scss create mode 100644 src/app/shared/theme/skins/gray-purple.scss create mode 100644 src/app/shared/theme/skins/light-blue.scss create mode 100644 src/app/shared/theme/skins/light-red.scss create mode 100644 src/app/shared/theme/skins/light-teal.scss create mode 100644 src/app/shared/theme/skins/self-blue.scss create mode 100644 src/app/shared/theme/skins/self-brown.scss create mode 100644 src/app/shared/theme/skins/self-gray.scss create mode 100644 src/app/shared/theme/skins/self-green.scss create mode 100644 src/app/shared/theme/skins/self-pink.scss create mode 100644 src/app/shared/theme/skins/self-yellow.scss create mode 100644 src/app/shared/theme/styles/change-theme.scss create mode 100644 src/app/shared/theme/styles/constants.scss create mode 100644 src/app/shared/theme/styles/perfect-scrollbar.scss create mode 100644 src/app/shared/theme/styles/root.scss create mode 100644 src/app/shared/theme/styles/styles.scss create mode 100644 src/app/shared/theme/styles/theme.scss create mode 100644 src/assets/.gitkeep create mode 100644 src/assets/images/RTL1.jpg create mode 100644 src/assets/images/RTL2.jpg create mode 100644 src/assets/images/favicon.ico create mode 100644 src/browserslist create mode 100644 src/environments/environment.prod.ts create mode 100644 src/environments/environment.ts create mode 100644 src/environments/version.ts create mode 100644 src/index.html create mode 100644 src/karma.conf.js create mode 100644 src/main.ts create mode 100644 src/polyfills.ts create mode 100644 src/test.ts create mode 100644 src/tsconfig.app.json create mode 100644 src/tsconfig.spec.json create mode 100644 src/tslint.json create mode 100644 tsconfig.json create mode 100644 tslint.json diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..21968762 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +# Editor configuration, see http://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = tab +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/.gitignore b/.gitignore index 57154db7..4b4bf590 100644 --- a/.gitignore +++ b/.gitignore @@ -1,60 +1,43 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (http://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# Typescript v1 declaration files -typings/ - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env - -RTL.conf \ No newline at end of file +# See http://help.github.com/ignore-files/ for more about ignoring files. +# compiled output +/dist +/tmp +/out-tsc + +# dependencies +/node_modules + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +# misc +/.sass-cache +/connect.lock +/coverage +/libpeerconnection.log +npm-debug.log +yarn-error.log +testem.log +/typings + +# System Files +.DS_Store +Thumbs.db + +RTL.conf +/logs +/cookies +RTL.log diff --git a/angular.json b/angular.json new file mode 100644 index 00000000..7668ef9f --- /dev/null +++ b/angular.json @@ -0,0 +1,125 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "RTLApp": { + "root": "", + "sourceRoot": "src", + "projectType": "application", + "prefix": "rtl", + "schematics": {}, + "targets": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "angular", + "index": "src/index.html", + "main": "src/main.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "src/tsconfig.app.json", + "assets": [ + "src/assets" + ], + "styles": [ + "src/app/shared/theme/styles/styles.scss" + ], + "scripts": [] + }, + "configurations": { + "production": { + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ], + "optimization": true, + "outputHashing": "all", + "sourceMap": false, + "extractCss": true, + "namedChunks": false, + "aot": true, + "extractLicenses": true, + "vendorChunk": false, + "buildOptimizer": true + } + } + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "options": { + "browserTarget": "RTLApp:build" + }, + "configurations": { + "production": { + "browserTarget": "RTLApp:build:production" + } + } + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "RTLApp:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "src/test.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "src/tsconfig.spec.json", + "karmaConfig": "src/karma.conf.js", + "styles": [ + "src/app/shared/theme/styles/styles.scss" + ], + "scripts": [], + "assets": [ + "src/assets" + ] + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": [ + "src/tsconfig.app.json", + "src/tsconfig.spec.json" + ], + "exclude": [ + "**/node_modules/**" + ] + } + } + } + }, + "RTLApp-e2e": { + "root": "e2e/", + "projectType": "application", + "targets": { + "e2e": { + "builder": "@angular-devkit/build-angular:protractor", + "options": { + "protractorConfig": "e2e/protractor.conf.js", + "devServerTarget": "RTLApp:serve" + }, + "configurations": { + "production": { + "devServerTarget": "RTLApp:serve:production" + } + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": "e2e/tsconfig.e2e.json", + "exclude": [ + "**/node_modules/**" + ] + } + } + } + } + }, + "defaultProject": "RTLApp" +} \ No newline at end of file diff --git a/e2e/protractor.conf.js b/e2e/protractor.conf.js new file mode 100644 index 00000000..86776a39 --- /dev/null +++ b/e2e/protractor.conf.js @@ -0,0 +1,28 @@ +// Protractor configuration file, see link for more information +// https://github.com/angular/protractor/blob/master/lib/config.ts + +const { SpecReporter } = require('jasmine-spec-reporter'); + +exports.config = { + allScriptsTimeout: 11000, + specs: [ + './src/**/*.e2e-spec.ts' + ], + capabilities: { + 'browserName': 'chrome' + }, + directConnect: true, + baseUrl: 'http://localhost:4200/', + framework: 'jasmine', + jasmineNodeOpts: { + showColors: true, + defaultTimeoutInterval: 30000, + print: function() {} + }, + onPrepare() { + require('ts-node').register({ + project: require('path').join(__dirname, './tsconfig.e2e.json') + }); + jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); + } +}; \ No newline at end of file diff --git a/e2e/src/app.e2e-spec.ts b/e2e/src/app.e2e-spec.ts new file mode 100644 index 00000000..1d80d64a --- /dev/null +++ b/e2e/src/app.e2e-spec.ts @@ -0,0 +1,14 @@ +import { AppPage } from './app.po'; + +describe('workspace-project App', () => { + let page: AppPage; + + beforeEach(() => { + page = new AppPage(); + }); + + it('should display welcome message', () => { + page.navigateTo(); + expect(page.getParagraphText()).toEqual('Welcome to RTLApp!'); + }); +}); diff --git a/e2e/src/app.po.ts b/e2e/src/app.po.ts new file mode 100644 index 00000000..82ea75ba --- /dev/null +++ b/e2e/src/app.po.ts @@ -0,0 +1,11 @@ +import { browser, by, element } from 'protractor'; + +export class AppPage { + navigateTo() { + return browser.get('/'); + } + + getParagraphText() { + return element(by.css('app-root h1')).getText(); + } +} diff --git a/e2e/tsconfig.e2e.json b/e2e/tsconfig.e2e.json new file mode 100644 index 00000000..a6dd6220 --- /dev/null +++ b/e2e/tsconfig.e2e.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/app", + "module": "commonjs", + "target": "es5", + "types": [ + "jasmine", + "jasminewd2", + "node" + ] + } +} \ No newline at end of file diff --git a/prebuild.js b/prebuild.js new file mode 100644 index 00000000..b05e3772 --- /dev/null +++ b/prebuild.js @@ -0,0 +1,12 @@ +const path = require('path'); +const fs = require('fs'); +const appVersion = require('./package.json').version; +const versionFilePath = path.join(__dirname + '/src/environments/version.ts'); +const versionStr = `export const VERSION = '${appVersion}';`; +fs.writeFile(versionFilePath, versionStr, { flat: 'w' }, function (err) { + if (err) { + return console.log(err); + } + console.log(`Updating application version ${appVersion}`); + console.log(`${'Writing version module to '}${versionFilePath}\n`); +}); diff --git a/product management/Channels Details.png b/product management/Channels Details.png new file mode 100644 index 0000000000000000000000000000000000000000..b95029dddb34840d934f7443ca776877e92f7ae5 GIT binary patch literal 85962 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 z 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 literal 0 HcmV?d00001 diff --git a/product management/Channels Lookup.png b/product management/Channels Lookup.png new file mode 100644 index 0000000000000000000000000000000000000000..4dc94001d27d28685fcc0b29e016002224024344 GIT binary patch literal 52505 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

y>|g@xp}#7FkD@e_Kr+zsZJJ3~{cu)~tK~ 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

!86e4;k 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 z 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 literal 0 HcmV?d00001 diff --git a/product management/Home Page.png b/product management/Home Page.png new file mode 100644 index 0000000000000000000000000000000000000000..91b8e6a707fe1607db65567304f928829502025e GIT binary patch literal 63267 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 literal 0 HcmV?d00001 diff --git a/product management/Node Lookup.png b/product management/Node Lookup.png new file mode 100644 index 0000000000000000000000000000000000000000..8c7b7e30b90665937007040a8a102bea879ef21b GIT binary patch literal 54417 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%0AsQ&G_CZmqoMv|Uhz@G6BXv9%h$JHOYoNK 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

3{*PHS#920o5_n8P-7sCHxaTLdwFH~ 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

6Rq)g#86R0$l~2!UB7pgRgm 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 oA6;ikaVi0QDAi6Mf7I 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 X9@Gmpe`J0L{->;q{QCc{ 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 YyMdQ5k8Ah#>cGo&7lmBzbm-jw0Aw9M2><{9 literal 0 HcmV?d00001 diff --git a/product management/roadmap.md b/product management/roadmap.md new file mode 100644 index 00000000..d0b2ae4d --- /dev/null +++ b/product management/roadmap.md @@ -0,0 +1,44 @@ +# Product Roadmap for RTL Application + +## Version 0.0.1-alpha (Minimum Viable Product) + +Start +- Unlock Wallet + +Home Page +- Wallet Balance +- Channel Balance +- Channel Status +- Chain Sync Status +- Fee Report + +Peer Management +- Listing of Connected Peers +- Initiate Connection with peers with the public key + +Channel Management +- Status of Channels (Active, Inactive, Pending) +- Listing of Channels +- Open Channel with connected peers + +## Version 0.0.2 +Globalization - Allow for Language customization + +## Feature Backlog +Start +- Create Wallet + + Home Page +- Network Status + +Channel Management +- Channel Detail - Bi-Directional channel balance view +- Close Channel + +LN Wallet +- Generate pub key to recieve Bitcoin +- Send Bitcoin to an address + +Payments +- Decode payment request +- Send payment diff --git a/protractor.conf.js b/protractor.conf.js new file mode 100644 index 00000000..7ee3b5ee --- /dev/null +++ b/protractor.conf.js @@ -0,0 +1,28 @@ +// Protractor configuration file, see link for more information +// https://github.com/angular/protractor/blob/master/lib/config.ts + +const { SpecReporter } = require('jasmine-spec-reporter'); + +exports.config = { + allScriptsTimeout: 11000, + specs: [ + './e2e/**/*.e2e-spec.ts' + ], + capabilities: { + 'browserName': 'chrome' + }, + directConnect: true, + baseUrl: 'http://localhost:4200/', + framework: 'jasmine', + jasmineNodeOpts: { + showColors: true, + defaultTimeoutInterval: 30000, + print: function() {} + }, + onPrepare() { + require('ts-node').register({ + project: 'e2e/tsconfig.e2e.json' + }); + jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); + } +}; diff --git a/src/app/app.component.html b/src/app/app.component.html new file mode 100644 index 00000000..50d2776a --- /dev/null +++ b/src/app/app.component.html @@ -0,0 +1,78 @@ +

+ + + + + +
+ +
+ +
+
+

Ride The Lightning (Beta)

+
+
+ +
+
+
+ vpn_key +
 {{information?.identity_pubkey}} + + file_copyCopied +
+
+ +
+ +
+
+
+ + +
+ +
+
+ settings +
+
+ + + +
+
+ +

Loading RTL...

+
+
diff --git a/src/app/app.component.scss b/src/app/app.component.scss new file mode 100644 index 00000000..3c613452 --- /dev/null +++ b/src/app/app.component.scss @@ -0,0 +1,4 @@ +.inline-spinner { + display: inline-flex !important; + top: 0px !important; +} diff --git a/src/app/app.component.ts b/src/app/app.component.ts new file mode 100644 index 00000000..d994d495 --- /dev/null +++ b/src/app/app.component.ts @@ -0,0 +1,166 @@ +import { Component, OnInit, AfterViewInit, OnDestroy, ViewChild, HostListener } from '@angular/core'; +import { Router } from '@angular/router'; +import { Subject } from 'rxjs'; +import { takeUntil, filter } from 'rxjs/operators'; +import { Store } from '@ngrx/store'; +import { Actions } from '@ngrx/effects'; +import { UserIdleService } from 'angular-user-idle'; + +import { LoggerService } from './shared/services/logger.service'; +import { Settings, Authentication } from './shared/models/RTLconfig'; +import { GetInfo } from './shared/models/lndModels'; + +import * as RTLActions from './shared/store/rtl.actions'; +import * as fromRTLReducer from './shared/store/rtl.reducers'; + +@Component({ + selector: 'rtl-app', + templateUrl: './app.component.html', + styleUrls: ['./app.component.scss'] +}) +export class AppComponent implements OnInit, AfterViewInit, OnDestroy { + @ViewChild('sideNavigation') sideNavigation: any; + @ViewChild('settingSidenav') settingSidenav: any; + public information: GetInfo = {}; + public flgLoading: Array = [true]; // 0: Info + public flgCopied = false; + public settings: Settings; + public authSettings: Authentication; + public accessKey = ''; + public smallScreen = false; + unsubs: Array> = [new Subject(), new Subject(), new Subject()]; + + constructor(private logger: LoggerService, private store: Store, private actions$: Actions, + private userIdle: UserIdleService, private router: Router) {} + + ngOnInit() { + this.store.dispatch(new RTLActions.FetchSettings()); + this.accessKey = this.readAccessKey(); + this.store.select('rtlRoot') + .pipe(takeUntil(this.unsubs[0])) + .subscribe(rtlStore => { + this.settings = rtlStore.settings; + this.information = rtlStore.information; + this.authSettings = rtlStore.authSettings; + this.flgLoading[0] = (undefined !== this.information.identity_pubkey) ? false : true; + if (window.innerWidth <= 768) { + this.settings.menu = 'Vertical'; + this.settings.flgSidenavOpened = false; + this.settings.flgSidenavPinned = false; + } + if (window.innerWidth <= 414) { + this.smallScreen = true; + } + this.logger.info(this.settings); + if (!sessionStorage.getItem('token')) { + this.flgLoading[0] = false; + } + }); + if (sessionStorage.getItem('token')) { + this.store.dispatch(new RTLActions.FetchInfo()); + } + this.actions$ + .pipe( + takeUntil(this.unsubs[1]), + filter((action) => action.type === RTLActions.INIT_APP_DATA || action.type === RTLActions.SET_SETTINGS || action.type === RTLActions.SET_AUTH_SETTINGS) + ).subscribe((actionPayload: (RTLActions.InitAppData | RTLActions.SetSettings | RTLActions.SetAuthSettings)) => { + if (actionPayload.type === RTLActions.SET_AUTH_SETTINGS) { + if (!sessionStorage.getItem('token')) { + if (+actionPayload.payload.rtlSSO) { + this.store.dispatch(new RTLActions.Signin(window.btoa(this.accessKey))); + } else { + this.router.navigate([this.authSettings.logoutRedirectLink]); + } + } + } else if (actionPayload.type === RTLActions.INIT_APP_DATA) { + this.store.dispatch(new RTLActions.FetchInfo()); + } else if (actionPayload.type === RTLActions.SET_SETTINGS) { + if (this.settings.menu === 'Horizontal') { + this.settingSidenav.toggle(); // To dynamically update the width to 100% after side nav is closed + setTimeout(() => { this.settingSidenav.toggle(); }, 100); + } + } + }); + this.actions$ + .pipe( + takeUntil(this.unsubs[1]), + filter((action) => action.type === RTLActions.SET_INFO) + ).subscribe((infoData: RTLActions.SetInfo) => { + if (undefined !== infoData.payload.identity_pubkey) { + this.initializeRemainingData(); + } + }); + this.userIdle.startWatching(); + this.userIdle.onTimerStart().subscribe(count => {}); + this.userIdle.onTimeout().subscribe(() => { + if (sessionStorage.getItem('token')) { + this.logger.warn('Time limit exceeded for session inactivity! Logging out!'); + this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: { + type: 'WARN', + titleMessage: 'Time limit exceeded for session inactivity! Logging out!' + }})); + this.store.dispatch(new RTLActions.Signout()); + this.userIdle.resetTimer(); + } + }); + } + + private readAccessKey() { + const url = window.location.href; + return url.substring(url.lastIndexOf('/') + 1); + } + + initializeRemainingData() { + this.store.dispatch(new RTLActions.FetchPeers()); + this.store.dispatch(new RTLActions.FetchBalance('channels')); + this.store.dispatch(new RTLActions.FetchFees()); + this.store.dispatch(new RTLActions.FetchNetwork()); + this.store.dispatch(new RTLActions.FetchChannels({routeParam: 'all', channelStatus: ''})); + this.store.dispatch(new RTLActions.FetchChannels({routeParam: 'pending', channelStatus: ''})); + this.store.dispatch(new RTLActions.FetchInvoices()); + this.store.dispatch(new RTLActions.FetchPayments()); + } + + ngAfterViewInit() { + if (!this.settings.flgSidenavPinned) { + this.sideNavigation.close(); + this.settingSidenav.toggle(); + } + if (window.innerWidth <= 768) { + this.sideNavigation.close(); + this.settingSidenav.toggle(); + } + } + + @HostListener('window:resize') + public onWindowResize(): void { + if (window.innerWidth <= 768) { + this.settings.menu = 'Vertical'; + this.settings.flgSidenavOpened = false; + this.settings.flgSidenavPinned = false; + } + } + + sideNavToggle() { + this.sideNavigation.toggle(); + } + + onNavigationClicked(event: any) { + if (window.innerWidth <= 414) { + this.sideNavigation.close(); + } + } + + copiedText(payload) { + this.flgCopied = true; + setTimeout(() => {this.flgCopied = false; }, 5000); + this.logger.info('Copied Text: ' + payload); + } + + ngOnDestroy() { + this.unsubs.forEach(unsub => { + unsub.next(); + unsub.complete(); + }); + } +} diff --git a/src/app/app.module.ts b/src/app/app.module.ts new file mode 100644 index 00000000..f4fdd850 --- /dev/null +++ b/src/app/app.module.ts @@ -0,0 +1,103 @@ +import { BrowserModule } from '@angular/platform-browser'; +import { NgModule } from '@angular/core'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; +import { StoreModule } from '@ngrx/store'; +import { EffectsModule } from '@ngrx/effects'; +import { StoreDevtoolsModule } from '@ngrx/store-devtools'; +import { UserIdleModule } from 'angular-user-idle'; + +import { OverlayContainer } from '@angular/cdk/overlay'; +import { NgxChartsModule } from '@swimlane/ngx-charts'; + +import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar'; +import { PERFECT_SCROLLBAR_CONFIG } from 'ngx-perfect-scrollbar'; +import { PerfectScrollbarConfigInterface } from 'ngx-perfect-scrollbar'; + +const DEFAULT_PERFECT_SCROLLBAR_CONFIG: PerfectScrollbarConfigInterface = { + suppressScrollX: false +}; + +import { environment } from '../environments/environment'; +import { routing } from './app.routing'; +import { SharedModule } from './shared/shared.module'; +import { ThemeOverlay } from './shared/theme/overlay-container/theme-overlay'; +import { AppComponent } from './app.component'; +import { HomeComponent } from './pages/home/home.component'; +import { PeersComponent } from './pages/peers/peers.component'; +import { SendReceiveTransComponent } from './pages/transactions/send-receive/send-receive-trans.component'; +import { InvoicesComponent } from './pages/invoices/invoices.component'; +import { ServerConfigComponent } from './pages/server-config/server-config.component'; +import { HelpComponent } from './pages/help/help.component'; +import { UnlockLNDComponent } from './pages/unlock-lnd/unlock-lnd.component'; +import { PaymentsComponent } from './pages/payments/payments.component'; +import { SideNavigationComponent } from './pages/navigation/side-navigation/side-navigation.component'; +import { TopMenuComponent } from './pages/navigation/top-menu/top-menu.component'; +import { HorizontalNavigationComponent } from './pages/navigation/horizontal-navigation/horizontal-navigation.component'; +import { ChannelManageComponent } from './pages/channels/channel-manage/channel-manage.component'; +import { ChannelPendingComponent } from './pages/channels/channel-pending/channel-pending.component'; +import { SigninComponent } from './pages/signin/signin.component'; + +import { RTLRootReducer } from './shared/store/rtl.reducers'; +import { RTLEffects } from './shared/store/rtl.effects'; + +import { LoggerService, ConsoleLoggerService } from './shared/services/logger.service'; +import { AuthGuard, LNDUnlockedGuard } from './shared/services/auth.guard'; +import { AuthInterceptor } from './shared/services/auth.interceptor'; +import { ChannelClosedComponent } from './pages/channels/channel-closed/channel-closed.component'; +import { ListTransactionsComponent } from './pages/transactions/list-transactions/list-transactions.component'; +import { LookupsComponent } from './pages/lookups/lookups.component'; +import { ForwardingHistoryComponent } from './pages/switch/forwarding-history.component'; +import { ChannelLookupComponent } from './pages/lookups/channel-lookup/channel-lookup.component'; +import { NodeLookupComponent } from './pages/lookups/node-lookup/node-lookup.component'; + +@NgModule({ + imports: [ + BrowserModule, + BrowserAnimationsModule, + FormsModule, + ReactiveFormsModule, + HttpClientModule, + PerfectScrollbarModule, + SharedModule, + NgxChartsModule, + routing, + UserIdleModule.forRoot({idle: 60 * 60, timeout: 1, ping: null}), + StoreModule.forRoot({rtlRoot: RTLRootReducer}), + EffectsModule.forRoot([RTLEffects]), + !environment.production ? StoreDevtoolsModule.instrument() : [] + ], + declarations: [ + AppComponent, + HomeComponent, + PeersComponent, + SendReceiveTransComponent, + InvoicesComponent, + ServerConfigComponent, + HelpComponent, + UnlockLNDComponent, + PaymentsComponent, + SideNavigationComponent, + TopMenuComponent, + HorizontalNavigationComponent, + ChannelManageComponent, + ChannelPendingComponent, + SigninComponent, + ChannelClosedComponent, + ListTransactionsComponent, + LookupsComponent, + ForwardingHistoryComponent, + ChannelLookupComponent, + NodeLookupComponent + ], + providers: [ + { provide: LoggerService, useClass: ConsoleLoggerService }, + { provide: PERFECT_SCROLLBAR_CONFIG, useValue: DEFAULT_PERFECT_SCROLLBAR_CONFIG }, + { provide: OverlayContainer, useClass: ThemeOverlay }, + { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }, + AuthGuard, LNDUnlockedGuard + ], + bootstrap: [AppComponent] +}) +export class AppModule {} diff --git a/src/app/app.routing.ts b/src/app/app.routing.ts new file mode 100644 index 00000000..3918f710 --- /dev/null +++ b/src/app/app.routing.ts @@ -0,0 +1,46 @@ +import { Routes, RouterModule } from '@angular/router'; +import { ModuleWithProviders } from '@angular/core'; + +import { NotFoundComponent } from './shared/components/not-found/not-found.component'; + +import { HomeComponent } from './pages/home/home.component'; +import { UnlockLNDComponent } from './pages/unlock-lnd/unlock-lnd.component'; +import { ChannelClosedComponent } from './pages/channels/channel-closed/channel-closed.component'; +import { ChannelManageComponent } from './pages/channels/channel-manage/channel-manage.component'; +import { ChannelPendingComponent } from './pages/channels/channel-pending/channel-pending.component'; +import { PeersComponent } from './pages/peers/peers.component'; +import { SendReceiveTransComponent } from './pages/transactions/send-receive/send-receive-trans.component'; +import { ListTransactionsComponent } from './pages/transactions/list-transactions/list-transactions.component'; +import { PaymentsComponent } from './pages/payments/payments.component'; +import { ServerConfigComponent } from './pages/server-config/server-config.component'; +import { HelpComponent } from './pages/help/help.component'; +import { InvoicesComponent } from './pages/invoices/invoices.component'; +import { LookupsComponent } from './pages/lookups/lookups.component'; +import { SigninComponent } from './pages/signin/signin.component'; +import { ForwardingHistoryComponent } from './pages/switch/forwarding-history.component'; +import { SsoFailedComponent } from './shared/components/sso-failed/sso-failed.component'; + +import { AuthGuard, LNDUnlockedGuard } from './shared/services/auth.guard'; + +export const routes: Routes = [ + { path: '', redirectTo: '/home', pathMatch: 'full', canActivate: [AuthGuard, LNDUnlockedGuard] }, + { path: 'unlocklnd', component: UnlockLNDComponent, canActivate: [AuthGuard] }, + { path: 'home', component: HomeComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, + { path: 'peers', component: PeersComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, + { path: 'chnlclosed', component: ChannelClosedComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, + { path: 'chnlmanage', component: ChannelManageComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, + { path: 'chnlpending', component: ChannelPendingComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, + { path: 'transsendreceive', component: SendReceiveTransComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, + { path: 'translist', component: ListTransactionsComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, + { path: 'payments', component: PaymentsComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, + { path: 'invoices', component: InvoicesComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, + { path: 'switch', component: ForwardingHistoryComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, + { path: 'lookups', component: LookupsComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, + { path: 'sconfig', component: ServerConfigComponent, canActivate: [AuthGuard] }, + { path: 'login', component: SigninComponent }, + { path: 'help', component: HelpComponent }, + { path: 'ssoerror', component: SsoFailedComponent }, + { path: '**', component: NotFoundComponent } +]; + +export const routing: ModuleWithProviders = RouterModule.forRoot(routes, { enableTracing: true }); diff --git a/src/app/pages/channels/channel-closed/channel-closed.component.html b/src/app/pages/channels/channel-closed/channel-closed.component.html new file mode 100644 index 00000000..bf79c325 --- /dev/null +++ b/src/app/pages/channels/channel-closed/channel-closed.component.html @@ -0,0 +1,64 @@ +
+
+ + + +

Closed Channels

+
+
+ +
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Close Type {{channel.close_type || 'COOPERATIVE_CLOSE'}} Channel Point {{channel.channel_point | slice:0:10}}... ID {{channel.chan_id}} Closing Txn Hash +
{{channel.closing_tx_hash | slice:0:10}}...
Pub Key +
{{channel.remote_pubkey | slice:0:10}}...
Capacity {{channel.capacity | number}} Close Height {{channel.close_height | number}} Settled Balance {{channel.settled_balance | number}} Time Locked Balance {{channel.time_locked_balance | number}}
+
+
+
+
+
+ \ No newline at end of file diff --git a/src/app/pages/channels/channel-closed/channel-closed.component.scss b/src/app/pages/channels/channel-closed/channel-closed.component.scss new file mode 100644 index 00000000..801fe9ca --- /dev/null +++ b/src/app/pages/channels/channel-closed/channel-closed.component.scss @@ -0,0 +1,25 @@ +.mat-column-close_type { + flex: 0 0 16%; + min-width: 160px; +} + +.mat-column-chan_id { + flex: 0 0 17%; + min-width: 170px; +} + +table { + width:100%; +} + +.table-container { + height: 79vh; + overflow: auto; +} + +@media screen and (max-width: 414px) { + .table-container { + height: 68vh; + overflow: auto; + } +} diff --git a/src/app/pages/channels/channel-closed/channel-closed.component.spec.ts b/src/app/pages/channels/channel-closed/channel-closed.component.spec.ts new file mode 100644 index 00000000..325af666 --- /dev/null +++ b/src/app/pages/channels/channel-closed/channel-closed.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ChannelClosedComponent } from './channel-closed.component'; + +describe('ChannelClosedComponent', () => { + let component: ChannelClosedComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ChannelClosedComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ChannelClosedComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/channels/channel-closed/channel-closed.component.ts b/src/app/pages/channels/channel-closed/channel-closed.component.ts new file mode 100644 index 00000000..099cde55 --- /dev/null +++ b/src/app/pages/channels/channel-closed/channel-closed.component.ts @@ -0,0 +1,104 @@ +import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; +import { Store } from '@ngrx/store'; + +import { MatTableDataSource, MatSort } from '@angular/material'; +import { ClosedChannel } from '../../../shared/models/lndModels'; +import { LoggerService } from '../../../shared/services/logger.service'; + +import { RTLEffects } from '../../../shared/store/rtl.effects'; +import * as RTLActions from '../../../shared/store/rtl.actions'; +import * as fromRTLReducer from '../../../shared/store/rtl.reducers'; + +@Component({ + selector: 'rtl-channel-closed', + templateUrl: './channel-closed.component.html', + styleUrls: ['./channel-closed.component.scss'] +}) +export class ChannelClosedComponent implements OnInit, OnDestroy { + @ViewChild(MatSort) sort: MatSort; + public displayedColumns = []; + public closedChannels: any; + public flgLoading: Array = [true]; + public selectedFilter = ''; + private unsub: Array> = [new Subject(), new Subject()]; + + constructor(private logger: LoggerService, private store: Store, private rtlEffects: RTLEffects) { + switch (true) { + case (window.innerWidth <= 415): + this.displayedColumns = ['close_type', 'chan_id', 'settled_balance']; + break; + case (window.innerWidth > 415 && window.innerWidth <= 730): + this.displayedColumns = ['close_type', 'channel_point', 'chan_id', 'settled_balance']; + break; + case (window.innerWidth > 730 && window.innerWidth <= 1024): + this.displayedColumns = ['close_type', 'channel_point', 'chan_id', 'capacity', 'close_height', 'settled_balance']; + break; + case (window.innerWidth > 1024 && window.innerWidth <= 1280): + this.displayedColumns = ['close_type', 'channel_point', 'chan_id', 'closing_tx_hash', 'remote_pubkey', 'capacity', + 'close_height', 'settled_balance', 'time_locked_balance']; + break; + default: + this.displayedColumns = ['close_type', 'channel_point', 'chan_id', 'closing_tx_hash', 'remote_pubkey', 'capacity', + 'close_height', 'settled_balance', 'time_locked_balance']; + break; + } + } + + ngOnInit() { + this.store.dispatch(new RTLActions.FetchChannels({routeParam: 'closed', channelStatus: ''})); + this.store.select('rtlRoot') + .pipe(takeUntil(this.unsub[0])) + .subscribe((rtlStore: fromRTLReducer.State) => { + rtlStore.effectErrors.forEach(effectsErr => { + if (effectsErr.action === 'FetchChannels/closed') { + this.flgLoading[0] = 'error'; + } + }); + if (undefined !== rtlStore.closedChannels && rtlStore.closedChannels.length > 0) { + this.loadClosedChannelsTable(rtlStore.closedChannels); + } + if (this.flgLoading[0] !== 'error') { + this.flgLoading[0] = (undefined !== rtlStore.closedChannels) ? false : true; + } + this.logger.info(rtlStore); + }); + + } + + applyFilter(selFilter: string) { + this.selectedFilter = selFilter; + this.closedChannels.filter = selFilter; + } + + onClosedChannelClick(selRow: ClosedChannel, event: any) { + const selChannel = this.closedChannels.data.filter(closedChannel => { + return closedChannel.chan_id === selRow.chan_id; + })[0]; + const reorderedChannel = JSON.parse(JSON.stringify(selChannel, ['close_type', 'channel_point', 'chan_id', 'closing_tx_hash', 'remote_pubkey', 'capacity', + 'close_height', 'settled_balance', 'time_locked_balance'] , 2)); + this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: { + type: 'INFO', + message: JSON.stringify(reorderedChannel) + }})); + } + + loadClosedChannelsTable(closedChannels) { + this.closedChannels = new MatTableDataSource([...closedChannels]); + this.closedChannels.sort = this.sort; + this.logger.info(this.closedChannels); + } + + resetData() { + this.selectedFilter = ''; + } + + ngOnDestroy() { + this.unsub.forEach(completeSub => { + completeSub.next(); + completeSub.complete(); + }); + } + +} diff --git a/src/app/pages/channels/channel-manage/channel-manage.component.html b/src/app/pages/channels/channel-manage/channel-manage.component.html new file mode 100644 index 00000000..65a1a09a --- /dev/null +++ b/src/app/pages/channels/channel-manage/channel-manage.component.html @@ -0,0 +1,131 @@ +
+
+ + + +

Add Channel

+
+
+ +
+ + + + {{peer.alias}} + + + + + + (Wallet Bal: {{totalBalance}}, Remaining Bal: {{totalBalance - ((fundingAmount) ? fundingAmount : 0)}}) + +
+ Options +
+ +
+ + + + {{transType.name}} + + + +
+
+ + + + + + + + + +
+
+ Spend Unconfirmed Output +
+
+
+ +
+
+ +
+
+
+
+
+
+ + +
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Disconnect link_offeditedit Status {{channel.active}} ID {{channel.chan_id}} Pub Key +
{{channel.remote_pubkey | slice:0:10}}...
Alias {{channel.remote_alias}} Capacity {{channel.capacity | number}} Local Bal {{channel.local_balance | number}} Remote Bal {{channel.remote_balance | number}} {{information?.smaller_currency_unit}} Sent {{channel.total_satoshis_sent | number}} {{information?.smaller_currency_unit}} Recv {{channel.total_satoshis_received | number}} Fee {{channel.commit_fee | number}}
+
+
+
+
+
+ \ No newline at end of file diff --git a/src/app/pages/channels/channel-manage/channel-manage.component.scss b/src/app/pages/channels/channel-manage/channel-manage.component.scss new file mode 100644 index 00000000..ee209344 --- /dev/null +++ b/src/app/pages/channels/channel-manage/channel-manage.component.scss @@ -0,0 +1,50 @@ +.mat-column-close, .mat-column-update, .mat-column-active { + flex: 0 0 6%; + min-width: 50px; +} + +mat-cell.mat-column-close, .mat-column-update { + cursor: pointer; +} + +.mat-column-chan_id { + flex: 0 0 16%; + min-width: 160px; +} + +.mat-checkbox-inner-container:focus, .mat-checkbox-input:focus { + outline: none !important; +} + +.size-40 { + font-size: 40px; + margin-left: -30%; +} + +.mat-button-text { + font-size: 24px; + padding-bottom: 20px; +} + +.flex-ellipsis { + padding-right: 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +table { + width:100%; +} + +.table-container { + height: 68vh; + overflow: auto; +} + +@media screen and (max-width: 414px) { + .table-container { + height: 31vh; + overflow: auto; + } +} diff --git a/src/app/pages/channels/channel-manage/channel-manage.component.spec.ts b/src/app/pages/channels/channel-manage/channel-manage.component.spec.ts new file mode 100644 index 00000000..8c1baf54 --- /dev/null +++ b/src/app/pages/channels/channel-manage/channel-manage.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ChannelManageComponent } from './channel-manage.component'; + +describe('ChannelManageComponent', () => { + let component: ChannelManageComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ChannelManageComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ChannelManageComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/channels/channel-manage/channel-manage.component.ts b/src/app/pages/channels/channel-manage/channel-manage.component.ts new file mode 100644 index 00000000..4c6639a5 --- /dev/null +++ b/src/app/pages/channels/channel-manage/channel-manage.component.ts @@ -0,0 +1,251 @@ +import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core'; +import { Subject } from 'rxjs'; +import { takeUntil, filter } from 'rxjs/operators'; +import { Store } from '@ngrx/store'; +import { Actions } from '@ngrx/effects'; + +import { MatTableDataSource, MatSort } from '@angular/material'; +import { Channel, Peer, GetInfo } from '../../../shared/models/lndModels'; +import { LoggerService } from '../../../shared/services/logger.service'; + +import { RTLEffects } from '../../../shared/store/rtl.effects'; +import * as RTLActions from '../../../shared/store/rtl.actions'; +import * as fromRTLReducer from '../../../shared/store/rtl.reducers'; + +@Component({ + selector: 'rtl-channel-manage', + templateUrl: './channel-manage.component.html', + styleUrls: ['./channel-manage.component.scss'] +}) +export class ChannelManageComponent implements OnInit, OnDestroy { + @ViewChild(MatSort) sort: MatSort; + public totalBalance = 0; + public selectedPeer = ''; + public fundingAmount: number; + public displayedColumns = []; + public channels: any; + public peers: Peer[] = []; + public information: GetInfo = {}; + public flgLoading: Array = [true]; + public selectedFilter = ''; + public statusFilters = ['Active', 'Inactive']; + public myChanPolicy: any = {}; + public selFilter = ''; + public flgSticky = true; + public transTypes = [{id: '0', name: 'Default Priority'}, {id: '1', name: 'Target Confirmation Blocks'}, {id: '2', name: 'Fee'}]; + public selTransType = '0'; + public transTypeValue = {blocks: '', fees: ''}; + public spendUnconfirmed = false; + public moreOptions = false; + private unsub: Array> = [new Subject(), new Subject(), new Subject(), new Subject()]; + + constructor(private logger: LoggerService, private store: Store, private rtlEffects: RTLEffects, private actions$: Actions) { + switch (true) { + case (window.innerWidth <= 415): + this.displayedColumns = ['close', 'update', 'active', 'chan_id', 'remote_alias']; + break; + case (window.innerWidth > 415 && window.innerWidth <= 730): + this.displayedColumns = ['close', 'update', 'active', 'chan_id', 'remote_alias', 'capacity']; + break; + case (window.innerWidth > 730 && window.innerWidth <= 1024): + this.displayedColumns = ['close', 'update', 'active', 'chan_id', 'remote_alias', 'capacity', 'local_balance', 'remote_balance']; + break; + case (window.innerWidth > 1024 && window.innerWidth <= 1280): + this.displayedColumns = ['close', 'update', 'active', 'chan_id', 'remote_alias', 'capacity', 'local_balance', 'remote_balance', 'total_satoshis_sent', + 'total_satoshis_received', 'commit_fee']; + break; + default: + this.displayedColumns = ['close', 'update', 'active', 'chan_id', 'remote_pubkey', 'remote_alias', 'capacity', 'local_balance', 'remote_balance', + 'total_satoshis_sent', 'total_satoshis_received', 'commit_fee']; + break; + } + } + + ngOnInit() { + this.store.select('rtlRoot') + .pipe(takeUntil(this.unsub[0])) + .subscribe((rtlStore: fromRTLReducer.State) => { + rtlStore.effectErrors.forEach(effectsErr => { + if (effectsErr.action === 'FetchChannels/all') { + this.flgLoading[0] = 'error'; + } + }); + this.information = rtlStore.information; + this.peers = rtlStore.peers; + this.peers.forEach(peer => { + if (undefined === peer.alias || peer.alias === '') { + peer.alias = peer.pub_key.substring(0, 15) + '...'; + } + }); + + this.totalBalance = +rtlStore.blockchainBalance.total_balance; + if (undefined !== rtlStore.allChannels && rtlStore.allChannels.length > 0) { + this.loadChannelsTable(rtlStore.allChannels); + } + if (this.flgLoading[0] !== 'error') { + this.flgLoading[0] = (undefined !== rtlStore.allChannels) ? false : true; + } + + this.logger.info(rtlStore); + }); + } + + onOpenChannel(form: any) { + this.store.dispatch(new RTLActions.OpenSpinner('Opening Channel...')); + let transTypeValue = '0'; + if (this.selTransType === '1') { + transTypeValue = this.transTypeValue.blocks; + } else if (this.selTransType === '2') { + transTypeValue = this.transTypeValue.fees; + } + this.store.dispatch(new RTLActions.SaveNewChannel({ + selectedPeerPubkey: this.selectedPeer, fundingAmount: this.fundingAmount, + transType: this.selTransType, transTypeValue: transTypeValue, spendUnconfirmed: this.spendUnconfirmed + })); + } + + onChannelUpdate(channelToUpdate: any) { + if (channelToUpdate === 'all') { + const titleMsg = 'Updated Values for ALL Channels'; + const confirmationMsg = {}; + this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data: { + type: 'CONFIRM', titleMessage: titleMsg, noBtnText: 'Cancel', yesBtnText: 'Update', message: JSON.stringify(confirmationMsg), flgShowInput: true, getInputs: [ + {placeholder: 'Base Fee msat', inputType: 'number', inputValue: 1000}, + {placeholder: 'Fee Rate mili msat', inputType: 'number', inputValue: 1, min: 1}, + {placeholder: 'Time Lock Delta', inputType: 'number', inputValue: 144} + ] + }})); + this.rtlEffects.closeConfirm + .pipe(takeUntil(this.unsub[2])) + .subscribe(confirmRes => { + if (confirmRes) { + const base_fee = confirmRes[0].inputValue; + const fee_rate = confirmRes[1].inputValue; + const time_lock_delta = confirmRes[2].inputValue; + this.store.dispatch(new RTLActions.OpenSpinner('Updating Channel Policy...')); + this.store.dispatch(new RTLActions.UpdateChannels({baseFeeMsat: base_fee, feeRate: fee_rate, timeLockDelta: time_lock_delta, chanPoint: 'all'})); + } + }); + } else { + this.myChanPolicy = {fee_base_msat: 0, fee_rate_milli_msat: 0, time_lock_delta: 0}; + this.store.dispatch(new RTLActions.OpenSpinner('Fetching Channel Policy...')); + this.store.dispatch(new RTLActions.ChannelLookup(channelToUpdate.chan_id.toString())); + this.rtlEffects.setLookup + .pipe(takeUntil(this.unsub[3])) + .subscribe(resLookup => { + this.logger.info(resLookup); + if (resLookup.node1_pub === this.information.identity_pubkey) { + this.myChanPolicy = resLookup.node1_policy; + } else if (resLookup.node2_pub === this.information.identity_pubkey) { + this.myChanPolicy = resLookup.node2_policy; + } else { + this.myChanPolicy = {fee_base_msat: 0, fee_rate_milli_msat: 0, time_lock_delta: 0}; + } + this.logger.info(this.myChanPolicy); + this.store.dispatch(new RTLActions.CloseSpinner()); + const titleMsg = 'Updated Values for Channel Point: ' + channelToUpdate.channel_point; + const confirmationMsg = {}; + this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data: { + type: 'CONFIRM', titleMessage: titleMsg, noBtnText: 'Cancel', yesBtnText: 'Update', message: JSON.stringify(confirmationMsg), flgShowInput: true, getInputs: [ + {placeholder: 'Base Fee msat', inputType: 'number', inputValue: (this.myChanPolicy.fee_base_msat === '') ? 0 : this.myChanPolicy.fee_base_msat}, + {placeholder: 'Fee Rate mili msat', inputType: 'number', inputValue: this.myChanPolicy.fee_rate_milli_msat, min: 1}, + {placeholder: 'Time Lock Delta', inputType: 'number', inputValue: this.myChanPolicy.time_lock_delta} + ] + }})); + }); + this.rtlEffects.closeConfirm + .pipe(takeUntil(this.unsub[2])) + .subscribe(confirmRes => { + if (confirmRes) { + const base_fee = confirmRes[0].inputValue; + const fee_rate = confirmRes[1].inputValue; + const time_lock_delta = confirmRes[2].inputValue; + this.store.dispatch(new RTLActions.OpenSpinner('Updating Channel Policy...')); + this.store.dispatch(new RTLActions.UpdateChannels({baseFeeMsat: base_fee, feeRate: fee_rate, timeLockDelta: time_lock_delta, chanPoint: channelToUpdate.channel_point})); + } + }); + } + this.applyFilter(); + } + + onChannelClose(channelToClose: Channel) { + this.store.dispatch(new RTLActions.OpenConfirmation({ + width: '70%', data: { type: 'CONFIRM', titleMessage: 'Closing channel: ' + channelToClose.chan_id, noBtnText: 'Cancel', yesBtnText: 'Disconnect' + }})); + this.rtlEffects.closeConfirm + .pipe(takeUntil(this.unsub[1])) + .subscribe(confirmRes => { + if (confirmRes) { + this.store.dispatch(new RTLActions.OpenSpinner('Closing Channel...')); + this.store.dispatch(new RTLActions.CloseChannel({channelPoint: channelToClose.channel_point, forcibly: true, channelStatus: channelToClose.active})); + } + }); + } + + applyFilter() { + this.selectedFilter = this.selFilter; + this.channels.filter = this.selFilter; + } + + onChannelClick(selRow: Channel, event: any) { + const flgCloseClicked = + event.target.className.includes('mat-column-close') + || event.target.className.includes('mat-column-update') + || event.target.className.includes('mat-icon'); + if (flgCloseClicked) { + return; + } + const selChannel = this.channels.data.filter(channel => { + return channel.chan_id === selRow.chan_id; + })[0]; + const reorderedChannel = JSON.parse(JSON.stringify(selChannel, [ + 'active', 'remote_pubkey', 'remote_alias', 'channel_point', 'chan_id', 'capacity', 'local_balance', 'remote_balance', 'commit_fee', 'commit_weight', + 'fee_per_kw', 'unsettled_balance', 'total_satoshis_sent', 'total_satoshis_received', 'num_updates', 'pending_htlcs', 'csv_delay', 'private' + ] , 2)); + this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: { + type: 'INFO', + message: JSON.stringify(reorderedChannel) + }})); + } + + loadChannelsTable(channels) { + channels.sort(function(a, b) { + return (a.active === b.active) ? 0 : ((b.active) ? 1 : -1); + }); + channels.forEach(channel => { + if (channel.active === true || channel.active === 'Active') { + channel.active = 'Active'; + } else { + channel.active = 'Inactive'; + } + }); + this.channels = new MatTableDataSource([...channels]); + this.channels.sort = this.sort; + this.logger.info(this.channels); + } + + resetData() { + this.selectedPeer = ''; + this.fundingAmount = 0; + this.moreOptions = false; + this.spendUnconfirmed = false; + this.selTransType = '0'; + this.transTypeValue = {blocks: '', fees: ''}; + } + + onMoreOptionsChange(event: any) { + if (!event.checked) { + this.spendUnconfirmed = false; + this.selTransType = '0'; + this.transTypeValue = {blocks: '', fees: ''}; + } + } + + ngOnDestroy() { + this.unsub.forEach(completeSub => { + completeSub.next(); + completeSub.complete(); + }); + } + +} diff --git a/src/app/pages/channels/channel-pending/channel-pending.component.html b/src/app/pages/channels/channel-pending/channel-pending.component.html new file mode 100644 index 00000000..59cf8f94 --- /dev/null +++ b/src/app/pages/channels/channel-pending/channel-pending.component.html @@ -0,0 +1,252 @@ +
+
+ + + +

Pending Channels

+ +
+
+ +
+

Total Limbo Balance: + {{pendingChannels.btc_total_limbo_balance | number}} {{information?.currency_unit}}

+ +

Total Limbo Balance: {{pendingChannels.total_limbo_balance | number}} + {{information?.smaller_currency_unit}}

+
+
+
+ + + + +

Pending Open Channels({{pendingOpenChannelsLength}})

+
+ +
+ + + Remote Node Pub + {{channel.channel.remote_node_pub}} + + + + Local Balance + {{channel.channel.local_balance | + number}} + + + + Commit Fee + {{channel.commit_fee | number}} + + + + + Remote Balance + {{channel.channel.remote_balance | + number}} + + + + Capacity + {{channel.channel.capacity | + number}} + + + + Commit Weight + {{channel.commit_weight | number}} + + + + + Fee Per KW + {{channel.fee_per_kw | number}} + + + + + Confirmation Height + {{channel.confirmation_height | + number}} + + + Channel Point + {{channel.channel.channel_point}} + + + + +
+ + + +

Pending Force Closing Channels({{pendingForceClosingChannelsLength}})

+
+ +
+ + + Remote Node Pub + {{channel.channel.remote_node_pub}} + + + + Recovered Balance + {{channel.recovered_balance | + number}} + + + + Limbo Balance + {{channel.limbo_balance | number}} + + + + + Block Till Maturity + {{channel.blocks_til_maturity | + number}} + + + + Maturity Height + {{channel.maturity_height | number}} + + + + + Local Balance + {{channel.channel.local_balance | + number}} + + + + Remote Balance + {{channel.channel.remote_balance | + number}} + + + + Capacity + {{channel.channel.capacity | + number}} + + + Transaction Id + +
{{channel.closing_txid}}
+
+
+ + Channel Point + {{channel.channel.channel_point}} + + + +
+
+ + + +

Pending Closing Channels({{pendingClosingChannelsLength}})

+
+ +
+ + + Remote Node Pub + {{channel.channel.remote_node_pub}} + + + + Local Balance + {{channel.channel.local_balance | + number}} + + + + Remote Balance + {{channel.channel.remote_balance | + number}} + + + + Capacity + {{channel.channel.capacity | + number}} + + + Transaction Id + +
{{channel.closing_txid}}
+
+
+ + Channel Point + {{channel.channel.channel_point}} + + + +
+
+ + + +

Waiting Close Channels({{pendingWaitClosingChannelsLength}})

+
+ +
+ + + Remote Node Pub + {{channel.channel.remote_node_pub}} + + + + Limbo Balance + {{channel.limbo_balance | number}} + + + + + Local Balance + {{channel.channel.local_balance | + number}} + + + + Remote Balance + {{channel.channel.remote_balance | + number}} + + + + Capacity + {{channel.channel.capacity | + number}} + + + Channel Point + {{channel.channel.channel_point}} + + + + +
+
+
+
+
+
+
\ No newline at end of file diff --git a/src/app/pages/channels/channel-pending/channel-pending.component.scss b/src/app/pages/channels/channel-pending/channel-pending.component.scss new file mode 100644 index 00000000..4ddbcf5b --- /dev/null +++ b/src/app/pages/channels/channel-pending/channel-pending.component.scss @@ -0,0 +1,6 @@ +.flex-ellipsis { + padding-right: 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} diff --git a/src/app/pages/channels/channel-pending/channel-pending.component.spec.ts b/src/app/pages/channels/channel-pending/channel-pending.component.spec.ts new file mode 100644 index 00000000..2b53efe0 --- /dev/null +++ b/src/app/pages/channels/channel-pending/channel-pending.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ChannelPendingComponent } from './channel-pending.component'; + +describe('ChannelPendingComponent', () => { + let component: ChannelPendingComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ChannelPendingComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ChannelPendingComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/channels/channel-pending/channel-pending.component.ts b/src/app/pages/channels/channel-pending/channel-pending.component.ts new file mode 100644 index 00000000..d4ee3e64 --- /dev/null +++ b/src/app/pages/channels/channel-pending/channel-pending.component.ts @@ -0,0 +1,241 @@ +import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; +import { Store } from '@ngrx/store'; + +import { MatTableDataSource, MatSort } from '@angular/material'; +import { Channel, GetInfo, PendingChannels } from '../../../shared/models/lndModels'; +import { Settings } from '../../../shared/models/RTLconfig'; +import { LoggerService } from '../../../shared/services/logger.service'; + +import { RTLEffects } from '../../../shared/store/rtl.effects'; +import * as RTLActions from '../../../shared/store/rtl.actions'; +import * as fromRTLReducer from '../../../shared/store/rtl.reducers'; + +@Component({ + selector: 'rtl-channel-pending', + templateUrl: './channel-pending.component.html', + styleUrls: ['./channel-pending.component.scss'] +}) +export class ChannelPendingComponent implements OnInit, OnDestroy { + @ViewChild(MatSort) sort: MatSort; + public selectedFilter = 0; + public settings: Settings; + public information: GetInfo = {}; + public pendingChannels: PendingChannels = {}; + public displayedClosingColumns = [ + 'closing_txid', + 'channel_point', 'remote_balance', 'local_balance', 'remote_node_pub', 'capacity' + ]; + public pendingClosingChannelsLength = 0; + public pendingClosingChannels: any; + public displayedForceClosingColumns = [ + 'closing_txid', 'limbo_balance', 'maturity_height', 'blocks_til_maturity', 'recovered_balance', + 'channel_point', 'remote_balance', 'local_balance', 'remote_node_pub', 'capacity' + ]; + public pendingForceClosingChannelsLength = 0; + public pendingForceClosingChannels: any; + public displayedOpenColumns = [ + 'commit_weight', 'confirmation_height', 'fee_per_kw', 'commit_fee', + 'channel_point', 'remote_balance', 'local_balance', 'remote_node_pub', 'capacity' + ]; + public pendingOpenChannelsLength = 0; + public pendingOpenChannels: any; + public displayedWaitClosingColumns = [ + 'limbo_balance', + 'channel_point', 'remote_balance', 'local_balance', 'remote_node_pub', 'capacity' + ]; + public pendingWaitClosingChannelsLength = 0; + public pendingWaitClosingChannels: any; + public flgLoading: Array = [true]; + private unsub: Array> = [new Subject(), new Subject()]; + + constructor(private logger: LoggerService, private store: Store, private rtlEffects: RTLEffects) { + switch (true) { + case (window.innerWidth <= 415): + this.displayedClosingColumns = ['remote_node_pub', 'local_balance', 'remote_balance']; + this.displayedForceClosingColumns = ['remote_node_pub', 'recovered_balance', 'limbo_balance']; + this.displayedOpenColumns = ['remote_node_pub', 'local_balance', 'commit_fee']; + this.displayedWaitClosingColumns = ['remote_node_pub', 'limbo_balance', 'local_balance']; + break; + case (window.innerWidth > 415 && window.innerWidth <= 730): + this.displayedClosingColumns = ['remote_node_pub', 'local_balance', 'remote_balance', 'capacity']; + this.displayedForceClosingColumns = ['remote_node_pub', 'recovered_balance', 'limbo_balance', 'blocks_til_maturity', 'maturity_height']; + this.displayedOpenColumns = ['remote_node_pub', 'local_balance', 'commit_fee', 'remote_balance']; + this.displayedWaitClosingColumns = ['remote_node_pub', 'limbo_balance', 'local_balance', 'remote_balance']; + break; + case (window.innerWidth > 730 && window.innerWidth <= 1024): + this.displayedClosingColumns = ['remote_node_pub', 'local_balance', 'remote_balance', 'capacity', 'closing_txid']; + this.displayedForceClosingColumns = ['remote_node_pub', 'recovered_balance', 'limbo_balance', 'blocks_til_maturity', 'maturity_height', 'local_balance']; + this.displayedOpenColumns = ['remote_node_pub', 'local_balance', 'commit_fee', 'remote_balance', 'capacity']; + this.displayedWaitClosingColumns = ['remote_node_pub', 'limbo_balance', 'local_balance', 'remote_balance', 'capacity', 'channel_point']; + break; + case (window.innerWidth > 1024 && window.innerWidth <= 1280): + this.displayedClosingColumns = ['remote_node_pub', 'local_balance', 'remote_balance', 'capacity', 'closing_txid', 'channel_point']; + this.displayedForceClosingColumns = [ + 'remote_node_pub', 'recovered_balance', 'limbo_balance', 'blocks_til_maturity', + 'maturity_height', 'local_balance', 'remote_balance', 'capacity', 'closing_txid', 'channel_point' + ]; + this.displayedOpenColumns = [ + 'remote_node_pub', 'local_balance', 'commit_fee', 'remote_balance', 'capacity', 'commit_weight', 'fee_per_kw', 'confirmation_height', 'channel_point' + ]; + this.displayedWaitClosingColumns = ['remote_node_pub', 'limbo_balance', 'local_balance', 'remote_balance', 'capacity', 'channel_point']; + break; + default: + this.displayedClosingColumns = ['remote_node_pub', 'local_balance', 'remote_balance', 'capacity', 'closing_txid', 'channel_point']; + this.displayedForceClosingColumns = [ + 'remote_node_pub', 'recovered_balance', 'limbo_balance', 'blocks_til_maturity', + 'maturity_height', 'local_balance', 'remote_balance', 'capacity', 'closing_txid', 'channel_point' + ]; + this.displayedOpenColumns = [ + 'remote_node_pub', 'local_balance', 'commit_fee', 'remote_balance', 'capacity', 'commit_weight', 'fee_per_kw', 'confirmation_height', 'channel_point' + ]; + this.displayedWaitClosingColumns = ['remote_node_pub', 'limbo_balance', 'local_balance', 'remote_balance', 'capacity', 'channel_point']; + break; + } + } + + ngOnInit() { + this.store.select('rtlRoot') + .pipe(takeUntil(this.unsub[0])) + .subscribe((rtlStore: fromRTLReducer.State) => { + rtlStore.effectErrors.forEach(effectsErr => { + if (effectsErr.action === 'FetchChannels/pending') { + this.flgLoading[0] = 'error'; + } + }); + + this.settings = rtlStore.settings; + this.information = rtlStore.information; + this.pendingChannels = rtlStore.pendingChannels; + if (undefined !== this.pendingChannels.total_limbo_balance) { + this.flgLoading[1] = false; + if (undefined !== this.pendingChannels.pending_closing_channels) { + this.loadClosingChannelsTable(this.pendingChannels.pending_closing_channels); + } + if (undefined !== this.pendingChannels.pending_force_closing_channels) { + this.loadForceClosingChannelsTable(this.pendingChannels.pending_force_closing_channels); + } + if (undefined !== this.pendingChannels.pending_open_channels) { + this.loadOpenChannelsTable(this.pendingChannels.pending_open_channels); + } + if (undefined !== this.pendingChannels.waiting_close_channels) { + this.loadWaitClosingChannelsTable(this.pendingChannels.waiting_close_channels); + } + } + if (this.flgLoading[0] !== 'error') { + this.flgLoading[0] = (undefined !== this.information.identity_pubkey) ? false : true; + } + this.logger.info(rtlStore); + }); + + } + + onOpenClick(selRow: any, event: any) { + const selChannel = this.pendingOpenChannels.data.filter(channel => { + return channel.channel.channel_point === selRow.channel.channel_point; + })[0]; + const fcChannelObj1 = JSON.parse(JSON.stringify(selChannel, ['commit_weight', 'confirmation_height', 'fee_per_kw', 'commit_fee'], 2)); + const fcChannelObj2 = JSON.parse(JSON.stringify(selChannel.channel, ['channel_point', 'remote_balance', 'local_balance', 'remote_node_pub', 'capacity'], 2)); + const reorderedChannel = {}; + Object.assign(reorderedChannel, fcChannelObj1, fcChannelObj2); + this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: { + type: 'INFO', + message: JSON.stringify(reorderedChannel) + }})); + } + + onForceClosingClick(selRow: any, event: any) { + const selChannel = this.pendingForceClosingChannels.data.filter(channel => { + return channel.channel.channel_point === selRow.channel.channel_point; + })[0]; + const fcChannelObj1 = JSON.parse(JSON.stringify(selChannel, ['closing_txid', 'limbo_balance', 'maturity_height', 'blocks_til_maturity', 'recovered_balance'], 2)); + const fcChannelObj2 = JSON.parse(JSON.stringify(selChannel.channel, ['channel_point', 'remote_balance', 'local_balance', 'remote_node_pub', 'capacity'], 2)); + const reorderedChannel = {}; + Object.assign(reorderedChannel, fcChannelObj1, fcChannelObj2); + this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: { + type: 'INFO', + message: JSON.stringify(reorderedChannel) + }})); + } + + onClosingClick(selRow: any, event: any) { + const selChannel = this.pendingClosingChannels.data.filter(channel => { + return channel.channel.channel_point === selRow.channel.channel_point; + })[0]; + const fcChannelObj1 = JSON.parse(JSON.stringify(selChannel, ['closing_txid'], 2)); + const fcChannelObj2 = JSON.parse(JSON.stringify(selChannel.channel, ['channel_point', 'remote_balance', 'local_balance', 'remote_node_pub', 'capacity'], 2)); + const reorderedChannel = {}; + Object.assign(reorderedChannel, fcChannelObj1, fcChannelObj2); + this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: { + type: 'INFO', + message: JSON.stringify(reorderedChannel) + }})); + } + + onWaitClosingClick(selRow: any, event: any) { + const selChannel = this.pendingWaitClosingChannels.data.filter(channel => { + return channel.channel.channel_point === selRow.channel.channel_point; + })[0]; + const fcChannelObj1 = JSON.parse(JSON.stringify(selChannel, ['limbo_balance'], 2)); + const fcChannelObj2 = JSON.parse(JSON.stringify(selChannel.channel, ['channel_point', 'remote_balance', 'local_balance', 'remote_node_pub', 'capacity'], 2)); + const reorderedChannel = {}; + Object.assign(reorderedChannel, fcChannelObj1, fcChannelObj2); + this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: { + type: 'INFO', + message: JSON.stringify(reorderedChannel) + }})); + } + + loadOpenChannelsTable(channels) { + channels.sort(function(a, b) { + return (a.active === b.active) ? 0 : ((b.active) ? -1 : 1); + }); + this.pendingOpenChannelsLength = (undefined !== channels.length) ? channels.length : 0; + this.pendingOpenChannels = new MatTableDataSource([...channels]); + this.pendingOpenChannels.sort = this.sort; + this.logger.info(this.pendingOpenChannels); + } + + loadForceClosingChannelsTable(channels) { + channels.sort(function(a, b) { + return (a.active === b.active) ? 0 : ((b.active) ? -1 : 1); + }); + this.pendingForceClosingChannelsLength = (undefined !== channels.length) ? channels.length : 0; + this.pendingForceClosingChannels = new MatTableDataSource([...channels]); + this.pendingForceClosingChannels.sort = this.sort; + this.logger.info(this.pendingForceClosingChannels); + } + + loadClosingChannelsTable(channels) { + channels.sort(function(a, b) { + return (a.active === b.active) ? 0 : ((b.active) ? -1 : 1); + }); + this.pendingClosingChannelsLength = (undefined !== channels.length) ? channels.length : 0; + this.pendingClosingChannels = new MatTableDataSource([...channels]); + this.pendingClosingChannels.sort = this.sort; + this.logger.info(this.pendingClosingChannels); + } + + loadWaitClosingChannelsTable(channels) { + channels.sort(function(a, b) { + return (a.active === b.active) ? 0 : ((b.active) ? -1 : 1); + }); + this.pendingWaitClosingChannelsLength = (undefined !== channels.length) ? channels.length : 0; + this.pendingWaitClosingChannels = new MatTableDataSource([...channels]); + this.pendingWaitClosingChannels.sort = this.sort; + this.logger.info(this.pendingWaitClosingChannels); + } + + applyFilter(selFilter: number) { + this.selectedFilter = selFilter; + } + + ngOnDestroy() { + this.unsub.forEach(completeSub => { + completeSub.next(); + completeSub.complete(); + }); + } + +} diff --git a/src/app/pages/help/help.component.html b/src/app/pages/help/help.component.html new file mode 100644 index 00000000..38191ad6 --- /dev/null +++ b/src/app/pages/help/help.component.html @@ -0,0 +1,20 @@ +
+
+ + + +

Help

+
+
+ + + + {{helpTopic.question}} + + {{helpTopic.answer}} + +
+
+
+
+
\ No newline at end of file diff --git a/src/app/pages/help/help.component.scss b/src/app/pages/help/help.component.scss new file mode 100644 index 00000000..f4bcac9e --- /dev/null +++ b/src/app/pages/help/help.component.scss @@ -0,0 +1,3 @@ +.mat-card-content { + margin-bottom: 4px; +} diff --git a/src/app/pages/help/help.component.ts b/src/app/pages/help/help.component.ts new file mode 100644 index 00000000..3ba67079 --- /dev/null +++ b/src/app/pages/help/help.component.ts @@ -0,0 +1,29 @@ +import { Component, OnInit } from '@angular/core'; + +export class HelpTopic { + question: string; + answer: string; + + constructor(ques: string, ans: string) { + this.question = ques; + this.answer = ans; + } +} + +@Component({ + selector: 'rtl-help', + templateUrl: './help.component.html', + styleUrls: ['./help.component.scss'] +}) +export class HelpComponent implements OnInit { + public helpTopics: Array = []; + + constructor() {} + + ngOnInit() { + // this.helpTopics.push(new HelpTopic('Set LND home directory?', + // 'Pass the directroy information while getting the server up with --lndir "local-lnd-path".
Example: node rtl --lndir C:\lnd\dir\path')); + this.helpTopics.push(new HelpTopic('Change theme?', 'Click on rotating setting icon on the right side of the screen and choose from the given options.')); + } + +} diff --git a/src/app/pages/home/home.component.html b/src/app/pages/home/home.component.html new file mode 100644 index 00000000..bbd82d00 --- /dev/null +++ b/src/app/pages/home/home.component.html @@ -0,0 +1,237 @@ +
+
+ + + +
Wallet Balance
+
+
+ + + account_balance_wallet + + +

{{BTCtotalBalance | number}} {{information?.currency_unit}}

+

{{totalBalance | number}} {{information?.smaller_currency_unit}}

+
+
+ + +
+
+
+ + + +
Peers
+
+
+ + + group + +

{{totalPeers | number}}

+ +

0

+
+
+ + +
+
+
+ + + +
Channel Balance
+
+
+ + + linear_scale + + +

{{BTCchannelBalance | number}} {{information?.currency_unit}}

+

{{channelBalance | number}} {{information?.smaller_currency_unit}}

+
+
+ + +
+
+
+ + + +
Chain Sync Status
+
+
+ + + sync + + check_circle + + cancel + + + + +
+
+
+
+
+
+ + + +
Fee Report
+
+
+ +
+ + Daily ({{information?.smaller_currency_unit}}) + {{fees?.day_fee_sum}} + + + + Weekly ({{information?.smaller_currency_unit}}) + {{fees?.week_fee_sum}} + + + + Monthly ({{information?.smaller_currency_unit}}) + {{fees?.month_fee_sum}} + + +
+ + +
+
+ + + +
Channel Status
+
+
+ +
+ + Active +

{{activeChannels}}

+ +
+ + Inactive +

{{inactiveChannels}}

+ +
+ + Pending +

{{pendingChannels}}

+ +
+
+ + +
+
+
+
+
+ + + +
Local-Remote Channel Capacity
+
+
+ +
+
+ + +
+
+ + +
+
+
+
+ + + +
Network Information
+
+
+ +
+ + Network Capacity ({{information?.currency_unit}}) + {{networkInfo?.btc_total_network_capacity | number}} + Network Capacity ({{information?.smaller_currency_unit}}) + {{networkInfo?.total_network_capacity | number}} + + + + Number of Nodes + {{networkInfo?.num_nodes | number}} + + + + Number of Channels + {{networkInfo?.num_channels | number}} + + + + Max Out Degree + {{networkInfo?.max_out_degree | number}} + + + + Avg Out Degree + {{networkInfo?.avg_out_degree | number:'1.0-2'}} + + + + Max Channel Size ({{information?.currency_unit}}) + Max Channel Size ({{information?.smaller_currency_unit}}) + {{networkInfo?.btc_max_channel_size | number}} + {{networkInfo?.max_channel_size | number}} + + + + Avg Channel Size ({{information?.currency_unit}}) + Avg Channel Size ({{information?.smaller_currency_unit}}) + {{networkInfo?.btc_avg_channel_size | number}} + {{networkInfo?.avg_channel_size | number:'1.0-2'}} + + + + Min Channel Size ({{information?.currency_unit}}) + Min Channel Size ({{information?.smaller_currency_unit}}) + {{networkInfo?.btc_min_channel_size | number}} + {{networkInfo?.min_channel_size | number}} + + +
+ + +
+
+
+
+

Sats

diff --git a/src/app/pages/home/home.component.scss b/src/app/pages/home/home.component.scss new file mode 100644 index 00000000..ca8052d8 --- /dev/null +++ b/src/app/pages/home/home.component.scss @@ -0,0 +1,12 @@ +.network-info-list .mat-list-item { + height: 44px; +} + +.mat-column-bytes_sent, .mat-column-bytes_recv, .mat-column-sat_sent, .mat-column-sat_recv, .mat-column-inbound, .mat-column-ping_time { + flex: 0 0 8%; + min-width: 80px; +} + +.card-chnl-balances { + min-height: 354px; +} diff --git a/src/app/pages/home/home.component.spec.ts b/src/app/pages/home/home.component.spec.ts new file mode 100644 index 00000000..490e81bd --- /dev/null +++ b/src/app/pages/home/home.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HomeComponent } from './home.component'; + +describe('HomeComponent', () => { + let component: HomeComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ HomeComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(HomeComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/home/home.component.ts b/src/app/pages/home/home.component.ts new file mode 100644 index 00000000..4fae5f12 --- /dev/null +++ b/src/app/pages/home/home.component.ts @@ -0,0 +1,148 @@ +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; +import { Store } from '@ngrx/store'; + +import { LoggerService } from '../../shared/services/logger.service'; +import { GetInfo, NetworkInfo, Fees, Peer } from '../../shared/models/lndModels'; +import { Settings } from '../../shared/models/RTLconfig'; + +import * as fromRTLReducer from '../../shared/store/rtl.reducers'; + +@Component({ + selector: 'rtl-home', + templateUrl: './home.component.html', + styleUrls: ['./home.component.scss'] +}) +export class HomeComponent implements OnInit, OnDestroy { + public settings: Settings; + public fees: Fees; + public information: GetInfo = {}; + public remainder = 0; + public totalPeers = -1; + public totalBalance = ''; + public channelBalance = ''; + public BTCtotalBalance = ''; + public BTCchannelBalance = ''; + public networkInfo: NetworkInfo = {}; + public flgLoading: Array = [true, true, true, true, true, true, true, true]; // 0: Info, 1: Fee, 2: Wallet, 3: Channel, 4: Network + private unsub: Array> = [new Subject(), new Subject(), new Subject()]; + public channels: any; + public position = 'below'; + public activeChannels = 0; + public inactiveChannels = 0; + public pendingChannels = 0; + public peers: Peer[] = []; + barPadding = 0; + maxBalanceValue = 0; + totalBalances = [...[{'name': 'Local Balance', 'value': 0}, {'name': 'Remote Balance', 'value': 0}]]; + flgTotalCalculated = false; + view = []; + yAxisLabel = 'Balance'; + colorScheme = {domain: ['#FFFFFF']}; + + constructor(private logger: LoggerService, private store: Store) { + switch (true) { + case (window.innerWidth <= 730): + this.view = [250, 352]; + break; + case (window.innerWidth > 415 && window.innerWidth <= 730): + this.view = [280, 352]; + break; + case (window.innerWidth > 730 && window.innerWidth <= 1024): + this.view = [300, 352]; + break; + case (window.innerWidth > 1024 && window.innerWidth <= 1280): + this.view = [350, 352]; + break; + default: + this.view = [300, 352]; + break; + } + Object.assign(this, this.totalBalances); + } + + ngOnInit() { + this.flgTotalCalculated = false; + this.store.select('rtlRoot') + .pipe(takeUntil(this.unsub[0])) + .subscribe((rtlStore: fromRTLReducer.State) => { + rtlStore.effectErrors.forEach(effectsErr => { + if (effectsErr.action === 'FetchInfo') { + this.flgLoading[0] = 'error'; + } + if (effectsErr.action === 'FetchFees') { + this.flgLoading[1] = 'error'; + } + if (effectsErr.action === 'FetchBalance/blockchain') { + this.flgLoading[2] = 'error'; + } + if (effectsErr.action === 'FetchBalance/channels') { + this.flgLoading[3] = 'error'; + } + if (effectsErr.action === 'FetchNetwork') { + this.flgLoading[4] = 'error'; + } + if (effectsErr.action === 'FetchChannels/all') { + this.flgLoading[5] = 'error'; + this.flgLoading[6] = 'error'; + } + }); + this.settings = rtlStore.settings; + this.information = rtlStore.information; + if (this.flgLoading[0] !== 'error') { + this.flgLoading[0] = (undefined !== this.information.identity_pubkey) ? false : true; + } + + this.fees = rtlStore.fees; + if (this.flgLoading[1] !== 'error') { + this.flgLoading[1] = (undefined !== this.fees.day_fee_sum) ? false : true; + } + + this.totalBalance = rtlStore.blockchainBalance.total_balance; + this.BTCtotalBalance = rtlStore.blockchainBalance.btc_total_balance; + if (this.flgLoading[2] !== 'error') { + this.flgLoading[2] = ('' !== this.totalBalance) ? false : true; + } + + this.channelBalance = rtlStore.channelBalance.balance; + this.BTCchannelBalance = rtlStore.channelBalance.btc_balance; + if (this.flgLoading[3] !== 'error') { + this.flgLoading[3] = ('' !== this.channelBalance) ? false : true; + } + + this.networkInfo = rtlStore.networkInfo; + if (this.flgLoading[4] !== 'error') { + this.flgLoading[4] = (undefined !== this.networkInfo.num_nodes) ? false : true; + } + + this.totalBalances = [...[{'name': 'Local Balance', 'value': +rtlStore.totalLocalBalance}, {'name': 'Remote Balance', 'value': +rtlStore.totalRemoteBalance}]]; + this.maxBalanceValue = (rtlStore.totalLocalBalance > rtlStore.totalRemoteBalance) ? rtlStore.totalLocalBalance : rtlStore.totalRemoteBalance; + if (rtlStore.totalLocalBalance >= 0 && rtlStore.totalRemoteBalance >= 0) { + this.flgTotalCalculated = true; + if (this.flgLoading[5] !== 'error') { + this.flgLoading[5] = false; + } + } + + this.activeChannels = rtlStore.numberOfActiveChannels; + this.inactiveChannels = rtlStore.numberOfInactiveChannels; + this.pendingChannels = (undefined !== rtlStore.pendingChannels.pending_open_channels) ? rtlStore.pendingChannels.pending_open_channels.length : 0; + if (rtlStore.totalLocalBalance >= 0 && rtlStore.totalRemoteBalance >= 0 && this.flgLoading[6] !== 'error') { + this.flgLoading[6] = false; + } + + this.totalPeers = rtlStore.peers.length; + + this.logger.info(rtlStore); + }); + } + + ngOnDestroy() { + this.unsub.forEach(completeSub => { + completeSub.next(); + completeSub.complete(); + }); + } + +} diff --git a/src/app/pages/invoices/invoices.component.html b/src/app/pages/invoices/invoices.component.html new file mode 100644 index 00000000..53477439 --- /dev/null +++ b/src/app/pages/invoices/invoices.component.html @@ -0,0 +1,77 @@ +
+
+ + + +

Invoices

+
+
+ +
+ + + + + + +
+ +
+
+ +
+
+
+
+
+
+ + +
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Creation Date {{invoice.creation_date_str}} Settle Date {{invoice.settle_date_str}} Memo {{invoice.memo}} Value ({{(settings?.satsToBTC) ? information?.currency_unit : information?.smaller_currency_unit}}) {{(settings?.satsToBTC) ? (invoice?.btc_value | number:'1.0-3') : (invoice?.value | number)}} Settled {{invoice.settled}} Expiry (Sec) {{invoice.expiry | number}} CLTV Expiry {{invoice.cltv_expiry | number}} Amount Paid ({{(settings?.satsToBTC) ? information?.currency_unit : information?.smaller_currency_unit}}) {{(settings?.satsToBTC) ? (invoice?.btc_amt_paid_sat | number:'1.0-3') : (invoice?.amt_paid_sat | number)}}
+
+
+
+
+
diff --git a/src/app/pages/invoices/invoices.component.scss b/src/app/pages/invoices/invoices.component.scss new file mode 100644 index 00000000..785c97c4 --- /dev/null +++ b/src/app/pages/invoices/invoices.component.scss @@ -0,0 +1,23 @@ +.mat-column-value { + padding-right: 1rem; +} + +.mat-column-settled { + padding-left: 1rem; +} + +table { + width:100%; +} + +.table-container { + height: 68vh; + overflow: auto; +} + +@media screen and (max-width: 414px) { + .table-container { + max-height: 31vh; + overflow: auto; + } +} diff --git a/src/app/pages/invoices/invoices.component.ts b/src/app/pages/invoices/invoices.component.ts new file mode 100644 index 00000000..ab20c975 --- /dev/null +++ b/src/app/pages/invoices/invoices.component.ts @@ -0,0 +1,141 @@ +import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core'; +import { formatDate } from '@angular/common'; +import { Subject } from 'rxjs'; +import { takeUntil, filter } from 'rxjs/operators'; +import { Store } from '@ngrx/store'; +import { Actions } from '@ngrx/effects'; + +import { MatTableDataSource, MatSort } from '@angular/material'; +import { Settings } from '../../shared/models/RTLconfig'; +import { GetInfo, Invoice } from '../../shared/models/lndModels'; +import { LoggerService } from '../../shared/services/logger.service'; + +import { newlyAddedRowAnimation } from '../../shared/animation/row-animation'; +import * as RTLActions from '../../shared/store/rtl.actions'; +import * as fromRTLReducer from '../../shared/store/rtl.reducers'; + +@Component({ + selector: 'rtl-invoices', + templateUrl: './invoices.component.html', + styleUrls: ['./invoices.component.scss'], + animations: [newlyAddedRowAnimation] +}) +export class InvoicesComponent implements OnInit, OnDestroy { + @ViewChild(MatSort) sort: MatSort; + public newlyAddedInvoiceMemo = ''; + public newlyAddedInvoiceValue = 0; + public flgAnimate = true; + public settings: Settings; + public memo = ''; + public invoiceValue: number; + public displayedColumns = []; + public invoicePaymentReq = ''; + public invoices: any; + public information: GetInfo = {}; + public flgLoading: Array = [true]; + private unSubs: Array> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject()]; + + constructor(private logger: LoggerService, private store: Store, private actions$: Actions) { + switch (true) { + case (window.innerWidth <= 415): + this.displayedColumns = ['creation_date', 'memo', 'value', 'settled']; + break; + case (window.innerWidth > 415 && window.innerWidth <= 730): + this.displayedColumns = ['creation_date', 'settle_date', 'memo', 'value', 'settled', 'amt_paid_sat']; + break; + case (window.innerWidth > 730 && window.innerWidth <= 1024): + this.displayedColumns = ['creation_date', 'settle_date', 'memo', 'value', 'settled', 'amt_paid_sat']; + break; + case (window.innerWidth > 1024 && window.innerWidth <= 1280): + this.displayedColumns = ['creation_date', 'settle_date', 'memo', 'value', 'settled', 'amt_paid_sat', 'expiry', 'cltv_expiry']; + break; + default: + this.displayedColumns = ['creation_date', 'settle_date', 'memo', 'value', 'settled', 'amt_paid_sat', 'expiry', 'cltv_expiry']; + break; + } + } + + ngOnInit() { + this.store.select('rtlRoot') + .pipe(takeUntil(this.unSubs[0])) + .subscribe((rtlStore: fromRTLReducer.State) => { + rtlStore.effectErrors.forEach(effectsErr => { + if (effectsErr.action === 'FetchInvoices') { + this.flgLoading[0] = 'error'; + } + }); + this.settings = rtlStore.settings; + this.information = rtlStore.information; + this.logger.info(rtlStore); + this.loadInvoicesTable(rtlStore.invoices); + if (this.flgLoading[0] !== 'error') { + this.flgLoading[0] = (undefined !== rtlStore.invoices[0]) ? false : true; + } + }); + + } + + onAddInvoice(form: any) { + this.flgAnimate = true; + this.newlyAddedInvoiceMemo = this.memo; + this.newlyAddedInvoiceValue = this.invoiceValue; + this.store.dispatch(new RTLActions.OpenSpinner('Adding Invoice...')); + this.store.dispatch(new RTLActions.SaveNewInvoice({memo: this.memo, invoiceValue: this.invoiceValue})); + this.actions$ + .pipe( + takeUntil(this.unSubs[1]), + filter((action) => action.type === RTLActions.ADD_INVOICE) + ).subscribe((newInvoiceAction: RTLActions.AddInvoice) => { + this.logger.info(newInvoiceAction.payload); + this.invoicePaymentReq = newInvoiceAction.payload.payment_request; + }); + + } + + onInvoiceClick(selRow: Invoice, event: any) { + const selInvoice = this.invoices.data.filter(invoice => { + return invoice.payment_request === selRow.payment_request; + })[0]; + const reorderedInvoice = JSON.parse(JSON.stringify(selInvoice, [ + 'creation_date_str', 'settle_date_str', 'memo', 'receipt', 'r_preimage', 'r_hash', 'value', 'settled', 'payment_request', + 'description_hash', 'expiry', 'fallback_addr', 'cltv_expiry', 'route_hints', 'private', 'add_index', 'settle_index', + 'amt_paid', 'amt_paid_sat', 'amt_paid_msat' + ] , 2)); + this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: { + type: 'INFO', + message: JSON.stringify(reorderedInvoice) + }})); + } + + loadInvoicesTable(invoices) { + this.invoices = new MatTableDataSource([...invoices]); + this.invoices.sort = this.sort; + this.invoices.data.forEach(invoice => { + if (undefined !== invoice.creation_date_str) { + invoice.creation_date_str = (invoice.creation_date_str === '') ? '' : formatDate(invoice.creation_date_str, 'MMM/dd/yy HH:mm:ss', 'en-US'); + } + if (undefined !== invoice.settle_date_str) { + invoice.settle_date_str = (invoice.settle_date_str === '') ? '' : formatDate(invoice.settle_date_str, 'MMM/dd/yy HH:mm:ss', 'en-US'); + } + }); + setTimeout(() => { this.flgAnimate = false; }, 5000); + this.logger.info(this.invoices); + } + + resetData() { + this.memo = ''; + this.invoiceValue = 0; + } + + applyFilter(selFilter: string) { + this.invoices.filter = selFilter; + } + + ngOnDestroy() { + this.unSubs.forEach(completeSub => { + completeSub.next(); + completeSub.complete(); + }); + } + +} diff --git a/src/app/pages/lookups/channel-lookup/channel-lookup.component.css b/src/app/pages/lookups/channel-lookup/channel-lookup.component.css new file mode 100644 index 00000000..ef68f255 --- /dev/null +++ b/src/app/pages/lookups/channel-lookup/channel-lookup.component.css @@ -0,0 +1,3 @@ +.mat-list-base .mat-list-item, .mat-list-base .mat-list-option { + height: 38px !important; +} \ No newline at end of file diff --git a/src/app/pages/lookups/channel-lookup/channel-lookup.component.html b/src/app/pages/lookups/channel-lookup/channel-lookup.component.html new file mode 100644 index 00000000..0ed05159 --- /dev/null +++ b/src/app/pages/lookups/channel-lookup/channel-lookup.component.html @@ -0,0 +1,109 @@ +
+ + + + Channel Id + {{lookupResult.channel_id}} + + + + Channel Point + {{lookupResult.chan_point}} + + + + Last Update + {{lookupResult.last_update_str}} + + + + Capacity (Sats) + {{lookupResult.capacity | number}} + + + + +
+
+
+ + + +
Node 1
+
Node 1 (Your Node)
+
+
+ + + {{lookupResult.node1_pub}} + + + + Time Lock Delta + {{lookupResult.node1_policy.time_lock_delta}} + + + + Min HTLC + {{lookupResult.node1_policy.min_htlc}} + + + + Fee Base Msat + {{lookupResult.node1_policy.fee_base_msat}} + + + + Fee Rate Milli Msat + {{lookupResult.node1_policy.fee_rate_milli_msat}} + + + + Disabled + {{lookupResult.node1_policy.disabled}} + + + +
+
+
+ + + +
Node 2
+
Node 2 (Your Node)
+
+
+ + + {{lookupResult.node2_pub}} + + + + Time Lock Delta + {{lookupResult.node2_policy.time_lock_delta}} + + + + Min HTLC + {{lookupResult.node2_policy.min_htlc}} + + + + Fee Base Msat + {{lookupResult.node2_policy.fee_base_msat}} + + + + Fee Rate Milli Msat + {{lookupResult.node2_policy.fee_rate_milli_msat}} + + + + Disabled + {{lookupResult.node2_policy.disabled}} + + + +
+
diff --git a/src/app/pages/lookups/channel-lookup/channel-lookup.component.spec.ts b/src/app/pages/lookups/channel-lookup/channel-lookup.component.spec.ts new file mode 100644 index 00000000..919141e4 --- /dev/null +++ b/src/app/pages/lookups/channel-lookup/channel-lookup.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ChannelLookupComponent } from './channel-lookup.component'; + +describe('ChannelLookupComponent', () => { + let component: ChannelLookupComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ChannelLookupComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ChannelLookupComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/lookups/channel-lookup/channel-lookup.component.ts b/src/app/pages/lookups/channel-lookup/channel-lookup.component.ts new file mode 100644 index 00000000..8e39ff24 --- /dev/null +++ b/src/app/pages/lookups/channel-lookup/channel-lookup.component.ts @@ -0,0 +1,40 @@ +import { Component, OnInit, Input } from '@angular/core'; +import { formatDate } from '@angular/common'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; +import { Store } from '@ngrx/store'; + +import { ChannelEdge } from '../../../shared/models/lndModels'; +import * as fromRTLReducer from '../../../shared/store/rtl.reducers'; + +@Component({ + selector: 'rtl-channel-lookup', + templateUrl: './channel-lookup.component.html', + styleUrls: ['./channel-lookup.component.css'] +}) +export class ChannelLookupComponent implements OnInit { + @Input() lookupResult: ChannelEdge; + public node1_match = false; + public node2_match = false; + private unSubs: Array> = [new Subject(), new Subject(), new Subject(), new Subject()]; + + constructor(private store: Store) { } + + ngOnInit() { + if (undefined !== this.lookupResult && undefined !== this.lookupResult.last_update_str) { + this.lookupResult.last_update_str = (this.lookupResult.last_update_str === '') ? + '' : formatDate(this.lookupResult.last_update_str, 'MMM/dd/yy HH:mm:ss', 'en-US'); + } + this.store.select('rtlRoot') + .pipe(takeUntil(this.unSubs[0])) + .subscribe((rtlStore: fromRTLReducer.State) => { + if (this.lookupResult.node1_pub === rtlStore.information.identity_pubkey) { + this.node1_match = true; + } + if (this.lookupResult.node2_pub === rtlStore.information.identity_pubkey) { + this.node2_match = true; + } + }); + } + +} diff --git a/src/app/pages/lookups/lookups.component.html b/src/app/pages/lookups/lookups.component.html new file mode 100644 index 00000000..501d586c --- /dev/null +++ b/src/app/pages/lookups/lookups.component.html @@ -0,0 +1,47 @@ +
+
+ + + +

Lookups

+
+
+ +
+ + + + {{lookupField.name}} + + + + + + +
+ +
+
+ +
+
+
+
+
+
+ + + +

{{selectedField.name}} Details

+
+
+ +
+ + +

Error! Unable to find details!

+
+
+
+
+
diff --git a/src/app/pages/lookups/lookups.component.scss b/src/app/pages/lookups/lookups.component.scss new file mode 100644 index 00000000..d45059cb --- /dev/null +++ b/src/app/pages/lookups/lookups.component.scss @@ -0,0 +1,14 @@ +.tree-invisible { + display: none; +} + +.lookup-tree ul, +.lookup-tree li { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +.pl-3 { + padding-left: 3rem; +} \ No newline at end of file diff --git a/src/app/pages/lookups/lookups.component.spec.ts b/src/app/pages/lookups/lookups.component.spec.ts new file mode 100644 index 00000000..428d1de1 --- /dev/null +++ b/src/app/pages/lookups/lookups.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LookupsComponent } from './lookups.component'; + +describe('LookupsComponent', () => { + let component: LookupsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ LookupsComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(LookupsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/lookups/lookups.component.ts b/src/app/pages/lookups/lookups.component.ts new file mode 100644 index 00000000..79ae3cd9 --- /dev/null +++ b/src/app/pages/lookups/lookups.component.ts @@ -0,0 +1,94 @@ +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { Subject } from 'rxjs'; +import { takeUntil, filter } from 'rxjs/operators'; +import { Store } from '@ngrx/store'; +import { Actions } from '@ngrx/effects'; + +import { LoggerService } from '../../shared/services/logger.service'; + +import * as RTLActions from '../../shared/store/rtl.actions'; +import * as fromRTLReducer from '../../shared/store/rtl.reducers'; + +@Component({ + selector: 'rtl-lookups', + templateUrl: './lookups.component.html', + styleUrls: ['./lookups.component.scss'] +}) +export class LookupsComponent implements OnInit, OnDestroy { + public lookupKey = ''; + public lookupValue = {}; + public flgSetLookupValue = false; + public temp: any; + public messageObj = []; + public selectedField = { id: '0', name: 'Node', placeholder: 'Pubkey'}; + public lookupFields = [ + { id: '0', name: 'Node', placeholder: 'Pubkey'}, + { id: '1', name: 'Channel', placeholder: 'Channel ID'} + ]; + public flgLoading: Array = [true]; + private unSubs: Array> = [new Subject()]; + + constructor(private logger: LoggerService, private store: Store, private actions$: Actions) {} + + ngOnInit() { + this.actions$ + .pipe( + takeUntil(this.unSubs[0]), + filter((action) => (action.type === RTLActions.SET_LOOKUP || action.type === RTLActions.EFFECT_ERROR)) + ).subscribe((resLookup: RTLActions.SetLookup) => { + if (resLookup.payload.action === 'Lookup') { + this.flgLoading[0] = 'error'; + } else { + this.flgLoading[0] = true; + this.lookupValue = JSON.parse(JSON.stringify(resLookup.payload)); + this.flgSetLookupValue = true; + this.logger.info(this.lookupValue); + } + }); + } + + onLookup() { + this.flgSetLookupValue = false; + this.lookupValue = {}; + this.store.dispatch(new RTLActions.OpenSpinner('Searching ' + this.selectedField.name + '...')); + switch (this.selectedField.id) { + case '0': + this.store.dispatch(new RTLActions.PeerLookup(this.lookupKey.trim())); + break; + case '1': + this.store.dispatch(new RTLActions.ChannelLookup(this.lookupKey.trim())); + break; + default: + break; + } + } + + onSelectChange(event: any) { + this.flgSetLookupValue = false; + this.lookupKey = ''; + this.lookupValue = {}; + } + + resetData() { + this.flgSetLookupValue = false; + this.lookupKey = ''; + this.selectedField = { id: '0', name: 'Node', placeholder: 'Pubkey'}; + this.lookupValue = {}; + this.flgLoading.forEach((flg, i) => { + this.flgLoading[i] = true; + }); + } + + clearLookupValue() { + this.lookupValue = {}; + this.flgSetLookupValue = false; + } + + ngOnDestroy() { + this.unSubs.forEach(completeSub => { + completeSub.next(); + completeSub.complete(); + }); + } + +} diff --git a/src/app/pages/lookups/node-lookup/node-lookup.component.css b/src/app/pages/lookups/node-lookup/node-lookup.component.css new file mode 100644 index 00000000..ddab909a --- /dev/null +++ b/src/app/pages/lookups/node-lookup/node-lookup.component.css @@ -0,0 +1,7 @@ +.mat-table { + width:99%; +} + +.mat-list-base .mat-list-item, .mat-list-base .mat-list-option { + height: 38px !important; +} diff --git a/src/app/pages/lookups/node-lookup/node-lookup.component.html b/src/app/pages/lookups/node-lookup/node-lookup.component.html new file mode 100644 index 00000000..719dbef2 --- /dev/null +++ b/src/app/pages/lookups/node-lookup/node-lookup.component.html @@ -0,0 +1,56 @@ +
+
+ + +
+ + Alias + {{lookupResult.node.alias}} + + + + Pub Key + {{lookupResult.node.pub_key}} + + + + Color + {{lookupResult.node?.color}} + + + + Last Update + {{lookupResult.node.last_update_str}} + + + + Total Capacity (Sats) + {{lookupResult.total_capacity | number}} + + + + Number of Channels + {{lookupResult.num_channels | number}} + + + + + Addresses + + + Network +
{{address?.network}}
+
+ + Address +
{{address?.addr}}
+
+ + +
+
+
+
+
+
+
\ No newline at end of file diff --git a/src/app/pages/lookups/node-lookup/node-lookup.component.spec.ts b/src/app/pages/lookups/node-lookup/node-lookup.component.spec.ts new file mode 100644 index 00000000..64bc61bf --- /dev/null +++ b/src/app/pages/lookups/node-lookup/node-lookup.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { NodeLookupComponent } from './node-lookup.component'; + +describe('NodeLookupComponent', () => { + let component: NodeLookupComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ NodeLookupComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(NodeLookupComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/lookups/node-lookup/node-lookup.component.ts b/src/app/pages/lookups/node-lookup/node-lookup.component.ts new file mode 100644 index 00000000..dfb8a241 --- /dev/null +++ b/src/app/pages/lookups/node-lookup/node-lookup.component.ts @@ -0,0 +1,24 @@ +import { Component, OnInit, Input } from '@angular/core'; +import { formatDate } from '@angular/common'; + +import { GraphNode } from '../../../shared/models/lndModels'; + +@Component({ + selector: 'rtl-node-lookup', + templateUrl: './node-lookup.component.html', + styleUrls: ['./node-lookup.component.css'] +}) +export class NodeLookupComponent implements OnInit { + @Input() lookupResult: GraphNode; + public displayedColumns = ['network', 'addr']; + + constructor() { } + + ngOnInit() { + if (undefined !== this.lookupResult && undefined !== this.lookupResult.node && undefined !== this.lookupResult.node.last_update_str) { + this.lookupResult.node.last_update_str = (this.lookupResult.node.last_update_str === '') ? + '' : formatDate(this.lookupResult.node.last_update_str, 'MMM/dd/yy HH:mm:ss', 'en-US'); + } + } + +} diff --git a/src/app/pages/navigation/horizontal-navigation/horizontal-navigation.component.html b/src/app/pages/navigation/horizontal-navigation/horizontal-navigation.component.html new file mode 100644 index 00000000..816d2551 --- /dev/null +++ b/src/app/pages/navigation/horizontal-navigation/horizontal-navigation.component.html @@ -0,0 +1,19 @@ +
+
+ +
+ + +
+ +
+
+
+
+
diff --git a/src/app/pages/navigation/horizontal-navigation/horizontal-navigation.component.scss b/src/app/pages/navigation/horizontal-navigation/horizontal-navigation.component.scss new file mode 100644 index 00000000..010435ed --- /dev/null +++ b/src/app/pages/navigation/horizontal-navigation/horizontal-navigation.component.scss @@ -0,0 +1,19 @@ +.mat-menu-panel.child-menu { + min-width: 88px; + width:88px; + border-radius: 0; + margin-left: 30%; + margin-top: 6%; + .mat-menu-content { + .mat-menu-item { + padding: 0; + margin-top: -3px; + .mat-icon { + margin-right: 0; + } + button { + border-radius: 0; + } + } + } +} diff --git a/src/app/pages/navigation/horizontal-navigation/horizontal-navigation.component.spec.ts b/src/app/pages/navigation/horizontal-navigation/horizontal-navigation.component.spec.ts new file mode 100644 index 00000000..04191181 --- /dev/null +++ b/src/app/pages/navigation/horizontal-navigation/horizontal-navigation.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HorizontalNavigationComponent } from './horizontal-navigation.component'; + +describe('HorizontalNavigationComponent', () => { + let component: HorizontalNavigationComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ HorizontalNavigationComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(HorizontalNavigationComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/navigation/horizontal-navigation/horizontal-navigation.component.ts b/src/app/pages/navigation/horizontal-navigation/horizontal-navigation.component.ts new file mode 100644 index 00000000..c908cf98 --- /dev/null +++ b/src/app/pages/navigation/horizontal-navigation/horizontal-navigation.component.ts @@ -0,0 +1,69 @@ +import { Component, OnInit } from '@angular/core'; +import { Subject } from 'rxjs'; +import { takeUntil, filter } from 'rxjs/operators'; +import { Store } from '@ngrx/store'; +import { Actions } from '@ngrx/effects'; + +import { LoggerService } from '../../../shared/services/logger.service'; +import { MENU_DATA } from '../../../shared/models/navMenu'; + +import { RTLEffects } from '../../../shared/store/rtl.effects'; +import * as RTLActions from '../../../shared/store/rtl.actions'; +import * as fromRTLReducer from '../../../shared/store/rtl.reducers'; + +@Component({ + selector: 'rtl-horizontal-navigation', + templateUrl: './horizontal-navigation.component.html', + styleUrls: ['./horizontal-navigation.component.scss'] +}) +export class HorizontalNavigationComponent implements OnInit { + public menuNodes = []; + public logoutNode = []; + public showLogout = false; + public numPendingChannels = 0; + private unSubs = [new Subject(), new Subject(), new Subject()]; + + constructor(private logger: LoggerService, private store: Store, private actions$: Actions, private rtlEffects: RTLEffects) { + this.menuNodes = MENU_DATA.children; + } + + ngOnInit() { + this.store.select('rtlRoot') + .pipe(takeUntil(this.unSubs[0])) + .subscribe((rtlStore: fromRTLReducer.State) => { + this.numPendingChannels = rtlStore.numberOfPendingChannels; + }); + this.actions$ + .pipe( + takeUntil(this.unSubs[2]), + filter((action) => action.type === RTLActions.SIGNOUT || action.type === RTLActions.SIGNIN) + ).subscribe((action) => { + this.logger.warn(action); + if (action.type === RTLActions.SIGNIN) { + this.menuNodes.push({id: 100, parentId: 0, name: 'Logout', icon: 'eject'}); + } + if (action.type === RTLActions.SIGNOUT) { + this.menuNodes.pop(); + } + }); + if (sessionStorage.getItem('token')) { + this.menuNodes.push({id: 100, parentId: 0, name: 'Logout', icon: 'eject'}); + } + } + + onClick(node) { + if (node.name === 'Logout') { + this.store.dispatch(new RTLActions.OpenConfirmation({ + width: '70%', data: { type: 'CONFIRM', titleMessage: 'Logout from this device?', noBtnText: 'Cancel', yesBtnText: 'Logout' + }})); + this.rtlEffects.closeConfirm + .pipe(takeUntil(this.unSubs[1])) + .subscribe(confirmRes => { + if (confirmRes) { + this.showLogout = false; + this.store.dispatch(new RTLActions.Signout()); + } + }); + } + } +} diff --git a/src/app/pages/navigation/side-navigation/side-navigation.component.html b/src/app/pages/navigation/side-navigation/side-navigation.component.html new file mode 100644 index 00000000..2f549a82 --- /dev/null +++ b/src/app/pages/navigation/side-navigation/side-navigation.component.html @@ -0,0 +1,65 @@ + +
+ + + + + + +
+
+

Alias: {{information?.alias}}

+

Chain: {{informationChain.chain | titlecase}} [{{informationChain.network | titlecase}}]

+

LND Version: {{information?.version}}

+
+
+ + + + {{node.icon}} + {{node.name}} + + + +
+
+ {{node.icon}}{{node.name}} +
+ +
+
+
+ + + {{node.icon}} + {{node.name}} + + + + + + {{node.icon}} + {{node.name}} + + + +
+ {{node.icon}} + {{node.name}} +
+
+ +
+
+
+ + + {{node.icon}} + {{node.name}} + + diff --git a/src/app/pages/navigation/side-navigation/side-navigation.component.scss b/src/app/pages/navigation/side-navigation/side-navigation.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/pages/navigation/side-navigation/side-navigation.component.spec.ts b/src/app/pages/navigation/side-navigation/side-navigation.component.spec.ts new file mode 100644 index 00000000..660c9832 --- /dev/null +++ b/src/app/pages/navigation/side-navigation/side-navigation.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SideNavigationComponent } from './side-navigation.component'; + +describe('SideNavigationComponent', () => { + let component: SideNavigationComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ SideNavigationComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SideNavigationComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/navigation/side-navigation/side-navigation.component.ts b/src/app/pages/navigation/side-navigation/side-navigation.component.ts new file mode 100644 index 00000000..d05bb1be --- /dev/null +++ b/src/app/pages/navigation/side-navigation/side-navigation.component.ts @@ -0,0 +1,153 @@ +import { Component, OnInit, OnDestroy, Output, EventEmitter } from '@angular/core'; +import { Router } from '@angular/router'; +import { Subject, Observable, of } from 'rxjs'; +import { takeUntil, filter } from 'rxjs/operators'; +import { Store } from '@ngrx/store'; +import { Actions } from '@ngrx/effects'; +import { environment } from '../../../../environments/environment'; + +import { FlatTreeControl } from '@angular/cdk/tree'; +import { MatTreeFlatDataSource, MatTreeFlattener } from '@angular/material/tree'; + +import { Settings } from '../../../shared/models/RTLconfig'; +import { LoggerService } from '../../../shared/services/logger.service'; +import { GetInfo, GetInfoChain } from '../../../shared/models/lndModels'; +import { MenuNode, FlatMenuNode, MENU_DATA } from '../../../shared/models/navMenu'; + +import { RTLEffects } from '../../../shared/store/rtl.effects'; +import * as RTLActions from '../../../shared/store/rtl.actions'; +import * as fromRTLReducer from '../../../shared/store/rtl.reducers'; + +@Component({ + selector: 'rtl-side-navigation', + templateUrl: './side-navigation.component.html', + styleUrls: ['./side-navigation.component.scss'] +}) +export class SideNavigationComponent implements OnInit, OnDestroy { + @Output() ChildNavClicked = new EventEmitter(); + public version = ''; + public settings: Settings; + public information: GetInfo = {}; + public informationChain: GetInfoChain = {}; + public flgLoading = true; + public logoutNode = [{id: 100, parentId: 0, name: 'Logout', icon: 'eject'}]; + public showLogout = false; + public numPendingChannels = 0; + public smallScreen = false; + private unSubs = [new Subject(), new Subject(), new Subject()]; + treeControl: FlatTreeControl; + treeControlLogout: FlatTreeControl; + treeFlattener: MatTreeFlattener; + treeFlattenerLogout: MatTreeFlattener; + navMenus: MatTreeFlatDataSource; + navMenusLogout: MatTreeFlatDataSource; + + constructor(private logger: LoggerService, private store: Store, private actions$: Actions, private rtlEffects: RTLEffects, private router: Router) { + this.version = environment.VERSION; + if (MENU_DATA.children[MENU_DATA.children.length - 1].id === 100) { + MENU_DATA.children.pop(); + } + this.treeFlattener = new MatTreeFlattener(this.transformer, this.getLevel, this.isExpandable, this.getChildren); + this.treeControl = new FlatTreeControl(this.getLevel, this.isExpandable); + this.navMenus = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener); + this.navMenus.data = MENU_DATA.children; + + this.treeFlattenerLogout = new MatTreeFlattener(this.transformer, this.getLevel, this.isExpandable, this.getChildren); + this.treeControlLogout = new FlatTreeControl(this.getLevel, this.isExpandable); + this.navMenusLogout = new MatTreeFlatDataSource(this.treeControlLogout, this.treeFlattenerLogout); + this.navMenusLogout.data = this.logoutNode; + } + + ngOnInit() { + this.store.select('rtlRoot') + .pipe(takeUntil(this.unSubs[0])) + .subscribe((rtlStore: fromRTLReducer.State) => { + this.settings = rtlStore.settings; + this.information = rtlStore.information; + this.numPendingChannels = rtlStore.numberOfPendingChannels; + + if (undefined !== this.information.identity_pubkey) { + if (undefined !== this.information.chains && typeof this.information.chains[0] === 'string') { + this.informationChain.chain = this.information.chains[0].toString(); + this.informationChain.network = (this.information.testnet) ? 'Testnet' : 'Mainnet'; + } else if (typeof this.information.chains[0] === 'object' && this.information.chains[0].hasOwnProperty('chain')) { + const getInfoChain = this.information.chains[0]; + this.informationChain.chain = getInfoChain.chain; + this.informationChain.network = getInfoChain.network; + } + } else { + this.informationChain.chain = ''; + this.informationChain.network = ''; + } + + this.flgLoading = (undefined !== this.information.identity_pubkey) ? false : true; + this.showLogout = (sessionStorage.getItem('token')) ? true : false; + if (!sessionStorage.getItem('token')) { + this.flgLoading = false; + } + if (window.innerWidth <= 414) { + this.smallScreen = true; + } + this.logger.info(rtlStore); + }); + this.actions$ + .pipe( + takeUntil(this.unSubs[2]), + filter((action) => action.type === RTLActions.SIGNOUT) + ).subscribe(() => { + this.showLogout = false; + }); + } + + private transformer(node: MenuNode, level: number) { return new FlatMenuNode(!!node.children, level, node.id, node.parentId, node.name, node.icon, node.link); } + + private getLevel(node: FlatMenuNode) { return node.level; } + + private isExpandable(node: FlatMenuNode) { return node.expandable; } + + private getChildren(node: MenuNode): Observable { return of(node.children); } + + hasChild(_: number, _nodeData: FlatMenuNode) { return _nodeData.expandable; } + + toggleTree(node: FlatMenuNode) { + this.treeControl.collapseAll(); + if (node.parentId === 0) { + this.treeControl.expandDescendants(node); + this.router.navigate([node.link]); + } else { + const parentNode = this.treeControl.dataNodes.filter(dataNode => { + return dataNode.id === node.parentId; + })[0]; + this.treeControl.expandDescendants(parentNode); + } + } + + onClick(node: MenuNode) { + if (node.name === 'Logout') { + this.store.dispatch(new RTLActions.OpenConfirmation({ + width: '70%', data: { type: 'CONFIRM', titleMessage: 'Logout from this device?', noBtnText: 'Cancel', yesBtnText: 'Logout' + }})); + this.rtlEffects.closeConfirm + .pipe(takeUntil(this.unSubs[1])) + .subscribe(confirmRes => { + if (confirmRes) { + this.showLogout = false; + this.store.dispatch(new RTLActions.Signout()); + } + }); + } + this.ChildNavClicked.emit(node); + } + + onChildNavClicked(node) { + this.ChildNavClicked.emit(node); + } + + ngOnDestroy() { + this.unSubs.forEach(completeSub => { + completeSub.next(); + completeSub.complete(); + }); + } + +} diff --git a/src/app/pages/navigation/top-menu/top-menu.component.html b/src/app/pages/navigation/top-menu/top-menu.component.html new file mode 100644 index 00000000..1946b13a --- /dev/null +++ b/src/app/pages/navigation/top-menu/top-menu.component.html @@ -0,0 +1,22 @@ + +

+ publish + Version: {{version}} +

+ + perm_data_setting + Node Config + + + help + Help + + + eject + Logout + +
+ + diff --git a/src/app/pages/navigation/top-menu/top-menu.component.scss b/src/app/pages/navigation/top-menu/top-menu.component.scss new file mode 100644 index 00000000..6a2bd51c --- /dev/null +++ b/src/app/pages/navigation/top-menu/top-menu.component.scss @@ -0,0 +1,26 @@ +.mat-menu-panel.top-menu{ + .mat-toolbar, .mat-toolbar-row{ + height: 100px !important; + padding: 0 16px !important; + } + .info-block{ + width: 230px; + p{ + font-size: 16px; + line-height: 22px; + text-align: center; + } + } + .mat-menu-item{ + height: 36px; + line-height: 36px; + } + .mat-menu-content { + p{ + cursor: default; + mat-icon, span, div { + cursor: default; + } + } + } +} diff --git a/src/app/pages/navigation/top-menu/top-menu.component.spec.ts b/src/app/pages/navigation/top-menu/top-menu.component.spec.ts new file mode 100644 index 00000000..999b9093 --- /dev/null +++ b/src/app/pages/navigation/top-menu/top-menu.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TopMenuComponent } from './top-menu.component'; + +describe('TopMenuComponent', () => { + let component: TopMenuComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ TopMenuComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(TopMenuComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/navigation/top-menu/top-menu.component.ts b/src/app/pages/navigation/top-menu/top-menu.component.ts new file mode 100644 index 00000000..c74c01b0 --- /dev/null +++ b/src/app/pages/navigation/top-menu/top-menu.component.ts @@ -0,0 +1,93 @@ +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { Subject } from 'rxjs/Subject'; +import { takeUntil, filter } from 'rxjs/operators'; +import { Store } from '@ngrx/store'; +import { Actions } from '@ngrx/effects'; + +import { Settings } from '../../../shared/models/RTLconfig'; +import { LoggerService } from '../../../shared/services/logger.service'; +import { GetInfo, GetInfoChain } from '../../../shared/models/lndModels'; +import { environment } from '../../../../environments/environment'; + +import { RTLEffects } from '../../../shared/store/rtl.effects'; +import * as fromRTLReducer from '../../../shared/store/rtl.reducers'; +import * as RTLActions from '../../../shared/store/rtl.actions'; + +@Component({ + selector: 'rtl-top-menu', + templateUrl: './top-menu.component.html', + styleUrls: ['./top-menu.component.scss'] +}) +export class TopMenuComponent implements OnInit, OnDestroy { + public settings: Settings; + public version = ''; + public information: GetInfo = {}; + public informationChain: GetInfoChain = {}; + public flgLoading = true; + public showLogout = false; + private unSubs = [new Subject(), new Subject(), new Subject()]; + + constructor(private logger: LoggerService, private store: Store, private rtlEffects: RTLEffects, private actions$: Actions) { + this.version = environment.VERSION; + } + + ngOnInit() { + this.store.select('rtlRoot') + .pipe(takeUntil(this.unSubs[0])) + .subscribe((rtlStore: fromRTLReducer.State) => { + this.settings = rtlStore.settings; + + this.information = rtlStore.information; + this.flgLoading = (undefined !== this.information.identity_pubkey) ? false : true; + + if (undefined !== this.information.identity_pubkey) { + if (undefined !== this.information.chains && typeof this.information.chains[0] === 'string') { + this.informationChain.chain = this.information.chains[0].toString(); + this.informationChain.network = (this.information.testnet) ? 'Testnet' : 'Mainnet'; + } else if (typeof this.information.chains[0] === 'object' && this.information.chains[0].hasOwnProperty('chain')) { + const getInfoChain = this.information.chains[0]; + this.informationChain.chain = getInfoChain.chain; + this.informationChain.network = getInfoChain.network; + } + } else { + this.informationChain.chain = ''; + this.informationChain.network = ''; + } + this.showLogout = (sessionStorage.getItem('token')) ? true : false; + + this.logger.info(rtlStore); + if (!sessionStorage.getItem('token')) { + this.flgLoading = false; + } + }); + this.actions$ + .pipe( + takeUntil(this.unSubs[2]), + filter((action) => action.type === RTLActions.SIGNOUT) + ).subscribe(() => { + this.showLogout = false; + }); + } + + onClick() { + this.store.dispatch(new RTLActions.OpenConfirmation({ + width: '70%', data: { type: 'CONFIRM', titleMessage: 'Logout from this device?', noBtnText: 'Cancel', yesBtnText: 'Logout' + }})); + this.rtlEffects.closeConfirm + .pipe(takeUntil(this.unSubs[1])) + .subscribe(confirmRes => { + if (confirmRes) { + this.showLogout = false; + this.store.dispatch(new RTLActions.Signout()); + } + }); + } + + ngOnDestroy() { + this.unSubs.forEach(completeSub => { + completeSub.next(); + completeSub.complete(); + }); + } + +} diff --git a/src/app/pages/payments/payments.component.html b/src/app/pages/payments/payments.component.html new file mode 100644 index 00000000..cf89b995 --- /dev/null +++ b/src/app/pages/payments/payments.component.html @@ -0,0 +1,81 @@ +
+
+ + + +

Verify and Send Payments

+
+
+ +
+
+ + + +
+
+ + +
+
+
+
+
+
+ + +
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Creation Date{{payment?.creation_date_str}}Payment Hash +
{{payment?.payment_hash | slice:0:10}}...
+
Fee{{payment?.fee | number}}Value{{payment?.value | number}}Payment Pre Image +
{{payment?.payment_preimage | slice:0:10}}...
+
Value MSat{{payment?.value_msat | number}}Value Sat{{payment?.value_sat | number}}Path{{payment?.path?.length || 0}} Hops
+
+
+
+
+
diff --git a/src/app/pages/payments/payments.component.scss b/src/app/pages/payments/payments.component.scss new file mode 100644 index 00000000..a59d5a78 --- /dev/null +++ b/src/app/pages/payments/payments.component.scss @@ -0,0 +1,43 @@ +.mat-column-path { + padding-left: 10px; +} + +.mat-expansion-panel-header { + padding: 0; +} + +.mat-accordion .mat-expansion-panel { + padding: 0 10px; +} + +.ml-minus-24px { + margin-left: -24px; +} + +.info-column { + flex: 1 1 34%; + box-sizing: border-box; + max-width: 34%; +} + +.info-value { + flex: 1 1 64%; + max-width: 64%; + word-break: break-word; +} + +table { + width:100%; +} + +.table-container { + height: 68vh; + overflow: auto; +} + +@media screen and (max-width: 414px) { + .table-container { + max-height: 46vh; + overflow: auto; + } +} diff --git a/src/app/pages/payments/payments.component.ts b/src/app/pages/payments/payments.component.ts new file mode 100644 index 00000000..e9c24bd2 --- /dev/null +++ b/src/app/pages/payments/payments.component.ts @@ -0,0 +1,192 @@ +import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core'; +import { formatDate } from '@angular/common'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; +import { Store } from '@ngrx/store'; + +import { MatTableDataSource, MatSort } from '@angular/material'; +import { Settings } from '../../shared/models/RTLconfig'; +import { GetInfo, Payment, PayRequest } from '../../shared/models/lndModels'; +import { LoggerService } from '../../shared/services/logger.service'; + +import { newlyAddedRowAnimation } from '../../shared/animation/row-animation'; +import { RTLEffects } from '../../shared/store/rtl.effects'; +import * as RTLActions from '../../shared/store/rtl.actions'; +import * as fromRTLReducer from '../../shared/store/rtl.reducers'; + +@Component({ + selector: 'rtl-payments', + templateUrl: './payments.component.html', + styleUrls: ['./payments.component.scss'], + animations: [newlyAddedRowAnimation] +}) +export class PaymentsComponent implements OnInit, OnDestroy { + @ViewChild(MatSort) sort: MatSort; + @ViewChild('sendPaymentForm') form; + public newlyAddedPayment = ''; + public flgAnimate = true; + public settings: Settings; + public flgLoading: Array = [true]; + public information: GetInfo = {}; + public payments: any; + public paymentJSONArr: Payment[] = []; + public displayedColumns = []; + public paymentDecoded: PayRequest = {}; + public paymentRequest = ''; + private unsub: Array> = [new Subject(), new Subject(), new Subject(), new Subject()]; + + constructor(private logger: LoggerService, private store: Store, private rtlEffects: RTLEffects) { + switch (true) { + case (window.innerWidth <= 415): + this.displayedColumns = ['creation_date', 'fee', 'value']; + break; + case (window.innerWidth > 415 && window.innerWidth <= 730): + this.displayedColumns = ['creation_date', 'payment_hash', 'fee', 'value', 'payment_preimage']; + break; + case (window.innerWidth > 730 && window.innerWidth <= 1024): + this.displayedColumns = ['creation_date', 'payment_hash', 'fee', 'value', 'payment_preimage', 'path']; + break; + case (window.innerWidth > 1024 && window.innerWidth <= 1280): + this.displayedColumns = ['creation_date', 'payment_hash', 'fee', 'value', 'payment_preimage', 'value_msat', 'value_sat', 'path']; + break; + default: + this.displayedColumns = ['creation_date', 'payment_hash', 'fee', 'value', 'payment_preimage', 'value_msat', 'value_sat', 'path']; + break; + } + } + + ngOnInit() { + this.store.select('rtlRoot') + .pipe(takeUntil(this.unsub[0])) + .subscribe((rtlStore: fromRTLReducer.State) => { + rtlStore.effectErrors.forEach(effectsErr => { + if (effectsErr.action === 'FetchPayments') { + this.flgLoading[0] = 'error'; + } + }); + this.settings = rtlStore.settings; + this.information = rtlStore.information; + this.paymentJSONArr = (rtlStore.payments.length > 0) ? rtlStore.payments : []; + this.payments = (undefined === rtlStore.payments) ? new MatTableDataSource([]) : new MatTableDataSource([...this.paymentJSONArr]); + this.payments.data = this.paymentJSONArr; + this.payments.sort = this.sort; + this.payments.data.forEach(payment => { + payment.creation_date_str = (payment.creation_date_str === '') ? '' : formatDate(payment.creation_date_str, 'MMM/dd/yy HH:mm:ss', 'en-US'); + }); + setTimeout(() => { this.flgAnimate = false; }, 5000); + if (this.flgLoading[0] !== 'error') { + this.flgLoading[0] = (undefined !== this.paymentJSONArr[0]) ? false : true; + } + this.logger.info(rtlStore); + }); + + } + + onSendPayment() { + if (undefined !== this.paymentDecoded.timestamp_str) { + this.sendPayment(); + } else { + this.store.dispatch(new RTLActions.OpenSpinner('Decoding Payment...')); + this.store.dispatch(new RTLActions.DecodePayment(this.paymentRequest)); + this.rtlEffects.setDecodedPayment + .pipe(takeUntil(this.unsub[1])) + .subscribe(decodedPayment => { + this.paymentDecoded = decodedPayment; + if (undefined !== this.paymentDecoded.timestamp_str) { + this.paymentDecoded.timestamp_str = (this.paymentDecoded.timestamp_str === '') ? '' : + formatDate(this.paymentDecoded.timestamp_str, 'MMM/dd/yy HH:mm:ss', 'en-US'); + if (undefined === this.paymentDecoded.num_satoshis) { + this.paymentDecoded.num_satoshis = '0'; + } + this.sendPayment(); + } else { + this.resetData(); + } + }); + } + + } + + sendPayment() { + this.flgAnimate = true; + this.newlyAddedPayment = this.paymentDecoded.payment_hash; + if (undefined === this.paymentDecoded.num_satoshis || this.paymentDecoded.num_satoshis === '' || this.paymentDecoded.num_satoshis === '0') { + const titleMsg = 'This is an empty invoice. Enter the amount (Sats) to pay.'; + this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data: { + type: 'CONFIRM', titleMessage: titleMsg, message: JSON.stringify(this.paymentDecoded), noBtnText: 'Cancel', yesBtnText: 'Send', flgShowInput: true, getInputs: [ + {placeholder: 'Amount (Sats)', inputType: 'number', inputValue: ''} + ] + }})); + this.rtlEffects.closeConfirm + .pipe(takeUntil(this.unsub[2])) + .subscribe(confirmRes => { + if (confirmRes) { + this.paymentDecoded.num_satoshis = confirmRes[0].inputValue; + this.store.dispatch(new RTLActions.OpenSpinner('Sending Payment...')); + this.store.dispatch(new RTLActions.SendPayment([this.paymentRequest, this.paymentDecoded, true])); + this.resetData(); + } + }); + } else { + this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data: { + type: 'CONFIRM', titleMessage: 'Send Payment', noBtnText: 'Cancel', yesBtnText: 'Send', message: JSON.stringify(this.paymentDecoded) + }})); + this.rtlEffects.closeConfirm + .pipe(takeUntil(this.unsub[3])) + .subscribe(confirmRes => { + if (confirmRes) { + this.store.dispatch(new RTLActions.OpenSpinner('Sending Payment...')); + this.store.dispatch(new RTLActions.SendPayment([this.paymentRequest, this.paymentDecoded, false])); + this.resetData(); + } + }); + } + } + + onVerifyPayment() { + this.store.dispatch(new RTLActions.OpenSpinner('Decoding Payment...')); + this.store.dispatch(new RTLActions.DecodePayment(this.paymentRequest)); + this.rtlEffects.setDecodedPayment.subscribe(decodedPayment => { + this.paymentDecoded = decodedPayment; + if (undefined !== this.paymentDecoded.timestamp_str) { + this.paymentDecoded.timestamp_str = (this.paymentDecoded.timestamp_str === '') ? '' : + formatDate(this.paymentDecoded.timestamp_str, 'MMM/dd/yy HH:mm:ss', 'en-US'); + } else { + this.resetData(); + } + }); + } + + resetData() { + this.form.reset(); + } + + onPaymentClick(selRow: Payment, event: any) { + const flgExpansionClicked = event.target.className.includes('mat-expansion-panel-header') || event.target.className.includes('mat-expansion-indicator'); + if (flgExpansionClicked) { + return; + } + const selPayment = this.payments.data.filter(payment => { + return payment.payment_hash === selRow.payment_hash; + })[0]; + const reorderedPayment = JSON.parse(JSON.stringify(selPayment, [ + 'creation_date_str', 'payment_hash', 'fee', 'value_msat', 'value_sat', 'value', 'payment_preimage', 'path' + ] , 2)); + this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: { + type: 'INFO', + message: JSON.stringify(reorderedPayment) + }})); + } + + applyFilter(selFilter: string) { + this.payments.filter = selFilter; + } + + ngOnDestroy() { + this.unsub.forEach(completeSub => { + completeSub.next(); + completeSub.complete(); + }); + } + +} diff --git a/src/app/pages/peers/peers.component.html b/src/app/pages/peers/peers.component.html new file mode 100644 index 00000000..f29dacfd --- /dev/null +++ b/src/app/pages/peers/peers.component.html @@ -0,0 +1,87 @@ +
+
+ + + +

Add Peer

+
+
+ +
+ + + +
+ +
+
+ +
+
+
+
+
+
+ + +
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Detachlink_off Pub Key +
{{peer?.pub_key | slice:0:10}}...
+
Alias {{peer?.alias}} Address {{peer?.address}} Bytes Sent {{peer?.bytes_sent | number}} Bytes Recv {{peer?.bytes_recv | number}} {{information?.smaller_currency_unit}} Sent {{peer?.sat_sent | number}} {{information?.smaller_currency_unit}} Recv {{peer?.sat_recv | number}} Inbound {{peer?.inbound}} Ping {{peer?.ping_time | number}}
+
+
+
+
+
diff --git a/src/app/pages/peers/peers.component.scss b/src/app/pages/peers/peers.component.scss new file mode 100644 index 00000000..4d8df74b --- /dev/null +++ b/src/app/pages/peers/peers.component.scss @@ -0,0 +1,30 @@ +.mat-column-detach { + flex: 0 0 5%; + min-width: 50px; +} + +.mat-column-alias, .mat-column-address { + flex: 0 0 15%; + min-width: 100px; +} + +mat-cell.mat-column-detach { + cursor: pointer; +} + + +table { + width:100%; +} + +.table-container { + height: 68vh; + overflow: auto; +} + +@media screen and (max-width: 414px) { + .table-container { + height: 40vh; + overflow: auto; + } +} diff --git a/src/app/pages/peers/peers.component.spec.ts b/src/app/pages/peers/peers.component.spec.ts new file mode 100644 index 00000000..a5fe2db8 --- /dev/null +++ b/src/app/pages/peers/peers.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PeersComponent } from './peers.component'; + +describe('PeersComponent', () => { + let component: PeersComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ PeersComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(PeersComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/peers/peers.component.ts b/src/app/pages/peers/peers.component.ts new file mode 100644 index 00000000..7b23b2ac --- /dev/null +++ b/src/app/pages/peers/peers.component.ts @@ -0,0 +1,157 @@ +import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core'; +import { Subject } from 'rxjs'; +import { takeUntil, filter, take } from 'rxjs/operators'; +import { Store } from '@ngrx/store'; +import { Actions } from '@ngrx/effects'; + +import { MatTableDataSource, MatSort } from '@angular/material'; +import { Peer, GetInfo } from '../../shared/models/lndModels'; +import { LoggerService } from '../../shared/services/logger.service'; + +import { newlyAddedRowAnimation } from '../../shared/animation/row-animation'; +import { RTLEffects } from '../../shared/store/rtl.effects'; +import * as RTLActions from '../../shared/store/rtl.actions'; +import * as fromRTLReducer from '../../shared/store/rtl.reducers'; + +@Component({ + selector: 'rtl-peers', + templateUrl: './peers.component.html', + styleUrls: ['./peers.component.scss'], + animations: [newlyAddedRowAnimation] +}) +export class PeersComponent implements OnInit, OnDestroy { + @ViewChild(MatSort) sort: MatSort; + public newlyAddedPeer = ''; + public flgAnimate = true; + public displayedColumns = []; + public peerAddress = ''; + public peers: any; + public information: GetInfo = {}; + public flgLoading: Array = [true]; // 0: peers + private unSubs: Array> = [new Subject(), new Subject(), new Subject(), new Subject()]; + + constructor(private logger: LoggerService, private store: Store, private rtlEffects: RTLEffects, private actions$: Actions) { + switch (true) { + case (window.innerWidth <= 415): + this.displayedColumns = ['detach', 'pub_key', 'alias']; + break; + case (window.innerWidth > 415 && window.innerWidth <= 730): + this.displayedColumns = ['detach', 'pub_key', 'alias', 'address', 'sat_sent', 'sat_recv']; + break; + case (window.innerWidth > 730 && window.innerWidth <= 1024): + this.displayedColumns = ['detach', 'pub_key', 'alias', 'address', 'sat_sent', 'sat_recv', 'inbound']; + break; + case (window.innerWidth > 1024 && window.innerWidth <= 1280): + this.displayedColumns = ['detach', 'pub_key', 'alias', 'address', 'sat_sent', 'sat_recv', 'inbound', 'ping_time']; + break; + default: + this.displayedColumns = ['detach', 'pub_key', 'alias', 'address', 'bytes_sent', 'bytes_recv', 'sat_sent', 'sat_recv', 'inbound', 'ping_time']; + break; + } + } + + ngOnInit() { + this.store.select('rtlRoot') + .pipe(takeUntil(this.unSubs[0])) + .subscribe((rtlStore: fromRTLReducer.State) => { + rtlStore.effectErrors.forEach(effectsErr => { + if (effectsErr.action === 'FetchPeers') { + this.flgLoading[0] = 'error'; + } + }); + this.information = rtlStore.information; + this.peers = new MatTableDataSource([]); + this.peers.data = []; + if (undefined !== rtlStore.peers) { + this.peers = new MatTableDataSource([...rtlStore.peers]); + this.peers.data = rtlStore.peers; + setTimeout(() => { this.flgAnimate = false; }, 5000); + } + this.peers.sort = this.sort; + if (this.flgLoading[0] !== 'error') { + this.flgLoading[0] = false; + } + this.logger.info(rtlStore); + }); + this.actions$ + .pipe( + takeUntil(this.unSubs[1]), + filter((action) => action.type === RTLActions.SET_PEERS) + ).subscribe((setPeers: RTLActions.SetPeers) => { + this.peerAddress = undefined; + }); + } + + onAddPeer(form: any) { + this.flgAnimate = true; + const pattern = '^([a-zA-Z0-9]){1,66}@(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]):[0-9]+$'; + const deviderIndex = this.peerAddress.search('@'); + let pubkey = ''; + let host = ''; + + if (new RegExp(pattern).test(this.peerAddress)) { + pubkey = this.peerAddress.substring(0, deviderIndex); + host = this.peerAddress.substring(deviderIndex + 1); + this.addPeerWithParams(pubkey, host); + } else { + pubkey = (deviderIndex > -1) ? this.peerAddress.substring(0, deviderIndex) : this.peerAddress; + this.store.dispatch(new RTLActions.OpenSpinner('Getting Node Address...')); + this.store.dispatch(new RTLActions.FetchGraphNode(pubkey)); + this.rtlEffects.setGraphNode + .pipe(take(1)) + .subscribe(graphNode => { + host = (undefined === graphNode.node.addresses || undefined === graphNode.node.addresses[0].addr) ? '' : graphNode.node.addresses[0].addr; + this.addPeerWithParams(pubkey, host); + }); + } + } + + addPeerWithParams(pubkey: string, host: string) { + this.newlyAddedPeer = pubkey; + this.store.dispatch(new RTLActions.OpenSpinner('Adding Peer...')); + this.store.dispatch(new RTLActions.SaveNewPeer({pubkey: pubkey, host: host, perm: false})); + } + + onPeerClick(selRow: Peer, event: any) { + const flgCloseClicked = event.target.className.includes('mat-column-detach') || event.target.className.includes('mat-icon'); + if (flgCloseClicked) { + return; + } + const selPeer = this.peers.data.filter(peer => { + return peer.pub_key === selRow.pub_key; + })[0]; + const reorderedPeer = JSON.parse(JSON.stringify(selPeer, [ + 'pub_key', 'alias', 'address', 'bytes_sent', 'bytes_recv', 'sat_sent', 'sat_recv', 'inbound', 'ping_time' + ] , 2)); + this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: { type: 'INFO', message: JSON.stringify(reorderedPeer)}})); + } + + resetData() { + this.peerAddress = ''; + } + + onPeerDetach(peerToDetach: Peer) { + const msg = 'Detach peer: ' + peerToDetach.pub_key; + const msg_type = 'CONFIRM'; + this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data: { type: msg_type, titleMessage: msg, noBtnText: 'Cancel', yesBtnText: 'Detach'}})); + this.rtlEffects.closeConfirm + .pipe(takeUntil(this.unSubs[3])) + .subscribe(confirmRes => { + if (confirmRes) { + this.store.dispatch(new RTLActions.OpenSpinner('Detaching Peer...')); + this.store.dispatch(new RTLActions.DetachPeer({pubkey: peerToDetach.pub_key})); + } + }); + } + + applyFilter(selFilter: string) { + this.peers.filter = selFilter; + } + + ngOnDestroy() { + this.unSubs.forEach(completeSub => { + completeSub.next(); + completeSub.complete(); + }); + } +} diff --git a/src/app/pages/server-config/server-config.component.html b/src/app/pages/server-config/server-config.component.html new file mode 100644 index 00000000..f412064d --- /dev/null +++ b/src/app/pages/server-config/server-config.component.html @@ -0,0 +1,37 @@ +
+
+ + + +

Show Configurations

+
+
+ +
+ + LND + BITCOIND + RTL + +
+ + +
+
+
+ + + +

{{conf}}

+
+ +

{{conf}}

+
+ +
+
+
+
+
+
+
diff --git a/src/app/pages/server-config/server-config.component.scss b/src/app/pages/server-config/server-config.component.scss new file mode 100644 index 00000000..15d29fee --- /dev/null +++ b/src/app/pages/server-config/server-config.component.scss @@ -0,0 +1,3 @@ +h4 { + word-break: break-word; +} diff --git a/src/app/pages/server-config/server-config.component.ts b/src/app/pages/server-config/server-config.component.ts new file mode 100644 index 00000000..ec82a59e --- /dev/null +++ b/src/app/pages/server-config/server-config.component.ts @@ -0,0 +1,72 @@ +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; +import { Store } from '@ngrx/store'; + +import { RTLEffects } from '../../shared/store/rtl.effects'; +import * as RTLActions from '../../shared/store/rtl.actions'; +import * as fromRTLReducer from '../../shared/store/rtl.reducers'; +import { Authentication } from '../../shared/models/RTLconfig'; + +@Component({ + selector: 'rtl-server-config', + templateUrl: './server-config.component.html', + styleUrls: ['./server-config.component.scss'] +}) +export class ServerConfigComponent implements OnInit, OnDestroy { + public selectedNodeType = 'lnd'; + public authSettings: Authentication = {}; + public showLND = false; + public showBitcoind = false; + public configData = ''; + private unsubs: Array> = [new Subject(), new Subject()]; + + constructor(private store: Store, private rtlEffects: RTLEffects) {} + + ngOnInit() { + this.store.select('rtlRoot') + .pipe(takeUntil(this.unsubs[0])) + .subscribe((rtlStore: fromRTLReducer.State) => { + rtlStore.effectErrors.forEach(effectsErr => { + if (effectsErr.action === 'fetchConfig') { + this.resetData(); + } + }); + this.authSettings = rtlStore.authSettings; + if (undefined !== this.authSettings && this.authSettings.lndConfigPath !== '') { + this.showLND = true; + } + if (undefined !== this.authSettings && undefined !== this.authSettings.bitcoindConfigPath && this.authSettings.bitcoindConfigPath !== '') { + this.showBitcoind = true; + } + }); + } + + onSelectionChange(event) { + this.selectedNodeType = event.value; + this.configData = ''; + } + + onShowConfig() { + this.store.dispatch(new RTLActions.OpenSpinner('Opening Config File...')); + this.store.dispatch(new RTLActions.FetchConfig(this.selectedNodeType)); + this.rtlEffects.showLNDConfig + .pipe(takeUntil(this.unsubs[1])) + .subscribe((configFile: any) => { + this.configData = (configFile === '' || undefined === configFile) ? [] : configFile.split('\n'); + }); + } + + resetData() { + this.configData = ''; + this.selectedNodeType = 'lnd'; + } + + ngOnDestroy() { + this.unsubs.forEach(completeSub => { + completeSub.next(); + completeSub.complete(); + }); + } + +} diff --git a/src/app/pages/signin/signin.component.html b/src/app/pages/signin/signin.component.html new file mode 100644 index 00000000..6a141a34 --- /dev/null +++ b/src/app/pages/signin/signin.component.html @@ -0,0 +1,22 @@ +
+
+ + + +

Login to RTL

+
+
+ +
+ + + {{hintStr}} + + + +
+
+
+
+
+ \ No newline at end of file diff --git a/src/app/pages/signin/signin.component.scss b/src/app/pages/signin/signin.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/pages/signin/signin.component.ts b/src/app/pages/signin/signin.component.ts new file mode 100644 index 00000000..0a166d32 --- /dev/null +++ b/src/app/pages/signin/signin.component.ts @@ -0,0 +1,59 @@ +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; +import { Store } from '@ngrx/store'; + +import { LoggerService } from '../../shared/services/logger.service'; +import * as fromRTLReducer from '../../shared/store/rtl.reducers'; +import * as RTLActions from '../../shared/store/rtl.actions'; + +@Component({ + selector: 'rtl-signin', + templateUrl: './signin.component.html', + styleUrls: ['./signin.component.scss'] +}) +export class SigninComponent implements OnInit, OnDestroy { + password = ''; + nodeAuthType = ''; + rtlSSO = 0; + rtlCookiePath = ''; + hintStr = ''; + accessKey = ''; + + private unsub: Array> = [new Subject(), new Subject(), new Subject()]; + + constructor(private logger: LoggerService, private store: Store) { } + + ngOnInit() { + this.store.select('rtlRoot') + .pipe(takeUntil(this.unsub[0])) + .subscribe((rtlStore: fromRTLReducer.State) => { + rtlStore.effectErrors.forEach(effectsErr => { + this.logger.error(effectsErr); + }); + this.nodeAuthType = rtlStore.authSettings.nodeAuthType; + this.logger.info(rtlStore); + if (this.nodeAuthType.toUpperCase() === 'DEFAULT') { + this.hintStr = 'Enter RPC password'; + } else { + this.hintStr = ''; // Do not remove, initial passowrd 'DEFAULT' is initilizing its value + } + }); + } + + onSignin() { + this.store.dispatch(new RTLActions.Signin(window.btoa(this.password))); + } + + resetData() { + this.password = ''; + } + + ngOnDestroy() { + this.unsub.forEach(completeSub => { + completeSub.next(); + completeSub.complete(); + }); + } + +} diff --git a/src/app/pages/switch/forwarding-history.component.html b/src/app/pages/switch/forwarding-history.component.html new file mode 100644 index 00000000..52b8e8ae --- /dev/null +++ b/src/app/pages/switch/forwarding-history.component.html @@ -0,0 +1,87 @@ +
+
+ + + +

Forwarding History

+ +
+
+ +
+
+ + + + + + + + + + +
+
+ + +
+
+
+
+
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Timestamp{{fhEvent.timestamp_str}}Chan Id In{{fhEvent.chan_id_in}}Alias In{{fhEvent.alias_in}}Chan Id Out{{fhEvent.chan_id_out}}Alias Out{{fhEvent.alias_out}}Amount + Out (Sats){{fhEvent.amt_out | number}}Amount + In (Sats){{fhEvent.amt_in | number}}Fee + (Sats){{fhEvent.fee | number}}
+
+
+
+
+
\ No newline at end of file diff --git a/src/app/pages/switch/forwarding-history.component.scss b/src/app/pages/switch/forwarding-history.component.scss new file mode 100644 index 00000000..bf2b3bd5 --- /dev/null +++ b/src/app/pages/switch/forwarding-history.component.scss @@ -0,0 +1,21 @@ +.mat-column-amt_in { + flex: 0 0 15%; + min-width: 120px; + padding-right: 20px; +} + +table { + width:100%; +} + +.table-container { + height: 72vh; + overflow: auto; +} + +@media screen and (max-width: 414px) { + .table-container { + height: 53vh; + overflow: auto; + } +} diff --git a/src/app/pages/switch/forwarding-history.component.spec.ts b/src/app/pages/switch/forwarding-history.component.spec.ts new file mode 100644 index 00000000..f5c03c97 --- /dev/null +++ b/src/app/pages/switch/forwarding-history.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ForwardingHistoryComponent } from './forwarding-history.component'; + +describe('ForwardingHistoryComponent', () => { + let component: ForwardingHistoryComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ForwardingHistoryComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ForwardingHistoryComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/switch/forwarding-history.component.ts b/src/app/pages/switch/forwarding-history.component.ts new file mode 100644 index 00000000..ff0678dc --- /dev/null +++ b/src/app/pages/switch/forwarding-history.component.ts @@ -0,0 +1,123 @@ +import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core'; +import { formatDate } from '@angular/common'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; +import { Store } from '@ngrx/store'; + +import { MatTableDataSource, MatSort } from '@angular/material'; +import { ForwardingEvent } from '../../shared/models/lndModels'; +import { LoggerService } from '../../shared/services/logger.service'; + +import * as RTLActions from '../../shared/store/rtl.actions'; +import * as fromRTLReducer from '../../shared/store/rtl.reducers'; + +@Component({ + selector: 'rtl-forwarding-history', + templateUrl: './forwarding-history.component.html', + styleUrls: ['./forwarding-history.component.scss'] +}) +export class ForwardingHistoryComponent implements OnInit, OnDestroy { + @ViewChild(MatSort) sort: MatSort; + public displayedColumns = []; + public forwardingHistoryEvents: any; + public lastOffsetIndex = 0; + public flgLoading: Array = [true]; + public today = new Date(Date.now()); + public yesterday = new Date(this.today.getFullYear(), this.today.getMonth(), this.today.getDate() - 1, this.today.getHours(), this.today.getMinutes(), this.today.getSeconds()); + public endDate = this.today; + public startDate = this.yesterday; + private unsub: Array> = [new Subject(), new Subject()]; + + constructor(private logger: LoggerService, private store: Store) { + switch (true) { + case (window.innerWidth <= 415): + this.displayedColumns = ['timestamp', 'amt_out', 'amt_in']; + break; + case (window.innerWidth > 415 && window.innerWidth <= 730): + this.displayedColumns = ['timestamp', 'amt_out', 'amt_in', 'fee']; + break; + case (window.innerWidth > 730 && window.innerWidth <= 1024): + this.displayedColumns = ['timestamp', 'chan_id_in', 'chan_id_out', 'amt_out', 'amt_in', 'fee']; + break; + case (window.innerWidth > 1024 && window.innerWidth <= 1280): + this.displayedColumns = ['timestamp', 'chan_id_in', 'chan_id_out', 'amt_out', 'amt_in', 'fee']; + break; + default: + this.displayedColumns = ['timestamp', 'chan_id_in', 'chan_id_out', 'amt_out', 'amt_in', 'fee']; + break; + } + } + + ngOnInit() { + this.store.dispatch(new RTLActions.GetForwardingHistory({})); + this.store.select('rtlRoot') + .pipe(takeUntil(this.unsub[0])) + .subscribe((rtlStore: fromRTLReducer.State) => { + rtlStore.effectErrors.forEach(effectsErr => { + if (effectsErr.action === 'GetForwardingHistory') { + this.flgLoading[0] = 'error'; + } + }); + if (undefined !== rtlStore.forwardingHistory && undefined !== rtlStore.forwardingHistory.forwarding_events) { + this.lastOffsetIndex = rtlStore.forwardingHistory.last_offset_index; + this.loadForwardingEventsTable(rtlStore.forwardingHistory.forwarding_events); + } + if (this.flgLoading[0] !== 'error') { + this.flgLoading[0] = (undefined !== rtlStore.forwardingHistory) ? false : true; + } + this.logger.info(rtlStore); + }); + + } + + onForwardingEventClick(selRow: ForwardingEvent, event: any) { + const selFEvent = this.forwardingHistoryEvents.data.filter(fhEvent => { + return fhEvent.chan_id_in === selRow.chan_id_in; + })[0]; + const reorderedFHEvent = JSON.parse(JSON.stringify(selFEvent, ['timestamp_str', 'chan_id_in', 'alias_in', 'chan_id_out', 'alias_out', 'amt_out', 'amt_in', 'fee'] , 2)); + this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: { + type: 'INFO', + message: JSON.stringify(reorderedFHEvent) + }})); + } + + loadForwardingEventsTable(forwardingEvents: ForwardingEvent[]) { + this.forwardingHistoryEvents = new MatTableDataSource([...forwardingEvents]); + this.forwardingHistoryEvents.sort = this.sort; + this.forwardingHistoryEvents.data.forEach(event => { + event.timestamp_str = (event.timestamp_str === '') ? '' : formatDate(event.timestamp_str, 'MMM/dd/yy HH:mm:ss', 'en-US'); + }); + + this.logger.info(this.forwardingHistoryEvents); + } + + onForwardingHistoryFetch() { + if (undefined === this.endDate || this.endDate == null) { + this.endDate = new Date(); + } + if (undefined === this.startDate || this.startDate == null) { + this.startDate = new Date(this.endDate.getFullYear(), this.endDate.getMonth(), this.endDate.getDate() - 1); + } + this.store.dispatch(new RTLActions.GetForwardingHistory({ + end_time: Math.round(this.endDate.getTime() / 1000).toString(), + start_time: Math.round(this.startDate.getTime() / 1000).toString() + })); + } + + resetData() { + this.endDate = new Date(); + this.startDate = new Date(this.endDate.getFullYear(), this.endDate.getMonth(), this.endDate.getDate() - 1); + if (undefined !== this.forwardingHistoryEvents) { + this.forwardingHistoryEvents.data = []; + } + } + + ngOnDestroy() { + this.resetData(); + this.unsub.forEach(completeSub => { + completeSub.next(); + completeSub.complete(); + }); + } + +} diff --git a/src/app/pages/transactions/list-transactions/list-transactions.component.html b/src/app/pages/transactions/list-transactions/list-transactions.component.html new file mode 100644 index 00000000..89d225d5 --- /dev/null +++ b/src/app/pages/transactions/list-transactions/list-transactions.component.html @@ -0,0 +1,57 @@ +
+
+ + + +

Transactions

+
+
+ +
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Destination Addresses{{trans?.dest_addresses?.length || 0}} Addr Timestamp {{trans.time_stamp_str}} Num Confirmations {{trans.num_confirmations | number}} Total Fees {{trans.total_fees | number}} Block Hash {{trans.block_hash | slice:0:10}}... Block Height {{trans.block_height | number}} Txn Hash
{{trans.tx_hash | slice:0:10}}...
Amount {{trans.amount | number}}
+
+
+
+
+
diff --git a/src/app/pages/transactions/list-transactions/list-transactions.component.scss b/src/app/pages/transactions/list-transactions/list-transactions.component.scss new file mode 100644 index 00000000..f02ab006 --- /dev/null +++ b/src/app/pages/transactions/list-transactions/list-transactions.component.scss @@ -0,0 +1,31 @@ +.mat-column-tx_hash, .mat-column-block_hash { + padding-left: 10px; +} + +.mat-expansion-panel-header { + padding: 0; +} + +.mat-accordion .mat-expansion-panel { + padding: 0 10px; +} + +.ml-minus-24px { + margin-left: -24px; +} + +table { + width:100%; +} + +.table-container { + height: 78vh; + overflow: auto; +} + +@media screen and (max-width: 414px) { + .table-container { + height: 68vh; + overflow: auto; + } +} diff --git a/src/app/pages/transactions/list-transactions/list-transactions.component.spec.ts b/src/app/pages/transactions/list-transactions/list-transactions.component.spec.ts new file mode 100644 index 00000000..9222f131 --- /dev/null +++ b/src/app/pages/transactions/list-transactions/list-transactions.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ListTransactionsComponent } from './list-transactions.component'; + +describe('ListTransactionsComponent', () => { + let component: ListTransactionsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ListTransactionsComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ListTransactionsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/transactions/list-transactions/list-transactions.component.ts b/src/app/pages/transactions/list-transactions/list-transactions.component.ts new file mode 100644 index 00000000..75ca8ea2 --- /dev/null +++ b/src/app/pages/transactions/list-transactions/list-transactions.component.ts @@ -0,0 +1,110 @@ +import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core'; +import { formatDate } from '@angular/common'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; +import { Store } from '@ngrx/store'; + +import { MatTableDataSource, MatSort } from '@angular/material'; +import { Transaction } from '../../../shared/models/lndModels'; +import { LoggerService } from '../../../shared/services/logger.service'; + +import { RTLEffects } from '../../../shared/store/rtl.effects'; +import * as RTLActions from '../../../shared/store/rtl.actions'; +import * as fromRTLReducer from '../../../shared/store/rtl.reducers'; + +@Component({ + selector: 'rtl-list-transactions', + templateUrl: './list-transactions.component.html', + styleUrls: ['./list-transactions.component.scss'] +}) +export class ListTransactionsComponent implements OnInit, OnDestroy { + @ViewChild(MatSort) sort: MatSort; + public displayedColumns = []; + public listTransactions: any; + public flgLoading: Array = [true]; + private unsub: Array> = [new Subject(), new Subject()]; + + constructor(private logger: LoggerService, private store: Store, private rtlEffects: RTLEffects) { + switch (true) { + case (window.innerWidth <= 415): + this.displayedColumns = ['dest_addresses', 'total_fees', 'amount']; + break; + case (window.innerWidth > 415 && window.innerWidth <= 730): + this.displayedColumns = ['dest_addresses', 'time_stamp', 'total_fees', 'amount']; + break; + case (window.innerWidth > 730 && window.innerWidth <= 1024): + this.displayedColumns = ['dest_addresses', 'time_stamp', 'num_confirmations', 'total_fees', 'tx_hash', 'amount']; + break; + case (window.innerWidth > 1024 && window.innerWidth <= 1280): + this.displayedColumns = ['dest_addresses', 'time_stamp', 'num_confirmations', 'total_fees', 'tx_hash', 'amount']; + break; + default: + this.displayedColumns = ['dest_addresses', 'time_stamp', 'num_confirmations', 'total_fees', 'block_hash', 'block_height', 'tx_hash', 'amount']; + break; + } + } + + ngOnInit() { + this.store.dispatch(new RTLActions.FetchTransactions()); + this.store.select('rtlRoot') + .pipe(takeUntil(this.unsub[0])) + .subscribe((rtlStore: fromRTLReducer.State) => { + rtlStore.effectErrors.forEach(effectsErr => { + if (effectsErr.action === 'FetchTransactions') { + this.flgLoading[0] = 'error'; + } + }); + if (undefined !== rtlStore.transactions && rtlStore.transactions.length > 0) { + this.loadTransactionsTable(rtlStore.transactions); + } + if (this.flgLoading[0] !== 'error') { + this.flgLoading[0] = (undefined !== rtlStore.transactions) ? false : true; + } + this.logger.info(rtlStore); + }); + + } + + applyFilter(selFilter: string) { + this.listTransactions.filter = selFilter; + } + + onTransactionClick(selRow: Transaction, event: any) { + const flgExpansionClicked = event.target.className.includes('mat-expansion-panel-header') || event.target.className.includes('mat-expansion-indicator'); + if (flgExpansionClicked) { + return; + } + const selTransaction = this.listTransactions.data.filter(transaction => { + return transaction.tx_hash === selRow.tx_hash; + })[0]; + const reorderedTransactions = JSON.parse(JSON.stringify(selTransaction, [ + 'dest_addresses', 'time_stamp_str', 'num_confirmations', 'total_fees', 'block_hash', 'block_height', 'tx_hash', 'amount' + ] , 2)); + this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: { + type: 'INFO', + message: JSON.stringify(reorderedTransactions) + }})); + } + + loadTransactionsTable(transactions) { + this.listTransactions = new MatTableDataSource([...transactions]); + this.listTransactions.sort = this.sort; + this.listTransactions.data.forEach(transaction => { + if (undefined !== transaction.time_stamp_str) { + transaction.time_stamp_str = (transaction.time_stamp_str === '') ? '' : formatDate(transaction.time_stamp_str, 'MMM/dd/yy HH:mm:ss', 'en-US'); + } + }); + this.logger.info(this.listTransactions); + } + + resetData() { + } + + ngOnDestroy() { + this.unsub.forEach(completeSub => { + completeSub.next(); + completeSub.complete(); + }); + } + +} diff --git a/src/app/pages/transactions/send-receive/send-receive-trans.component.html b/src/app/pages/transactions/send-receive/send-receive-trans.component.html new file mode 100644 index 00000000..33d753bf --- /dev/null +++ b/src/app/pages/transactions/send-receive/send-receive-trans.component.html @@ -0,0 +1,163 @@ +
+
Don't be #reckless. #craefulgang #craefulgang #craefulgang.
+
+
+
+ + + +
Total Balance
+ +
+
+ + + + + + + +

{{blockchainBalance?.btc_total_balance | number}} {{information?.currency_unit}}

+

{{blockchainBalance?.total_balance | number}} {{information?.smaller_currency_unit}}

+
+
+ + +
+
+
+ + + +
Confirmed Balance
+ +
+
+ + + + + + + +

{{blockchainBalance?.btc_confirmed_balance | number}} {{information?.currency_unit}}

+

{{blockchainBalance?.confirmed_balance | number}} {{information?.smaller_currency_unit}}

+
+
+ + +
+
+
+ + + +
Unconfirmed Balance
+ +
+
+ + + + + + + +

{{blockchainBalance?.btc_unconfirmed_balance | number}} {{information?.currency_unit}}

+

{{blockchainBalance?.unconfirmed_balance | number}} {{information?.smaller_currency_unit}}

+
+
+ + +
+
+
+ + + +

Receive Funds

+
+
+ +
+
+ + + + {{addressType.addressTp}} + + + +
+
+ +
+
+ +
+
+ + + +
+
+ +
+
+
+
+
+
+ + + +

Send Funds

+
+
+ +
+
+ + + +
+
+ + Sweep All + + + + +
+
+
+
+ + + + {{transType.name}} + + + +
+
+ + + + + + +
+
+ + +
+
+
+
+
+
+

Sats

diff --git a/src/app/pages/transactions/send-receive/send-receive-trans.component.scss b/src/app/pages/transactions/send-receive/send-receive-trans.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/pages/transactions/send-receive/send-receive-trans.component.ts b/src/app/pages/transactions/send-receive/send-receive-trans.component.ts new file mode 100644 index 00000000..d24db3ff --- /dev/null +++ b/src/app/pages/transactions/send-receive/send-receive-trans.component.ts @@ -0,0 +1,175 @@ +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { Subject } from 'rxjs'; +import { takeUntil, take } from 'rxjs/operators'; +import { Store } from '@ngrx/store'; + +import { Settings } from '../../../shared/models/RTLconfig'; +import { GetInfo, Balance, ChannelsTransaction, AddressType } from '../../../shared/models/lndModels'; +import { Authentication } from '../../../shared/models/RTLconfig'; +import { LoggerService } from '../../../shared/services/logger.service'; + +import { RTLEffects } from '../../../shared/store/rtl.effects'; +import * as RTLActions from '../../../shared/store/rtl.actions'; +import * as fromRTLReducer from '../../../shared/store/rtl.reducers'; + +@Component({ + selector: 'rtl-send-receive-trans', + templateUrl: './send-receive-trans.component.html', + styleUrls: ['./send-receive-trans.component.scss'] +}) +export class SendReceiveTransComponent implements OnInit, OnDestroy { + public settings: Settings; + public addressTypes = []; + public flgLoadingWallet: Boolean | 'error' = true; + public selectedAddress: AddressType = {}; + public blockchainBalance: Balance = {}; + public information: GetInfo = {}; + public authSettings: Authentication = {}; + public newAddress = ''; + public transaction: ChannelsTransaction = {}; + public transTypes = [{id: '1', name: 'Target Confirmation Blocks'}, {id: '2', name: 'Fee'}]; + public selTransType = '1'; + public flgCustomAmount = '1'; + private unsub: Array> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject()]; + + constructor(private logger: LoggerService, private store: Store, private rtlEffects: RTLEffects) {} + + ngOnInit() { + this.store.select('rtlRoot') + .pipe(takeUntil(this.unsub[0])) + .subscribe((rtlStore: fromRTLReducer.State) => { + rtlStore.effectErrors.forEach(effectsErr => { + if (effectsErr.action === 'FetchBalance/blockchain') { + this.flgLoadingWallet = 'error'; + } + }); + this.settings = rtlStore.settings; + this.information = rtlStore.information; + this.addressTypes = rtlStore.addressTypes; + this.authSettings = rtlStore.authSettings; + + this.blockchainBalance = rtlStore.blockchainBalance; + if (undefined === this.blockchainBalance.total_balance) { + this.blockchainBalance.total_balance = '0'; + } + if (undefined === this.blockchainBalance.confirmed_balance) { + this.blockchainBalance.confirmed_balance = '0'; + } + if (undefined === this.blockchainBalance.unconfirmed_balance) { + this.blockchainBalance.unconfirmed_balance = '0'; + } + if (this.flgLoadingWallet !== 'error') { + this.flgLoadingWallet = false; + } + + this.logger.info(rtlStore); + }); + + } + + onGenerateAddress() { + this.store.dispatch(new RTLActions.OpenSpinner('Getting New Address...')); + this.store.dispatch(new RTLActions.GetNewAddress(this.selectedAddress)); + this.rtlEffects.setNewAddress + .pipe(takeUntil(this.unsub[1])) + .subscribe(newAddress => { + this.newAddress = newAddress; + }); + } + + onSendFunds() { + const confirmationMsg = { + 'BTC Address': this.transaction.address, + }; + if (!+this.flgCustomAmount) { + confirmationMsg['Sweep All'] = 'True'; + this.transaction.sendAll = true; + } else { + confirmationMsg['Amount (' + this.information.smaller_currency_unit + ')'] = this.transaction.amount; + this.transaction.sendAll = false; + } + if (this.selTransType === '1') { + delete this.transaction.fees; + confirmationMsg['Target Confirmation Blocks'] = this.transaction.blocks; + } else { + delete this.transaction.blocks; + confirmationMsg['Fee (' + this.information.smaller_currency_unit + '/Byte)'] = this.transaction.fees; + } + this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data: + {type: 'CONFIRM', message: JSON.stringify(confirmationMsg), noBtnText: 'Cancel', yesBtnText: 'Send'} + })); + + this.rtlEffects.closeConfirm + .pipe(takeUntil(this.unsub[2])) + .subscribe(confirmRes => { + if (confirmRes) { + if (this.transaction.sendAll && !+this.authSettings.rtlSSO) { + this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data: + {type: 'CONFIRM', titleMessage: 'Enter Login Password', noBtnText: 'Cancel', yesBtnText: 'Authorize', flgShowInput: true, getInputs: [ + {placeholder: 'Enter Login Password', inputType: 'password', inputValue: ''} + ]} + })); + this.rtlEffects.closeConfirm + .pipe(takeUntil(this.unsub[3])) + .subscribe(pwdConfirmRes => { + if (pwdConfirmRes) { + const pwd = pwdConfirmRes[0].inputValue; + this.store.dispatch(new RTLActions.IsAuthorized(window.btoa(pwd))); + this.rtlEffects.isAuthorizedRes + .pipe(take(1)) + .subscribe(authRes => { + if (authRes !== 'ERROR') { + this.dispatchToSendFunds(); + } + }); + } + }); + } else { + this.dispatchToSendFunds(); + } + } + }); + } + + dispatchToSendFunds() { + this.store.dispatch(new RTLActions.OpenSpinner('Sending Funds...')); + this.store.dispatch(new RTLActions.SetChannelTransaction(this.transaction)); + this.transaction = {address: '', amount: 0, blocks: 0, fees: 0}; + } + + get invalidValues(): boolean { + return (undefined === this.transaction.address || this.transaction.address === '') + || (+this.flgCustomAmount && (undefined === this.transaction.amount || this.transaction.amount <= 0)) + || (this.selTransType === '1' && (undefined === this.transaction.blocks || this.transaction.blocks <= 0)) + || (this.selTransType === '2' && (undefined === this.transaction.fees || this.transaction.fees <= 0)); + } + + onCustomClicked() { + this.flgCustomAmount = '1'; + } + + onOptionChange(event) { + if (!+this.flgCustomAmount) { + delete this.transaction.amount; + } + } + + resetData() { + this.transaction.address = ''; + this.transaction.amount = 0; + this.transaction.blocks = 0; + this.transaction.fees = 0; + } + + resetReceiveData() { + this.selectedAddress = {}; + this.newAddress = ''; + } + + ngOnDestroy() { + this.unsub.forEach(completeSub => { + completeSub.next(); + completeSub.complete(); + }); + } +} diff --git a/src/app/pages/unlock-lnd/unlock-lnd.component.html b/src/app/pages/unlock-lnd/unlock-lnd.component.html new file mode 100644 index 00000000..e91c9aa0 --- /dev/null +++ b/src/app/pages/unlock-lnd/unlock-lnd.component.html @@ -0,0 +1,21 @@ +
+
+ + + +

Unlock LND Wallet

+
+
+ +
+ + + Enter LND Wallet Password + + + +
+
+
+
+
diff --git a/src/app/pages/unlock-lnd/unlock-lnd.component.scss b/src/app/pages/unlock-lnd/unlock-lnd.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/pages/unlock-lnd/unlock-lnd.component.ts b/src/app/pages/unlock-lnd/unlock-lnd.component.ts new file mode 100644 index 00000000..62536af4 --- /dev/null +++ b/src/app/pages/unlock-lnd/unlock-lnd.component.ts @@ -0,0 +1,41 @@ +import { Component, OnInit, OnDestroy } from '@angular/core'; +import { Router } from '@angular/router'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; +import { Store } from '@ngrx/store'; + +import { LoggerService } from '../../shared/services/logger.service'; + +import * as RTLActions from '../../shared/store/rtl.actions'; +import * as fromRTLReducer from '../../shared/store/rtl.reducers'; + +@Component({ + selector: 'rtl-unlock-lnd', + templateUrl: './unlock-lnd.component.html', + styleUrls: ['./unlock-lnd.component.scss'] +}) +export class UnlockLNDComponent implements OnInit, OnDestroy { + walletPassword = ''; + private unsub = new Subject(); + + constructor(private store: Store) {} + + ngOnInit() { + this.walletPassword = ''; + } + + onOperateWallet(operation: string) { + this.store.dispatch(new RTLActions.OpenSpinner('Unlocking...')); + this.store.dispatch(new RTLActions.OperateWallet({operation: operation, pwd: this.walletPassword})); + } + + resetData() { + this.walletPassword = ''; + } + + ngOnDestroy() { + this.unsub.next(); + this.unsub.complete(); + } + +} diff --git a/src/app/shared/animation/row-animation.ts b/src/app/shared/animation/row-animation.ts new file mode 100644 index 00000000..6dba26f1 --- /dev/null +++ b/src/app/shared/animation/row-animation.ts @@ -0,0 +1,10 @@ +import { trigger, state, animate, transition, style } from '@angular/animations'; + +export const newlyAddedRowAnimation = [ + trigger('newlyAddedRowAnimation', [ + state('notAdded, void', style({ transform: 'translateX(0)' })), + state('added', style({ transform: 'translateX(1.5)', border: '1px solid' })), + transition('added <=> notAdded', animate('2000ms ease-out')), + transition('added <=> void', animate('2000ms ease-out')) + ]) +]; diff --git a/src/app/shared/components/alert-message/alert-message.component.html b/src/app/shared/components/alert-message/alert-message.component.html new file mode 100644 index 00000000..57480a6b --- /dev/null +++ b/src/app/shared/components/alert-message/alert-message.component.html @@ -0,0 +1,35 @@ +
+
+ +

{{data.type}}

+ close +
+ +
+

{{data.titleMessage | titlecase}}

+
+
+
{{obj[0] | titlecase}}
+
:
+
+
+ {{obj[1] | number:'1.0-3'}} +
+ + {{obj[1]}} + + file_copyCopied +
+
+ +
+
+
+
+ +
+ +
+
+
+
diff --git a/src/app/shared/components/alert-message/alert-message.component.scss b/src/app/shared/components/alert-message/alert-message.component.scss new file mode 100644 index 00000000..b35af4b1 --- /dev/null +++ b/src/app/shared/components/alert-message/alert-message.component.scss @@ -0,0 +1,40 @@ +.p-2 { + padding: 1rem; +} + +.pb-1 { + padding-bottom: 0.3rem; +} + +.pb-2 { + padding-bottom: 1rem; +} + +.mb-1 { + margin-bottom: 0.5rem; +} + +.wrap-text { + -ms-word-break: break-all; + word-break: break-all; + word-break: break-word; + -webkit-hyphens: auto; + -moz-hyphens: auto; + hyphens: auto; +} + +.mat-icon[type="button"] { + cursor: pointer; +} + +.new-line { + white-space: pre-wrap; +} + +.title-message { + font-size: 110%; +} + +.mt-minus-40px { + margin-top:-40px; +} diff --git a/src/app/shared/components/alert-message/alert-message.component.ts b/src/app/shared/components/alert-message/alert-message.component.ts new file mode 100644 index 00000000..7217cd03 --- /dev/null +++ b/src/app/shared/components/alert-message/alert-message.component.ts @@ -0,0 +1,106 @@ +import { Component, OnInit, Inject } from '@angular/core'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; + +import { LoggerService } from '../../../shared/services/logger.service'; +import { AlertData } from '../../../shared/models/alertData'; + +@Component({ + selector: 'rtl-alert-message', + templateUrl: './alert-message.component.html', + styleUrls: ['./alert-message.component.scss'] +}) +export class AlertMessageComponent implements OnInit { + public msgTypeBackground = 'bg-primary p-1'; + public msgTypeForeground = 'primary'; + public messageObj = []; + public flgCopied = false; + + constructor(public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: AlertData, private logger: LoggerService) { } + + ngOnInit() { + this.setStyleOnAlertType(); + this.convertJSONData(); + } + + setStyleOnAlertType() { + // INFO/WARN/ERROR/SUCCESS/CONFIRM + if (this.data.type === 'WARN') { + this.msgTypeBackground = 'bg-accent p-1'; + this.msgTypeForeground = 'accent'; + } + if (this.data.type === 'ERROR') { + this.msgTypeBackground = 'bg-warn p-1'; + this.msgTypeForeground = 'warn'; + if (undefined === this.data.message && undefined === this.data.titleMessage && this.messageObj.length <= 0 ) { + this.data.titleMessage = 'Please Check Server Connection'; + } + } + } + + convertJSONData() { + this.data.message = (undefined === this.data.message) ? '' : this.data.message.replace(/{/g, '').replace(/"/g, '').replace(/}/g, '').replace(/\n/g, ''); + // Start: For Payment Path + const arrayStartIdx = this.data.message.search('\\['); + const arrayEndIdx = this.data.message.search('\\]'); + if (arrayStartIdx > -1 && arrayEndIdx > -1) { + this.data.message = this.data.message.substring(0, arrayStartIdx).concat( + this.data.message.substring(arrayStartIdx + 1, arrayEndIdx).replace(/,/g, '\n'), + this.data.message.substring(arrayEndIdx + 1)); + } + // End: For Payment Path + this.messageObj = (this.data.message === '') ? [] : this.data.message.split(','); + this.messageObj.forEach((obj, idx) => { + this.messageObj[idx] = obj.split(':'); + this.messageObj[idx][0] = this.messageObj[idx][0].replace('_str', ''); + this.messageObj[idx][0] = this.messageObj[idx][0].replace(/_/g, ' '); // To replace Backend Data's '_' + // Start: To Merge Time Value Again with ':', example Payment Creation Time + if (this.messageObj[idx].length > 2) { + this.messageObj[idx].forEach((dataValue, j) => { + if (j === 0 || j === 1) { + return; + } else { + this.messageObj[idx][1] = this.messageObj[idx][1] + ':' + this.messageObj[idx][j]; + } + }); + } + // End: To Merge Time Value Again with ':', example Payment Creation Time + }); + } + + showCopyOption(key): boolean { + let flgFoundKey = false; + const showCopyOnKeys = ['payment request']; + showCopyOnKeys.filter((arrKey) => { + if (arrKey === key) { + flgFoundKey = true; + return true; + } + }); + return flgFoundKey; + } + + copiedText(payload) { + this.flgCopied = true; + setTimeout(() => {this.flgCopied = false; }, 5000); + this.logger.info('Copied Text: ' + payload); + } + + isNumber(value, key): boolean { + let flgFoundKey = false; + const notNumberKeys = ['chan id', 'creation date', 'chan id out', 'chan id in']; + notNumberKeys.filter((arrKey) => { + if (arrKey === key) { + flgFoundKey = true; + } + }); + if (!flgFoundKey) { + return new RegExp(/^[0-9]+$/).test(value); + } else { + return false; + } + } + + onClose() { + this.dialogRef.close(false); + } +} diff --git a/src/app/shared/components/confirmation-message/confirmation-message.component.html b/src/app/shared/components/confirmation-message/confirmation-message.component.html new file mode 100644 index 00000000..f1a1b94b --- /dev/null +++ b/src/app/shared/components/confirmation-message/confirmation-message.component.html @@ -0,0 +1,39 @@ +
+
+ +

{{data.type}}

+ close +
+ +
+

{{data.titleMessage | titlecase}}

+
+ + + +
+
+
+
{{obj[0] | titlecase}}
+
:
+
+
+ {{obj[1] | number:'1.0-3'}} +
+ + {{obj[1]}} + + file_copyCopied +
+
+
+
+ +
+ + + +
+
+
+
diff --git a/src/app/shared/components/confirmation-message/confirmation-message.component.scss b/src/app/shared/components/confirmation-message/confirmation-message.component.scss new file mode 100644 index 00000000..79c78813 --- /dev/null +++ b/src/app/shared/components/confirmation-message/confirmation-message.component.scss @@ -0,0 +1,16 @@ +.new-line { + white-space: pre-wrap; +} + +.wrap-text { + -ms-word-break: break-all; + word-break: break-all; + word-break: break-word; + -webkit-hyphens: auto; + -moz-hyphens: auto; + hyphens: auto; +} + +.title-message { + font-size: 110%; +} diff --git a/src/app/shared/components/confirmation-message/confirmation-message.component.ts b/src/app/shared/components/confirmation-message/confirmation-message.component.ts new file mode 100644 index 00000000..f6a3e5f1 --- /dev/null +++ b/src/app/shared/components/confirmation-message/confirmation-message.component.ts @@ -0,0 +1,107 @@ +import { Component, OnInit, Inject } from '@angular/core'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; +import { Store } from '@ngrx/store'; + +import { LoggerService } from '../../../shared/services/logger.service'; +import { AlertData, InputData } from '../../../shared/models/alertData'; + +import * as RTLActions from '../../../shared/store/rtl.actions'; +import * as fromRTLReducer from '../../../shared/store/rtl.reducers'; + +@Component({ + selector: 'rtl-confirmation-message', + templateUrl: './confirmation-message.component.html', + styleUrls: ['./confirmation-message.component.scss'] +}) +export class ConfirmationMessageComponent implements OnInit { + public msgTypeBackground = 'bg-primary p-1'; + public msgTypeForeground = 'primary'; + public noBtnText = 'No'; + public yesBtnText = 'Yes'; + public messageObj = []; + public flgCopied = false; + public flgShowInput = false; + public getInputs: Array = [{placeholder: '', inputType: 'text', inputValue: ''}]; + + constructor(public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: AlertData, private logger: LoggerService, + private store: Store) { } + + ngOnInit() { + this.flgShowInput = this.data.flgShowInput; + this.getInputs = this.data.getInputs; + this.noBtnText = (undefined !== this.data.noBtnText) ? this.data.noBtnText : 'No'; + this.yesBtnText = (undefined !== this.data.yesBtnText) ? this.data.yesBtnText : 'Yes'; + + // INFO/WARN/ERROR/SUCCESS/CONFIRM + if (this.data.type === 'WARN') { + this.msgTypeBackground = 'bg-accent p-1'; + } + if (this.data.type === 'ERROR') { + this.msgTypeBackground = 'bg-warn p-1'; + this.msgTypeForeground = 'warn'; + } + this.data.message = (undefined === this.data.message) ? '' : this.data.message.replace(/{/g, '').replace(/"/g, '').replace(/}/g, '').replace(/\n/g, ''); + // Start: For Payment Path + const arrayStartIdx = this.data.message.search('\\['); + const arrayEndIdx = this.data.message.search('\\]'); + if (arrayStartIdx > -1 && arrayEndIdx > -1) { + this.data.message = this.data.message.substring(0, arrayStartIdx).concat( + this.data.message.substring(arrayStartIdx + 1, arrayEndIdx).replace(/,/g, '\n'), + this.data.message.substring(arrayEndIdx + 1)); + } + // End: For Payment Path + this.messageObj = (this.data.message === '') ? [] : this.data.message.split(','); + this.messageObj.forEach((obj, idx) => { + this.messageObj[idx] = obj.split(':'); + this.messageObj[idx][0] = this.messageObj[idx][0].replace(/_/g, ' '); // To replace Backend Data's '_' + // Start: To Merge Time Value Again with ':', example Payment Creation Time + if (this.messageObj[idx].length > 2) { + this.messageObj[idx].forEach((dataValue, j) => { + if (j === 0 || j === 1) { + return; + } else { + this.messageObj[idx][1] = this.messageObj[idx][1] + ':' + this.messageObj[idx][j]; + } + }); + } + // End: To Merge Time Value Again with ':', example Payment Creation Time + }); + } + + showCopyOption(key): boolean { + let flgFoundKey = false; + const showCopyOnKeys = ['payment request']; + showCopyOnKeys.filter((arrKey) => { + if (arrKey === key) { + flgFoundKey = true; + return true; + } + }); + return flgFoundKey; + } + + copiedText(payload) { + this.flgCopied = true; + setTimeout(() => {this.flgCopied = false; }, 5000); + this.logger.info('Copied Text: ' + payload); + } + + isNumber(value, key): boolean { + let flgFoundKey = false; + const notNumberKeys = ['chan id', 'creation date']; + notNumberKeys.filter((arrKey) => { + if (arrKey === key) { + flgFoundKey = true; + } + }); + if (!flgFoundKey) { + return new RegExp(/^[0-9]+$/).test(value); + } else { + return false; + } + } + + onClose(dialogRes: any) { + this.store.dispatch(new RTLActions.CloseConfirmation(dialogRes)); + } +} diff --git a/src/app/shared/components/not-found/not-found.component.html b/src/app/shared/components/not-found/not-found.component.html new file mode 100644 index 00000000..c12b788e --- /dev/null +++ b/src/app/shared/components/not-found/not-found.component.html @@ -0,0 +1,16 @@ +
+ +
+ +

404

+
+ + +
This page does not exist!
+ +
+
+
+
diff --git a/src/app/shared/components/not-found/not-found.component.ts b/src/app/shared/components/not-found/not-found.component.ts new file mode 100644 index 00000000..834aa818 --- /dev/null +++ b/src/app/shared/components/not-found/not-found.component.ts @@ -0,0 +1,16 @@ +import { Component } from '@angular/core'; +import { Router } from '@angular/router'; + +@Component({ + selector: 'rtl-not-found', + templateUrl: './not-found.component.html' +}) +export class NotFoundComponent { + + constructor(public router: Router) {} + + goHome(): void { + this.router.navigate(['/']); + } + +} diff --git a/src/app/shared/components/settings-nav/settings-nav.component.html b/src/app/shared/components/settings-nav/settings-nav.component.html new file mode 100644 index 00000000..19278ec9 --- /dev/null +++ b/src/app/shared/components/settings-nav/settings-nav.component.html @@ -0,0 +1,74 @@ + +

Settings

+
+
+ +
+

Currency Unit

+
+ {{currencyUnit}} + +
+ +
+

Menu

+ + {{menu}} + + +
+

Menu Type

+ + {{menuType}} + + +
+
+

Sidenav Options

+
+ Opened + +
+
+ Pinned + +
+
+ +
+

Skins

+
+
+
+
+
+
+
+
+
+
+ + +
+
diff --git a/src/app/shared/components/settings-nav/settings-nav.component.scss b/src/app/shared/components/settings-nav/settings-nav.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/shared/components/settings-nav/settings-nav.component.spec.ts b/src/app/shared/components/settings-nav/settings-nav.component.spec.ts new file mode 100644 index 00000000..05f43ea7 --- /dev/null +++ b/src/app/shared/components/settings-nav/settings-nav.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SettingsNavComponent } from './settings-nav.component'; + +describe('SettingsNavComponent', () => { + let component: SettingsNavComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ SettingsNavComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SettingsNavComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/components/settings-nav/settings-nav.component.ts b/src/app/shared/components/settings-nav/settings-nav.component.ts new file mode 100644 index 00000000..97f9a4c0 --- /dev/null +++ b/src/app/shared/components/settings-nav/settings-nav.component.ts @@ -0,0 +1,80 @@ +import { Component, OnInit, OnDestroy, Output, EventEmitter } from '@angular/core'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; +import { Store } from '@ngrx/store'; + +import { Settings } from '../../models/RTLconfig'; +import { GetInfo } from '../../models/lndModels'; +import { LoggerService } from '../../services/logger.service'; + +import * as RTLActions from '../../store/rtl.actions'; +import * as fromRTLReducer from '../../store/rtl.reducers'; + +@Component({ + selector: 'rtl-settings-nav', + templateUrl: './settings-nav.component.html', + styleUrls: ['./settings-nav.component.scss'] +}) +export class SettingsNavComponent implements OnInit, OnDestroy { + public information: GetInfo = {}; + public settings: Settings; + public menus = ['Vertical', 'Horizontal']; + public menuTypes = ['Regular', 'Compact', 'Mini']; + public selectedMenu: string; + public selectedMenuType: string; + public currencyUnit = 'BTC'; + public showSettingOption = true; + unsubs: Array> = [new Subject(), new Subject()]; + @Output('done') done: EventEmitter = new EventEmitter(); + + constructor(private logger: LoggerService, private store: Store) {} + + ngOnInit() { + this.store.select('rtlRoot') + .pipe(takeUntil(this.unsubs[0])) + .subscribe((rtlStore: fromRTLReducer.State) => { + this.settings = rtlStore.settings; + this.selectedMenu = this.settings.menu; + this.selectedMenuType = this.settings.menuType; + if (window.innerWidth <= 768) { + this.settings.menu = 'Vertical'; + this.settings.flgSidenavOpened = false; + this.settings.flgSidenavPinned = false; + this.showSettingOption = false; + } + this.information = rtlStore.information; + this.currencyUnit = (undefined !== this.information && undefined !== this.information.currency_unit) ? this.information.currency_unit : 'BTC'; + this.logger.info(rtlStore); + }); + } + + public chooseMenu() { + this.settings.menu = this.selectedMenu; + } + + public chooseMenuType() { + this.settings.menuType = this.selectedMenuType; + } + + toggleSettings(toggleField: string) { + this.settings[toggleField] = !this.settings[toggleField]; + } + + changeTheme(newTheme: string) { + this.settings.theme = newTheme; + } + + onClose() { + this.logger.info(this.settings); + this.store.dispatch(new RTLActions.SaveSettings(this.settings)); + this.done.emit(); + } + + ngOnDestroy() { + this.unsubs.forEach(unsub => { + unsub.next(); + unsub.complete(); + }); + } + +} diff --git a/src/app/shared/components/spinner-dialog/spinner-dialog.component.html b/src/app/shared/components/spinner-dialog/spinner-dialog.component.html new file mode 100644 index 00000000..3d4e3539 --- /dev/null +++ b/src/app/shared/components/spinner-dialog/spinner-dialog.component.html @@ -0,0 +1,6 @@ +
+
+ +

{{data.titleMessage}}

+
+
diff --git a/src/app/shared/components/spinner-dialog/spinner-dialog.component.scss b/src/app/shared/components/spinner-dialog/spinner-dialog.component.scss new file mode 100644 index 00000000..8d712cca --- /dev/null +++ b/src/app/shared/components/spinner-dialog/spinner-dialog.component.scss @@ -0,0 +1,4 @@ +.spinner-container { + position: absolute; + left: 50%; +} diff --git a/src/app/shared/components/spinner-dialog/spinner-dialog.component.ts b/src/app/shared/components/spinner-dialog/spinner-dialog.component.ts new file mode 100644 index 00000000..162cc3dd --- /dev/null +++ b/src/app/shared/components/spinner-dialog/spinner-dialog.component.ts @@ -0,0 +1,16 @@ +import { Component, OnInit, Inject } from '@angular/core'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; + +@Component({ + selector: 'rtl-spinner-dialog', + templateUrl: './spinner-dialog.component.html', + styleUrls: ['./spinner-dialog.component.scss'] +}) +export class SpinnerDialogComponent implements OnInit { + + constructor(public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: any) { } + + ngOnInit() { + } + +} diff --git a/src/app/shared/components/sso-failed/sso-failed.component.html b/src/app/shared/components/sso-failed/sso-failed.component.html new file mode 100644 index 00000000..7318507c --- /dev/null +++ b/src/app/shared/components/sso-failed/sso-failed.component.html @@ -0,0 +1,15 @@ +
+ +
+ +

401

+
+ + +
Single Sign On Failed!
+
+
+
+
diff --git a/src/app/shared/components/sso-failed/sso-failed.component.ts b/src/app/shared/components/sso-failed/sso-failed.component.ts new file mode 100644 index 00000000..c0653b4d --- /dev/null +++ b/src/app/shared/components/sso-failed/sso-failed.component.ts @@ -0,0 +1,14 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'rtl-sso-failed', + templateUrl: './sso-failed.component.html' +}) +export class SsoFailedComponent implements OnInit { + + constructor() { } + + ngOnInit() { + } + +} diff --git a/src/app/shared/directive/clipboard.directive.spec.ts b/src/app/shared/directive/clipboard.directive.spec.ts new file mode 100644 index 00000000..79021ddf --- /dev/null +++ b/src/app/shared/directive/clipboard.directive.spec.ts @@ -0,0 +1,8 @@ +import { ClipboardDirective } from './clipboard.directive'; + +describe('ClipboardDirective', () => { + it('should create an instance', () => { + const directive = new ClipboardDirective(); + expect(directive).toBeTruthy(); + }); +}); diff --git a/src/app/shared/directive/clipboard.directive.ts b/src/app/shared/directive/clipboard.directive.ts new file mode 100644 index 00000000..9a49de3e --- /dev/null +++ b/src/app/shared/directive/clipboard.directive.ts @@ -0,0 +1,28 @@ +import { Directive, Input, Output, EventEmitter, HostListener } from '@angular/core'; + +@Directive({ + selector: '[rtlClipboard]' +}) +export class ClipboardDirective { + @Input() payload: string; + + @Output('copied') + public copied: EventEmitter = new EventEmitter(); + + @HostListener('click', ['$event']) + public onClick(event: MouseEvent): void { + event.preventDefault(); + if (!this.payload) { + return; + } + const listener = (e: ClipboardEvent) => { + const clipboard = e.clipboardData || window['clipboardData']; + clipboard.setData('text', this.payload.toString()); + e.preventDefault(); + this.copied.emit(this.payload); + }; + document.addEventListener('copy', listener, false); + document.execCommand('copy'); + document.removeEventListener('copy', listener, false); + } +} diff --git a/src/app/shared/models/RTLconfig.ts b/src/app/shared/models/RTLconfig.ts new file mode 100644 index 00000000..663c0f17 --- /dev/null +++ b/src/app/shared/models/RTLconfig.ts @@ -0,0 +1,31 @@ +export class Settings { + constructor( + public flgSidenavOpened: boolean, + public flgSidenavPinned: boolean, + public menu: string, + public menuType: string, + public theme: string, + public satsToBTC: boolean + ) { } +} + +export class Authentication { + constructor( + public lndServerUrl?: string, + public macaroonPath?: string, + public nodeAuthType?: string, + public lndConfigPath?: string, + public bitcoindConfigPath?: string, + public rtlPass?: string, + public enableLogging?: string, + public rtlSSO?: number, + public logoutRedirectLink?: string + ) { } +} + +export class RTLConfiguration { + constructor( + public settings: Settings, + public authentication: Authentication + ) { } +} diff --git a/src/app/shared/models/alertData.ts b/src/app/shared/models/alertData.ts new file mode 100644 index 00000000..d37427c7 --- /dev/null +++ b/src/app/shared/models/alertData.ts @@ -0,0 +1,15 @@ +export interface InputData { + placeholder: string; + inputValue?: string; + inputType?: string; +} + +export interface AlertData { + type: string; // INFO/WARN/ERROR/SUCCESS/CONFIRM + titleMessage?: string; + message?: string; + noBtnText?: string; + yesBtnText?: string; + flgShowInput?: boolean; + getInputs?: Array; +} diff --git a/src/app/shared/models/errorPayload.ts b/src/app/shared/models/errorPayload.ts new file mode 100644 index 00000000..9abcb4b0 --- /dev/null +++ b/src/app/shared/models/errorPayload.ts @@ -0,0 +1,7 @@ +export interface ErrorPayload { + action?: string; + code?: string; + message?: string; + URL?: string; + filePath?: string; +} diff --git a/src/app/shared/models/lndModels.ts b/src/app/shared/models/lndModels.ts new file mode 100644 index 00000000..a1e48064 --- /dev/null +++ b/src/app/shared/models/lndModels.ts @@ -0,0 +1,340 @@ +export interface AddressType { + addressId?: string; + addressTp?: string; + addressDetails?: string; +} + +export interface Balance { + btc_balance?: string; // For Channels Balance + balance?: string; // For Channels Balance + btc_pending_open_balance?: string; // For Channels Balance + pending_open_balance?: string; // For Channels Balance + btc_total_balance?: string; // For Blockchain Balance + total_balance?: string; // For Blockchain Balance + btc_confirmed_balance?: string; // For Blockchain Balance + confirmed_balance?: string; // For Blockchain Balance + btc_unconfirmed_balance?: string; // For Blockchain Balance + unconfirmed_balance?: string; // For Blockchain Balance +} + +export interface ChannelFeeReport { + chan_point?: string; + base_fee_msat?: number; + fee_per_mil?: number; + fee_rate?: number; +} + +export interface Channel { + active?: boolean; + remote_pubkey?: string; + remote_alias?: string; + channel_point?: string; + chan_id?: number; + capacity?: number; + local_balance?: number; + remote_balance?: number; + commit_fee?: number; + commit_weight?: number; + fee_per_kw?: number; + unsettled_balance?: number; + total_satoshis_sent?: number; + total_satoshis_received?: number; + num_updates?: number; + pending_htlcs?: HTLC[]; + csv_delay?: number; + private?: boolean; +} + +export interface PendingChannels { + total_limbo_balance?: number; + btc_total_limbo_balance?: number; + pending_closing_channels?: Array; + pending_force_closing_channels?: Array; + pending_open_channels?: Array; + waiting_close_channels?: Array; +} + +export interface ClosedChannel { + time_locked_balance?: string; + closing_tx_hash?: string; + close_type?: any; + close_height?: number; + chain_hash?: string; + channel_point?: string; + chan_id?: string; + remote_pubkey?: string; + capacity?: string; + settled_balance?: string; +} + +export interface NetworkGraph { + nodes: LightningNode[]; + edges: ChannelEdge[]; +} + +export interface LightningNode { + last_update?: number; + pub_key?: string; + alias?: string; + addresses?: NodeAddress[]; + color?: string; +} + +export interface NodeAddress { + network?: string; + addr?: string; +} + +export interface ChannelEdge { + channel_id?: string; + chan_point?: string; + last_update?: number; + last_update_str?: string; + node1_pub?: string; + node2_pub?: string; + capacity?: string; + node1_policy?: RoutingPolicy; + node2_policy?: RoutingPolicy; +} + +export interface RoutingPolicy { + time_lock_delta?: number; + min_htlc?: string; + fee_base_msat?: string; + fee_rate_milli_msat?: string; + disabled?: boolean; +} + +export interface SigmaNode { + id: string; + label: string; + x: number; + y: number; + size: number; +} + +export interface SigmaEdge { + id: string; + source: string; + target: string; +} + +export interface FeeLimit { + percent?: number; + fixed?: number; +} + +export interface Fees { + channel_fees?: ChannelFeeReport[]; + day_fee_sum?: number; + week_fee_sum?: number; + month_fee_sum?: number; + btc_day_fee_sum?: number; + btc_week_fee_sum?: number; + btc_month_fee_sum?: number; +} + +export interface GetInfoChain { + chain?: string; + network?: string; +} + +export interface GetInfo { + identity_pubkey?: string; + alias?: string; + num_pending_channels?: number; + num_active_channels?: number; + num_peers?: number; + block_height?: number; + block_hash?: string; + synced_to_chain?: boolean; + testnet?: boolean; + chains?: GetInfoChain[] | string[]; + uris?: string[]; + best_header_timestamp?: number; + version?: string; + currency_unit?: string; + smaller_currency_unit?: string; +} + +export interface GraphNode { + node?: LightningNode; + num_channels?: number; + total_capacity?: string; +} + +export interface HopHint { + cltv_expiry_delta?: number; + node_id?: string; + chan_id?: number; + fee_proportional_millionths?: number; + fee_base_msat?: number; +} + +export interface HTLC { + incoming?: boolean; + amount?: number; + hash_lock?: string; + expiration_height?: number; +} + +export interface Invoice { + memo?: string; + receipt?: string; + r_preimage?: string; + r_hash?: string; + value?: string; + btc_value?: string; + settled?: boolean; + creation_date?: string; + creation_date_str?: string; + settle_date?: string; + settle_date_str?: string; + payment_request?: string; + description_hash?: string; + expiry?: string; + fallback_addr?: string; + cltv_expiry?: string; + route_hints?: RouteHint[]; + private?: boolean; + add_index?: string; + settle_index?: string; + amt_paid?: string; + amt_paid_sat?: string; + btc_amt_paid_sat?: string; + amt_paid_msat?: string; +} + +export interface ListInvoices { + invoices?: Invoice[]; + last_index_offset?: string; + first_index_offset?: string; +} + +export interface LightningNode { + last_update?: number; + last_update_str?: string; + pub_key?: string; + alias?: string; + addresses?: NodeAddress[]; + color?: string; +} + +export interface NetworkInfo { + num_nodes?: number; + btc_max_channel_size?: string; + max_channel_size?: string; + btc_avg_channel_size?: string; + avg_channel_size?: string; + graph_diameter?: number; + num_channels?: number; + max_out_degree?: number; + btc_total_network_capacity?: string; + total_network_capacity?: string; + avg_out_degree?: number; + btc_min_channel_size?: string; + min_channel_size?: string; +} + +export interface NodeAddress { + network?: string; + address?: string; +} + +export interface Payment { + creation_date?: number; + creation_date_str?: string; + payment_hash?: string; + path?: string[]; + fee?: number; + value_msat?: number; + value_sat?: number; + value?: number; + payment_preimage?: string; +} + +export interface PayRequest { + payment_hash?: string; + route_hints?: RouteHint[]; + timestamp?: number; + timestamp_str?: string; + fallback_addr?: string; + cltv_expiry?: number; + description_hash?: string; + destination?: string; + expiry?: number; + description?: string; + num_satoshis?: string; + btc_num_satoshis?: string; +} + +export interface Peer { + pub_key?: string; + alias?: string; + address?: string; // host + bytes_sent?: number; + bytes_recv?: number; + sat_sent?: string; + sat_recv?: string; + inbound?: boolean; + ping_time?: number; +} + +export interface RouteHint { + hop_hints?: HopHint[]; +} + +export interface SendPayment { + dest_string?: string; + dest?: string; + payment_hash_string?: string; + payment_request?: string; + fee_limit?: FeeLimit; + amt?: number; + payment_hash?: string; + final_cltv_delta?: number; +} + +export interface ChannelsTransaction { + address?: string; + amount?: number; + sendAll?: boolean; + blocks?: number; + fees?: number; +} + +export interface Transaction { + dest_addresses?: string[]; + time_stamp?: string; + time_stamp_str?: string; + num_confirmations?: number; + total_fees?: string; + block_hash?: string; + block_height?: number; + tx_hash?: string; + amount?: string; +} + +export interface SwitchReq { + num_max_events?: number; + index_offset?: number; + end_time?: string; + start_time?: string; +} + +export interface ForwardingEvent { + timestamp?: string; + timestamp_str?: string; + chan_id_out?: string; + alias_out?: string; + amt_out?: string; + amt_in?: string; + chan_id_in?: string; + alias_in?: string; + fee?: string; +} + +export interface SwitchRes { + last_offset_index?: number; + forwarding_events?: ForwardingEvent[]; +} diff --git a/src/app/shared/models/navMenu.ts b/src/app/shared/models/navMenu.ts new file mode 100644 index 00000000..c0564a35 --- /dev/null +++ b/src/app/shared/models/navMenu.ts @@ -0,0 +1,39 @@ +export const MENU_DATA: MenuNode = { + id: 0, + parentId: 0, + name: 'root', + icon: 'root', + link: 'root', + children: [ + {id: 1, parentId: 0, name: 'Home', icon: 'home', link: '/home'}, + {id: 2, parentId: 0, name: 'LND Wallet', icon: 'account_balance_wallet', link: '/transsendreceive', children: [ + {id: 21, parentId: 2, name: 'Send/Receive', icon: 'compare_arrows', link: '/transsendreceive'}, + {id: 22, parentId: 2, name: 'List Transactions', icon: 'list_alt', link: '/translist'}, + ]}, + {id: 3, parentId: 0, name: 'Peers', icon: 'group', link: '/peers'}, + {id: 4, parentId: 0, name: 'Channels', icon: 'settings_ethernet', link: '/chnlmanage', children: [ + {id: 41, parentId: 4, name: 'Management', icon: 'subtitles', link: '/chnlmanage'}, + {id: 42, parentId: 4, name: 'Pending', icon: 'watch', link: '/chnlpending'}, + {id: 43, parentId: 4, name: 'Closed', icon: 'watch_later', link: '/chnlclosed'} + ]}, + {id: 5, parentId: 0, name: 'Payments', icon: 'payment', link: '/payments'}, + {id: 6, parentId: 0, name: 'Invoices', icon: 'receipt', link: '/invoices'}, + {id: 7, parentId: 0, name: 'Forwarding History', icon: 'timeline', link: '/switch'}, + {id: 8, parentId: 0, name: 'Lookups', icon: 'search', link: '/lookups'}, + {id: 9, parentId: 0, name: 'Node Config', icon: 'perm_data_setting', link: '/sconfig'}, + {id: 10, parentId: 0, name: 'Help', icon: 'help', link: '/help'} + ] +}; + +export class MenuNode { + id: number; + parentId: number; + name?: string; + icon?: string; + link?: any; + children?: MenuNode[]; +} + +export class FlatMenuNode { + constructor(public expandable: boolean, public level: number, public id: number, public parentId: number, public name: string, public icon: string, public link: string) {} +} diff --git a/src/app/shared/services/auth.guard.ts b/src/app/shared/services/auth.guard.ts new file mode 100644 index 00000000..a3f12af5 --- /dev/null +++ b/src/app/shared/services/auth.guard.ts @@ -0,0 +1,29 @@ +import { CanActivate } from '@angular/router'; +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; + +@Injectable() +export class AuthGuard implements CanActivate { + constructor() {} + + canActivate(): boolean | Observable | Promise { + if (!sessionStorage.getItem('token')) { + return false; + } else { + return true; + } + } +} + +@Injectable() +export class LNDUnlockedGuard implements CanActivate { + constructor() {} + + canActivate(): boolean | Observable | Promise { + if (!sessionStorage.getItem('lndUnlocked')) { + return false; + } else { + return true; + } + } +} diff --git a/src/app/shared/services/auth.interceptor.ts b/src/app/shared/services/auth.interceptor.ts new file mode 100644 index 00000000..ad47aca3 --- /dev/null +++ b/src/app/shared/services/auth.interceptor.ts @@ -0,0 +1,21 @@ +import { Injectable } from '@angular/core'; +import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http'; +import { Observable } from 'rxjs'; + +@Injectable() +export class AuthInterceptor implements HttpInterceptor { + + constructor() {} + + intercept(req: HttpRequest, next: HttpHandler): Observable> { + if (sessionStorage.getItem('token')) { + const cloned = req.clone({ + headers: req.headers.set('Authorization', 'Bearer ' + sessionStorage.getItem('token')) + }); + return next.handle(cloned); + } else { + return next.handle(req); + } + } + +} diff --git a/src/app/shared/services/logger.service.ts b/src/app/shared/services/logger.service.ts new file mode 100644 index 00000000..22ae50d9 --- /dev/null +++ b/src/app/shared/services/logger.service.ts @@ -0,0 +1,50 @@ +import { Injectable } from '@angular/core'; +import { environment } from '../../../environments/environment'; +export let isDebugMode = environment.isDebugMode; +const noop = (): any => undefined; + +export abstract class Logger { + info: any; + warn: any; + error: any; +} + +@Injectable() +export class LoggerService implements Logger { + info: any; + warn: any; + error: any; + invokeConsoleMethod(type: string, args?: any): void {} +} + +@Injectable() +export class ConsoleLoggerService implements Logger { + get info() { + if (isDebugMode) { + return console.log.bind(console); + } else { + return noop; + } + } + + get warn() { + if (isDebugMode) { + return console.warn.bind(console); + } else { + return noop; + } + } + + get error() { + if (isDebugMode) { + return console.error.bind(console); + } else { + return noop; + } + } + + invokeConsoleMethod(type: string, args?: any): void { + const logFn: Function = (console)[type] || console.log || noop; + logFn.apply(console, [args]); + } +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts new file mode 100644 index 00000000..c2cca0b3 --- /dev/null +++ b/src/app/shared/shared.module.ts @@ -0,0 +1,105 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { FlexLayoutModule } from '@angular/flex-layout'; +import { + MatButtonModule, MatButtonToggleModule, MatCardModule, MatCheckboxModule, MatDialogModule, MatExpansionModule, MatGridListModule, MatDatepickerModule, + MatIconModule, MatInputModule, MatListModule, MatMenuModule, MatProgressBarModule, MatProgressSpinnerModule, MatRadioModule, MatTreeModule, MatNativeDateModule, + MatSelectModule, MatSidenavModule, MatSlideToggleModule, MatSortModule, MatTableModule, MatToolbarModule, MatTooltipModule, MAT_DIALOG_DEFAULT_OPTIONS, MatBadgeModule +} from '@angular/material'; +import { QRCodeModule } from 'angularx-qrcode'; +import { AlertMessageComponent } from './components/alert-message/alert-message.component'; +import { ConfirmationMessageComponent } from './components/confirmation-message/confirmation-message.component'; +import { SpinnerDialogComponent } from './components/spinner-dialog/spinner-dialog.component'; +import { NotFoundComponent } from './components/not-found/not-found.component'; +import { SettingsNavComponent } from './components/settings-nav/settings-nav.component'; +import { ClipboardDirective } from './directive/clipboard.directive'; +import { SsoFailedComponent } from './components/sso-failed/sso-failed.component'; + +@NgModule({ + imports: [ + CommonModule, + FormsModule, + ReactiveFormsModule, + FlexLayoutModule, + MatButtonModule, + MatButtonToggleModule, + MatCardModule, + MatCheckboxModule, + MatDialogModule, + MatExpansionModule, + MatGridListModule, + MatDatepickerModule, + MatNativeDateModule, + MatIconModule, + MatInputModule, + MatListModule, + MatMenuModule, + MatProgressBarModule, + MatProgressSpinnerModule, + MatRadioModule, + MatTreeModule, + MatSelectModule, + MatSidenavModule, + MatSlideToggleModule, + MatSortModule, + MatTableModule, + MatToolbarModule, + MatTooltipModule, + MatBadgeModule, + QRCodeModule + ], + exports: [ + FlexLayoutModule, + MatButtonModule, + MatButtonToggleModule, + MatCardModule, + MatCheckboxModule, + MatDialogModule, + MatExpansionModule, + MatGridListModule, + MatDatepickerModule, + MatNativeDateModule, + MatIconModule, + MatInputModule, + MatListModule, + MatMenuModule, + MatProgressBarModule, + MatProgressSpinnerModule, + MatRadioModule, + MatTreeModule, + MatSelectModule, + MatSidenavModule, + MatSlideToggleModule, + MatSortModule, + MatTableModule, + MatToolbarModule, + MatTooltipModule, + MatBadgeModule, + AlertMessageComponent, + ConfirmationMessageComponent, + SpinnerDialogComponent, + NotFoundComponent, + SettingsNavComponent, + ClipboardDirective, + QRCodeModule + ], + declarations: [ + AlertMessageComponent, + ConfirmationMessageComponent, + SpinnerDialogComponent, + NotFoundComponent, + SettingsNavComponent, + ClipboardDirective, + SsoFailedComponent + ], + entryComponents: [ + AlertMessageComponent, + SpinnerDialogComponent, + ConfirmationMessageComponent + ], + providers: [ + { provide: MAT_DIALOG_DEFAULT_OPTIONS, useValue: { hasBackdrop: true, autoFocus: true, disableClose: true, role: 'dialog', width: '700px' } } + ] +}) +export class SharedModule { } diff --git a/src/app/shared/store/rtl.actions.ts b/src/app/shared/store/rtl.actions.ts new file mode 100644 index 00000000..129bfffa --- /dev/null +++ b/src/app/shared/store/rtl.actions.ts @@ -0,0 +1,405 @@ +import { Action } from '@ngrx/store'; +import { Settings, Authentication } from '../models/RTLconfig'; +import { ErrorPayload } from '../models/errorPayload'; +import { + GetInfo, Peer, Balance, NetworkInfo, Fees, Channel, Invoice, Payment, GraphNode, AddressType, + PayRequest, ChannelsTransaction, PendingChannels, ClosedChannel, Transaction, SwitchReq, SwitchRes +} from '../models/lndModels'; +import { MatDialogConfig } from '@angular/material'; + +export const CLEAR_EFFECT_ERROR = 'CLEAR_EFFECT_ERROR'; +export const EFFECT_ERROR = 'EFFECT_ERROR'; +export const OPEN_SPINNER = 'OPEN_SPINNER'; +export const CLOSE_SPINNER = 'CLOSE_SPINNER'; +export const OPEN_ALERT = 'OPEN_ALERT'; +export const CLOSE_ALERT = 'CLOSE_ALERT'; +export const OPEN_CONFIRMATION = 'OPEN_CONFIRMATION'; +export const CLOSE_CONFIRMATION = 'CLOSE_CONFIRMATION'; +export const FETCH_STORE = 'FETCH_STORE'; +export const SET_STORE = 'SET_STORE'; +export const FETCH_SETTINGS = 'FETCH_SETTINGS'; +export const SET_SETTINGS = 'SET_SETTINGS'; +export const SET_AUTH_SETTINGS = 'SET_AUTH_SETTINGS'; +export const SAVE_SETTINGS = 'SAVE_SETTINGS'; +export const FETCH_INFO = 'FETCH_INFO'; +export const SET_INFO = 'SET_INFO'; +export const FETCH_PEERS = 'FETCH_PEERS'; +export const SET_PEERS = 'SET_PEERS'; +export const SAVE_NEW_PEER = 'SAVE_NEW_PEER'; +export const ADD_PEER = 'ADD_PEER'; +export const DETACH_PEER = 'DETACH_PEER'; +export const REMOVE_PEER = 'REMOVE_PEER'; +export const SAVE_NEW_INVOICE = 'SAVE_NEW_INVOICE'; +export const ADD_INVOICE = 'ADD_INVOICE'; +export const FETCH_FEES = 'FETCH_FEES'; +export const SET_FEES = 'SET_FEES'; +export const FETCH_BALANCE = 'FETCH_BALANCE'; +export const SET_BALANCE = 'SET_BALANCE'; +export const FETCH_NETWORK = 'FETCH_NETWORK'; +export const SET_NETWORK = 'SET_NETWORK'; +export const FETCH_CHANNELS = 'FETCH_CHANNELS'; +export const SET_CHANNELS = 'SET_CHANNELS'; +export const UPDATE_CHANNELS = 'UPDATE_CHANNELS'; +export const SET_PENDING_CHANNELS = 'SET_PENDING_CHANNELS'; +export const SET_CLOSED_CHANNELS = 'SET_CLOSED_CHANNELS'; +export const SAVE_NEW_CHANNEL = 'SAVE_NEW_CHANNEL'; +export const CLOSE_CHANNEL = 'CLOSE_CHANNEL'; +export const REMOVE_CHANNEL = 'REMOVE_CHANNEL'; +export const FETCH_INVOICES = 'FETCH_INVOICES'; +export const SET_INVOICES = 'SET_INVOICES'; +export const FETCH_TRANSACTIONS = 'FETCH_TRANSACTIONS'; +export const SET_TRANSACTIONS = 'SET_TRANSACTIONS'; +export const FETCH_PAYMENTS = 'FETCH_PAYMENTS'; +export const SET_PAYMENTS = 'SET_PAYMENTS'; +export const DECODE_PAYMENT = 'DECODE_PAYMENT'; +export const SEND_PAYMENT = 'SEND_PAYMENT'; +export const SET_DECODED_PAYMENT = 'SET_DECODED_PAYMENT'; +export const FETCH_GRAPH_NODE = 'FETCH_GRAPH_NODE'; +export const SET_GRAPH_NODE = 'SET_GRAPH_NODE'; +export const GET_NEW_ADDRESS = 'GET_NEW_ADDRESS'; +export const SET_NEW_ADDRESS = 'SET_NEW_ADDRESS'; +export const SET_CHANNEL_TRANSACTION = 'SET_CHANNEL_TRANSACTION'; +export const OPERATE_WALLET = 'OPERATE_WALLET'; +export const FETCH_CONFIG = 'FETCH_CONFIG'; +export const SHOW_CONFIG = 'SHOW_CONFIG'; +export const IS_AUTHORIZED = 'IS_AUTHORIZED'; +export const IS_AUTHORIZED_RES = 'IS_AUTHORIZED_RES'; +export const SIGNIN = 'SIGNIN'; +export const SIGNOUT = 'SIGNOUT'; +export const INIT_APP_DATA = 'INIT_APP_DATA'; +export const PEER_LOOKUP = 'PEER_LOOKUP'; +export const CHANNEL_LOOKUP = 'CHANNEL_LOOKUP'; +export const INVOICE_LOOKUP = 'INVOICE_LOOKUP'; +export const SET_LOOKUP = 'SET_LOOKUP'; +export const GET_FORWARDING_HISTORY = 'GET_FORWARDING_HISTORY'; +export const SET_FORWARDING_HISTORY = 'SET_FORWARDING_HISTORY'; + +export class ClearEffectError implements Action { + readonly type = CLEAR_EFFECT_ERROR; + constructor(public payload: string) {} // payload = errorAction +} + +export class EffectError implements Action { + readonly type = EFFECT_ERROR; + constructor(public payload: ErrorPayload) {} +} + +export class OpenSpinner implements Action { + readonly type = OPEN_SPINNER; + constructor(public payload: string) {} // payload = titleMessage +} + +export class CloseSpinner implements Action { + readonly type = CLOSE_SPINNER; +} + +export class OpenAlert implements Action { + readonly type = OPEN_ALERT; + constructor(public payload: MatDialogConfig) {} +} + +export class CloseAlert implements Action { + readonly type = CLOSE_ALERT; +} + +export class OpenConfirmation implements Action { + readonly type = OPEN_CONFIRMATION; + constructor(public payload: MatDialogConfig) {} +} + +export class CloseConfirmation implements Action { + readonly type = CLOSE_CONFIRMATION; + constructor(public payload: boolean) {} +} + +export class FetchSettings implements Action { + readonly type = FETCH_SETTINGS; +} + +export class SetSettings implements Action { + readonly type = SET_SETTINGS; + constructor(public payload: Settings) {} +} + +export class SetAuthSettings implements Action { + readonly type = SET_AUTH_SETTINGS; + constructor(public payload: Authentication) {} +} + +export class SaveSettings implements Action { + readonly type = SAVE_SETTINGS; + constructor(public payload: Settings) {} +} + +export class FetchInfo implements Action { + readonly type = FETCH_INFO; +} + +export class SetInfo implements Action { + readonly type = SET_INFO; + constructor(public payload: GetInfo) {} +} + +export class FetchPeers implements Action { + readonly type = FETCH_PEERS; +} + +export class SetPeers implements Action { + readonly type = SET_PEERS; + constructor(public payload: Peer[]) {} +} + +export class SaveNewPeer implements Action { + readonly type = SAVE_NEW_PEER; + constructor(public payload: {pubkey: string, host: string, perm: boolean}) {} +} + +export class AddPeer implements Action { + readonly type = ADD_PEER; + constructor(public payload: Peer) {} +} + +export class DetachPeer implements Action { + readonly type = DETACH_PEER; + constructor(public payload: {pubkey: string}) {} +} + +export class RemovePeer implements Action { + readonly type = REMOVE_PEER; + constructor(public payload: {pubkey: string}) {} +} + +export class SaveNewInvoice implements Action { + readonly type = SAVE_NEW_INVOICE; + constructor(public payload: {memo: string, invoiceValue: number}) {} +} + +export class AddInvoice implements Action { + readonly type = ADD_INVOICE; + constructor(public payload: Invoice) {} +} + +export class FetchFees implements Action { + readonly type = FETCH_FEES; +} + +export class SetFees implements Action { + readonly type = SET_FEES; + constructor(public payload: Fees) {} +} + +export class FetchBalance implements Action { + readonly type = FETCH_BALANCE; + constructor(public payload: string) {} // payload = routeParam +} + +export class SetBalance implements Action { + readonly type = SET_BALANCE; + constructor(public payload: {target: string, balance: Balance}) {} +} + +export class FetchNetwork implements Action { + readonly type = FETCH_NETWORK; +} + +export class SetNetwork implements Action { + readonly type = SET_NETWORK; + constructor(public payload: NetworkInfo) {} +} + +export class FetchChannels implements Action { + readonly type = FETCH_CHANNELS; + constructor(public payload: {routeParam: string, channelStatus: string}) {} +} + +export class SetChannels implements Action { + readonly type = SET_CHANNELS; + constructor(public payload: Channel[]) {} +} + +export class UpdateChannels implements Action { + readonly type = UPDATE_CHANNELS; + constructor(public payload: any) {} +} + +export class SetPendingChannels implements Action { + readonly type = SET_PENDING_CHANNELS; + constructor(public payload: PendingChannels) {} +} + +export class SetClosedChannels implements Action { + readonly type = SET_CLOSED_CHANNELS; + constructor(public payload: ClosedChannel[]) {} +} + +export class SaveNewChannel implements Action { + readonly type = SAVE_NEW_CHANNEL; + constructor(public payload: {selectedPeerPubkey: string, fundingAmount: number, transType: string, transTypeValue: string, spendUnconfirmed: boolean}) {} +} + +export class CloseChannel implements Action { + readonly type = CLOSE_CHANNEL; + constructor(public payload: {channelPoint: string, forcibly: boolean, channelStatus: boolean}) {} +} + +export class RemoveChannel implements Action { + readonly type = REMOVE_CHANNEL; + constructor(public payload: {channelPoint: string}) {} +} + +export class FetchInvoices implements Action { + readonly type = FETCH_INVOICES; +} + +export class SetInvoices implements Action { + readonly type = SET_INVOICES; + constructor(public payload: Invoice[]) {} +} + +export class FetchTransactions implements Action { + readonly type = FETCH_TRANSACTIONS; +} + +export class SetTransactions implements Action { + readonly type = SET_TRANSACTIONS; + constructor(public payload: Transaction[]) {} +} + +export class FetchPayments implements Action { + readonly type = FETCH_PAYMENTS; +} + +export class SetPayments implements Action { + readonly type = SET_PAYMENTS; + constructor(public payload: Payment[]) {} +} + +export class DecodePayment implements Action { + readonly type = DECODE_PAYMENT; + constructor(public payload: string) {} // payload = routeParam +} + +export class SetDecodedPayment implements Action { + readonly type = SET_DECODED_PAYMENT; + constructor(public payload: PayRequest) {} +} + +export class SendPayment implements Action { + readonly type = SEND_PAYMENT; + constructor(public payload: [string, PayRequest, boolean]) {} // payload = [paymentReqStr, paymentDecoded, EmptyAmtInvoice] +} + +export class FetchGraphNode implements Action { + readonly type = FETCH_GRAPH_NODE; + constructor(public payload: string) {} // payload = pubkey +} + +export class SetGraphNode implements Action { + readonly type = SET_GRAPH_NODE; + constructor(public payload: GraphNode) {} +} + +export class GetNewAddress implements Action { + readonly type = GET_NEW_ADDRESS; + constructor(public payload: AddressType) {} +} + +export class SetNewAddress implements Action { + readonly type = SET_NEW_ADDRESS; + constructor(public payload: string) {} // payload = newAddress +} + +export class SetChannelTransaction implements Action { + readonly type = SET_CHANNEL_TRANSACTION; + constructor(public payload: ChannelsTransaction) {} +} + +export class OperateWallet implements Action { + readonly type = OPERATE_WALLET; + constructor(public payload: {operation: string, pwd: string}) {} +} + +export class FetchConfig implements Action { + readonly type = FETCH_CONFIG; + constructor(public payload: string) {} // payload = lnd/bitcoin node +} + +export class ShowConfig implements Action { + readonly type = SHOW_CONFIG; + constructor(public payload: any) {} // payload = Config File +} + +export class PeerLookup implements Action { + readonly type = PEER_LOOKUP; + constructor(public payload: string) {} // payload = pubkey +} + +export class ChannelLookup implements Action { + readonly type = CHANNEL_LOOKUP; + constructor(public payload: string) {} // payload = chanID +} + +export class InvoiceLookup implements Action { + readonly type = INVOICE_LOOKUP; + constructor(public payload: string) {} // payload = rHashStr +} + +export class SetLookup implements Action { + readonly type = SET_LOOKUP; + constructor(public payload: any) {} // payload = lookup Response (Peer/Channel/Invoice) +} + +export class GetForwardingHistory implements Action { + readonly type = GET_FORWARDING_HISTORY; + constructor(public payload: SwitchReq) {} +} + +export class SetForwardingHistory implements Action { + readonly type = SET_FORWARDING_HISTORY; + constructor(public payload: SwitchRes) {} +} + +export class IsAuthorized implements Action { + readonly type = IS_AUTHORIZED; + constructor(public payload: string) {} // payload = password +} + +export class IsAuthorizedRes implements Action { + readonly type = IS_AUTHORIZED_RES; + constructor(public payload: any) {} // payload = token/error +} + +export class Signin implements Action { + readonly type = SIGNIN; + constructor(public payload: string) {} // payload = password +} + +export class Signout implements Action { + readonly type = SIGNOUT; + constructor() {} +} + +export class InitAppData implements Action { + readonly type = INIT_APP_DATA; +} + +export type RTLActions = + ClearEffectError | EffectError | OpenSpinner | CloseSpinner | + FetchSettings | SetSettings | SaveSettings | SetAuthSettings | + OpenAlert | CloseAlert | OpenConfirmation | CloseConfirmation | + FetchInfo | SetInfo | + FetchPeers | SetPeers | AddPeer | DetachPeer | SaveNewPeer | RemovePeer | + AddInvoice | SaveNewInvoice | GetForwardingHistory | SetForwardingHistory | + FetchFees | SetFees | + FetchBalance | SetBalance | + FetchNetwork | SetNetwork | + FetchChannels | SetChannels | SetPendingChannels | SetClosedChannels | UpdateChannels | + SaveNewChannel | CloseChannel | RemoveChannel | + FetchTransactions | SetTransactions | + FetchInvoices | SetInvoices | + FetchPayments | SetPayments | SendPayment | + DecodePayment | SetDecodedPayment | + FetchGraphNode | SetGraphNode | + GetNewAddress | SetNewAddress | SetChannelTransaction | OperateWallet | + FetchConfig | ShowConfig | PeerLookup | ChannelLookup | InvoiceLookup | SetLookup | + IsAuthorized | IsAuthorizedRes | Signin | Signout | InitAppData; diff --git a/src/app/shared/store/rtl.effects.ts b/src/app/shared/store/rtl.effects.ts new file mode 100644 index 00000000..a224c6bd --- /dev/null +++ b/src/app/shared/store/rtl.effects.ts @@ -0,0 +1,1064 @@ +import { Injectable, OnDestroy } from '@angular/core'; +import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http'; +import { Router } from '@angular/router'; +import { Store } from '@ngrx/store'; +import { Actions, Effect, ofType } from '@ngrx/effects'; +import { of, Subject } from 'rxjs'; +import { map, mergeMap, catchError, take, withLatestFrom } from 'rxjs/operators'; + +import { MatDialog } from '@angular/material'; + +import { environment } from '../../../environments/environment'; +import { LoggerService } from '../services/logger.service'; +import { Settings } from '../models/RTLconfig'; +import { GetInfo, Fees, Balance, NetworkInfo, Payment, Invoice, GraphNode, Transaction, SwitchReq } from '../models/lndModels'; + +import { SpinnerDialogComponent } from '../components/spinner-dialog/spinner-dialog.component'; +import { AlertMessageComponent } from '../components/alert-message/alert-message.component'; +import { ConfirmationMessageComponent } from '../components/confirmation-message/confirmation-message.component'; + +import * as RTLActions from './rtl.actions'; +import * as fromRTLReducer from './rtl.reducers'; + +@Injectable() +export class RTLEffects implements OnDestroy { + dialogRef: any; + private unSubs: Array> = [new Subject(), new Subject()]; + + constructor( + private actions$: Actions, + private httpClient: HttpClient, + private store: Store, + private logger: LoggerService, + public dialog: MatDialog, + private router: Router) { } + + @Effect({ dispatch: false }) + openSpinner = this.actions$.pipe( + ofType(RTLActions.OPEN_SPINNER), + map((action: RTLActions.OpenSpinner) => { + this.dialogRef = this.dialog.open(SpinnerDialogComponent, { data: { titleMessage: action.payload}}); + } + )); + + @Effect({ dispatch: false }) + closeSpinner = this.actions$.pipe( + ofType(RTLActions.CLOSE_SPINNER), + map((action: RTLActions.CloseSpinner) => { + this.dialogRef.close(); + } + )); + + @Effect({ dispatch: false }) + openAlert = this.actions$.pipe( + ofType(RTLActions.OPEN_ALERT), + map((action: RTLActions.OpenAlert) => { + this.dialogRef = this.dialog.open(AlertMessageComponent, action.payload); + } + )); + + @Effect({ dispatch: false }) + closeAlert = this.actions$.pipe( + ofType(RTLActions.CLOSE_ALERT), + map((action: RTLActions.CloseAlert) => { + this.dialogRef.close(); + } + )); + + @Effect({ dispatch: false }) + openConfirm = this.actions$.pipe( + ofType(RTLActions.OPEN_CONFIRMATION), + map((action: RTLActions.OpenConfirmation) => { + this.dialogRef = this.dialog.open(ConfirmationMessageComponent, action.payload); + }) + ); + + @Effect({ dispatch: false }) + closeConfirm = this.actions$.pipe( + ofType(RTLActions.CLOSE_CONFIRMATION), + take(1), + map((action: RTLActions.CloseConfirmation) => { + this.dialogRef.close(); + this.logger.info(action.payload); + return action.payload; + } + )); + + @Effect() + settingFetch = this.actions$.pipe( + ofType(RTLActions.FETCH_SETTINGS), + mergeMap((action: RTLActions.FetchSettings) => { + this.store.dispatch(new RTLActions.ClearEffectError('FetchSettings')); + return this.httpClient.get(environment.CONF_API + '/rtlconf'); + }), + map((rtlConfig: any) => { + this.logger.info(rtlConfig); + this.store.dispatch(new RTLActions.SetAuthSettings(rtlConfig.authSettings)); + return { + type: RTLActions.SET_SETTINGS, + payload: (undefined !== rtlConfig && undefined !== rtlConfig.settings) ? rtlConfig.settings : + {'flgSidenavOpened': true, 'flgSidenavPinned': true, 'menu': 'Vertical', 'menuType': 'Regular', 'theme': 'dark-blue', 'satsToBTC': false} + }; + }, + catchError((err) => { + this.logger.error(err); + this.store.dispatch(new RTLActions.EffectError({ action: 'FetchSettings', code: err.status, message: err.error.error })); + return of(); + }) + )); + + @Effect({ dispatch: false }) + settingSave = this.actions$.pipe( + ofType(RTLActions.SAVE_SETTINGS), + mergeMap((action: RTLActions.SaveSettings) => { + return this.httpClient.post(environment.CONF_API, { updatedSettings: action.payload }); + } + )); + + @Effect() + infoFetch = this.actions$.pipe( + ofType(RTLActions.FETCH_INFO), + withLatestFrom(this.store.select('rtlRoot')), + mergeMap(([action, store]: [RTLActions.FetchInfo, fromRTLReducer.State]) => { + this.store.dispatch(new RTLActions.ClearEffectError('FetchInfo')); + return this.httpClient.get(environment.GETINFO_API) + .pipe( + map((info) => { + this.logger.info(info); + if (undefined === info.identity_pubkey) { + sessionStorage.removeItem('lndUnlocked'); + this.logger.info('Redirecting to Unlock'); + this.router.navigate(['/unlocklnd']); + return of(); + } else { + sessionStorage.setItem('lndUnlocked', 'true'); + return { + type: RTLActions.SET_INFO, + payload: (undefined !== info) ? info : {} + }; + } + }), + catchError((err) => { + this.logger.error(err); + this.store.dispatch(new RTLActions.EffectError({ action: 'FetchInfo', code: err.status, message: err.error.error })); + if (+store.authSettings.rtlSSO) { + this.router.navigate(['/ssoerror']); + } else { + if (err.status === 401) { + this.logger.info('Redirecting to Signin'); + this.router.navigate([store.authSettings.logoutRedirectLink]); + return of(); + } else { + this.logger.info('Redirecting to Unlock'); + this.router.navigate(['/unlocklnd']); + return of(); + } + } + }) + ); + } + )); + + @Effect() + peersFetch = this.actions$.pipe( + ofType(RTLActions.FETCH_PEERS), + mergeMap((action: RTLActions.FetchPeers) => { + this.store.dispatch(new RTLActions.ClearEffectError('FetchPeers')); + return this.httpClient.get(environment.PEERS_API) + .pipe( + map((peers: any) => { + this.logger.info(peers); + return { + type: RTLActions.SET_PEERS, + payload: (undefined !== peers) ? peers : [] + }; + }), + catchError((err: any) => { + this.store.dispatch(new RTLActions.EffectError({ action: 'FetchPeers', code: err.status, message: err.error.error })); + this.logger.error(err); + return of(); + }) + ); + } + )); + + @Effect() + saveNewPeer = this.actions$.pipe( + ofType(RTLActions.SAVE_NEW_PEER), + mergeMap((action: RTLActions.SaveNewPeer) => { + return this.httpClient.post(environment.PEERS_API, {pubkey: action.payload.pubkey, host: action.payload.host, perm: action.payload.perm}) + .pipe( + map((postRes: any) => { + this.logger.info(postRes); + this.store.dispatch(new RTLActions.CloseSpinner()); + this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', data: { type: 'SUCCESS', titleMessage: 'Peer Added Successfully!'}})); + return { + type: RTLActions.SET_PEERS, + payload: (undefined !== postRes && postRes.length > 0) ? postRes : [] + }; + }), + catchError((err: any) => { + this.store.dispatch(new RTLActions.CloseSpinner()); + this.logger.error(err); + return of( + { + type: RTLActions.OPEN_ALERT, + payload: { width: '70%', data: {type: 'ERROR', titleMessage: 'Add Peer Failed', + message: JSON.stringify({code: err.status, Message: err.error.error}) + }} + } + ); + }) + ); + } + )); + + @Effect() + detachPeer = this.actions$.pipe( + ofType(RTLActions.DETACH_PEER), + mergeMap((action: RTLActions.DetachPeer) => { + return this.httpClient.delete(environment.PEERS_API + '/' + action.payload.pubkey) + .pipe( + map((postRes: any) => { + this.logger.info(postRes); + this.store.dispatch(new RTLActions.CloseSpinner()); + this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', data: {type: 'SUCCESS', titleMessage: 'Peer Detached Successfully!'}})); + return { + type: RTLActions.REMOVE_PEER, + payload: { pubkey: action.payload.pubkey } + }; + }), + catchError((err: any) => { + this.store.dispatch(new RTLActions.CloseSpinner()); + this.logger.error(err); + return of( + { + type: RTLActions.OPEN_ALERT, + payload: { width: '70%', data: {type: 'ERROR', titleMessage: 'Unable to Detach Peer. Try again later.', + message: JSON.stringify({code: err.status, Message: err.error.error})} + } + } + ); + }) + ); + } + )); + + @Effect() + saveNewInvoice = this.actions$.pipe( + ofType(RTLActions.SAVE_NEW_INVOICE), + mergeMap((action: RTLActions.SaveNewInvoice) => { + return this.httpClient.post(environment.INVOICES_API, {memo: action.payload.memo, amount: action.payload.invoiceValue}) + .pipe( + map((postRes: any) => { + postRes.memo = action.payload.memo; + postRes.value = action.payload.invoiceValue; + postRes.expiry = '3600'; + postRes.cltv_expiry = '144'; + postRes.creation_date = Math.round(new Date().getTime() / 1000).toString(); + postRes.creation_date_str = new Date(+postRes.creation_date * 1000).toUTCString(); + this.logger.info(postRes); + this.store.dispatch(new RTLActions.CloseSpinner()); + const msg = { payment_request: postRes.payment_request }; + this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', + data: { type: 'SUCCESS', titleMessage: 'Invoice Added Successfully!', message: JSON.stringify(msg) }})); + return { + type: RTLActions.ADD_INVOICE, + payload: postRes + }; + }), + catchError((err: any) => { + this.store.dispatch(new RTLActions.CloseSpinner()); + this.logger.error(err); + return of( + { + type: RTLActions.OPEN_ALERT, + payload: { width: '70%', data: {type: 'ERROR', titleMessage: 'Add Invoice Failed', + message: JSON.stringify({code: err.status, Message: err.error.error}) + }} + } + ); + }) + ); + } + )); + + @Effect() + openNewChannel = this.actions$.pipe( + ofType(RTLActions.SAVE_NEW_CHANNEL), + mergeMap((action: RTLActions.SaveNewChannel) => { + return this.httpClient.post(environment.CHANNELS_API, { + node_pubkey: action.payload.selectedPeerPubkey, local_funding_amount: action.payload.fundingAmount, + trans_type: action.payload.transType, trans_type_value: action.payload.transTypeValue, spend_unconfirmed: action.payload.spendUnconfirmed + }) + .pipe( + map((postRes: any) => { + this.logger.info(postRes); + this.store.dispatch(new RTLActions.CloseSpinner()); + this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', data: {type: 'SUCCESS', titleMessage: 'Channel Added Successfully!'}})); + this.store.dispatch(new RTLActions.FetchBalance('blockchain')); + this.store.dispatch(new RTLActions.FetchChannels({routeParam: 'all', channelStatus: ''})); + return { + type: RTLActions.FETCH_CHANNELS, + payload: {routeParam: 'pending', channelStatus: ''} + }; + }), + catchError((err: any) => { + this.store.dispatch(new RTLActions.CloseSpinner()); + this.logger.error(err); + return of( + { + type: RTLActions.OPEN_ALERT, + payload: { width: '70%', data: {type: 'ERROR', titleMessage: 'Open Channel Failed', + message: JSON.stringify({code: err.status, Message: err.error.error}) + }} + } + ); + }) + ); + } + )); + + @Effect() + updateChannel = this.actions$.pipe( + ofType(RTLActions.UPDATE_CHANNELS), + mergeMap((action: RTLActions.UpdateChannels) => { + return this.httpClient.post(environment.CHANNELS_API + '/chanPolicy', + { baseFeeMsat: action.payload.baseFeeMsat, feeRate: action.payload.feeRate, timeLockDelta: action.payload.timeLockDelta, chanPoint: action.payload.chanPoint }) + .pipe( + map((postRes: any) => { + this.logger.info(postRes); + this.store.dispatch(new RTLActions.CloseSpinner()); + this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', data: {type: 'SUCCESS', titleMessage: 'Channel Updated Successfully!'}})); + return { + type: RTLActions.FETCH_CHANNELS, + payload: {routeParam: 'all', channelStatus: ''} + }; + }), + catchError((err: any) => { + this.store.dispatch(new RTLActions.CloseSpinner()); + this.logger.error(err); + return of( + { + type: RTLActions.OPEN_ALERT, + payload: { width: '70%', data: {type: 'ERROR', titleMessage: 'Update Channel Failed', + message: JSON.stringify({code: err.status, Message: err.error.error}) + }} + } + ); + }) + ); + } + )); + + @Effect() + closeChannel = this.actions$.pipe( + ofType(RTLActions.CLOSE_CHANNEL), + mergeMap((action: RTLActions.CloseChannel) => { + return this.httpClient.delete(environment.CHANNELS_API + '/' + action.payload.channelPoint + '?force=' + action.payload.forcibly) + .pipe( + map((postRes: any) => { + this.logger.info(postRes); + this.store.dispatch(new RTLActions.CloseSpinner()); + this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', data: {type: 'SUCCESS', titleMessage: 'Channel Closed Successfully!'}})); + this.store.dispatch(new RTLActions.FetchBalance('channels')); + this.store.dispatch(new RTLActions.FetchBalance('blockchain')); + this.store.dispatch(new RTLActions.FetchChannels({routeParam: 'all', channelStatus: ''})); + if (action.payload.channelStatus) { + this.store.dispatch(new RTLActions.FetchChannels({routeParam: 'closed', channelStatus: ''})); + } else { + this.store.dispatch(new RTLActions.FetchChannels({routeParam: 'pending', channelStatus: ''})); + } + return { + type: RTLActions.REMOVE_CHANNEL, + payload: { channelPoint: action.payload.channelPoint } + }; + }), + catchError((err: any) => { + this.store.dispatch(new RTLActions.CloseSpinner()); + this.logger.error(err); + return of( + { + type: RTLActions.OPEN_ALERT, + payload: { width: '70%', data: {type: 'ERROR', titleMessage: 'Unable to Close Channel. Try again later.', + message: JSON.stringify({code: err.status, Message: err.error.error.message})}} + } + ); + }) + ); + } + )); + + @Effect() + fetchFees = this.actions$.pipe( + ofType(RTLActions.FETCH_FEES), + mergeMap((action: RTLActions.FetchFees) => { + this.store.dispatch(new RTLActions.ClearEffectError('FetchFees')); + return this.httpClient.get(environment.FEES_API); + }), + map((fees) => { + this.logger.info(fees); + return { + type: RTLActions.SET_FEES, + payload: (undefined !== fees) ? fees : {} + }; + }), + catchError((err: any) => { + this.logger.error(err); + this.store.dispatch(new RTLActions.EffectError({ action: 'FetchFees', code: err.status, message: err.error.error })); + return of(); + } + )); + + @Effect() + balanceFetch = this.actions$.pipe( + ofType(RTLActions.FETCH_BALANCE), + mergeMap((action: RTLActions.FetchBalance) => { + this.store.dispatch(new RTLActions.ClearEffectError('FetchBalance/' + action.payload)); + return this.httpClient.get(environment.BALANCE_API + '/' + action.payload) + .pipe( + map((res: any) => { + if (action.payload === 'channels') { + this.store.dispatch(new RTLActions.FetchBalance('blockchain')); + } + this.logger.info(res); + const emptyRes = (action.payload === 'channels') ? {balance: '', btc_balance: ''} : {total_balance: '', btc_total_balance: ''}; + return { + type: RTLActions.SET_BALANCE, + payload: (undefined !== res) ? { target: action.payload, balance: res } : { target: action.payload, balance: emptyRes } + }; + }), + catchError((err: any) => { + this.logger.error(err); + this.store.dispatch(new RTLActions.EffectError({ action: 'FetchBalance/' + action.payload, code: err.status, message: err.error.error })); + return of(); + } + )); + } + )); + + @Effect() + networkInfoFetch = this.actions$.pipe( + ofType(RTLActions.FETCH_NETWORK), + mergeMap((action: RTLActions.FetchNetwork) => { + this.store.dispatch(new RTLActions.ClearEffectError('FetchNetwork')); + return this.httpClient.get(environment.NETWORK_API + '/info'); + }), + map((networkInfo) => { + this.logger.info(networkInfo); + return { + type: RTLActions.SET_NETWORK, + payload: (undefined !== networkInfo) ? networkInfo : {} + }; + }), + catchError((err: any) => { + this.logger.error(err); + this.store.dispatch(new RTLActions.EffectError({ action: 'FetchNetwork', code: err.status, message: err.error.error })); + return of(); + } + )); + + @Effect() + channelsFetch = this.actions$.pipe( + ofType(RTLActions.FETCH_CHANNELS), + mergeMap((action: RTLActions.FetchChannels) => { + const options = + (undefined === action.payload.channelStatus || action.payload.channelStatus === '') ? {} : { params: new HttpParams().set(action.payload.channelStatus, 'true') }; + return this.httpClient.get(environment.CHANNELS_API + '/' + action.payload.routeParam, options) + .pipe( + map((channels: any) => { + this.logger.info(channels); + if (action.payload.routeParam === 'pending') { + return { + type: RTLActions.SET_PENDING_CHANNELS, + payload: (undefined !== channels) ? channels : {} + }; + } else if (action.payload.routeParam === 'closed') { + return { + type: RTLActions.SET_CLOSED_CHANNELS, + payload: (undefined !== channels && undefined !== channels.channels && channels.channels.length > 0) ? channels.channels : [] + }; + } else if (action.payload.routeParam === 'all') { + return { + type: RTLActions.SET_CHANNELS, + payload: (undefined !== channels && undefined !== channels.channels && channels.channels.length > 0) ? channels.channels : [] + }; + } + }, + catchError((err: any) => { + this.logger.error(err); + this.store.dispatch(new RTLActions.EffectError({ action: 'FetchChannels/' + action.payload.routeParam, code: err.status, message: err.error.error })); + return of(); + }) + )); + } + )); + + @Effect() + invoicesFetch = this.actions$.pipe( + ofType(RTLActions.FETCH_INVOICES), + mergeMap((action: RTLActions.FetchInvoices) => { + this.store.dispatch(new RTLActions.ClearEffectError('FetchInvoices')); + return this.httpClient.get(environment.INVOICES_API); + }), + map((res: any) => { + this.logger.info(res); + return { + type: RTLActions.SET_INVOICES, + payload: (undefined !== res && undefined !== res.invoices && res.invoices.length > 0) ? res.invoices : [] + }; + }), + catchError((err: any) => { + this.logger.error(err); + this.store.dispatch(new RTLActions.EffectError({ action: 'FetchInvoices', code: err.status, message: err.error.error })); + return of(); + } + )); + + @Effect() + transactionsFetch = this.actions$.pipe( + ofType(RTLActions.FETCH_TRANSACTIONS), + mergeMap((action: RTLActions.FetchTransactions) => { + this.store.dispatch(new RTLActions.ClearEffectError('FetchTransactions')); + return this.httpClient.get(environment.TRANSACTIONS_API); + }), + map((transactions) => { + this.logger.info(transactions); + return { + type: RTLActions.SET_TRANSACTIONS, + payload: (undefined !== transactions && transactions.length > 0) ? transactions : [] + }; + }), + catchError((err: any) => { + this.logger.error(err); + this.store.dispatch(new RTLActions.EffectError({ action: 'FetchTransactions', code: err.status, message: err.error.error })); + return of(); + } + )); + + @Effect() + paymentsFetch = this.actions$.pipe( + ofType(RTLActions.FETCH_PAYMENTS), + mergeMap((action: RTLActions.FetchPayments) => { + this.store.dispatch(new RTLActions.ClearEffectError('FetchPayments')); + return this.httpClient.get(environment.PAYMENTS_API); + }), + map((payments) => { + this.logger.info(payments); + return { + type: RTLActions.SET_PAYMENTS, + payload: (undefined !== payments) ? payments : [] + }; + }), + catchError((err: any) => { + this.logger.error(err); + this.store.dispatch(new RTLActions.EffectError({ action: 'FetchPayments', code: err.status, message: err.error.error })); + return of(); + } + )); + + @Effect() + decodePayment = this.actions$.pipe( + ofType(RTLActions.DECODE_PAYMENT), + mergeMap((action: RTLActions.DecodePayment) => { + return this.httpClient.get(environment.PAYREQUEST_API + '/' + action.payload) + .pipe( + map((decodedPayment) => { + this.logger.info(decodedPayment); + this.store.dispatch(new RTLActions.CloseSpinner()); + return { + type: RTLActions.SET_DECODED_PAYMENT, + payload: (undefined !== decodedPayment) ? decodedPayment : {} + }; + }), + catchError((err: any) => { + this.store.dispatch(new RTLActions.CloseSpinner()); + this.logger.error(err); + return of( + { + type: RTLActions.OPEN_ALERT, + payload: { width: '70%', data: {type: 'ERROR', titleMessage: 'Decode Payment Failed', + message: JSON.stringify({Code: err.status, Message: err.error.error, URL: environment.PAYREQUEST_API + '/' + action.payload})}} + } + ); + }) + ); + }) + ); + + @Effect({ dispatch: false }) + setDecodedPayment = this.actions$.pipe( + ofType(RTLActions.SET_DECODED_PAYMENT), + map((action: RTLActions.SetDecodedPayment) => { + this.logger.info(action.payload); + return action.payload; + }) + ); + + @Effect() + sendPayment = this.actions$.pipe( + ofType(RTLActions.SEND_PAYMENT), + withLatestFrom(this.store.select('rtlRoot')), + mergeMap(([action, store]: [RTLActions.SendPayment, fromRTLReducer.State]) => { + let queryHeaders = {}; + if (action.payload[2]) { + queryHeaders = {paymentDecoded: action.payload[1]}; + } else { + queryHeaders = {paymentReq: action.payload[0]}; + } + return this.httpClient.post(environment.CHANNELS_API + '/transactions', queryHeaders) + .pipe( + map((sendRes: any) => { + this.logger.info(sendRes); + this.store.dispatch(new RTLActions.CloseSpinner()); + if (sendRes.payment_error) { + this.logger.error('Error: ' + sendRes.payment_error); + return of({ + type: RTLActions.OPEN_ALERT, + payload: { width: '70%', data: {type: 'ERROR', titleMessage: 'Send Payment Failed', + message: JSON.stringify( + {code: sendRes.payment_error.status, Message: sendRes.payment_error.error.message, URL: environment.CHANNELS_API + '/transactions/' + action.payload[0]} + ) + }} + }); + } else { + const confirmationMsg = { 'Destination': action.payload[1].destination, 'Timestamp': action.payload[1].timestamp_str, 'Expiry': action.payload[1].expiry }; + confirmationMsg['Amount (' + ((undefined === store.information.smaller_currency_unit) ? + 'Sats' : store.information.smaller_currency_unit) + ')'] = action.payload[1].num_satoshis; + const msg = {}; + msg['Total Fee (' + ((undefined === store.information.smaller_currency_unit) ? 'Sats' : store.information.smaller_currency_unit) + ')'] = + (sendRes.payment_route.total_fees_msat / 1000); + Object.assign(msg, confirmationMsg); + this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', + data: { type: 'SUCCESS', titleMessage: 'Payment Sent Successfully!', message: JSON.stringify(msg) }})); + this.store.dispatch(new RTLActions.FetchChannels({routeParam: 'all', channelStatus: ''})); + this.store.dispatch(new RTLActions.FetchPayments()); + return { + type: RTLActions.SET_DECODED_PAYMENT, + payload: {} + }; + } + }), + catchError((err: any) => { + this.store.dispatch(new RTLActions.CloseSpinner()); + this.logger.error(err); + return of( + { + type: RTLActions.OPEN_ALERT, + payload: { width: '70%', data: {type: 'ERROR', titleMessage: 'Send Payment Failed', + message: JSON.stringify({code: err.status, Message: err.error.error, URL: environment.CHANNELS_API + '/transactions/' + action.payload[0]})}} + } + ); + }) + ); + }) + ); + + @Effect() + graphNodeFetch = this.actions$.pipe( + ofType(RTLActions.FETCH_GRAPH_NODE), + mergeMap((action: RTLActions.FetchGraphNode) => { + return this.httpClient.get(environment.NETWORK_API + '/node/' + action.payload) + .pipe(map((graphNode: any) => { + this.logger.info(graphNode); + this.store.dispatch(new RTLActions.CloseSpinner()); + return { + type: RTLActions.SET_GRAPH_NODE, + payload: (undefined !== graphNode) ? graphNode : {} + }; + }), + catchError((err: any) => { + this.store.dispatch(new RTLActions.CloseSpinner()); + this.logger.error(err); + return of( + { + type: RTLActions.OPEN_ALERT, + payload: { width: '70%', data: {type: 'ERROR', titleMessage: 'Get Node Address Failed', + message: JSON.stringify({Code: err.status, Message: err.error.error})}} + } + ); + })); + } + )); + + @Effect({ dispatch: false }) + setGraphNode = this.actions$.pipe( + ofType(RTLActions.SET_GRAPH_NODE), + map((action: RTLActions.SetGraphNode) => { + this.logger.info(action.payload); + return action.payload; + }) + ); + + @Effect() + getNewAddress = this.actions$.pipe( + ofType(RTLActions.GET_NEW_ADDRESS), + mergeMap((action: RTLActions.GetNewAddress) => { + return this.httpClient.get(environment.NEW_ADDRESS_API + '?type=' + action.payload.addressId) + .pipe(map((newAddress: any) => { + this.logger.info(newAddress); + this.store.dispatch(new RTLActions.CloseSpinner()); + return { + type: RTLActions.SET_NEW_ADDRESS, + payload: (undefined !== newAddress && undefined !== newAddress.address) ? newAddress.address : {} + }; + }), + catchError((err: any) => { + this.store.dispatch(new RTLActions.CloseSpinner()); + this.logger.error(err); + return of( + { + type: RTLActions.OPEN_ALERT, + payload: { width: '70%', data: {type: 'ERROR', titleMessage: 'Generate New Address Failed', + message: JSON.stringify({Code: err.status, Message: err.error.error, URL: environment.NEW_ADDRESS_API + '?type=' + action.payload.addressId})}} + } + ); + })); + }) + ); + + @Effect({ dispatch: false }) + setNewAddress = this.actions$.pipe( + ofType(RTLActions.SET_NEW_ADDRESS), + map((action: RTLActions.SetNewAddress) => { + this.logger.info(action.payload); + return action.payload; + }) + ); + + @Effect() + configFetch = this.actions$.pipe( + ofType(RTLActions.FETCH_CONFIG), + mergeMap((action: RTLActions.FetchConfig) => { + this.store.dispatch(new RTLActions.ClearEffectError('fetchConfig')); + return this.httpClient.get(environment.CONF_API + '/config/' + action.payload) + .pipe( + map((configFile: any) => { + this.store.dispatch(new RTLActions.CloseSpinner()); + return { + type: RTLActions.SHOW_CONFIG, + payload: configFile + }; + }), + catchError((err: any) => { + this.store.dispatch(new RTLActions.CloseSpinner()); + this.logger.error(err); + this.store.dispatch(new RTLActions.EffectError({ action: 'fetchConfig', code: err.status, message: err.error.error })); + return of( + { + type: RTLActions.OPEN_ALERT, + payload: { width: '70%', data: {type: 'ERROR', titleMessage: 'Fetch Config Failed!', + message: JSON.stringify({Code: err.status, Message: err.error.error})}} + } + ); + } + )); + }) + ); + + @Effect({ dispatch: false }) + showLNDConfig = this.actions$.pipe( + ofType(RTLActions.SHOW_CONFIG), + map((action: RTLActions.ShowConfig) => { + this.logger.info(action.payload); + return action.payload; + }) + ); + + @Effect() + SetChannelTransaction = this.actions$.pipe( + ofType(RTLActions.SET_CHANNEL_TRANSACTION), + mergeMap((action: RTLActions.SetChannelTransaction) => { + this.store.dispatch(new RTLActions.ClearEffectError('SetChannelTransaction')); + return this.httpClient.post(environment.TRANSACTIONS_API, + { amount: action.payload.amount, address: action.payload.address, sendAll: action.payload.sendAll, fees: action.payload.fees, blocks: action.payload.blocks } + ) + .pipe( + map((postRes: any) => { + this.logger.info(postRes); + this.store.dispatch(new RTLActions.CloseSpinner()); + return { + type: RTLActions.OPEN_ALERT, + payload: { data: {type: 'SUCCESS', titleMessage: 'Fund Sent Successfully!'} } + }; + }), + catchError((err: any) => { + this.store.dispatch(new RTLActions.CloseSpinner()); + this.store.dispatch(new RTLActions.EffectError({ action: 'SetChannelTransaction', code: err.status, message: err.error.error })); + this.logger.error(err); + return of( + { + type: RTLActions.OPEN_ALERT, + payload: { width: '70%', data: {type: 'ERROR', titleMessage: 'Sending Fund Failed', + message: JSON.stringify({Code: err.status, Message: err.error.error})}} + } + ); + })); + }) + ); + + @Effect() + fetchForwardingHistory = this.actions$.pipe( + ofType(RTLActions.GET_FORWARDING_HISTORY), + mergeMap((action: RTLActions.GetForwardingHistory) => { + this.store.dispatch(new RTLActions.ClearEffectError('GetForwardingHistory')); + const queryHeaders: SwitchReq = { + num_max_events: action.payload.num_max_events, index_offset: action.payload.index_offset, end_time: action.payload.end_time , start_time: action.payload.start_time + }; + return this.httpClient.post(environment.SWITCH_API, queryHeaders) + .pipe( + map((fhRes: any) => { + this.logger.info(fhRes); + return { + type: RTLActions.SET_FORWARDING_HISTORY, + payload: fhRes + }; + }), + catchError((err: any) => { + this.store.dispatch(new RTLActions.EffectError({ action: 'GetForwardingHistory', code: err.status, message: err.error.error })); + this.logger.error(err); + return of( + { + type: RTLActions.OPEN_ALERT, + payload: { width: '70%', data: {type: 'ERROR', titleMessage: 'Get Forwarding History Failed', + message: JSON.stringify({code: err.status, Message: err.error.error, URL: environment.SWITCH_API})}} + } + ); + }) + ); + }) + ); + + @Effect({ dispatch : false }) + operateWallet = this.actions$.pipe( + ofType(RTLActions.OPERATE_WALLET), + mergeMap((action: RTLActions.OperateWallet) => { + return this.httpClient.post(environment.WALLET_API + '/' + action.payload.operation, { wallet_password: action.payload.pwd }) + .pipe( + map((postRes) => { + this.logger.info(postRes); + this.store.dispatch(new RTLActions.CloseSpinner()); + this.store.dispatch(new RTLActions.OpenSpinner('Initializing Node...')); + this.logger.info('Successfully Unlocked!'); + sessionStorage.setItem('lndUnlocked', 'true'); + setTimeout(() => { + this.store.dispatch(new RTLActions.CloseSpinner()); + this.logger.info('Successfully Initialized!'); + this.store.dispatch(new RTLActions.InitAppData()); + this.router.navigate(['/']); + }, 1000 * 90); + return of({}); + }), + catchError((err) => { + this.store.dispatch(new RTLActions.CloseSpinner()); + this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', data: {type: 'ERROR', titleMessage: err.error.error}})); + this.logger.error(err.error.error); + return of(); + }) + ); + } + )); + + @Effect() + isAuthorized = this.actions$.pipe( + ofType(RTLActions.IS_AUTHORIZED), + withLatestFrom(this.store.select('rtlRoot')), + mergeMap(([action, store]: [RTLActions.IsAuthorized, fromRTLReducer.State]) => { + this.store.dispatch(new RTLActions.ClearEffectError('IsAuthorized')); + return this.httpClient.post(environment.AUTHENTICATE_API, { password: action.payload }) + .pipe( + map((postRes: any) => { + this.logger.info(postRes); + this.logger.info('Successfully Authorized!'); + return { + type: RTLActions.IS_AUTHORIZED_RES, + payload: postRes + }; + }), + catchError((err) => { + this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', data: {type: 'ERROR', titleMessage: 'Authorization Failed', + message: JSON.stringify({Code: err.status, Message: err.error.error})}})); + this.store.dispatch(new RTLActions.EffectError({ action: 'IsAuthorized', code: err.status, message: err.error.message })); + this.logger.error(err.error); + return of({ + type: RTLActions.IS_AUTHORIZED_RES, + payload: 'ERROR' + }); + }) + ); + })); + + @Effect({ dispatch: false }) + isAuthorizedRes = this.actions$.pipe( + ofType(RTLActions.IS_AUTHORIZED_RES), + map((action: RTLActions.IsAuthorizedRes) => { + return action.payload; + }) + ); + + @Effect({ dispatch: false }) + authSignin = this.actions$.pipe( + ofType(RTLActions.SIGNIN), + withLatestFrom(this.store.select('rtlRoot')), + mergeMap(([action, store]: [RTLActions.Signin, fromRTLReducer.State]) => { + this.store.dispatch(new RTLActions.ClearEffectError('Signin')); + return this.httpClient.post(environment.AUTHENTICATE_API, { password: action.payload }) + .pipe( + map((postRes: any) => { + this.logger.info(postRes); + this.logger.info('Successfully Authorized!'); + this.SetToken(postRes.token); + this.router.navigate(['/']); + }), + catchError((err) => { + this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', data: {type: 'ERROR', message: JSON.stringify(err.error)}})); + this.store.dispatch(new RTLActions.EffectError({ action: 'Signin', code: err.status, message: err.error.message })); + this.logger.error(err.error); + this.logger.info('Redirecting to Signin Error Page'); + if (+store.authSettings.rtlSSO) { + this.router.navigate(['/ssoerror']); + } else { + this.router.navigate([store.authSettings.logoutRedirectLink]); + } + return of(); + }) + ); + })); + + @Effect({ dispatch: false }) + signOut = this.actions$.pipe( + ofType(RTLActions.SIGNOUT), + withLatestFrom(this.store.select('rtlRoot')), + mergeMap(([action, store]: [RTLActions.Signout, fromRTLReducer.State]) => { + if (+store.authSettings.rtlSSO) { + window.location.href = store.authSettings.logoutRedirectLink; + } else { + this.router.navigate([store.authSettings.logoutRedirectLink]); + } + sessionStorage.removeItem('lndUnlocked'); + sessionStorage.removeItem('token'); + this.logger.warn('LOGGED OUT'); + return of(); + })); + + @Effect() + peerLookup = this.actions$.pipe( + ofType(RTLActions.PEER_LOOKUP), + mergeMap((action: RTLActions.PeerLookup) => { + this.store.dispatch(new RTLActions.ClearEffectError('Lookup')); + return this.httpClient.get(environment.NETWORK_API + '/node/' + action.payload) + .pipe( + map((resPeer) => { + this.logger.info(resPeer); + this.store.dispatch(new RTLActions.CloseSpinner()); + return { + type: RTLActions.SET_LOOKUP, + payload: resPeer + }; + }), + catchError((err: any) => { + this.store.dispatch(new RTLActions.CloseSpinner()); + this.store.dispatch(new RTLActions.EffectError({ action: 'Lookup', code: err.status, message: err.error.message })); + this.logger.error(err); + return of( + { + type: RTLActions.OPEN_ALERT, + payload: { width: '70%', data: {type: 'ERROR', titleMessage: 'Peer Lookup Failed', + message: JSON.stringify({Code: err.status, Message: err.error.error, URL: environment.NETWORK_API + '/node/' + action.payload})}} + } + ); + }) + ); + }) + ); + + @Effect() + channelLookup = this.actions$.pipe( + ofType(RTLActions.CHANNEL_LOOKUP), + mergeMap((action: RTLActions.ChannelLookup) => { + this.store.dispatch(new RTLActions.ClearEffectError('Lookup')); + return this.httpClient.get(environment.NETWORK_API + '/edge/' + action.payload) + .pipe( + map((resChannel) => { + this.logger.info(resChannel); + this.store.dispatch(new RTLActions.CloseSpinner()); + return { + type: RTLActions.SET_LOOKUP, + payload: resChannel + }; + }), + catchError((err: any) => { + this.store.dispatch(new RTLActions.CloseSpinner()); + this.store.dispatch(new RTLActions.EffectError({ action: 'Lookup', code: err.status, message: err.error.message })); + this.logger.error(err); + return of( + { + type: RTLActions.OPEN_ALERT, + payload: { width: '70%', data: {type: 'ERROR', titleMessage: 'Channel Lookup Failed', + message: JSON.stringify({Code: err.status, Message: err.error.error, URL: environment.NETWORK_API + '/edge/' + action.payload})}} + } + ); + }) + ); + }) + ); + + @Effect() + invoiceLookup = this.actions$.pipe( + ofType(RTLActions.INVOICE_LOOKUP), + mergeMap((action: RTLActions.InvoiceLookup) => { + this.store.dispatch(new RTLActions.ClearEffectError('Lookup')); + return this.httpClient.get(environment.INVOICES_API + '/' + action.payload) + .pipe( + map((resInvoice) => { + this.logger.info(resInvoice); + this.store.dispatch(new RTLActions.CloseSpinner()); + return { + type: RTLActions.SET_LOOKUP, + payload: resInvoice + }; + }), + catchError((err: any) => { + this.store.dispatch(new RTLActions.CloseSpinner()); + this.store.dispatch(new RTLActions.EffectError({ action: 'Lookup', code: err.status, message: err.error.message })); + this.logger.error(err); + return of( + { + type: RTLActions.OPEN_ALERT, + payload: { width: '70%', data: {type: 'ERROR', titleMessage: 'Invoice Lookup Failed', + message: JSON.stringify({Code: err.status, Message: err.error.error, URL: environment.INVOICES_API + '/' + action.payload})}} + } + ); + }) + ); + }) + ); + + @Effect({ dispatch: false }) + setLookup = this.actions$.pipe( + ofType(RTLActions.SET_LOOKUP), + map((action: RTLActions.SetLookup) => { + this.logger.info(action.payload); + return action.payload; + }) + ); + + SetToken(token: string) { + if (token) { + sessionStorage.setItem('lndUnlocked', 'true'); + sessionStorage.setItem('token', token); + this.store.dispatch(new RTLActions.InitAppData()); + } else { + sessionStorage.removeItem('lndUnlocked'); + sessionStorage.removeItem('token'); + } + } + + ngOnDestroy() { + this.unSubs.forEach(completeSub => { + completeSub.next(); + completeSub.complete(); + }); + } + +} diff --git a/src/app/shared/store/rtl.reducers.ts b/src/app/shared/store/rtl.reducers.ts new file mode 100644 index 00000000..3b0b2692 --- /dev/null +++ b/src/app/shared/store/rtl.reducers.ts @@ -0,0 +1,265 @@ +import * as RTLActions from './rtl.actions'; + +import { ErrorPayload } from '../models/errorPayload'; +import { Settings, Authentication } from '../models/RTLconfig'; +import { + GetInfo, GetInfoChain, Peer, AddressType, Fees, NetworkInfo, Balance, Channel, Payment, Invoice, PendingChannels, ClosedChannel, Transaction, SwitchRes +} from '../models/lndModels'; + +export interface State { + effectErrors: ErrorPayload[]; + settings: Settings; + authSettings: Authentication; + information: GetInfo; + peers: Peer[]; + fees: Fees; + networkInfo: NetworkInfo; + channelBalance: Balance; + blockchainBalance: Balance; + allChannels: Channel[]; + closedChannels: ClosedChannel[]; + pendingChannels: PendingChannels; + numberOfActiveChannels: number; + numberOfInactiveChannels: number; + numberOfPendingChannels: number; + totalLocalBalance: number; + totalRemoteBalance: number; + transactions: Transaction[]; + payments: Payment[]; + invoices: Invoice[]; + forwardingHistory: SwitchRes; + addressTypes: AddressType[]; +} + +const initialState: State = { + effectErrors: [], + settings: {flgSidenavOpened: true, flgSidenavPinned: true, menu: 'Vertical', menuType: 'Regular', theme: 'dark-blue', satsToBTC: false}, + authSettings: {nodeAuthType: 'CUSTOM', lndConfigPath: '', bitcoindConfigPath: '', rtlSSO: 0, logoutRedirectLink: '/login' }, + information: {}, + peers: [], + fees: {}, + networkInfo: {}, + channelBalance: {balance: '', btc_balance: ''}, + blockchainBalance: { total_balance: '', btc_total_balance: ''}, + allChannels: [], + closedChannels: [], + pendingChannels: {}, + numberOfActiveChannels: 0, + numberOfInactiveChannels: 0, + numberOfPendingChannels: -1, + totalLocalBalance: -1, + totalRemoteBalance: -1, + transactions: [], + payments: [], + invoices: [], + forwardingHistory: {}, + addressTypes: [ + { addressId: '0', addressTp: 'p2wkh', addressDetails: 'Pay to witness key hash'}, + { addressId: '1', addressTp: 'np2wkh', addressDetails: 'Pay to nested witness key hash (default)'} + ] +}; + +export function RTLRootReducer(state = initialState, action: RTLActions.RTLActions) { + switch (action.type) { + case RTLActions.CLEAR_EFFECT_ERROR: + const clearedEffectErrors = [...state.effectErrors]; + const removeEffectIdx = state.effectErrors.findIndex(err => { + return err.action === action.payload; + }); + if (removeEffectIdx > -1) { + clearedEffectErrors.splice(removeEffectIdx, 1); + } + return { + ...state, + effectErrors: clearedEffectErrors + }; + case RTLActions.EFFECT_ERROR: + return { + ...state, + effectErrors: [...state.effectErrors, action.payload] + }; + case RTLActions.SET_SETTINGS: + return { + ...state, + settings: action.payload + }; + case RTLActions.SET_AUTH_SETTINGS: + return { + ...state, + authSettings: action.payload + }; + case RTLActions.SET_INFO: + if (undefined !== action.payload.chains) { + if (typeof action.payload.chains[0] === 'string') { + action.payload.smaller_currency_unit = (action.payload.chains[0].toString().toLowerCase().indexOf('bitcoin') < 0) ? 'Litoshis' : 'Sats'; + action.payload.currency_unit = (action.payload.chains[0].toString().toLowerCase().indexOf('bitcoin') < 0) ? 'LTC' : 'BTC'; + } else if (typeof action.payload.chains[0] === 'object' && action.payload.chains[0].hasOwnProperty('chain')) { + const getInfoChain = action.payload.chains[0]; + action.payload.smaller_currency_unit = (getInfoChain.chain.toLowerCase().indexOf('bitcoin') < 0) ? 'Litoshis' : 'Sats'; + action.payload.currency_unit = (getInfoChain.chain.toLowerCase().indexOf('bitcoin') < 0) ? 'LTC' : 'BTC'; + } + action.payload.version = (undefined === action.payload.version) ? '' : action.payload.version.split(' ')[0]; + } else { + action.payload.smaller_currency_unit = 'Sats'; + action.payload.currency_unit = 'BTC'; + action.payload.version = (undefined === action.payload.version) ? '' : action.payload.version.split(' ')[0]; + } + return { + ...state, + information: action.payload + }; + case RTLActions.SET_PEERS: + return { + ...state, + peers: action.payload + }; + case RTLActions.ADD_PEER: + return { + ...state, + peers: [...state.peers, action.payload] + }; + case RTLActions.REMOVE_PEER: + const modifiedPeers = [...state.peers]; + const removePeerIdx = state.peers.findIndex(peer => { + return peer.pub_key === action.payload.pubkey; + }); + if (removePeerIdx > -1) { + modifiedPeers.splice(removePeerIdx, 1); + } + return { + ...state, + peers: modifiedPeers + }; + case RTLActions.ADD_INVOICE: + return { + ...state, + invoices: [action.payload, ...state.invoices] + }; + case RTLActions.SET_FEES: + return { + ...state, + fees: action.payload + }; + case RTLActions.SET_CLOSED_CHANNELS: + return { + ...state, + closedChannels: action.payload, + }; + case RTLActions.SET_PENDING_CHANNELS: + let pendingChannels = -1; + if (action.payload) { + pendingChannels = 0; + if (action.payload.pending_closing_channels) { + pendingChannels = pendingChannels + action.payload.pending_closing_channels.length; + } + if (action.payload.pending_force_closing_channels) { + pendingChannels = pendingChannels + action.payload.pending_force_closing_channels.length; + } + if (action.payload.pending_open_channels) { + pendingChannels = pendingChannels + action.payload.pending_open_channels.length; + } + if (action.payload.waiting_close_channels) { + pendingChannels = pendingChannels + action.payload.waiting_close_channels.length; + } + } + return { + ...state, + pendingChannels: action.payload, + numberOfPendingChannels: pendingChannels, + }; + case RTLActions.SET_CHANNELS: + let localBal = 0, remoteBal = 0, activeChannels = 0, inactiveChannels = 0; + if (action.payload) { + action.payload.filter(channel => { + if (undefined !== channel.local_balance) { + localBal = +localBal + +channel.local_balance; + } + if (undefined !== channel.remote_balance) { + remoteBal = +remoteBal + +channel.remote_balance; + } + if (channel.active === true) { + activeChannels = activeChannels + 1; + } else { + inactiveChannels = inactiveChannels + 1; + } + }); + } + return { + ...state, + allChannels: action.payload, + numberOfActiveChannels: activeChannels, + numberOfInactiveChannels: inactiveChannels, + totalLocalBalance: localBal, + totalRemoteBalance: remoteBal + }; + case RTLActions.REMOVE_CHANNEL: + const modifiedChannels = [...state.allChannels]; + const removeChannelIdx = state.allChannels.findIndex(channel => { + return channel.channel_point === action.payload.channelPoint; + }); + if (removeChannelIdx > -1) { + modifiedChannels.splice(removeChannelIdx, 1); + } + return { + ...state, + allChannels: modifiedChannels + }; + case RTLActions.SET_BALANCE: + if (action.payload.target === 'channels') { + return { + ...state, + channelBalance: action.payload.balance + }; + } else { + return { + ...state, + blockchainBalance: action.payload.balance + }; + } + case RTLActions.SET_NETWORK: + return { + ...state, + networkInfo: action.payload + }; + case RTLActions.SET_INVOICES: + return { + ...state, + invoices: action.payload + }; + case RTLActions.SET_TRANSACTIONS: + return { + ...state, + transactions: action.payload + }; + case RTLActions.SET_PAYMENTS: + return { + ...state, + payments: action.payload + }; + case RTLActions.SET_FORWARDING_HISTORY: + if (action.payload.forwarding_events) { + const storedChannels = [...state.allChannels]; + action.payload.forwarding_events.forEach(event => { + if (storedChannels) { + for (let idx = 0; idx < storedChannels.length; idx++) { + if (storedChannels[idx].chan_id.toString() === event.chan_id_in) { + event.alias_in = storedChannels[idx].remote_alias; + if (event.alias_out) { return; } + } + if (storedChannels[idx].chan_id.toString() === event.chan_id_out) { + event.alias_out = storedChannels[idx].remote_alias; + if (event.alias_in) { return; } + } + } + } + }); + } + return { + ...state, + forwardingHistory: action.payload + }; + default: + return state; + } + +} diff --git a/src/app/shared/theme/overlay-container/theme-overlay.ts b/src/app/shared/theme/overlay-container/theme-overlay.ts new file mode 100644 index 00000000..f264e406 --- /dev/null +++ b/src/app/shared/theme/overlay-container/theme-overlay.ts @@ -0,0 +1,12 @@ +import { Injectable } from '@angular/core'; +import { OverlayContainer } from '@angular/cdk/overlay'; + +@Injectable() +export class ThemeOverlay extends OverlayContainer { + _createContainer(): void { + const container = document.createElement('div'); + container.classList.add('cdk-overlay-container'); + document.getElementById('rtl-container').appendChild(container); + this._containerElement = container; + } +} diff --git a/src/app/shared/theme/skins/bluegray-amber.scss b/src/app/shared/theme/skins/bluegray-amber.scss new file mode 100644 index 00000000..5f483866 --- /dev/null +++ b/src/app/shared/theme/skins/bluegray-amber.scss @@ -0,0 +1,50 @@ +$custom-dark-theme-background: ( + status-bar: map_get($mat-blue-gray, 800), + app-bar: map_get($mat-blue-gray, 700), + background: map_get($mat-blue-gray, 100), + hover: rgba(map_get($mat-grey, 900), 0.04), + card: map_get($mat-blue-gray, 200), + dialog: map_get($mat-blue-gray, 200), + disabled-button: rgba(map_get($mat-grey, 900), 0.12), + raised-button: map-get($mat-blue-gray, 600), + focused-button: $light-focused, + selected-button: map_get($mat-grey, 800), + selected-disabled-button: map_get($mat-grey, 600), + disabled-button-toggle: map_get($mat-grey, 900), + unselected-chip: map_get($mat-grey, 700), + disabled-list-option: map_get($mat-grey, 900) +); + +$custom-dark-theme-foreground: ( + base: black, + divider: $dark-dividers, + dividers: $dark-dividers, + disabled: $dark-disabled-text, + disabled-button: rgba(black, 0.26), + disabled-text: $dark-disabled-text, + hint-text: $dark-disabled-text, + secondary-text: $dark-secondary-text, + icon: rgba(black, 0.54), + icons: rgba(black, 0.54), + text: rgba(black, 0.87), + slider-min: rgba(black, 0.87), + slider-off: rgba(black, 0.26), + slider-off-active: rgba(black, 0.38), +); + +@function create-custom-theme($primary, $accent, $warn: mat-palette($mat-red)) { + @return ( + primary: $primary, + accent: $accent, + warn: $warn, + is-dark: false, + foreground: $custom-dark-theme-foreground, + background: $custom-dark-theme-background + ); +} + +$amber-bluegray-primary: mat-palette($mat-amber, 500, 100, 700); +$amber-bluegray-accent: mat-palette($mat-purple); +$amber-bluegray-warn: mat-palette($mat-red, A700); + +$amber-bluegray-theme: create-custom-theme($amber-bluegray-primary, $amber-bluegray-accent, $amber-bluegray-warn); diff --git a/src/app/shared/theme/skins/bluegray-deeppurple.scss b/src/app/shared/theme/skins/bluegray-deeppurple.scss new file mode 100644 index 00000000..b9c7521f --- /dev/null +++ b/src/app/shared/theme/skins/bluegray-deeppurple.scss @@ -0,0 +1,50 @@ +$custom-dark-theme-background: ( + status-bar: map_get($mat-blue-gray, 800), + app-bar: map_get($mat-blue-gray, 700), + background: map_get($mat-blue-gray, 100), + hover: rgba(map_get($mat-grey, 900), 0.04), + card: map_get($mat-blue-gray, 200), + dialog: map_get($mat-blue-gray, 200), + disabled-button: rgba(map_get($mat-grey, 900), 0.12), + raised-button: map-get($mat-blue-gray, 600), + focused-button: $light-focused, + selected-button: map_get($mat-grey, 800), + selected-disabled-button: map_get($mat-grey, 600), + disabled-button-toggle: map_get($mat-grey, 900), + unselected-chip: map_get($mat-grey, 700), + disabled-list-option: map_get($mat-grey, 900) +); + +$custom-dark-theme-foreground: ( + base: black, + divider: $dark-dividers, + dividers: $dark-dividers, + disabled: $dark-disabled-text, + disabled-button: rgba(black, 0.26), + disabled-text: $dark-disabled-text, + hint-text: $dark-disabled-text, + secondary-text: $dark-secondary-text, + icon: rgba(black, 0.54), + icons: rgba(black, 0.54), + text: rgba(black, 0.87), + slider-min: rgba(black, 0.87), + slider-off: rgba(black, 0.26), + slider-off-active: rgba(black, 0.38), +); + +@function create-custom-theme($primary, $accent, $warn: mat-palette($mat-red)) { + @return ( + primary: $primary, + accent: $accent, + warn: $warn, + is-dark: false, + foreground: $custom-dark-theme-foreground, + background: $custom-dark-theme-background + ); +} + +$deeppurple-bluegray-primary: mat-palette($mat-deep-purple, 600, 100, 900); +$deeppurple-bluegray-accent: mat-palette($mat-pink); +$deeppurple-bluegray-warn: mat-palette($mat-red, A700); + +$deeppurple-bluegray-theme: create-custom-theme($deeppurple-bluegray-primary, $deeppurple-bluegray-accent, $deeppurple-bluegray-warn); diff --git a/src/app/shared/theme/skins/bluegray-lightgreen.scss b/src/app/shared/theme/skins/bluegray-lightgreen.scss new file mode 100644 index 00000000..5209daf2 --- /dev/null +++ b/src/app/shared/theme/skins/bluegray-lightgreen.scss @@ -0,0 +1,50 @@ +$custom-dark-theme-background: ( + status-bar: map_get($mat-blue-gray, 800), + app-bar: map_get($mat-blue-gray, 700), + background: map_get($mat-blue-gray, 100), + hover: rgba(map_get($mat-grey, 900), 0.04), + card: map_get($mat-blue-gray, 200), + dialog: map_get($mat-blue-gray, 200), + disabled-button: rgba(map_get($mat-grey, 900), 0.12), + raised-button: map-get($mat-blue-gray, 600), + focused-button: $light-focused, + selected-button: map_get($mat-grey, 800), + selected-disabled-button: map_get($mat-grey, 600), + disabled-button-toggle: map_get($mat-grey, 900), + unselected-chip: map_get($mat-grey, 700), + disabled-list-option: map_get($mat-grey, 900) +); + +$custom-dark-theme-foreground: ( + base: black, + divider: $dark-dividers, + dividers: $dark-dividers, + disabled: $dark-disabled-text, + disabled-button: rgba(black, 0.26), + disabled-text: $dark-disabled-text, + hint-text: $dark-disabled-text, + secondary-text: $dark-secondary-text, + icon: rgba(black, 0.54), + icons: rgba(black, 0.54), + text: rgba(black, 0.87), + slider-min: rgba(black, 0.87), + slider-off: rgba(black, 0.26), + slider-off-active: rgba(black, 0.38), +); + +@function create-custom-theme($primary, $accent, $warn: mat-palette($mat-red)) { + @return ( + primary: $primary, + accent: $accent, + warn: $warn, + is-dark: false, + foreground: $custom-dark-theme-foreground, + background: $custom-dark-theme-background + ); +} + +$lightgreen-bluegray-primary: mat-palette($mat-light-green, 700, 100, 900); +$lightgreen-bluegray-accent: mat-palette($mat-deep-orange); +$lightgreen-bluegray-warn: mat-palette($mat-red, A700); + +$lightgreen-bluegray-theme: create-custom-theme($lightgreen-bluegray-primary, $lightgreen-bluegray-accent, $lightgreen-bluegray-warn); diff --git a/src/app/shared/theme/skins/dark-blue.scss b/src/app/shared/theme/skins/dark-blue.scss new file mode 100644 index 00000000..1e7e5405 --- /dev/null +++ b/src/app/shared/theme/skins/dark-blue.scss @@ -0,0 +1,5 @@ +$blue-dark-primary: mat-palette($mat-light-blue, 700, 300, 900); +$blue-dark-accent: mat-palette($mat-amber, A100, 900, A700); +$blue-dark-warn: mat-palette($mat-red, A200); + +$blue-dark-theme: mat-dark-theme($blue-dark-primary, $blue-dark-accent, $blue-dark-warn); \ No newline at end of file diff --git a/src/app/shared/theme/skins/dark-green.scss b/src/app/shared/theme/skins/dark-green.scss new file mode 100644 index 00000000..e6e02e57 --- /dev/null +++ b/src/app/shared/theme/skins/dark-green.scss @@ -0,0 +1,5 @@ +$green-dark-primary: mat-palette($mat-green, 700, 600, 900); +$green-dark-accent: mat-palette($mat-amber, A100, 900, A700); +$green-dark-warn: mat-palette($mat-red, A200); + +$green-dark-theme: mat-dark-theme($green-dark-primary, $green-dark-accent, $green-dark-warn); \ No newline at end of file diff --git a/src/app/shared/theme/skins/dark-pink.scss b/src/app/shared/theme/skins/dark-pink.scss new file mode 100644 index 00000000..83e7c513 --- /dev/null +++ b/src/app/shared/theme/skins/dark-pink.scss @@ -0,0 +1,5 @@ +$pink-dark-primary: mat-palette($mat-pink, 700, 400, 900); +$pink-dark-accent: mat-palette($mat-blue-grey, 700, 500, 900); +$pink-dark-warn: mat-palette($mat-red, A200); + +$pink-dark-theme: mat-dark-theme($pink-dark-primary, $pink-dark-accent, $pink-dark-warn); \ No newline at end of file diff --git a/src/app/shared/theme/skins/gray-blue.scss b/src/app/shared/theme/skins/gray-blue.scss new file mode 100644 index 00000000..a8c9aeb3 --- /dev/null +++ b/src/app/shared/theme/skins/gray-blue.scss @@ -0,0 +1,50 @@ +$custom-dark-theme-background: ( + status-bar: map_get($mat-gray, 800), + app-bar: map_get($mat-gray, 700), + background: map_get($mat-gray, 100), + hover: rgba(map_get($mat-grey, 900), 0.04), + card: map_get($mat-gray, 200), + dialog: map_get($mat-gray, 200), + disabled-button: rgba(map_get($mat-grey, 900), 0.12), + raised-button: map-get($mat-gray, 600), + focused-button: $light-focused, + selected-button: map_get($mat-grey, 800), + selected-disabled-button: map_get($mat-grey, 600), + disabled-button-toggle: map_get($mat-grey, 900), + unselected-chip: map_get($mat-grey, 700), + disabled-list-option: map_get($mat-grey, 900) +); + +$custom-dark-theme-foreground: ( + base: black, + divider: $dark-dividers, + dividers: $dark-dividers, + disabled: $dark-disabled-text, + disabled-button: rgba(black, 0.26), + disabled-text: $dark-disabled-text, + hint-text: $dark-disabled-text, + secondary-text: $dark-secondary-text, + icon: rgba(black, 0.54), + icons: rgba(black, 0.54), + text: rgba(black, 0.87), + slider-min: rgba(black, 0.87), + slider-off: rgba(black, 0.26), + slider-off-active: rgba(black, 0.38), +); + +@function create-custom-theme($primary, $accent, $warn: mat-palette($mat-red)) { + @return ( + primary: $primary, + accent: $accent, + warn: $warn, + is-dark: false, + foreground: $custom-dark-theme-foreground, + background: $custom-dark-theme-background + ); +} + +$blue-gray-primary: mat-palette($mat-cyan, 500, 200, 900); +$blue-gray-accent: mat-palette($mat-deep-orange); +$blue-gray-warn: mat-palette($mat-red, A700); + +$blue-gray-theme: create-custom-theme($blue-gray-primary, $blue-gray-accent, $blue-gray-warn); diff --git a/src/app/shared/theme/skins/gray-lime.scss b/src/app/shared/theme/skins/gray-lime.scss new file mode 100644 index 00000000..eeba6cd4 --- /dev/null +++ b/src/app/shared/theme/skins/gray-lime.scss @@ -0,0 +1,50 @@ +$custom-dark-theme-background: ( + status-bar: map_get($mat-gray, 800), + app-bar: map_get($mat-gray, 700), + background: map_get($mat-gray, 100), + hover: rgba(map_get($mat-grey, 900), 0.04), + card: map_get($mat-gray, 200), + dialog: map_get($mat-gray, 200), + disabled-button: rgba(map_get($mat-grey, 900), 0.12), + raised-button: map-get($mat-gray, 600), + focused-button: $light-focused, + selected-button: map_get($mat-grey, 800), + selected-disabled-button: map_get($mat-grey, 600), + disabled-button-toggle: map_get($mat-grey, 900), + unselected-chip: map_get($mat-grey, 700), + disabled-list-option: map_get($mat-grey, 900) +); + +$custom-dark-theme-foreground: ( + base: black, + divider: $dark-dividers, + dividers: $dark-dividers, + disabled: $dark-disabled-text, + disabled-button: rgba(black, 0.26), + disabled-text: $dark-disabled-text, + hint-text: $dark-disabled-text, + secondary-text: $dark-secondary-text, + icon: rgba(black, 0.54), + icons: rgba(black, 0.54), + text: rgba(black, 0.87), + slider-min: rgba(black, 0.87), + slider-off: rgba(black, 0.26), + slider-off-active: rgba(black, 0.38), +); + +@function create-custom-theme($primary, $accent, $warn: mat-palette($mat-red)) { + @return ( + primary: $primary, + accent: $accent, + warn: $warn, + is-dark: false, + foreground: $custom-dark-theme-foreground, + background: $custom-dark-theme-background + ); +} + +$lime-gray-primary: mat-palette($mat-lime, 300, 100, 700); +$lime-gray-accent: mat-palette($mat-purple); +$lime-gray-warn: mat-palette($mat-red, A700); + +$lime-gray-theme: create-custom-theme($lime-gray-primary, $lime-gray-accent, $lime-gray-warn); diff --git a/src/app/shared/theme/skins/gray-purple.scss b/src/app/shared/theme/skins/gray-purple.scss new file mode 100644 index 00000000..a66143d8 --- /dev/null +++ b/src/app/shared/theme/skins/gray-purple.scss @@ -0,0 +1,50 @@ +$custom-dark-theme-background: ( + status-bar: map_get($mat-gray, 800), + app-bar: map_get($mat-gray, 700), + background: map_get($mat-gray, 100), + hover: rgba(map_get($mat-grey, 900), 0.04), + card: map_get($mat-gray, 200), + dialog: map_get($mat-gray, 200), + disabled-button: rgba(map_get($mat-grey, 900), 0.12), + raised-button: map-get($mat-gray, 600), + focused-button: $light-focused, + selected-button: map_get($mat-grey, 800), + selected-disabled-button: map_get($mat-grey, 600), + disabled-button-toggle: map_get($mat-grey, 900), + unselected-chip: map_get($mat-grey, 700), + disabled-list-option: map_get($mat-grey, 900) +); + +$custom-dark-theme-foreground: ( + base: black, + divider: $dark-dividers, + dividers: $dark-dividers, + disabled: $dark-disabled-text, + disabled-button: rgba(black, 0.26), + disabled-text: $dark-disabled-text, + hint-text: $dark-disabled-text, + secondary-text: $dark-secondary-text, + icon: rgba(black, 0.54), + icons: rgba(black, 0.54), + text: rgba(black, 0.87), + slider-min: rgba(black, 0.87), + slider-off: rgba(black, 0.26), + slider-off-active: rgba(black, 0.38), +); + +@function create-custom-theme($primary, $accent, $warn: mat-palette($mat-red)) { + @return ( + primary: $primary, + accent: $accent, + warn: $warn, + is-dark: false, + foreground: $custom-dark-theme-foreground, + background: $custom-dark-theme-background + ); +} + +$purple-gray-primary: mat-palette($mat-purple, 700, 100, 900); +$purple-gray-accent: mat-palette($mat-amber); +$purple-gray-warn: mat-palette($mat-red, A700); + +$purple-gray-theme: create-custom-theme($purple-gray-primary, $purple-gray-accent, $purple-gray-warn); diff --git a/src/app/shared/theme/skins/light-blue.scss b/src/app/shared/theme/skins/light-blue.scss new file mode 100644 index 00000000..3834dae3 --- /dev/null +++ b/src/app/shared/theme/skins/light-blue.scss @@ -0,0 +1,50 @@ +$custom-light-theme-background: ( + status-bar: map_get($mat-grey, 300), + app-bar: map_get($mat-grey, 100), + background:map_get($mat-gray, 100), + hover: rgba(black, 0.04), + card: map_get($mat-gray, 100), + dialog: map_get($mat-gray, 100), + disabled-button: rgba(black, 0.12), + raised-button: map_get($mat-grey, 50), + focused-button: $dark-focused, + selected-button: map_get($mat-grey, 300), + selected-disabled-button: map_get($mat-grey, 400), + disabled-button-toggle: map_get($mat-grey, 200), + unselected-chip: map_get($mat-grey, 300), + disabled-list-option: map_get($mat-grey, 200), +); + +$custom-light-theme-foreground: ( + base: black, + divider: $dark-dividers, + dividers: $dark-dividers, + disabled: $dark-disabled-text, + disabled-button: rgba(black, 0.26), + disabled-text: $dark-disabled-text, + hint-text: $dark-disabled-text, + secondary-text: $dark-secondary-text, + icon: rgba(black, 0.54), + icons: rgba(black, 0.54), + text: rgba(black, 0.87), + slider-min: rgba(black, 0.87), + slider-off: rgba(black, 0.26), + slider-off-active: rgba(black, 0.38), +); + +@function create-custom-theme($primary, $accent, $warn: mat-palette($mat-red)) { + @return ( + primary: $primary, + accent: $accent, + warn: $warn, + is-dark: false, + foreground: $custom-light-theme-foreground, + background: $custom-light-theme-background + ); +} + +$blue-light-primary: mat-palette($mat-indigo, 800, 300, 900); +$blue-light-accent: mat-palette($mat-pink, A200, A100, A400); +$blue-light-warn: mat-palette($mat-red, 500); + +$blue-light-theme: create-custom-theme($blue-light-primary, $blue-light-accent, $blue-light-warn); diff --git a/src/app/shared/theme/skins/light-red.scss b/src/app/shared/theme/skins/light-red.scss new file mode 100644 index 00000000..ee2a47e1 --- /dev/null +++ b/src/app/shared/theme/skins/light-red.scss @@ -0,0 +1,50 @@ +$custom-light-theme-background: ( + status-bar: map_get($mat-grey, 300), + app-bar: map_get($mat-grey, 100), + background:map_get($mat-gray, 100), + hover: rgba(black, 0.04), + card: map_get($mat-gray, 100), + dialog: map_get($mat-gray, 100), + disabled-button: rgba(black, 0.12), + raised-button: map_get($mat-grey, 50), + focused-button: $dark-focused, + selected-button: map_get($mat-grey, 300), + selected-disabled-button: map_get($mat-grey, 400), + disabled-button-toggle: map_get($mat-grey, 200), + unselected-chip: map_get($mat-grey, 300), + disabled-list-option: map_get($mat-grey, 200), +); + +$custom-light-theme-foreground: ( + base: black, + divider: $dark-dividers, + dividers: $dark-dividers, + disabled: $dark-disabled-text, + disabled-button: rgba(black, 0.26), + disabled-text: $dark-disabled-text, + hint-text: $dark-disabled-text, + secondary-text: $dark-secondary-text, + icon: rgba(black, 0.54), + icons: rgba(black, 0.54), + text: rgba(black, 0.87), + slider-min: rgba(black, 0.87), + slider-off: rgba(black, 0.26), + slider-off-active: rgba(black, 0.38), +); + +@function create-custom-theme($primary, $accent, $warn: mat-palette($mat-red)) { + @return ( + primary: $primary, + accent: $accent, + warn: $warn, + is-dark: false, + foreground: $custom-light-theme-foreground, + background: $custom-light-theme-background + ); +} + +$red-light-primary: mat-palette($mat-red, 800, 300, 900); +$red-light-accent: mat-palette($mat-green, 600, 300, 900); +$red-light-warn: mat-palette($mat-deep-orange, A400); + +$red-light-theme: create-custom-theme($red-light-primary, $red-light-accent, $red-light-warn); \ No newline at end of file diff --git a/src/app/shared/theme/skins/light-teal.scss b/src/app/shared/theme/skins/light-teal.scss new file mode 100644 index 00000000..30c9a6a6 --- /dev/null +++ b/src/app/shared/theme/skins/light-teal.scss @@ -0,0 +1,50 @@ +$custom-light-theme-background: ( + status-bar: map_get($mat-grey, 300), + app-bar: map_get($mat-grey, 100), + background:map_get($mat-gray, 100), + hover: rgba(black, 0.04), + card: map_get($mat-gray, 100), + dialog: map_get($mat-gray, 100), + disabled-button: rgba(black, 0.12), + raised-button: map_get($mat-grey, 50), + focused-button: $dark-focused, + selected-button: map_get($mat-grey, 300), + selected-disabled-button: map_get($mat-grey, 400), + disabled-button-toggle: map_get($mat-grey, 200), + unselected-chip: map_get($mat-grey, 300), + disabled-list-option: map_get($mat-grey, 200), +); + +$custom-light-theme-foreground: ( + base: black, + divider: $dark-dividers, + dividers: $dark-dividers, + disabled: $dark-disabled-text, + disabled-button: rgba(black, 0.26), + disabled-text: $dark-disabled-text, + hint-text: $dark-disabled-text, + secondary-text: $dark-secondary-text, + icon: rgba(black, 0.54), + icons: rgba(black, 0.54), + text: rgba(black, 0.87), + slider-min: rgba(black, 0.87), + slider-off: rgba(black, 0.26), + slider-off-active: rgba(black, 0.38), +); + +@function create-custom-theme($primary, $accent, $warn: mat-palette($mat-red)) { + @return ( + primary: $primary, + accent: $accent, + warn: $warn, + is-dark: false, + foreground: $custom-light-theme-foreground, + background: $custom-light-theme-background + ); +} + +$teal-light-primary: mat-palette($mat-teal, 800, 300, 900); +$teal-light-accent: mat-palette($mat-amber, A200, A100, A700); +$teal-light-warn: mat-palette($mat-red, A200); + +$teal-light-theme: create-custom-theme($teal-light-primary, $teal-light-accent, $teal-light-warn); \ No newline at end of file diff --git a/src/app/shared/theme/skins/self-blue.scss b/src/app/shared/theme/skins/self-blue.scss new file mode 100644 index 00000000..4d236ad7 --- /dev/null +++ b/src/app/shared/theme/skins/self-blue.scss @@ -0,0 +1,83 @@ +$custom-blue: ( + 50 : #f3f8fc, + 100 : #e2eef8, + 200 : #cfe2f4, + 300 : #bcd6ef, + 400 : #adceeb, + 500 : #9fc5e8, + 600 : #97bfe5, + 700 : #8db8e2, + 800 : #83b0de, + 900 : #72a3d8, + A100 : #ffffff, + A200 : #ffffff, + A400 : #eef6ff, + A700 : #d4e9ff, + contrast: ( + 50 : #ECEFF1, + 100 : #CFD8DC, + 200 : #37474F, + 300 : #37474F, + 400 : #37474F, + 500 : #607D8B, + 600 : #546E7A, + 700 : #455A64, + 800 : #37474F, + 900 : #263238, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); + +$custom-light-theme-background: ( + status-bar: map_get($mat-blue-gray, 300), + app-bar: map_get($mat-blue-gray, 300), + background: map_get($custom-blue, 50), + hover: rgba(black, 0.04), + card: map_get($custom-blue, 100), + dialog: map_get($custom-blue, 100), + disabled-button: rgba(black, 0.12), + raised-button: map_get($mat-blue-gray, 100), + focused-button: $dark-focused, + selected-button: map_get($mat-blue-gray, 300), + selected-disabled-button: map_get($mat-blue-gray, 400), + disabled-button-toggle: map_get($mat-blue-gray, 200), + unselected-chip: map_get($mat-blue-gray, 300), + disabled-list-option: map_get($mat-blue-gray, 200), +); + +$custom-light-theme-foreground: ( + base: map_get($mat-blue-gray, 900), + divider: $dark-dividers, + dividers: $dark-dividers, + disabled: $dark-disabled-text, + disabled-button: rgba(map_get($mat-blue-gray, 900), 0.26), + disabled-text: $dark-disabled-text, + hint-text: $dark-disabled-text, + secondary-text: $dark-secondary-text, + icon: rgba(map_get($mat-blue-gray, 900), 0.54), + icons: rgba(map_get($mat-blue-gray, 900), 0.54), + text: rgba(map_get($mat-blue-gray, 900), 0.87), + slider-min: rgba(map_get($mat-blue-gray, 900), 0.87), + slider-off: rgba(map_get($mat-blue-gray, 900), 0.26), + slider-off-active: rgba(map_get($mat-blue-gray, 900), 0.38), +); + +@function create-custom-theme($primary, $accent, $warn: mat-palette($mat-red)) { + @return ( + primary: $primary, + accent: $accent, + warn: $warn, + is-dark: false, + foreground: $custom-light-theme-foreground, + background: $custom-light-theme-background + ); +} + +$blue-primary: mat-palette($custom-blue, 200, 50, 800); +$blue-accent: mat-palette($mat-brown, 600, 300, 900); +$blue-warn: mat-palette($mat-red, 500); + +$blue-theme: create-custom-theme($blue-primary, $blue-accent, $blue-warn); \ No newline at end of file diff --git a/src/app/shared/theme/skins/self-brown.scss b/src/app/shared/theme/skins/self-brown.scss new file mode 100644 index 00000000..45718a78 --- /dev/null +++ b/src/app/shared/theme/skins/self-brown.scss @@ -0,0 +1,83 @@ +$custom-brown: ( + 50 : #fcf7f3, + 100 : #f8ece2, + 200 : #f4dfcf, + 300 : #efd2bc, + 400 : #ebc9ad, + 500 : #e8bf9f, + 600 : #e5b997, + 700 : #e2b18d, + 800 : #dea983, + 900 : #d89b72, + A100 : #ffffff, + A200 : #ffffff, + A400 : #fff5ee, + A700 : #ffe5d4, + contrast: ( + 50 : #ECEFF1, + 100 : #CFD8DC, + 200 : #37474F, + 300 : #37474F, + 400 : #37474F, + 500 : #607D8B, + 600 : #546E7A, + 700 : #455A64, + 800 : #37474F, + 900 : #263238, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); + +$custom-light-theme-background: ( + status-bar: map_get($mat-blue-gray, 300), + app-bar: map_get($mat-blue-gray, 300), + background: map_get($custom-brown, 50), + hover: rgba(black, 0.04), + card: map_get($custom-brown, 100), + dialog: map_get($custom-brown, 100), + disabled-button: rgba(black, 0.12), + raised-button: map_get($mat-blue-gray, 100), + focused-button: $dark-focused, + selected-button: map_get($mat-blue-gray, 300), + selected-disabled-button: map_get($mat-blue-gray, 400), + disabled-button-toggle: map_get($mat-blue-gray, 200), + unselected-chip: map_get($mat-blue-gray, 300), + disabled-list-option: map_get($mat-blue-gray, 200), +); + +$custom-light-theme-foreground: ( + base: map_get($mat-blue-gray, 900), + divider: $dark-dividers, + dividers: $dark-dividers, + disabled: $dark-disabled-text, + disabled-button: rgba(map_get($mat-blue-gray, 900), 0.26), + disabled-text: $dark-disabled-text, + hint-text: $dark-disabled-text, + secondary-text: $dark-secondary-text, + icon: rgba(map_get($mat-blue-gray, 900), 0.54), + icons: rgba(map_get($mat-blue-gray, 900), 0.54), + text: rgba(map_get($mat-blue-gray, 900), 0.87), + slider-min: rgba(map_get($mat-blue-gray, 900), 0.87), + slider-off: rgba(map_get($mat-blue-gray, 900), 0.26), + slider-off-active: rgba(map_get($mat-blue-gray, 900), 0.38), +); + +@function create-custom-theme($primary, $accent, $warn: mat-palette($mat-red)) { + @return ( + primary: $primary, + accent: $accent, + warn: $warn, + is-dark: false, + foreground: $custom-light-theme-foreground, + background: $custom-light-theme-background + ); +} + +$brown-primary: mat-palette($custom-brown, 200, 50, 800); +$brown-accent: mat-palette($mat-brown, 600, 300, 900); +$brown-warn: mat-palette($mat-red, 500); + +$brown-theme: create-custom-theme($brown-primary, $brown-accent, $brown-warn); \ No newline at end of file diff --git a/src/app/shared/theme/skins/self-gray.scss b/src/app/shared/theme/skins/self-gray.scss new file mode 100644 index 00000000..723ed183 --- /dev/null +++ b/src/app/shared/theme/skins/self-gray.scss @@ -0,0 +1,50 @@ +$custom-dark-theme-background: ( + status-bar: map_get($mat-gray, 900), + app-bar: map_get($mat-gray, 900), + background: map_get($mat-gray, 50), + hover: rgba(map_get($mat-grey, 900), 0.04), + card: map_get($mat-gray, 100), + dialog: map_get($mat-gray, 100), + disabled-button: rgba(map_get($mat-grey, 900), 0.12), + raised-button: map-get($mat-gray, 600), + focused-button: $light-focused, + selected-button: map_get($mat-grey, 800), + selected-disabled-button: map_get($mat-grey, 600), + disabled-button-toggle: map_get($mat-grey, 900), + unselected-chip: map_get($mat-grey, 700), + disabled-list-option: map_get($mat-grey, 900) +); + +$custom-dark-theme-foreground: ( + base: black, + divider: $dark-dividers, + dividers: $dark-dividers, + disabled: $dark-disabled-text, + disabled-button: rgba(black, 0.26), + disabled-text: $dark-disabled-text, + hint-text: $dark-disabled-text, + secondary-text: $dark-secondary-text, + icon: rgba(black, 0.54), + icons: rgba(black, 0.54), + text: rgba(black, 0.87), + slider-min: rgba(black, 0.87), + slider-off: rgba(black, 0.26), + slider-off-active: rgba(black, 0.38), +); + +@function create-custom-theme($primary, $accent, $warn: mat-palette($mat-red)) { + @return ( + primary: $primary, + accent: $accent, + warn: $warn, + is-dark: false, + foreground: $custom-dark-theme-foreground, + background: $custom-dark-theme-background + ); +} + +$gray-primary: mat-palette($mat-gray, 500, 200, 900); +$gray-accent: mat-palette($mat-indigo); +$gray-warn: mat-palette($mat-red, 900); + +$gray-theme: create-custom-theme($gray-primary, $gray-accent, $gray-warn); \ No newline at end of file diff --git a/src/app/shared/theme/skins/self-green.scss b/src/app/shared/theme/skins/self-green.scss new file mode 100644 index 00000000..44c1e29d --- /dev/null +++ b/src/app/shared/theme/skins/self-green.scss @@ -0,0 +1,83 @@ +$custom-green: ( + 50 : #f6faf5, + 100 : #e9f3e5, + 200 : #dbebd4, + 300 : #cce3c2, + 400 : #c1ddb5, + 500 : #b6d7a8, + 600 : #afd3a0, + 700 : #a6cd97, + 800 : #9ec78d, + 900 : #8ebe7d, + A100 : #ffffff, + A200 : #ffffff, + A400 : #e7ffde, + A700 : #d4ffc4, + contrast: ( + 50 : #ECEFF1, + 100 : #CFD8DC, + 200 : #37474F, + 300 : #37474F, + 400 : #37474F, + 500 : #607D8B, + 600 : #546E7A, + 700 : #455A64, + 800 : #37474F, + 900 : #263238, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); + +$custom-light-theme-background: ( + status-bar: map_get($mat-blue-gray, 300), + app-bar: map_get($mat-blue-gray, 300), + background: map_get($custom-green, 50), + hover: rgba(black, 0.04), + card: map_get($custom-green, 100), + dialog: map_get($custom-green, 100), + disabled-button: rgba(black, 0.12), + raised-button: map_get($mat-blue-gray, 100), + focused-button: $dark-focused, + selected-button: map_get($mat-blue-gray, 300), + selected-disabled-button: map_get($mat-blue-gray, 400), + disabled-button-toggle: map_get($mat-blue-gray, 200), + unselected-chip: map_get($mat-blue-gray, 300), + disabled-list-option: map_get($mat-blue-gray, 200), +); + +$custom-light-theme-foreground: ( + base: map_get($mat-blue-gray, 900), + divider: $dark-dividers, + dividers: $dark-dividers, + disabled: $dark-disabled-text, + disabled-button: rgba(map_get($mat-blue-gray, 900), 0.26), + disabled-text: $dark-disabled-text, + hint-text: $dark-disabled-text, + secondary-text: $dark-secondary-text, + icon: rgba(map_get($mat-blue-gray, 900), 0.54), + icons: rgba(map_get($mat-blue-gray, 900), 0.54), + text: rgba(map_get($mat-blue-gray, 900), 0.87), + slider-min: rgba(map_get($mat-blue-gray, 900), 0.87), + slider-off: rgba(map_get($mat-blue-gray, 900), 0.26), + slider-off-active: rgba(map_get($mat-blue-gray, 900), 0.38), +); + +@function create-custom-theme($primary, $accent, $warn: mat-palette($mat-red)) { + @return ( + primary: $primary, + accent: $accent, + warn: $warn, + is-dark: false, + foreground: $custom-light-theme-foreground, + background: $custom-light-theme-background + ); +} + +$green-primary: mat-palette($custom-green, 200, 50, 800); +$green-accent: mat-palette($mat-brown, 600, 300, 900); +$green-warn: mat-palette($mat-red, 500); + +$green-theme: create-custom-theme($green-primary, $green-accent, $green-warn); \ No newline at end of file diff --git a/src/app/shared/theme/skins/self-pink.scss b/src/app/shared/theme/skins/self-pink.scss new file mode 100644 index 00000000..b213deef --- /dev/null +++ b/src/app/shared/theme/skins/self-pink.scss @@ -0,0 +1,83 @@ +$custom-pink: ( + 50 : #fcf4f5, + 100 : #f8e3e6, + 200 : #f4d1d6, + 300 : #efbec5, + 400 : #ebb0b8, + 500 : #e8a2ac, + 600 : #e59aa5, + 700 : #e2909b, + 800 : #de8692, + 900 : #d87582, + A100 : #ffffff, + A200 : #ffffff, + A400 : #fff1f2, + A700 : #ffd7dc, + contrast: ( + 50 : #ECEFF1, + 100 : #CFD8DC, + 200 : #37474F, + 300 : #90A4AE, + 400 : #78909C, + 500 : #607D8B, + 600 : #546E7A, + 700 : #455A64, + 800 : #37474F, + 900 : #263238, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); + +$custom-light-theme-background: ( + status-bar: map_get($mat-blue-gray, 300), + app-bar: map_get($mat-blue-gray, 300), + background: map_get($custom-pink, 50), + hover: rgba(black, 0.04), + card: map_get($custom-pink, 100), + dialog: map_get($custom-pink, 100), + disabled-button: rgba(black, 0.12), + raised-button: map_get($mat-blue-gray, 100), + focused-button: $dark-focused, + selected-button: map_get($mat-blue-gray, 300), + selected-disabled-button: map_get($mat-blue-gray, 400), + disabled-button-toggle: map_get($mat-blue-gray, 200), + unselected-chip: map_get($mat-blue-gray, 300), + disabled-list-option: map_get($mat-blue-gray, 200), +); + +$custom-light-theme-foreground: ( + base: map_get($mat-blue-gray, 900), + divider: $dark-dividers, + dividers: $dark-dividers, + disabled: $dark-disabled-text, + disabled-button: rgba(map_get($mat-blue-gray, 900), 0.26), + disabled-text: $dark-disabled-text, + hint-text: $dark-disabled-text, + secondary-text: $dark-secondary-text, + icon: rgba(map_get($mat-blue-gray, 900), 0.54), + icons: rgba(map_get($mat-blue-gray, 900), 0.54), + text: rgba(map_get($mat-blue-gray, 900), 0.87), + slider-min: rgba(map_get($mat-blue-gray, 900), 0.87), + slider-off: rgba(map_get($mat-blue-gray, 900), 0.26), + slider-off-active: rgba(map_get($mat-blue-gray, 900), 0.38), +); + +@function create-custom-theme($primary, $accent, $warn: mat-palette($mat-red)) { + @return ( + primary: $primary, + accent: $accent, + warn: $warn, + is-dark: false, + foreground: $custom-light-theme-foreground, + background: $custom-light-theme-background + ); +} + +$pink-primary: mat-palette($custom-pink, 200, 50, 800); +$pink-accent: mat-palette($mat-blue-gray, 600, 300, 900); +$pink-warn: mat-palette($mat-red, 700); + +$pink-theme: create-custom-theme($pink-primary, $pink-accent, $pink-warn); \ No newline at end of file diff --git a/src/app/shared/theme/skins/self-yellow.scss b/src/app/shared/theme/skins/self-yellow.scss new file mode 100644 index 00000000..342f70b2 --- /dev/null +++ b/src/app/shared/theme/skins/self-yellow.scss @@ -0,0 +1,83 @@ +$custom-yellow: ( + 50 : #fffcf3, + 100 : #fff7e0, + 200 : #fff2cc, + 300 : #ffedb8, + 400 : #ffe9a8, + 500 : #ffe599, + 600 : #ffe291, + 700 : #ffde86, + 800 : #ffda7c, + 900 : #ffd36b, + A100 : #ffffff, + A200 : #ffffff, + A400 : #ffffff, + A700 : #fffbf3, + contrast: ( + 50 : #ECEFF1, + 100 : #CFD8DC, + 200 : #37474F, + 300 : #37474F, + 400 : #37474F, + 500 : #607D8B, + 600 : #546E7A, + 700 : #455A64, + 800 : #37474F, + 900 : #263238, + A100 : #000000, + A200 : #000000, + A400 : #000000, + A700 : #000000, + ) +); + +$custom-light-theme-background: ( + status-bar: map_get($mat-blue-gray, 300), + app-bar: map_get($mat-blue-gray, 300), + background: map_get($custom-yellow, 50), + hover: rgba(black, 0.04), + card: map_get($custom-yellow, 100), + dialog: map_get($custom-yellow, 100), + disabled-button: rgba(black, 0.12), + raised-button: map_get($mat-blue-gray, 100), + focused-button: $dark-focused, + selected-button: map_get($mat-blue-gray, 300), + selected-disabled-button: map_get($mat-blue-gray, 400), + disabled-button-toggle: map_get($mat-blue-gray, 200), + unselected-chip: map_get($mat-blue-gray, 300), + disabled-list-option: map_get($mat-blue-gray, 200), +); + +$custom-light-theme-foreground: ( + base: map_get($mat-blue-gray, 900), + divider: $dark-dividers, + dividers: $dark-dividers, + disabled: $dark-disabled-text, + disabled-button: rgba(map_get($mat-blue-gray, 900), 0.26), + disabled-text: $dark-disabled-text, + hint-text: $dark-disabled-text, + secondary-text: $dark-secondary-text, + icon: rgba(map_get($mat-blue-gray, 900), 0.54), + icons: rgba(map_get($mat-blue-gray, 900), 0.54), + text: rgba(map_get($mat-blue-gray, 900), 0.87), + slider-min: rgba(map_get($mat-blue-gray, 900), 0.87), + slider-off: rgba(map_get($mat-blue-gray, 900), 0.26), + slider-off-active: rgba(map_get($mat-blue-gray, 900), 0.38), +); + +@function create-custom-theme($primary, $accent, $warn: mat-palette($mat-red)) { + @return ( + primary: $primary, + accent: $accent, + warn: $warn, + is-dark: false, + foreground: $custom-light-theme-foreground, + background: $custom-light-theme-background + ); +} + +$yellow-primary: mat-palette($custom-yellow, 200, 50, 800); +$yellow-accent: mat-palette($mat-brown, 600, 300, 900); +$yellow-warn: mat-palette($mat-red, 500); + +$yellow-theme: create-custom-theme($yellow-primary, $yellow-accent, $yellow-warn); \ No newline at end of file diff --git a/src/app/shared/theme/styles/change-theme.scss b/src/app/shared/theme/styles/change-theme.scss new file mode 100644 index 00000000..7cb23e85 --- /dev/null +++ b/src/app/shared/theme/styles/change-theme.scss @@ -0,0 +1,63 @@ +@import "constants"; + +@mixin change-theme($theme) { + $primary: map-get($theme, primary); + $accent: map-get($theme, accent); + $warn: map-get($theme, warn); + $foreground: map-get($theme, foreground); + $background: map-get($theme, background); + $testColor: mat-palette($mat-red, A200); + + .bg-primary { + @include _mat-toolbar-color($primary); + } + + .bg-accent { + @include _mat-toolbar-color($accent); + } + + .bg-warn { + @include _mat-toolbar-color($warn); + } + + .bg-test { + @include _mat-toolbar-color($testColor); + } + + .foreground.mat-progress-spinner circle, .foreground.mat-spinner circle { + stroke: mat-color($foreground, text); + } + + .mat-toolbar-row, + .mat-toolbar-single-row { + height: $toolbar-height; + } + + .lnd-info{ + border-bottom: 1px solid mat-color($foreground, divider); + } + .horizontal-nav { + position: fixed; + top:74px; + z-index: 9999; + } + a { + color: mat-color($foreground, text); + } + + .active-link { + background: mat-color($primary); + } + + .h-active-link { + background: mat-color($primary, lighter) !important; + } + + .ngx-charts { + fill: mat-color($foreground, text); + .bar { + fill: mat-color($primary) !important; + cursor: default; + } + } +} diff --git a/src/app/shared/theme/styles/constants.scss b/src/app/shared/theme/styles/constants.scss new file mode 100644 index 00000000..1f69edae --- /dev/null +++ b/src/app/shared/theme/styles/constants.scss @@ -0,0 +1,11 @@ +$font-family: 'Roboto', sans-serif; +$font-size: 14px; +$toolbar-height: 46px; +$regular-sidenav-width: 250px; +$compact-sidenav-width: 185px; +$mini-sidenav-width: 100px; +$sidenav-info-height: 100px; +$settings-nav-width: 150px; +$gap: 8px; +$icon-size: 36px; +$pubkey-info-height: 15px; diff --git a/src/app/shared/theme/styles/perfect-scrollbar.scss b/src/app/shared/theme/styles/perfect-scrollbar.scss new file mode 100644 index 00000000..468b4e96 --- /dev/null +++ b/src/app/shared/theme/styles/perfect-scrollbar.scss @@ -0,0 +1,100 @@ +.ps { + overflow: hidden !important; + overflow-anchor: none; + -ms-overflow-style: none; + touch-action: auto; + -ms-touch-action: auto; + } + + .ps__rail-x { + display: none; + opacity: 0; + transition: background-color .2s linear, opacity .2s linear; + -webkit-transition: background-color .2s linear, opacity .2s linear; + height: 15px; + bottom: 0px; + margin-top: -15px; + position: relative; + } + + .ps__rail-y { + display: none; + opacity: 0; + transition: background-color .2s linear, opacity .2s linear; + -webkit-transition: background-color .2s linear, opacity .2s linear; + width: 0px; + right: 0; + position: relative; + } + + .ps--active-x > .ps__rail-x, + .ps--active-y > .ps__rail-y { + display: block; + background-color: transparent; + } + + .ps:hover > .ps__rail-x, + .ps:hover > .ps__rail-y, + .ps--focus > .ps__rail-x, + .ps--focus > .ps__rail-y, + .ps--scrolling-x > .ps__rail-x, + .ps--scrolling-y > .ps__rail-y { + opacity: 0.6; + } + + .ps .ps__rail-x:hover, + .ps .ps__rail-y:hover, + .ps .ps__rail-x:focus, + .ps .ps__rail-y:focus, + .ps .ps__rail-x.ps--clicking, + .ps .ps__rail-y.ps--clicking { + background-color: transparent; + opacity: 0.9; + } + + .ps__thumb-x { + background-color: #aaa; + border-radius: 6px; + transition: background-color .2s linear, height .2s ease-in-out; + -webkit-transition: background-color .2s linear, height .2s ease-in-out; + height: 4px; + bottom: 2px; + position: absolute; + } + + .ps__thumb-y { + background-color: #aaa; + border-radius: 6px; + transition: background-color .2s linear, width .2s ease-in-out; + -webkit-transition: background-color .2s linear, width .2s ease-in-out; + width: 4px; + right: 2px; + position: absolute; + } + + .ps__rail-x:hover > .ps__thumb-x, + .ps__rail-x:focus > .ps__thumb-x, + .ps__rail-x.ps--clicking .ps__thumb-x { + background-color: #999; + height: 6px; + } + + .ps__rail-y:hover > .ps__thumb-y, + .ps__rail-y:focus > .ps__thumb-y, + .ps__rail-y.ps--clicking .ps__thumb-y { + background-color: #999; + width: 6px; + } + + @supports (-ms-overflow-style: none) { + .ps { + overflow: auto !important; + } + } + + @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) { + .ps { + overflow: auto !important; + } + } + \ No newline at end of file diff --git a/src/app/shared/theme/styles/root.scss b/src/app/shared/theme/styles/root.scss new file mode 100644 index 00000000..9a89a5f6 --- /dev/null +++ b/src/app/shared/theme/styles/root.scss @@ -0,0 +1,782 @@ +@import "constants"; + +html, body { + width: 100%; + height: 99%; + font-family: $font-family !important; + font-size: $font-size !important; + line-height: 1.5; + overflow-x: hidden; +} + +.rtl-container{ + position:absolute; + width: 100%; + height: 100%; + top:0; + left:0; + right:0; + bottom:0; + .mat-menu-panel .mat-menu-content { + padding-top: 0; + padding-bottom: 0; + } + .top-toolbar { + left: $regular-sidenav-width; + width: calc(100% - #{$regular-sidenav-width}) !important; + } + .mat-sidenav-content { + margin-left: $regular-sidenav-width !important; + } + &.horizontal { + .top-toolbar, .pubkey-info-top { + left: 0; + width: 100% !important; + } + .mat-sidenav-content { + top: calc(#{$toolbar-height} + #{$gap} + #{$pubkey-info-height} + #{$toolbar-height}); + margin-left: 0 !important; + } + } + &.compact { + .sidenav{ + width: $compact-sidenav-width; + } + .mat-tree-node { + height: 76px; + padding: 0; + } + .top-toolbar, .pubkey-info-top { + left: $compact-sidenav-width; + width: calc(100% - #{$compact-sidenav-width}) !important; + } + .mat-sidenav-content { + margin-left: $compact-sidenav-width !important; + } + } + &.mini { + .sidenav { + width: $mini-sidenav-width; + } + .mat-tree-node { + padding: 0 8px 12px 8px; + .mat-icon { + font-size: $icon-size; + } + } + .top-toolbar, .pubkey-info-top { + left: $mini-sidenav-width; + width: calc(100% - #{$mini-sidenav-width}) !important; + } + .mat-sidenav-content { + margin-left: $mini-sidenav-width !important; + } + } +} + +.mat-sidenav-container .mat-sidenav-content { + top: calc(#{$toolbar-height} + #{$gap} + #{$pubkey-info-height}); + height: 100vh; +} + +.sidenav{ + width: $regular-sidenav-width; + height: 100%; + overflow: hidden !important; + overflow-anchor: none; + -ms-overflow-style: none; + touch-action: auto; + -ms-touch-action: auto; +} + +.font-9px { + font-size: 9px !important; +} + +.sticky { + position: fixed; + top: 0; + z-index: 9999; +} + +.horizontal-menu { + padding: 0; + z-index: 999; + position: fixed; + top: 0; + height: $toolbar-height; + overflow: visible; +} + +.top-bar { + position: relative; + top: 0; + bottom:0; + left:0; + right:0; + height: 0; +} + +.pubkey-info-top { + flex-wrap: wrap; + top: $toolbar-height; + margin-top: 1px; + min-height: $pubkey-info-height; + cursor: pointer; + display: flex; + left: $regular-sidenav-width; + width: calc(100% - #{$regular-sidenav-width}) !important; + align-content: center; +} + +.inner-sidenav-content { + position: relative; + // top: calc(#{$toolbar-height} + #{$gap} + #{$pubkey-info-height}); + top: 0; + bottom:0; + left:0; + right:0; + padding: 4px; + min-height: calc(100% - (#{$toolbar-height} + #{$gap}*4)); + max-height: 90vh; +} + +.top-50 { + top: 50px; +} + +*{ + margin: 0; + padding: 0; +} + +.rtl-spinner{ + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100%; + width: 100%; + position: fixed; + background: #fff; + z-index: 999999; + visibility: visible; + opacity: 1; + h4{ + margin-top: 10px; + } +} + +.mat-expansion-panel-header, .mat-menu-item, .mat-list .mat-list-item, .mat-nav-list .mat-list-item, .mat-selection-list .mat-list-item { + font-size: $font-size !important; +} + +.mat-raised-button { + width: 100%; + margin-top: 5px; + max-height: 36px; +} + +.padding-gap { + padding: $gap !important; +} + +.padding-gap-x { + padding: 0 $gap 0 $gap !important; +} + +.mat-raised-button { + margin-top: 5px !important; + max-height: 36px; +} + +.logo { + font-size: $font-size * 2; + font-weight: 700; + letter-spacing: 1px; +} + +.mat-card { + padding: 12px 24px !important; + overflow: hidden; + border-radius: 2px !important; +} + +.mat-toolbar-row, .mat-toolbar-single-row { + height: $toolbar-height; +} + +.mat-card-actions{ + display: block; + margin-bottom: 16px; + padding-left: 6px; + padding-right: 6px; +} + +.mat-card-content, .mat-card-subtitle, .mat-card-title { + display: block; + margin-bottom: 16px; +} + +.mat-card-header-text { + margin: 0 !important; + line-height: 1; +} + +.mat-form-field-wrapper { + width: 100%; + margin: 0 15px 0 0; +} + +.mat-select { + margin: 0 15px 0 0; +} + +.green { + color: #388e3c !important; +} + +.red { + color: #c62828 !important; +} + +.yellow { + color: #ffd740 !important; +} + +.mat-dialog-container { + padding: 0 !important; +} + +.mt-1px { + margin-top: 1px !important; +} + +.mt-1 { + margin-top: 0.55rem !important; +} + +.mb-1 { + margin-bottom: 0.55rem !important; +} + +.ml-1 { + margin-left: 0.55rem !important; +} + +.mr-1 { + margin-right: 0.55rem !important; +} + +.mx-1 { + margin: 0 0.55rem !important; +} + +.my-1 { + margin: 0.55rem 0 !important; +} + +.m-1 { + margin: 0.55rem !important; +} + +.mt-2 { + margin-top: 1rem !important; +} + +.mt-minus-1 { + margin-top: -0.5rem !important; +} + +.mb-2 { + margin-bottom: 1rem !important; +} + +.ml-2 { + margin-left: 1rem !important; +} + +.mr-2 { + margin-right: 1rem !important; +} + +.ml-4 { + margin-left: 2rem !important; +} + +.ml-8 { + margin-left: 4rem !important; +} + +.mr-4 { + margin-right: 2rem !important; +} + +.mx-2 { + margin: 0 1rem !important; +} + +.my-2 { + margin: 1rem 0 !important; +} + +.m-2 { + margin: 1rem !important; +} + +.pt-1 { + padding-top: 0.55rem !important; +} + +.pb-1 { + padding-bottom: 0.55rem !important; +} + +.pl-1 { + padding-left: 0.55rem !important; +} + +.pr-1 { + padding-right: 0.55rem !important; +} + +.pr-4px { + padding-right: 4px !important; +} + +.p-0 { + padding: 0 !important; +} + +.pl-0 { + padding-left: 0 !important; +} + +.px-1 { + padding: 0 0.55rem !important; +} + +.py-1 { + padding: 0.55rem 0 !important; +} + +.p-1 { + padding: 0.55rem !important; +} + +.pt-2 { + padding-top: 1rem !important; +} + +.pb-2 { + padding-bottom: 1rem !important; +} + +.pl-2 { + padding-left: 1rem !important; +} + +.pt-4 { + padding-top: 2rem !important; +} + +.pl-4 { + padding-left: 2rem !important; +} + +.pr-2 { + padding-right: 1rem !important; +} + +.pr-5 { + padding-right: 2.5rem !important; +} + +.px-2 { + padding: 0 1rem !important; +} + +.py-2 { + padding: 1rem 0 !important; +} + +.p-2 { + padding: 1rem !important; +} + +.m-1px { + margin: 1px !important; +} + +.overflow-x-auto { + overflow-x: auto; +} + +.overflow-y-auto { + overflow-y: auto; +} + +.overflow-auto { + overflow: auto; +} + +.mat-footer-row, .mat-header-row, .mat-row { + border-bottom-width: 0px; +} + +.mat-cell, .mat-header-cell, .mat-footer-cell { + border-bottom-width: 1px; + border-bottom-style: solid; + border-bottom-color: rgba(0, 0, 0, 0.12); +} + +.flex-ellipsis { + padding-right: 30px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.mat-list, .mat-list .mat-list-item .mat-list-item-content, .mat-nav-list, .mat-selection-list { + padding: 0 !important; +} + +.inline-spinner { + display: inline-flex !important; + top: 5px !important; +} + +.top-minus-5px { + position: relative; + top:-5px; +} + +.top-minus-15px { + position: relative; + top:-15px; +} + +.top-minus-25px { + position: relative; + top:-25px; + margin-bottom: -25px !important; +} + +.top-minus-30px { + position: relative; + top:-30px; +} + +.cursor-pointer { + cursor: pointer !important; +} + +.cursor-default { + cursor: default !important; +} + +.cursor-not-allowed { + cursor: not-allowed !important; +} + +.font-60-percent { + font-size: 60%; +} + +.inline-flex { + display: inline-flex !important; +} + +.error-border { + border: 1px solid red; + box-shadow: 0 3px 1px -2px rgba(255,0,0,.2), 0 2px 2px 0 rgba(255,0,0,.14), 0 1px 5px 0 rgba(255,0,0,.12) !important; +} + +.settings{ + position: fixed; + width: $settings-nav-width; + .container{ + padding: 6px 14px; + h4{ + border-bottom: 1px solid #ccc; + margin: 12px 0 6px 0; + } + .skin{ + width:32px; + height: 0px; + padding: 0; + overflow: hidden; + cursor: pointer; + border: 16px solid; + &.light-blue{ + border-top-color: #3F51B5; + border-bottom-color: #3F51B5; + border-left-color: #ffffff; + border-right-color: #ffffff; + } + &.light-teal{ + border-left-color: #ffffff; + border-right-color: #ffffff; + border-top-color: #009688; + border-bottom-color: #009688; + } + &.light-red{ + border-left-color: #ffffff; + border-right-color: #ffffff; + border-top-color: #F44336; + border-bottom-color: #F44336; + } + &.dark-blue{ + border-left-color: #262626; + border-right-color: #262626; + border-top-color: #0277bd; + border-bottom-color: #0277bd; + } + &.dark-green{ + border-left-color: #262626; + border-right-color: #262626; + border-top-color: #388E3C; + border-bottom-color: #388E3C; + } + &.dark-pink{ + border-left-color: #262626; + border-right-color: #262626; + border-top-color: #D81B60; + border-bottom-color: #D81B60; + } + &.gray-blue{ + border-left-color: #EEEEEE; + border-right-color: #EEEEEE; + border-top-color: #00BCD4; + border-bottom-color: #00BCD4; + } + &.gray-lime{ + border-left-color: #EEEEEE; + border-right-color: #EEEEEE; + border-top-color: #DCE775; + border-bottom-color: #DCE775; + } + &.gray-purple{ + border-left-color: #EEEEEE; + border-right-color: #EEEEEE; + border-top-color: #512DA8; + border-bottom-color: #512DA8; + } + &.bluegray-amber{ + border-left-color: #CFD8DC; + border-right-color: #CFD8DC; + border-top-color: #FFA000; + border-bottom-color: #FFA000; + } + &.bluegray-deeppurple{ + border-left-color: #CFD8DC; + border-right-color: #CFD8DC; + border-top-color: #5E35B1; + border-bottom-color: #5E35B1; + } + &.bluegray-lightgreen{ + border-left-color: #CFD8DC; + border-right-color: #CFD8DC; + border-top-color: #689F38; + border-bottom-color: #689F38; + } + &.self-gray{ + border-left-color: #FAFAFA; + border-right-color: #FAFAFA; + border-top-color: #9e9e9e; + border-bottom-color: #9e9e9e; + } + &.self-green{ + border-left-color: #dbebd4; + border-right-color: #dbebd4; + border-top-color: #9ec78d; + border-bottom-color: #9ec78d; + } + &.self-yellow{ + border-left-color: #fff2cc; + border-right-color: #fff2cc; + border-top-color: #ffda7c; + border-bottom-color: #ffda7c; + } + &.self-blue{ + border-left-color: #cfe2f4; + border-right-color: #cfe2f4; + border-top-color: #83b0de; + border-bottom-color: #83b0de; + } + &.self-brown{ + border-left-color: #f4dfcf; + border-right-color: #f4dfcf; + border-top-color: #dea983; + border-bottom-color: #dea983; + } + &.self-pink{ + border-left-color: #f4d1d6; + border-right-color: #f4d1d6; + border-top-color: #de8692; + border-bottom-color: #de8692; + } + } + } + + .mat-radio-group{ + display: inline-flex; + flex-direction: column; + .mat-radio-button{ + margin: 2px 0; + } + } + + .mat-slide-toggle{ + padding: 0px 14px; + } + +} + +.op-image{ + box-shadow: 0 0 2px #ccc; + border: 2px solid; + border-color: transparent; + cursor: pointer; + transition: 0.2s; +} + +.settings-icon{ + position: fixed; + top: 30%; + right: 0; + width: 42px; + height: 42px; + opacity: 0.6; + cursor: pointer; + z-index: 999999; +} + +.test-banner { + padding-top: 2px; + background-color: #FC7783; + text-transform: uppercase; + border-radius: 2px; +} + +.icon-large { + font-size: 70px; + margin-left: -100%; +} + +.icon-small { + height: 20px !important; + width: 20px !important; + font-size: 20px !important; +} + +.icon-smaller { + height: 10px !important; + width: 10px !important; + font-size: 10px !important; +} + +.copy-icon { + position: relative; + top: 5px; +} + +.copy-icon-smaller { + position: relative; + top: 2px; +} + +.top-5px { + position: relative; + top: 5px; +} + +.animate-settings { + -webkit-animation: animate-settings 10s linear infinite; + -moz-animation: animate-settings 10s linear infinite; + animation: animate-settings 10s linear infinite; +} +@keyframes animate-settings { + 100% {transform: rotate(360deg)} +} +@-moz-keyframes animate-settings { + 100% {-moz-transform: rotate(360deg)} +} +@-webkit-keyframes animate-settings { + 100% {-webkit-transform: rotate(360deg)} +} + +.size-30 { + font-size: 30px; +} + +.mt-minus-5 { + position: relative; + margin-top: -5px; +} + +.custom-card { + padding: 0px 0px 8px 0px !important; +} + +.not-found-box { + min-width: 30%; +} + +.w-100 { + width: 100% !important; +} + +.w-84 { + width: 84% !important; +} + +.h-100 { + height: 100% !important; +} + +a { + outline: none; + text-decoration: none; +} + +.mat-tree { + width: 100%; + margin-top: 8px; +} + +.mat-tree-node { + min-height: 42px !important; + padding: 0 12px 0 12px; + cursor: pointer; +} + +.mat-tree-node:focus, .mat-tree-node:active { + outline: none; +} + +.lnd-info { + height: $sidenav-info-height; +} + +.horizontal-button { + height: $toolbar-height; +} + +.mat-icon-36 { + width: $icon-size !important; + height: $icon-size !important; + font-size: $icon-size; +} + +.flex-wrap { + flex-wrap: wrap !important; +} + +.word-break { + word-break: break-all !important; +} + +.qr-border { + border: 2px solid white; +} diff --git a/src/app/shared/theme/styles/styles.scss b/src/app/shared/theme/styles/styles.scss new file mode 100644 index 00000000..abe37aeb --- /dev/null +++ b/src/app/shared/theme/styles/styles.scss @@ -0,0 +1,6 @@ +@import url('https://fonts.googleapis.com/css?family=Roboto:100,100i,300,300i,400,400i,500,500i,700,700i,900,900i'); +@import url('https://fonts.googleapis.com/icon?family=Material+Icons'); + +@import "/root"; +@import "/perfect-scrollbar"; +@import "/theme"; diff --git a/src/app/shared/theme/styles/theme.scss b/src/app/shared/theme/styles/theme.scss new file mode 100644 index 00000000..95217bba --- /dev/null +++ b/src/app/shared/theme/styles/theme.scss @@ -0,0 +1,96 @@ +@import '~@angular/material/theming'; +@include mat-core(); +@import 'change-theme'; + +.rtl-container{ + &.light-blue{ + @import "../skins/light-blue"; + @include angular-material-theme($blue-light-theme); + @include change-theme($blue-light-theme); + } + &.light-teal{ + @import "../skins/light-teal"; + @include angular-material-theme($teal-light-theme); + @include change-theme($teal-light-theme); + } + &.light-red{ + @import "../skins/light-red"; + @include angular-material-theme($red-light-theme); + @include change-theme($red-light-theme); + } + &.dark-blue{ + @import "../skins/dark-blue"; + @include angular-material-theme($blue-dark-theme); + @include change-theme($blue-dark-theme); + } + &.dark-green{ + @import "../skins/dark-green"; + @include angular-material-theme($green-dark-theme); + @include change-theme($green-dark-theme); + } + &.dark-pink{ + @import "../skins/dark-pink"; + @include angular-material-theme($pink-dark-theme); + @include change-theme($pink-dark-theme); + } + &.gray-blue{ + @import "../skins/gray-blue"; + @include angular-material-theme($blue-gray-theme); + @include change-theme($blue-gray-theme); + } + &.gray-lime{ + @import "../skins/gray-lime"; + @include angular-material-theme($lime-gray-theme); + @include change-theme($lime-gray-theme); + } + &.gray-purple{ + @import "../skins/gray-purple"; + @include angular-material-theme($purple-gray-theme); + @include change-theme($purple-gray-theme); + } + &.bluegray-amber{ + @import "../skins/bluegray-amber"; + @include angular-material-theme($amber-bluegray-theme); + @include change-theme($amber-bluegray-theme); + } + &.bluegray-deeppurple{ + @import "../skins/bluegray-deeppurple"; + @include angular-material-theme($deeppurple-bluegray-theme); + @include change-theme($deeppurple-bluegray-theme); + } + &.bluegray-lightgreen{ + @import "../skins/bluegray-lightgreen"; + @include angular-material-theme($lightgreen-bluegray-theme); + @include change-theme($lightgreen-bluegray-theme); + } + &.self-gray{ + @import "../skins/self-gray"; + @include angular-material-theme($gray-theme); + @include change-theme($gray-theme); + } + &.self-green{ + @import "../skins/self-green"; + @include angular-material-theme($green-theme); + @include change-theme($green-theme); + } + &.self-yellow{ + @import "../skins/self-yellow"; + @include angular-material-theme($yellow-theme); + @include change-theme($yellow-theme); + } + &.self-blue{ + @import "../skins/self-blue"; + @include angular-material-theme($blue-theme); + @include change-theme($blue-theme); + } + &.self-brown{ + @import "../skins/self-brown"; + @include angular-material-theme($brown-theme); + @include change-theme($brown-theme); + } + &.self-pink{ + @import "../skins/self-pink"; + @include angular-material-theme($pink-theme); + @include change-theme($pink-theme); + } +} diff --git a/src/assets/.gitkeep b/src/assets/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/src/assets/images/RTL1.jpg b/src/assets/images/RTL1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..09d4a96e57b998066b0cee8da31fc8b44538dc82 GIT binary patch literal 7747 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 literal 0 HcmV?d00001 diff --git a/src/assets/images/RTL2.jpg b/src/assets/images/RTL2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2f3a563420921c688fc1787ebc3360d126f417b3 GIT binary patch literal 9587 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 0.5% +last 2 versions +Firefox ESR +not dead +not IE 9-11 \ No newline at end of file diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts new file mode 100644 index 00000000..2ad8a3d0 --- /dev/null +++ b/src/environments/environment.prod.ts @@ -0,0 +1,24 @@ +import { VERSION } from './version'; + +export const API_URL = './api'; + +export const environment = { + production: true, + isDebugMode: false, + AUTHENTICATE_API: API_URL + '/authenticate', + BALANCE_API: API_URL + '/balance', + FEES_API: API_URL + '/fees', + PEERS_API: API_URL + '/peers', + CHANNELS_API: API_URL + '/channels', + GETINFO_API: API_URL + '/getinfo', + WALLET_API: API_URL + '/wallet', + NETWORK_API: API_URL + '/network', + NEW_ADDRESS_API : API_URL + '/newaddress', + TRANSACTIONS_API : API_URL + '/transactions', + CONF_API: API_URL + '/conf', + PAYREQUEST_API: API_URL + '/payreq', + PAYMENTS_API: API_URL + '/payments', + INVOICES_API: API_URL + '/invoices', + SWITCH_API: API_URL + '/switch', + VERSION: VERSION +}; diff --git a/src/environments/environment.ts b/src/environments/environment.ts new file mode 100644 index 00000000..2024cbe1 --- /dev/null +++ b/src/environments/environment.ts @@ -0,0 +1,24 @@ +import { VERSION } from './version'; + +export const API_URL = 'http://localhost:3000/rtl/api'; + +export const environment = { + production: false, + isDebugMode: true, + AUTHENTICATE_API: API_URL + '/authenticate', + BALANCE_API: API_URL + '/balance', + FEES_API: API_URL + '/fees', + PEERS_API: API_URL + '/peers', + CHANNELS_API: API_URL + '/channels', + GETINFO_API: API_URL + '/getinfo', + WALLET_API: API_URL + '/wallet', + NETWORK_API: API_URL + '/network', + NEW_ADDRESS_API : API_URL + '/newaddress', + TRANSACTIONS_API : API_URL + '/transactions', + CONF_API: API_URL + '/conf', + PAYREQUEST_API: API_URL + '/payreq', + PAYMENTS_API: API_URL + '/payments', + INVOICES_API: API_URL + '/invoices', + SWITCH_API: API_URL + '/switch', + VERSION: VERSION +}; diff --git a/src/environments/version.ts b/src/environments/version.ts new file mode 100644 index 00000000..716fbd1b --- /dev/null +++ b/src/environments/version.ts @@ -0,0 +1 @@ +export const VERSION = '0.2.16-beta'; \ No newline at end of file diff --git a/src/index.html b/src/index.html new file mode 100644 index 00000000..7999ed6e --- /dev/null +++ b/src/index.html @@ -0,0 +1,13 @@ + + + + + RTL + + + + + + + + diff --git a/src/karma.conf.js b/src/karma.conf.js new file mode 100644 index 00000000..b6e00421 --- /dev/null +++ b/src/karma.conf.js @@ -0,0 +1,31 @@ +// Karma configuration file, see link for more information +// https://karma-runner.github.io/1.0/config/configuration-file.html + +module.exports = function (config) { + config.set({ + basePath: '', + frameworks: ['jasmine', '@angular-devkit/build-angular'], + plugins: [ + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('karma-jasmine-html-reporter'), + require('karma-coverage-istanbul-reporter'), + require('@angular-devkit/build-angular/plugins/karma') + ], + client: { + clearContext: false // leave Jasmine Spec Runner output visible in browser + }, + coverageIstanbulReporter: { + dir: require('path').join(__dirname, '../coverage'), + reports: ['html', 'lcovonly'], + fixWebpackSourcePaths: true + }, + reporters: ['progress', 'kjhtml'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['Chrome'], + singleRun: false + }); +}; \ No newline at end of file diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 00000000..e44f3d92 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,12 @@ +import 'hammerjs'; +import { enableProdMode } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; +import { environment } from './environments/environment'; + +if (environment.production) { + enableProdMode(); +} + +platformBrowserDynamic().bootstrapModule(AppModule).catch(err => console.log(err)); diff --git a/src/polyfills.ts b/src/polyfills.ts new file mode 100644 index 00000000..480c13eb --- /dev/null +++ b/src/polyfills.ts @@ -0,0 +1,80 @@ +/** + * This file includes polyfills needed by Angular and is loaded before the app. + * You can add your own extra polyfills to this file. + * + * This file is divided into 2 sections: + * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. + * 2. Application imports. Files imported after ZoneJS that should be loaded before your main + * file. + * + * The current setup is for so-called "evergreen" browsers; the last versions of browsers that + * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), + * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. + * + * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html + */ + +/*************************************************************************************************** + * BROWSER POLYFILLS + */ + +/** IE9, IE10 and IE11 requires all of the following polyfills. **/ +import 'core-js/es6/symbol'; +import 'core-js/es6/object'; +import 'core-js/es6/function'; +import 'core-js/es6/parse-int'; +import 'core-js/es6/parse-float'; +import 'core-js/es6/number'; +import 'core-js/es6/math'; +import 'core-js/es6/string'; +import 'core-js/es6/date'; +import 'core-js/es6/array'; +import 'core-js/es6/regexp'; +import 'core-js/es6/map'; +import 'core-js/es6/weak-map'; +import 'core-js/es6/set'; + +/** IE10 and IE11 requires the following for NgClass support on SVG elements */ +// import 'classlist.js'; // Run `npm install --save classlist.js`. + +/** IE10 and IE11 requires the following for the Reflect API. */ +// import 'core-js/es6/reflect'; + + +/** Evergreen browsers require these. **/ +// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove. + + + +/** + * Web Animations `@angular/platform-browser/animations` + * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. + * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). + **/ +// import 'web-animations-js'; // Run `npm install --save web-animations-js`. + +/** + * By default, zone.js will patch all possible macroTask and DomEvents + * user can disable parts of macroTask/DomEvents patch by setting following flags + */ + + // (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame + // (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick + // (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames + + /* + * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js + * with the following flag, it will bypass `zone.js` patch for IE/Edge + */ +// (window as any).__Zone_enable_cross_context_check = true; + +/*************************************************************************************************** + * Zone JS is required by default for Angular itself. + */ +import 'zone.js/dist/zone'; // Included with Angular CLI. + + + +/*************************************************************************************************** + * APPLICATION IMPORTS + */ diff --git a/src/test.ts b/src/test.ts new file mode 100644 index 00000000..16317897 --- /dev/null +++ b/src/test.ts @@ -0,0 +1,20 @@ +// This file is required by karma.conf.js and loads recursively all the .spec and framework files + +import 'zone.js/dist/zone-testing'; +import { getTestBed } from '@angular/core/testing'; +import { + BrowserDynamicTestingModule, + platformBrowserDynamicTesting +} from '@angular/platform-browser-dynamic/testing'; + +declare const require: any; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting() +); +// Then we find all the tests. +const context = require.context('./', true, /\.spec\.ts$/); +// And load the modules. +context.keys().map(context); diff --git a/src/tsconfig.app.json b/src/tsconfig.app.json new file mode 100644 index 00000000..190fd300 --- /dev/null +++ b/src/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/app", + "types": [] + }, + "exclude": [ + "test.ts", + "**/*.spec.ts" + ] +} diff --git a/src/tsconfig.spec.json b/src/tsconfig.spec.json new file mode 100644 index 00000000..de773363 --- /dev/null +++ b/src/tsconfig.spec.json @@ -0,0 +1,18 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/spec", + "types": [ + "jasmine", + "node" + ] + }, + "files": [ + "test.ts", + "polyfills.ts" + ], + "include": [ + "**/*.spec.ts", + "**/*.d.ts" + ] +} diff --git a/src/tslint.json b/src/tslint.json new file mode 100644 index 00000000..9fceb7c0 --- /dev/null +++ b/src/tslint.json @@ -0,0 +1,17 @@ +{ + "extends": "../tslint.json", + "rules": { + "directive-selector": [ + true, + "attribute", + "rtl", + "camelCase" + ], + "component-selector": [ + true, + "element", + "rtl", + "kebab-case" + ] + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..3d5861df --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "importHelpers": true, + "outDir": "./angular", + "sourceMap": true, + "declaration": false, + "moduleResolution": "node", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "target": "es5", + "typeRoots": [ + "node_modules/@types" + ], + "lib": [ + "es2017", + "dom" + ] + } +} diff --git a/tslint.json b/tslint.json new file mode 100644 index 00000000..03baed77 --- /dev/null +++ b/tslint.json @@ -0,0 +1,141 @@ +{ + "rulesDirectory": [ + "node_modules/codelyzer" + ], + "rules": { + "arrow-return-shorthand": true, + "callable-types": true, + "class-name": true, + "comment-format": [ + true, + "check-space" + ], + "curly": true, + "eofline": true, + "forin": true, + "import-blacklist": [ + true + ], + "import-spacing": true, + "indent": [ + true, + "spaces" + ], + "interface-over-type-literal": true, + "label-position": true, + "max-line-length": [ + true, + 180 + ], + "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-use-before-declare": 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" + } + ], + "typeof-compare": true, + "unified-signatures": true, + "variable-name": false, + "whitespace": [ + true, + "check-branch", + "check-decl", + "check-operator", + "check-separator", + "check-type" + ], + "directive-selector": [ + true, + "attribute", + "rtl", + "camelCase" + ], + "component-selector": [ + true, + "element", + "rtl", + "kebab-case" + ], + "use-input-property-decorator": true, + "use-output-property-decorator": true, + "use-host-property-decorator": true, + "no-input-rename": true, + "no-output-rename": true, + "use-life-cycle-interface": true, + "use-pipe-transform-interface": true, + "component-class-suffix": true, + "directive-class-suffix": true, + "no-access-missing-member": true, + "templates-use-public": true, + "invoke-injectable": true + } +}