From 75a50e83d5d2669ac9289c653ce3d36a889c2927 Mon Sep 17 00:00:00 2001 From: Shahana Farooqui Date: Sat, 24 Aug 2019 16:35:31 -0400 Subject: [PATCH] Incomplete lazy load 4 Incomplete lazy load 4 --- package-lock.json | 1419 ++++++++++++++--- package.json | 6 +- src/app/app.component.html | 2 +- src/app/app.component.ts | 59 +- src/app/app.module.ts | 38 +- src/app/app.routing.ts | 12 +- src/app/c-lightning/cl-root.component.scss | 4 - src/app/c-lightning/cl-root.component.ts | 67 - src/app/c-lightning/cl.module.ts | 28 - src/app/c-lightning/cl.routing.ts | 19 - src/app/c-lightning/home/home.component.html | 2 - src/app/c-lightning/home/home.component.ts | 56 - src/app/c-lightning/store/cl.actions.ts | 33 - src/app/c-lightning/store/cl.effects.ts | 102 -- src/app/c-lightning/store/cl.reducers.ts | 49 - .../cl-root.component.html | 0 .../cl-root.component.scss} | 0 src/app/clightning/cl-root.component.ts | 166 ++ src/app/clightning/cl.module.ts | 31 + src/app/clightning/cl.routing.ts | 18 + src/app/clightning/home/home.component.html | 237 +++ src/app/clightning/home/home.component.scss | 12 + .../home/home.component.spec.ts | 0 src/app/clightning/home/home.component.ts | 148 ++ .../channel-backup.component.ts | 50 +- .../channel-closed.component.ts | 39 +- .../channel-manage.component.ts | 76 +- .../channel-pending.component.ts | 41 +- src/app/lnd/home/home.component.ts | 101 +- src/app/lnd/invoices/invoices.component.ts | 42 +- src/app/lnd/lnd-root.component.scss | 4 - src/app/lnd/lnd-root.component.ts | 211 ++- src/app/lnd/lnd.module.ts | 27 +- src/app/lnd/lnd.routing.ts | 49 +- .../channel-lookup.component.ts | 27 +- src/app/lnd/lookups/lookups.component.ts | 15 +- .../query-routes/query-routes.component.ts | 17 +- .../send-receive/payments.component.ts | 58 +- src/app/lnd/peers/peers.component.ts | 62 +- .../routing-peers/routing-peers.component.ts | 42 +- .../switch/forwarding-history.component.ts | 46 +- .../list-transactions.component.ts | 40 +- .../send-receive-trans.component.html | 2 +- .../send-receive-trans.component.ts | 57 +- .../lnd/unlock-lnd/unlock-lnd.component.ts | 35 +- .../confirmation-message.component.ts | 6 +- .../shared/components/help/help.component.ts | 2 + .../horizontal-navigation.component.html | 4 +- .../horizontal-navigation.component.ts | 25 +- .../side-navigation.component.html | 8 +- .../side-navigation.component.ts | 100 +- .../navigation/top-menu/top-menu.component.ts | 27 +- .../not-found/not-found.component.html | 1 + .../not-found/not-found.component.ts | 11 +- .../server-config/server-config.component.ts | 16 +- .../settings-nav/settings-nav.component.ts | 21 +- .../components/signin/signin.component.ts | 10 +- src/app/shared/models/clModels.ts | 43 - src/app/shared/models/lndModels.ts | 22 +- src/app/shared/models/navMenu.ts | 61 +- src/app/shared/services/auth.guard.ts | 14 + src/app/shared/shared.module.ts | 55 +- .../store/rtl.actions.ts} | 132 +- .../store/rtl.effects.ts} | 508 ++++-- .../store/rtl.reducers.ts} | 97 +- src/app/shared/theme/styles/change-theme.scss | 6 +- src/app/shared/theme/styles/root.scss | 18 + src/app/shared/theme/styles/styles.scss | 4 +- src/app/store/rtl.actions.ts | 118 -- src/app/store/rtl.effects.ts | 261 --- src/app/store/rtl.reducers.ts | 82 - .../super-user-dashboard.component.html | 2 - .../super-user-dashboard.component.scss | 0 .../super-user-dashboard.component.spec.ts | 25 - .../super-user-dashboard.component.ts | 70 - src/environments/version.ts | 2 +- 76 files changed, 3231 insertions(+), 2069 deletions(-) delete mode 100644 src/app/c-lightning/cl-root.component.scss delete mode 100644 src/app/c-lightning/cl-root.component.ts delete mode 100644 src/app/c-lightning/cl.module.ts delete mode 100644 src/app/c-lightning/cl.routing.ts delete mode 100644 src/app/c-lightning/home/home.component.html delete mode 100644 src/app/c-lightning/home/home.component.ts delete mode 100644 src/app/c-lightning/store/cl.actions.ts delete mode 100644 src/app/c-lightning/store/cl.effects.ts delete mode 100644 src/app/c-lightning/store/cl.reducers.ts rename src/app/{c-lightning => clightning}/cl-root.component.html (100%) rename src/app/{c-lightning/home/home.component.scss => clightning/cl-root.component.scss} (100%) create mode 100644 src/app/clightning/cl-root.component.ts create mode 100644 src/app/clightning/cl.module.ts create mode 100644 src/app/clightning/cl.routing.ts create mode 100644 src/app/clightning/home/home.component.html create mode 100644 src/app/clightning/home/home.component.scss rename src/app/{c-lightning => clightning}/home/home.component.spec.ts (100%) create mode 100644 src/app/clightning/home/home.component.ts delete mode 100644 src/app/shared/models/clModels.ts rename src/app/{lnd/store/lnd.actions.ts => shared/store/rtl.actions.ts} (75%) rename src/app/{lnd/store/lnd.effects.ts => shared/store/rtl.effects.ts} (69%) rename src/app/{lnd/store/lnd.reducers.ts => shared/store/rtl.reducers.ts} (72%) delete mode 100644 src/app/store/rtl.actions.ts delete mode 100644 src/app/store/rtl.effects.ts delete mode 100644 src/app/store/rtl.reducers.ts delete mode 100644 src/app/super-user-dashboard/super-user-dashboard.component.html delete mode 100644 src/app/super-user-dashboard/super-user-dashboard.component.scss delete mode 100644 src/app/super-user-dashboard/super-user-dashboard.component.spec.ts delete mode 100644 src/app/super-user-dashboard/super-user-dashboard.component.ts diff --git a/package-lock.json b/package-lock.json index b6e46fac..e9e39185 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "rtl", - "version": "0.4.7-beta", + "version": "0.4.8-beta", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1940,6 +1940,43 @@ "qrcodejs2": "0.0.2" } }, + "ansi-align": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", + "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "requires": { + "string-width": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "ansi-colors": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", @@ -2029,20 +2066,17 @@ "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" }, "arr-flatten": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" }, "arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" }, "array-find-index": { "version": "1.0.2", @@ -2072,8 +2106,7 @@ "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" }, "arraybuffer.slice": { "version": "0.0.7", @@ -2147,8 +2180,7 @@ "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" }, "ast-types-flow": { "version": "0.0.7", @@ -2168,8 +2200,7 @@ "async-each": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==" }, "async-foreach": { "version": "0.1.3", @@ -2190,8 +2221,7 @@ "atob": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" }, "autoprefixer": { "version": "9.6.0", @@ -2375,7 +2405,6 @@ "version": "0.11.2", "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, "requires": { "cache-base": "^1.0.1", "class-utils": "^0.3.5", @@ -2390,7 +2419,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, "requires": { "is-descriptor": "^1.0.0" } @@ -2399,7 +2427,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -2408,7 +2435,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -2417,7 +2443,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -2552,6 +2577,80 @@ } } }, + "boxen": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", + "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", + "requires": { + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^2.0.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^1.2.0", + "widest-line": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -2795,7 +2894,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, "requires": { "collection-visit": "^1.0.0", "component-emitter": "^1.2.1", @@ -2864,6 +2962,11 @@ "integrity": "sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg==", "dev": true }, + "capture-stack-trace": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", + "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==" + }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -2929,6 +3032,11 @@ "tslib": "^1.9.0" } }, + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==" + }, "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", @@ -2949,7 +3057,6 @@ "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, "requires": { "arr-union": "^3.1.0", "define-property": "^0.2.5", @@ -2961,7 +3068,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -2985,6 +3091,11 @@ } } }, + "cli-boxes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=" + }, "cli-cursor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", @@ -3074,7 +3185,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, "requires": { "map-visit": "^1.0.0", "object-visit": "^1.0.0" @@ -3084,7 +3194,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" } @@ -3092,8 +3201,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "colors": { "version": "1.1.2", @@ -3135,8 +3243,7 @@ "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" }, "component-inherit": { "version": "0.0.3", @@ -3193,6 +3300,34 @@ "typedarray": "^0.0.6" } }, + "configstore": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", + "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "requires": { + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + }, + "dependencies": { + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + } + } + }, "connect": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", @@ -3299,8 +3434,7 @@ "copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" }, "copy-webpack-plugin": { "version": "5.0.3", @@ -3366,6 +3500,14 @@ "elliptic": "^6.0.0" } }, + "create-error-class": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "requires": { + "capture-stack-trace": "^1.0.0" + } + }, "create-hash": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", @@ -3421,6 +3563,11 @@ "randomfill": "^1.0.3" } }, + "crypto-random-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=" + }, "css-parse": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz", @@ -3850,8 +3997,7 @@ "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" }, "deep-equal": { "version": "1.0.1", @@ -3859,6 +4005,11 @@ "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", "dev": true }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, "default-gateway": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", @@ -3899,7 +4050,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, "requires": { "is-descriptor": "^1.0.2", "isobject": "^3.0.1" @@ -3909,7 +4059,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -3918,7 +4067,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -3927,7 +4075,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -4133,6 +4280,19 @@ "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", "dev": true }, + "dot-prop": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", + "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "requires": { + "is-obj": "^1.0.0" + } + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + }, "duplexify": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", @@ -4168,9 +4328,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.202", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.202.tgz", - "integrity": "sha512-oJHvNNYM3Y9mJfiujbFQxRa0v7mzrc6Pv76fq6A4Dd6MxbfiVGhmgXtIeMBloTF8crmlJ1rXQW95VS4Zp/9ZSg==", + "version": "1.3.201", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.201.tgz", + "integrity": "sha512-aCTPIfY1Jvuam5b6vuWRjt1F8i4kY7zX0Qtpu5SNd6l1zjuxU9fDNpbM4o6+oJsra+TMD2o7D20GnkSIgpTr9w==", "dev": true }, "elliptic": { @@ -4500,7 +4660,6 @@ "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, "requires": { "debug": "^2.3.3", "define-property": "^0.2.5", @@ -4515,7 +4674,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -4524,7 +4682,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -4584,7 +4741,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, "requires": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" @@ -4594,7 +4750,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, "requires": { "is-plain-object": "^2.0.4" } @@ -4616,7 +4771,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, "requires": { "array-unique": "^0.3.2", "define-property": "^1.0.0", @@ -4632,7 +4786,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, "requires": { "is-descriptor": "^1.0.0" } @@ -4641,7 +4794,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -4650,7 +4802,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -4659,7 +4810,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -4668,7 +4818,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -4830,8 +4979,7 @@ "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" }, "for-own": { "version": "1.0.0", @@ -4866,7 +5014,6 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, "requires": { "map-cache": "^0.2.2" } @@ -5007,8 +5154,7 @@ "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" }, "getpass": { "version": "0.1.7", @@ -5035,7 +5181,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, "requires": { "is-glob": "^3.1.0", "path-dirname": "^1.0.0" @@ -5045,13 +5190,20 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, "requires": { "is-extglob": "^2.1.0" } } } }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "requires": { + "ini": "^1.3.4" + } + }, "globals": { "version": "9.18.0", "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", @@ -5090,6 +5242,31 @@ "minimatch": "~3.0.2" } }, + "got": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "requires": { + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" + }, + "dependencies": { + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + } + } + }, "graceful-fs": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", @@ -5183,8 +5360,7 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "has-symbols": { "version": "1.0.0", @@ -5201,7 +5377,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, "requires": { "get-value": "^2.0.6", "has-values": "^1.0.0", @@ -5212,7 +5387,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, "requires": { "is-number": "^3.0.0", "kind-of": "^4.0.0" @@ -5222,7 +5396,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, "requires": { "kind-of": "^3.0.2" }, @@ -5231,7 +5404,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -5242,7 +5414,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -5455,6 +5626,11 @@ "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", "dev": true }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=" + }, "ignore-walk": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", @@ -5505,6 +5681,11 @@ "resolve-from": "^3.0.0" } }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=" + }, "import-local": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", @@ -5518,8 +5699,7 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" }, "in-publish": { "version": "2.0.0", @@ -5706,7 +5886,6 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, "requires": { "kind-of": "^3.0.2" }, @@ -5715,7 +5894,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -5739,8 +5917,7 @@ "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "is-callable": { "version": "1.1.4", @@ -5748,11 +5925,18 @@ "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", "dev": true }, + "is-ci": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", + "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "requires": { + "ci-info": "^1.5.0" + } + }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, "requires": { "kind-of": "^3.0.2" }, @@ -5761,7 +5945,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -5778,7 +5961,6 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, "requires": { "is-accessor-descriptor": "^0.1.6", "is-data-descriptor": "^0.1.4", @@ -5788,8 +5970,7 @@ "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" } } }, @@ -5802,14 +5983,12 @@ "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" }, "is-finite": { "version": "1.0.2", @@ -5831,17 +6010,45 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, "requires": { "is-extglob": "^2.1.1" } }, + "is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + }, + "dependencies": { + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "requires": { + "path-is-inside": "^1.0.1" + } + } + } + }, + "is-npm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", + "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=" + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" + }, "is-path-cwd": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", @@ -5876,7 +6083,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, "requires": { "isobject": "^3.0.1" } @@ -5887,6 +6093,11 @@ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, + "is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=" + }, "is-regex": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", @@ -5896,11 +6107,15 @@ "has": "^1.0.1" } }, + "is-retry-allowed": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", + "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=" + }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, "is-symbol": { "version": "1.0.2", @@ -5924,8 +6139,7 @@ "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" }, "is-wsl": { "version": "1.1.0", @@ -5955,8 +6169,7 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" }, "isstream": { "version": "0.1.2", @@ -7142,8 +7355,15 @@ "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + }, + "latest-version": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", + "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "requires": { + "package-json": "^4.0.0" + } }, "lcid": { "version": "1.0.0", @@ -7370,6 +7590,11 @@ "signal-exit": "^3.0.0" } }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" + }, "lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", @@ -7466,8 +7691,7 @@ "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" }, "map-obj": { "version": "1.0.1", @@ -7478,11 +7702,15 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, "requires": { "object-visit": "^1.0.0" } }, + "material-design-icons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/material-design-icons/-/material-design-icons-3.0.1.tgz", + "integrity": "sha1-mnHEh0chjrylHlGmbaaCA4zct78=" + }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -7551,7 +7779,6 @@ "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -7572,7 +7799,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, "requires": { "arr-flatten": "^1.1.0", "array-unique": "^0.3.2", @@ -7590,7 +7816,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -7601,7 +7826,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, "requires": { "extend-shallow": "^2.0.1", "is-number": "^3.0.0", @@ -7613,7 +7837,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -7624,7 +7847,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, "requires": { "kind-of": "^3.0.2" }, @@ -7633,7 +7855,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -7644,7 +7865,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, "requires": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" @@ -7772,7 +7992,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, "requires": { "for-in": "^1.0.2", "is-extendable": "^1.0.1" @@ -7782,7 +8001,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, "requires": { "is-plain-object": "^2.0.4" } @@ -7872,7 +8090,6 @@ "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -8028,9 +8245,652 @@ "true-case-path": "^1.0.2" } }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "nodemon": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.1.tgz", + "integrity": "sha512-/DXLzd/GhiaDXXbGId5BzxP1GlsqtMGM9zTmkWrgXtSqjKmGSbLicM/oAy4FR0YWm14jCHRwnR31AHS2dYFHrg==", + "requires": { + "chokidar": "^2.1.5", + "debug": "^3.1.0", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.6", + "semver": "^5.5.0", + "supports-color": "^5.2.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.2", + "update-notifier": "^2.5.0" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==" + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + } + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + } + }, + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "optional": true, + "requires": { + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "optional": true + }, + "needle": { + "version": "2.3.0", + "bundled": true, + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "bundled": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "bundled": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "optional": true + }, + "semver": { + "version": "5.7.0", + "bundled": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "optional": true + } + } + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", "requires": { "abbrev": "1" @@ -8050,8 +8910,7 @@ "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "normalize-range": { "version": "0.1.2", @@ -8145,7 +9004,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, "requires": { "path-key": "^2.0.0" } @@ -8198,7 +9056,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, "requires": { "copy-descriptor": "^0.1.0", "define-property": "^0.2.5", @@ -8209,7 +9066,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -8218,7 +9074,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -8235,7 +9090,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, "requires": { "isobject": "^3.0.0" } @@ -8254,7 +9108,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, "requires": { "isobject": "^3.0.1" } @@ -8389,8 +9242,7 @@ "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" }, "p-is-promise": { "version": "2.1.0", @@ -8437,6 +9289,17 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, + "package-json": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", + "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "requires": { + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" + } + }, "pacote": { "version": "9.5.1", "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.5.1.tgz", @@ -8575,8 +9438,7 @@ "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" }, "path-browserify": { "version": "0.0.1", @@ -8587,8 +9449,7 @@ "path-dirname": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" }, "path-exists": { "version": "2.1.0", @@ -8606,14 +9467,12 @@ "path-is-inside": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" }, "path-parse": { "version": "1.0.6", @@ -8724,8 +9583,7 @@ "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" }, "postcss": { "version": "7.0.17", @@ -8829,8 +9687,7 @@ "prepend-http": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "dev": true + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" }, "process": { "version": "0.11.10", @@ -9023,6 +9880,11 @@ "resolved": "https://registry.npmjs.org/psl/-/psl-1.2.0.tgz", "integrity": "sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA==" }, + "pstree.remy": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.7.tgz", + "integrity": "sha512-xsMgrUwRpuGskEzBFkH8NmTimbZ5PcPup0LA8JJkHIm2IMUbQcpo3yeLNWVrufEYjh8YwtSVh0xz6UeWc5Oh5A==" + }, "public-encrypt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", @@ -9170,6 +10032,17 @@ "schema-utils": "^1.0.0" } }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, "read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -9288,7 +10161,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, "requires": { "extend-shallow": "^3.0.2", "safe-regex": "^1.1.0" @@ -9305,6 +10177,23 @@ "regjsparser": "^0.1.4" } }, + "registry-auth-token": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", + "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", + "requires": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "requires": { + "rc": "^1.0.1" + } + }, "regjsgen": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", @@ -9331,20 +10220,17 @@ "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" }, "repeat-element": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" }, "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" }, "repeating": { "version": "2.0.1", @@ -9454,8 +10340,7 @@ "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" }, "restore-cursor": { "version": "2.0.0", @@ -9470,8 +10355,7 @@ "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" }, "retry": { "version": "0.12.0", @@ -9503,6 +10387,11 @@ "inherits": "^2.0.1" } }, + "roboto-fontface": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/roboto-fontface/-/roboto-fontface-0.10.0.tgz", + "integrity": "sha512-OlwfYEgA2RdboZohpldlvJ1xngOins5d7ejqnIBWr9KaMxsnBqotpptRXTyfNRLnFpqzX6sTDt+X+a+6udnU8g==" + }, "run-async": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", @@ -9548,7 +10437,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, "requires": { "ret": "~0.1.10" } @@ -9678,6 +10566,14 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" }, + "semver-diff": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", + "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "requires": { + "semver": "^5.0.3" + } + }, "semver-dsl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/semver-dsl/-/semver-dsl-1.0.1.tgz", @@ -9790,7 +10686,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, "requires": { "extend-shallow": "^2.0.1", "is-extendable": "^0.1.1", @@ -9802,7 +10697,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -9862,7 +10756,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, "requires": { "shebang-regex": "^1.0.0" } @@ -9870,8 +10763,7 @@ "shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" }, "signal-exit": { "version": "3.0.2", @@ -9894,7 +10786,6 @@ "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, "requires": { "base": "^0.11.1", "debug": "^2.2.0", @@ -9910,7 +10801,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -9919,7 +10809,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, "requires": { "is-extendable": "^0.1.0" } @@ -9927,8 +10816,7 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" } } }, @@ -9936,7 +10824,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, "requires": { "define-property": "^1.0.0", "isobject": "^3.0.0", @@ -9947,7 +10834,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, "requires": { "is-descriptor": "^1.0.0" } @@ -9956,7 +10842,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -9965,7 +10850,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, "requires": { "kind-of": "^6.0.0" } @@ -9974,7 +10858,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", "is-data-descriptor": "^1.0.0", @@ -9987,7 +10870,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, "requires": { "kind-of": "^3.2.0" }, @@ -9996,7 +10878,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -10225,7 +11106,6 @@ "version": "0.5.2", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", - "dev": true, "requires": { "atob": "^2.1.1", "decode-uri-component": "^0.2.0", @@ -10255,8 +11135,7 @@ "source-map-url": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" }, "sourcemap-codec": { "version": "1.4.6", @@ -10408,7 +11287,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, "requires": { "extend-shallow": "^3.0.0" } @@ -10448,7 +11326,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, "requires": { "define-property": "^0.2.5", "object-copy": "^0.1.0" @@ -10458,7 +11335,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, "requires": { "is-descriptor": "^0.1.0" } @@ -10595,8 +11471,7 @@ "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" }, "strip-indent": { "version": "1.0.1", @@ -10606,6 +11481,11 @@ "get-stdin": "^4.0.1" } }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, "style-loader": { "version": "0.23.1", "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.23.1.tgz", @@ -10693,6 +11573,45 @@ "inherits": "2" } }, + "term-size": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", + "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "requires": { + "execa": "^0.7.0" + }, + "dependencies": { + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + } + } + }, "terser": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/terser/-/terser-4.1.2.tgz", @@ -10760,6 +11679,11 @@ "integrity": "sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==", "dev": true }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" + }, "timers-browserify": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", @@ -10800,7 +11724,6 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, "requires": { "kind-of": "^3.0.2" }, @@ -10809,7 +11732,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, "requires": { "is-buffer": "^1.1.5" } @@ -10820,7 +11742,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, "requires": { "define-property": "^2.0.2", "extend-shallow": "^3.0.2", @@ -10842,6 +11763,24 @@ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" }, + "touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "requires": { + "nopt": "~1.0.10" + }, + "dependencies": { + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "requires": { + "abbrev": "1" + } + } + } + }, "tough-cookie": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", @@ -11031,11 +11970,18 @@ "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", "dev": true }, + "undefsafe": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz", + "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=", + "requires": { + "debug": "^2.2.0" + } + }, "union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", @@ -11061,6 +12007,14 @@ "imurmurhash": "^0.1.4" } }, + "unique-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "requires": { + "crypto-random-string": "^1.0.0" + } + }, "universal-analytics": { "version": "0.4.20", "resolved": "https://registry.npmjs.org/universal-analytics/-/universal-analytics-0.4.20.tgz", @@ -11104,7 +12058,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, "requires": { "has-value": "^0.3.1", "isobject": "^3.0.0" @@ -11114,7 +12067,6 @@ "version": "0.3.1", "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, "requires": { "get-value": "^2.0.3", "has-values": "^0.1.4", @@ -11125,7 +12077,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, "requires": { "isarray": "1.0.0" } @@ -11135,16 +12086,64 @@ "has-values": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" } } }, + "unzip-response": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", + "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=" + }, "upath": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", - "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", - "dev": true + "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==" + }, + "update-notifier": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", + "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", + "requires": { + "boxen": "^1.2.1", + "chalk": "^2.0.1", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", + "is-installed-globally": "^0.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } }, "upper-case": { "version": "1.1.3", @@ -11162,8 +12161,7 @@ "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" }, "url": { "version": "0.11.0", @@ -11193,11 +12191,18 @@ "requires-port": "^1.0.0" } }, + "url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "requires": { + "prepend-http": "^1.0.1" + } + }, "use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" }, "useragent": { "version": "2.3.0", @@ -13046,6 +14051,43 @@ "string-width": "^1.0.2 || 2" } }, + "widest-line": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", + "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", + "requires": { + "string-width": "^2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "wordwrap": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", @@ -13083,6 +14125,16 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, + "write-file-atomic": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, "ws": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", @@ -13094,6 +14146,11 @@ "ultron": "~1.1.0" } }, + "xdg-basedir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=" + }, "xml2js": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", diff --git a/package.json b/package.json index c655b206..ce6c1034 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rtl", - "version": "0.4.7-beta", + "version": "0.4.8-beta", "license": "MIT", "scripts": { "ng": "ng", @@ -40,10 +40,13 @@ "hammerjs": "^2.0.8", "ini": "^1.3.5", "jsonwebtoken": "^8.4.0", + "material-design-icons": "^3.0.1", "ngx-perfect-scrollbar": "^6.3.1", "node-sass": "^4.12.0", + "nodemon": "^1.19.1", "optimist": "^0.6.1", "request-promise": "^4.2.2", + "roboto-fontface": "^0.10.0", "rxjs": "~6.5.2", "rxjs-compat": "^6.5.2", "sha256": "^0.2.0", @@ -67,7 +70,6 @@ "karma-coverage-istanbul-reporter": "~2.0.1", "karma-jasmine": "~2.0.1", "karma-jasmine-html-reporter": "^1.4.0", - "nodemon": "1.19.1", "protractor": "~5.4.0", "ts-node": "~7.0.0", "tslint": "~5.15.0", diff --git a/src/app/app.component.html b/src/app/app.component.html index ee88bd9b..93360b62 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -31,7 +31,7 @@
- +
settings diff --git a/src/app/app.component.ts b/src/app/app.component.ts index f9eba8cc..0fd89850 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -11,8 +11,8 @@ import { LoggerService } from './shared/services/logger.service'; import { RTLConfiguration, Settings, Node } from './shared/models/RTLconfig'; import { GetInfo } from './shared/models/lndModels'; -import * as RTLActions from './store/rtl.actions'; -import * as fromApp from './store/rtl.reducers'; +import * as RTLActions from './shared/store/rtl.actions'; +import * as fromRTLReducer from './shared/store/rtl.reducers'; @Component({ selector: 'rtl-app', @@ -22,25 +22,30 @@ import * as fromApp from './store/rtl.reducers'; export class AppComponent implements OnInit, AfterViewInit, OnDestroy { @ViewChild('sideNavigation', { static: false }) sideNavigation: any; @ViewChild('settingSidenav', { static: true }) settingSidenav: any; + public selNode: Node; public settings: Settings; public information: GetInfo = {}; - public flgLoading: Array = [true]; + public flgLoading: Array = [true]; // 0: Info public flgCopied = false; public appConfig: RTLConfiguration; public accessKey = ''; public smallScreen = false; - unSubs: Array> = [new Subject(), new Subject(), new Subject(), new Subject()]; + unsubs: Array> = [new Subject(), new Subject(), new Subject()]; - constructor(private logger: LoggerService, private store: Store, private actions$: Actions, private userIdle: UserIdleService, private router: Router, private activatedRoute: ActivatedRoute) {} + constructor(private logger: LoggerService, private store: Store, private actions$: Actions, + private userIdle: UserIdleService, private router: Router, private activatedRoute: ActivatedRoute) {} ngOnInit() { this.store.dispatch(new RTLActions.FetchRTLConfig()); this.accessKey = this.readAccessKey(); this.store.select('rtlRoot') - .pipe(takeUntil(this.unSubs[0])) + .pipe(takeUntil(this.unsubs[0])) .subscribe(rtlStore => { - this.settings = rtlStore.selNode.settings; + this.selNode = rtlStore.selNode; + this.settings = this.selNode.settings; this.appConfig = rtlStore.appConfig; + this.information = rtlStore.information; + this.flgLoading[0] = (undefined !== this.information.identity_pubkey) ? false : true; if (window.innerWidth <= 768) { this.settings.menu = 'Vertical'; this.settings.flgSidenavOpened = false; @@ -50,27 +55,44 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy { 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[3]), - filter(action => action.type === RTLActions.SET_RTL_CONFIG) - ).subscribe((actionPayload: RTLActions.SetRTLConfig) => { + takeUntil(this.unsubs[1]), + filter((action) => action.type === RTLActions.INIT_APP_DATA || action.type === RTLActions.SET_RTL_CONFIG) + ).subscribe((actionPayload: (RTLActions.InitAppData | RTLActions.SetRTLConfig)) => { if (actionPayload.type === RTLActions.SET_RTL_CONFIG) { if (!sessionStorage.getItem('token')) { if (+actionPayload.payload.sso.rtlSSO) { this.store.dispatch(new RTLActions.Signin(sha256(this.accessKey))); } else { - this.router.navigate([this.appConfig.sso.logoutRedirectLink], { relativeTo: this.activatedRoute }); + this.router.navigate([this.appConfig.sso.logoutRedirectLink]); } } if ( this.settings.menu === 'Horizontal' || this.settings.menuType === 'Compact' || this.settings.menuType === 'Mini') { - this.settingSidenav.toggle(); + this.settingSidenav.toggle(); // To dynamically update the width to 100% after side nav is closed setTimeout(() => { this.settingSidenav.toggle(); }, 100); } + } else if (actionPayload.type === RTLActions.INIT_APP_DATA) { + this.store.dispatch(new RTLActions.FetchInfo()); + } + }); + 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(); @@ -93,6 +115,17 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy { return url.substring(url.lastIndexOf('access-key=') + 11).trim(); } + 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'})); + this.store.dispatch(new RTLActions.FetchChannels({routeParam: 'pending'})); + this.store.dispatch(new RTLActions.FetchInvoices({num_max_invoices: 25, reversed: true})); + this.store.dispatch(new RTLActions.FetchPayments()); + } + ngAfterViewInit() { if (!this.settings.flgSidenavPinned) { this.sideNavigation.close(); @@ -130,7 +163,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy { } ngOnDestroy() { - this.unSubs.forEach(unsub => { + this.unsubs.forEach(unsub => { unsub.next(); unsub.complete(); }); diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 49d40661..c643e637 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,14 +1,14 @@ import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; +import { 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 { UserIdleModule } from 'angular-user-idle'; import { OverlayContainer } from '@angular/cdk/overlay'; - import { PerfectScrollbarModule } from 'ngx-perfect-scrollbar'; import { PERFECT_SCROLLBAR_CONFIG } from 'ngx-perfect-scrollbar'; import { PerfectScrollbarConfigInterface } from 'ngx-perfect-scrollbar'; @@ -17,46 +17,40 @@ 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 { SuperUserDashboardComponent } from './super-user-dashboard/super-user-dashboard.component'; + +import { environment } from '../environments/environment'; +import { RTLRootReducer } from './shared/store/rtl.reducers'; +import { RTLEffects } from './shared/store/rtl.effects'; import { CommonService } from './shared/services/common.service'; import { LoggerService, ConsoleLoggerService } from './shared/services/logger.service'; -import { AuthGuard, LNDUnlockedGuard } from './shared/services/auth.guard'; +import { AuthGuard } from './shared/services/auth.guard'; import { AuthInterceptor } from './shared/services/auth.interceptor'; -import * as fromApp from './store/rtl.reducers'; -import { RTLEffects } from './store/rtl.effects'; -import { LNDEffects } from './lnd/store/lnd.effects'; -import { CLEffects } from './c-lightning/store/cl.effects'; - @NgModule({ imports: [ BrowserModule, BrowserAnimationsModule, - HttpClientModule, - PerfectScrollbarModule, SharedModule, + PerfectScrollbarModule, routing, UserIdleModule.forRoot({idle: 60 * 60, timeout: 1, ping: null}), - StoreModule.forRoot(fromApp.appReducer), - EffectsModule.forRoot([RTLEffects, LNDEffects, CLEffects]), - !environment.production ? StoreDevtoolsModule.instrument() : [] + StoreModule.forRoot({rtlRoot: RTLRootReducer}), + EffectsModule.forRoot([RTLEffects]), + !environment.production ? StoreDevtoolsModule.instrument() : [] ], declarations: [ - AppComponent, - SuperUserDashboardComponent + AppComponent ], 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, CommonService + { provide: PERFECT_SCROLLBAR_CONFIG, useValue: DEFAULT_PERFECT_SCROLLBAR_CONFIG }, + { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }, + AuthGuard, CommonService ], bootstrap: [AppComponent] }) diff --git a/src/app/app.routing.ts b/src/app/app.routing.ts index 546f9ad8..d61149a3 100644 --- a/src/app/app.routing.ts +++ b/src/app/app.routing.ts @@ -1,20 +1,16 @@ import { Routes, RouterModule } from '@angular/router'; import { ModuleWithProviders } from '@angular/core'; +import { NotFoundComponent } from './shared/components/not-found/not-found.component'; import { ServerConfigComponent } from './shared/components/server-config/server-config.component'; import { HelpComponent } from './shared/components/help/help.component'; import { SigninComponent } from './shared/components/signin/signin.component'; import { SsoFailedComponent } from './shared/components/sso-failed/sso-failed.component'; -import { NotFoundComponent } from './shared/components/not-found/not-found.component'; import { AuthGuard } from './shared/services/auth.guard'; -import { SuperUserDashboardComponent } from './super-user-dashboard/super-user-dashboard.component'; - export const routes: Routes = [ - { path: '', redirectTo: '/dashboard', pathMatch: 'full' }, - { path: 'dashboard', component: SuperUserDashboardComponent }, - { path: 'lnd', loadChildren: () => import('./lnd/lnd.module').then(childModule => childModule.LndModule)}, - { path: 'cl', loadChildren: () => import('./c-lightning/cl.module').then(childModule => childModule.ClModule)}, + { path: 'lnd', loadChildren: () => import('./lnd/lnd.module').then(childModule => childModule.LNDModule), canActivate: [AuthGuard] }, + { path: 'cl', loadChildren: () => import('./clightning/cl.module').then(childModule => childModule.CLModule), canActivate: [AuthGuard] }, { path: 'sconfig', component: ServerConfigComponent, canActivate: [AuthGuard] }, { path: 'login', component: SigninComponent }, { path: 'help', component: HelpComponent }, @@ -22,4 +18,4 @@ export const routes: Routes = [ { path: '**', component: NotFoundComponent } ]; -export const routing: ModuleWithProviders = RouterModule.forRoot(routes, { enableTracing: true }); +export const routing: ModuleWithProviders = RouterModule.forRoot(routes); diff --git a/src/app/c-lightning/cl-root.component.scss b/src/app/c-lightning/cl-root.component.scss deleted file mode 100644 index 3c613452..00000000 --- a/src/app/c-lightning/cl-root.component.scss +++ /dev/null @@ -1,4 +0,0 @@ -.inline-spinner { - display: inline-flex !important; - top: 0px !important; -} diff --git a/src/app/c-lightning/cl-root.component.ts b/src/app/c-lightning/cl-root.component.ts deleted file mode 100644 index 74711e7b..00000000 --- a/src/app/c-lightning/cl-root.component.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Component, OnInit, OnDestroy } from '@angular/core'; -import { Router, ActivatedRoute } from '@angular/router'; -import { Subject } from 'rxjs'; -import { takeUntil, filter } from 'rxjs/operators'; -import { Store } from '@ngrx/store'; -import { Actions } from '@ngrx/effects'; - -import * as CLActions from './store/cl.actions'; -import * as RTLActions from '../store/rtl.actions'; -import * as fromApp from '../store/rtl.reducers'; - -@Component({ - selector: 'rtl-cl-root-app', - templateUrl: './cl-root.component.html', - styleUrls: ['./cl-root.component.scss'] -}) -export class ClRootComponent implements OnInit, OnDestroy { - unsubs: Array> = [new Subject(), new Subject()]; - - constructor(private store: Store, private actions$: Actions, private router: Router, private activatedRoute: ActivatedRoute) {} - - ngOnInit() { - console.warn('CL ROOT'); - // this.store.dispatch(new CLActions.FetchCLInfo()); - this.router.navigate(['./home'], {relativeTo: this.activatedRoute}); - // this.store.select('cl') - // .pipe(takeUntil(this.unsubs[0])) - // .subscribe(clStore => { - // console.warn(clStore); - // if (undefined !== clStore.information.identity_pubkey) { - // this.initializeRemainingData(); - // } - // }); - // this.actions$ - // .pipe( - // takeUntil(this.unSubs[3]), - // filter(action => action.type === RTLActions.INIT_APP_DATA || action.type === LNDActions.SET_INFO || action.type === CLActions.SET_CL_INFO) - // ).subscribe((actionPayload: RTLActions.InitAppData | LNDActions.SetInfo | CLActions.SetCLInfo) => { - // // if (actionPayload.type === RTLActions.INIT_APP_DATA) { - // if(this.information.identity_pubkey) { - // this.initializeRemainingData(); - // } - // }); - - } - - initializeRemainingData() { - console.warn('SOMETHING IS WRONG HERE'); - // this.store.dispatch(new CLActions.FetchCLFees()); - - // this.store.dispatch(new CLActions.FetchPeers()); - // this.store.dispatch(new CLActions.FetchBalance('channels')); - // this.store.dispatch(new CLActions.FetchFees()); - // this.store.dispatch(new CLActions.FetchNetwork()); - // this.store.dispatch(new CLActions.FetchChannels({routeParam: 'all'})); - // this.store.dispatch(new CLActions.FetchChannels({routeParam: 'pending'})); - // this.store.dispatch(new CLActions.FetchInvoices({num_max_invoices: 25, reversed: true})); - // this.store.dispatch(new CLActions.FetchPayments()); - } - - ngOnDestroy() { - this.unsubs.forEach(unsub => { - unsub.next(); - unsub.complete(); - }); - } -} diff --git a/src/app/c-lightning/cl.module.ts b/src/app/c-lightning/cl.module.ts deleted file mode 100644 index 5b572660..00000000 --- a/src/app/c-lightning/cl.module.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { NgxChartsModule } from '@swimlane/ngx-charts'; -import { StoreDevtoolsModule } from '@ngrx/store-devtools'; - -import { environment } from '../../environments/environment'; -import { SharedModule } from '../shared/shared.module'; - -import { clRouting } from './cl.routing'; -import { ClRootComponent } from './cl-root.component'; -import { HomeComponent } from './home/home.component'; - -@NgModule({ - imports: [ - CommonModule, - SharedModule, - clRouting, - NgxChartsModule, - !environment.production ? StoreDevtoolsModule.instrument() : [] - ], - declarations: [ - ClRootComponent, - HomeComponent - ], - providers: [], - bootstrap: [ClRootComponent] -}) -export class ClModule {} diff --git a/src/app/c-lightning/cl.routing.ts b/src/app/c-lightning/cl.routing.ts deleted file mode 100644 index bc1b6dd6..00000000 --- a/src/app/c-lightning/cl.routing.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Routes, RouterModule } from '@angular/router'; -import { ModuleWithProviders } from '@angular/core'; - -import { AuthGuard } from '../shared/services/auth.guard'; -import { NotFoundComponent } from '../shared/components/not-found/not-found.component'; - -import { ClRootComponent } from './cl-root.component'; -import { HomeComponent } from './home/home.component'; - -export const clRoutes: Routes = [ - { path: '', component: ClRootComponent, - children: [ - { path: 'home', component: HomeComponent, canActivate: [AuthGuard] }, - { path: '**', component: NotFoundComponent } - ] - } -]; - -export const clRouting: ModuleWithProviders = RouterModule.forChild(clRoutes); diff --git a/src/app/c-lightning/home/home.component.html b/src/app/c-lightning/home/home.component.html deleted file mode 100644 index 85eaba5c..00000000 --- a/src/app/c-lightning/home/home.component.html +++ /dev/null @@ -1,2 +0,0 @@ -

CL Home

-

{{information | json}}

diff --git a/src/app/c-lightning/home/home.component.ts b/src/app/c-lightning/home/home.component.ts deleted file mode 100644 index 50b8f272..00000000 --- a/src/app/c-lightning/home/home.component.ts +++ /dev/null @@ -1,56 +0,0 @@ -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 } from '../../shared/models/clModels'; - -import * as fromApp from '../../store/rtl.reducers'; - -@Component({ - selector: 'rtl-home', - templateUrl: './home.component.html', - styleUrls: ['./home.component.scss'] -}) -export class HomeComponent implements OnInit, OnDestroy { - public information: GetInfo = {}; - private unsubs: Array> = [new Subject(), new Subject()]; - - constructor(private logger: LoggerService, private store: Store) {} - - ngOnInit() { - console.warn('CL HOME'); - this.store.select('cl') - .pipe(takeUntil(this.unsubs[1])) - .subscribe(clStore => { - this.information = clStore.information; - if (undefined !== this.information.identity_pubkey) { - this.initializeRemainingData(); - } - this.logger.info(clStore); - }); - } - - initializeRemainingData() { - console.warn('SOMETHING IS WRONG HERE'); - // this.store.dispatch(new CLActions.FetchCLFees()); - - // this.store.dispatch(new CLActions.FetchPeers()); - // this.store.dispatch(new CLActions.FetchBalance('channels')); - // this.store.dispatch(new CLActions.FetchFees()); - // this.store.dispatch(new CLActions.FetchNetwork()); - // this.store.dispatch(new CLActions.FetchChannels({routeParam: 'all'})); - // this.store.dispatch(new CLActions.FetchChannels({routeParam: 'pending'})); - // this.store.dispatch(new CLActions.FetchInvoices({num_max_invoices: 25, reversed: true})); - // this.store.dispatch(new CLActions.FetchPayments()); - } - - ngOnDestroy() { - this.unsubs.forEach(completeSub => { - completeSub.next(); - completeSub.complete(); - }); - } - -} diff --git a/src/app/c-lightning/store/cl.actions.ts b/src/app/c-lightning/store/cl.actions.ts deleted file mode 100644 index 4c94d601..00000000 --- a/src/app/c-lightning/store/cl.actions.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Action } from '@ngrx/store'; -import { GetInfo } from '../../shared/models/clModels'; - -export const RESET_CL_STORE = 'RESET_CL_STORE'; -export const FETCH_CL_INFO = 'FETCH_CL_INFO'; -export const SET_CL_INFO = 'SET_CL_INFO'; -export const FETCH_CL_FEES = 'FETCH_CL_FEES'; -export const SET_CL_FEES = 'SET_CL_FEES'; - -export class ResetCLStore implements Action { - readonly type = RESET_CL_STORE; -} - -export class FetchCLInfo implements Action { - readonly type = FETCH_CL_INFO; -} - -export class SetCLInfo implements Action { - readonly type = SET_CL_INFO; - constructor(public payload: GetInfo) {} -} - -export class FetchCLFees implements Action { - readonly type = FETCH_CL_FEES; -} - -export class SetCLFees implements Action { - readonly type = SET_CL_FEES; - constructor(public payload: {}) {} -} - -export type CLActions = -ResetCLStore | FetchCLInfo | SetCLInfo | FetchCLFees | SetCLFees; diff --git a/src/app/c-lightning/store/cl.effects.ts b/src/app/c-lightning/store/cl.effects.ts deleted file mode 100644 index 55013c75..00000000 --- a/src/app/c-lightning/store/cl.effects.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { Injectable, OnDestroy } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; -import { Router, ActivatedRoute } from '@angular/router'; -import { Store } from '@ngrx/store'; -import { Actions, Effect, ofType } from '@ngrx/effects'; -import { of, Subject } from 'rxjs'; -import { map, mergeMap, catchError, withLatestFrom } from 'rxjs/operators'; - -import { MatDialog } from '@angular/material'; - -import { environment } from '../../../environments/environment'; -import { LoggerService } from '../../shared/services/logger.service'; -import { GetInfo } from '../../shared/models/clModels'; - -import * as RTLActions from '../../store/rtl.actions'; -import * as CLActions from './cl.actions'; -import * as fromApp from '../../store/rtl.reducers'; - -@Injectable() -export class CLEffects 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, - private activatedRoute: ActivatedRoute) { } - - @Effect() - infoFetch = this.actions$.pipe( - ofType(CLActions.FETCH_CL_INFO), - withLatestFrom(this.store.select('rtlRoot')), - mergeMap(([action, store]: [CLActions.FetchCLInfo, fromApp.RootState]) => { - 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('clUnlocked'); - return { - type: CLActions.SET_CL_INFO, - payload: {} - }; - } else { - sessionStorage.setItem('clUnlocked', 'true'); - return { - type: CLActions.SET_CL_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.appConfig.sso.rtlSSO) { - this.router.navigate(['../ssoerror'], {relativeTo: this.activatedRoute}); - } else { - if (err.status === 401) { - this.logger.info('Redirecting to Signin'); - this.router.navigate([store.appConfig.sso.logoutRedirectLink], {relativeTo: this.activatedRoute}); - return of(); - } - } - }) - ); - } - )); - - @Effect() - fetchFees = this.actions$.pipe( - ofType(CLActions.FETCH_CL_FEES), - mergeMap((action: CLActions.FetchCLFees) => { - this.store.dispatch(new RTLActions.ClearEffectError('FetchCLFees')); - return this.httpClient.get(environment.FEES_API); - }), - map((fees) => { - this.logger.info(fees); - return { - type: CLActions.SET_CL_FEES, - payload: (undefined !== fees) ? fees : {} - }; - }), - catchError((err: any) => { - this.logger.error(err); - this.store.dispatch(new RTLActions.EffectError({ action: 'FetchCLFees', code: err.status, message: err.error.error })); - return of(); - } - )); - - ngOnDestroy() { - this.unSubs.forEach(completeSub => { - completeSub.next(); - completeSub.complete(); - }); - } - -} diff --git a/src/app/c-lightning/store/cl.reducers.ts b/src/app/c-lightning/store/cl.reducers.ts deleted file mode 100644 index fe377d16..00000000 --- a/src/app/c-lightning/store/cl.reducers.ts +++ /dev/null @@ -1,49 +0,0 @@ -import * as CLActions from './cl.actions'; -import { GetInfo, GetInfoChain } from '../../shared/models/clModels'; - -export interface CLState { - information: GetInfo; - fees: {}; -} - -export const CLInitialState: CLState = { - information: {}, - fees: {} -}; - -export function CLReducer(state = CLInitialState, action: CLActions.CLActions) { - switch (action.type) { - case CLActions.RESET_CL_STORE: - return { - ...CLInitialState - }; - case CLActions.SET_CL_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 CLActions.SET_CL_FEES: - return { - ...state, - fees: action.payload - }; - default: - return state; - } - -} diff --git a/src/app/c-lightning/cl-root.component.html b/src/app/clightning/cl-root.component.html similarity index 100% rename from src/app/c-lightning/cl-root.component.html rename to src/app/clightning/cl-root.component.html diff --git a/src/app/c-lightning/home/home.component.scss b/src/app/clightning/cl-root.component.scss similarity index 100% rename from src/app/c-lightning/home/home.component.scss rename to src/app/clightning/cl-root.component.scss diff --git a/src/app/clightning/cl-root.component.ts b/src/app/clightning/cl-root.component.ts new file mode 100644 index 00000000..ea470bb4 --- /dev/null +++ b/src/app/clightning/cl-root.component.ts @@ -0,0 +1,166 @@ +import { Component, OnInit } from '@angular/core'; +import { Router, ActivatedRoute } from '@angular/router'; + +@Component({ + selector: 'rtl-cl-root', + templateUrl: './cl-root.component.html', + styleUrls: ['./cl-root.component.scss'] +}) +export class CLRootComponent implements OnInit { + + constructor(private router: Router, private activatedRoute: ActivatedRoute) {} + + ngOnInit() { + console.warn('CL ROOT'); + this.router.navigate(['./home'], {relativeTo: this.activatedRoute}); + } + + // @ViewChild('sideNavigation', { static: false }) sideNavigation: any; + // @ViewChild('settingSidenav', { static: true }) settingSidenav: any; + // public selNode: Node; + // public settings: Settings; + // public information: GetInfo = {}; + // public flgLoading: Array = [true]; // 0: Info + // public flgCopied = false; + // public appConfig: RTLConfiguration; + // 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.FetchRTLConfig()); + // this.accessKey = this.readAccessKey(); + // this.store.select('rtlRoot') + // .pipe(takeUntil(this.unsubs[0])) + // .subscribe(rtlStore => { + // this.selNode = rtlStore.selNode; + // this.settings = this.selNode.settings; + // this.appConfig = rtlStore.appConfig; + // this.information = rtlStore.information; + // 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_RTL_CONFIG) + // ).subscribe((actionPayload: (RTLActions.InitAppData | RTLActions.SetRTLConfig)) => { + // if (actionPayload.type === RTLActions.SET_RTL_CONFIG) { + // if (!sessionStorage.getItem('token')) { + // if (+actionPayload.payload.sso.rtlSSO) { + // this.store.dispatch(new RTLActions.Signin(sha256(this.accessKey))); + // } else { + // this.router.navigate([this.appConfig.sso.logoutRedirectLink]); + // } + // } + // if ( + // this.settings.menu === 'Horizontal' || + // this.settings.menuType === 'Compact' || + // this.settings.menuType === 'Mini') { + // this.settingSidenav.toggle(); // To dynamically update the width to 100% after side nav is closed + // setTimeout(() => { this.settingSidenav.toggle(); }, 100); + // } + // } else if (actionPayload.type === RTLActions.INIT_APP_DATA) { + // this.store.dispatch(new RTLActions.FetchInfo()); + // } + // }); + // 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('access-key=') + 11).trim(); + // } + + // 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'})); + // this.store.dispatch(new RTLActions.FetchChannels({routeParam: 'pending'})); + // this.store.dispatch(new RTLActions.FetchInvoices({num_max_invoices: 25, reversed: true})); + // 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/clightning/cl.module.ts b/src/app/clightning/cl.module.ts new file mode 100644 index 00000000..7e4c69c3 --- /dev/null +++ b/src/app/clightning/cl.module.ts @@ -0,0 +1,31 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { CLRouting } from './cl.routing'; +import { SharedModule } from '../shared/shared.module'; + +import { CLRootComponent } from './cl-root.component'; +import { CLHomeComponent } from './home/home.component'; + +import { CommonService } from '../shared/services/common.service'; +import { LoggerService, ConsoleLoggerService } from '../shared/services/logger.service'; +import { CLUnlockedGuard } from '../shared/services/auth.guard'; + +@NgModule({ + imports: [ + CommonModule, + SharedModule, + CLRouting + ], + declarations: [ + CLRootComponent, + CLHomeComponent + ], + providers: [ + { provide: LoggerService, useClass: ConsoleLoggerService }, + CLUnlockedGuard, + CommonService + ], + bootstrap: [CLRootComponent] +}) +export class CLModule {} diff --git a/src/app/clightning/cl.routing.ts b/src/app/clightning/cl.routing.ts new file mode 100644 index 00000000..2f444fc7 --- /dev/null +++ b/src/app/clightning/cl.routing.ts @@ -0,0 +1,18 @@ +import { Routes, RouterModule } from '@angular/router'; +import { ModuleWithProviders } from '@angular/core'; + +import { CLRootComponent } from './cl-root.component'; +import { CLHomeComponent } from './home/home.component'; + +import { CLUnlockedGuard } from '../shared/services/auth.guard'; +import { NotFoundComponent } from '../shared/components/not-found/not-found.component'; + +export const ClRoutes: Routes = [ + { path: '', component: CLRootComponent, + children: [ + { path: 'home', component: CLHomeComponent, canActivate: [CLUnlockedGuard] }, + { path: '**', component: NotFoundComponent } + ]} +]; + +export const CLRouting: ModuleWithProviders = RouterModule.forChild(ClRoutes); diff --git a/src/app/clightning/home/home.component.html b/src/app/clightning/home/home.component.html new file mode 100644 index 00000000..9d66881f --- /dev/null +++ b/src/app/clightning/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/clightning/home/home.component.scss b/src/app/clightning/home/home.component.scss new file mode 100644 index 00000000..ca8052d8 --- /dev/null +++ b/src/app/clightning/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/c-lightning/home/home.component.spec.ts b/src/app/clightning/home/home.component.spec.ts similarity index 100% rename from src/app/c-lightning/home/home.component.spec.ts rename to src/app/clightning/home/home.component.spec.ts diff --git a/src/app/clightning/home/home.component.ts b/src/app/clightning/home/home.component.ts new file mode 100644 index 00000000..ce40292a --- /dev/null +++ b/src/app/clightning/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 { Node } from '../../shared/models/RTLconfig'; + +import * as fromRTLReducer from '../../shared/store/rtl.reducers'; + +@Component({ + selector: 'rtl-cl-home', + templateUrl: './home.component.html', + styleUrls: ['./home.component.scss'] +}) +export class CLHomeComponent implements OnInit, OnDestroy { + public selNode: Node; + 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.selNode = rtlStore.selNode; + 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 !== null) ? rtlStore.peers.length : 0; + + this.logger.info(rtlStore); + }); + } + + ngOnDestroy() { + this.unsub.forEach(completeSub => { + completeSub.next(); + completeSub.complete(); + }); + } + +} diff --git a/src/app/lnd/channels/channel-backup/channel-backup.component.ts b/src/app/lnd/channels/channel-backup/channel-backup.component.ts index 7a0ff795..529e2d10 100644 --- a/src/app/lnd/channels/channel-backup/channel-backup.component.ts +++ b/src/app/lnd/channels/channel-backup/channel-backup.component.ts @@ -1,4 +1,5 @@ import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core'; +import { Router } from '@angular/router'; import { Subject } from 'rxjs'; import { takeUntil, filter } from 'rxjs/operators'; @@ -10,9 +11,9 @@ import { Node } from '../../../shared/models/RTLconfig'; import { Channel } from '../../../shared/models/lndModels'; import { LoggerService } from '../../../shared/services/logger.service'; -import * as LNDActions from '../../store/lnd.actions'; -import * as RTLActions from '../../../store/rtl.actions'; -import * as fromApp from '../../../store/rtl.reducers'; +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-backup', @@ -25,21 +26,27 @@ export class ChannelBackupComponent implements OnInit, OnDestroy { public displayedColumns = ['chan_id', 'backup', 'verify']; public selChannel: Channel; public channels: any; - public flgLoading: Array = [true]; + public flgLoading: Array = [true]; // 0: channels public flgSticky = false; - private unSubs: Array> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject()]; + private unSubs: Array> = [new Subject(), new Subject(), new Subject(), new Subject()]; - constructor(private logger: LoggerService, private store: Store, private actions$: Actions) {} + constructor(private logger: LoggerService, private store: Store, private rtlEffects: RTLEffects, private actions$: Actions, private router: Router) {} ngOnInit() { - this.store.select('lnd') - .pipe(takeUntil(this.unSubs[4])) - .subscribe(lndStore => { + this.store.select('rtlRoot') + .pipe(takeUntil(this.unSubs[0])) + .subscribe((rtlStore: fromRTLReducer.State) => { + this.selNode = rtlStore.selNode; + rtlStore.effectErrors.forEach(effectsErr => { + if (effectsErr.action === 'Fetchchannels') { + this.flgLoading[0] = 'error'; + } + }); this.channels = new MatTableDataSource([]); this.channels.data = []; - if (undefined !== lndStore.allChannels) { - this.channels = new MatTableDataSource([...lndStore.allChannels]); - this.channels.data = lndStore.allChannels; + if (undefined !== rtlStore.allChannels) { + this.channels = new MatTableDataSource([...rtlStore.allChannels]); + this.channels.data = rtlStore.allChannels; } this.channels.sort = this.sort; this.channels.filterPredicate = (channel: Channel, fltr: string) => { @@ -54,36 +61,25 @@ export class ChannelBackupComponent implements OnInit, OnDestroy { if (this.flgLoading[0] !== 'error') { this.flgLoading[0] = false; } - this.logger.info(lndStore); - }); - this.store.select('rtlRoot') - .pipe(takeUntil(this.unSubs[0])) - .subscribe((rtlStore: fromApp.RootState) => { - this.selNode = rtlStore.selNode; - rtlStore.effectErrors.forEach(effectsErr => { - if (effectsErr.action === 'Fetchchannels') { - this.flgLoading[0] = 'error'; - } - }); this.logger.info(rtlStore); }); this.actions$ .pipe( takeUntil(this.unSubs[1]), - filter((action) => action.type === LNDActions.SET_CHANNELS) - ).subscribe((setchannels: LNDActions.SetChannels) => { + filter((action) => action.type === RTLActions.SET_CHANNELS) + ).subscribe((setchannels: RTLActions.SetChannels) => { this.selChannel = undefined; }); } onBackupChannels(selChannel: Channel) { this.store.dispatch(new RTLActions.OpenSpinner('Backup Channels...')); - this.store.dispatch(new LNDActions.BackupChannels({channelPoint: (selChannel.channel_point) ? selChannel.channel_point : 'ALL', showMessage: ''})); + this.store.dispatch(new RTLActions.BackupChannels({channelPoint: (selChannel.channel_point) ? selChannel.channel_point : 'ALL', showMessage: ''})); } onVerifyChannels(selChannel: Channel) { this.store.dispatch(new RTLActions.OpenSpinner('Verify Channels...')); - this.store.dispatch(new LNDActions.VerifyChannels({channelPoint: (selChannel.channel_point) ? selChannel.channel_point : 'ALL'})); + this.store.dispatch(new RTLActions.VerifyChannels({channelPoint: (selChannel.channel_point) ? selChannel.channel_point : 'ALL'})); } onChannelClick(selRow: Channel, event: any) { diff --git a/src/app/lnd/channels/channel-closed/channel-closed.component.ts b/src/app/lnd/channels/channel-closed/channel-closed.component.ts index b1fb26e1..898bc50a 100644 --- a/src/app/lnd/channels/channel-closed/channel-closed.component.ts +++ b/src/app/lnd/channels/channel-closed/channel-closed.component.ts @@ -8,9 +8,9 @@ import { MatTableDataSource, MatSort } from '@angular/material'; import { ClosedChannel } from '../../../shared/models/lndModels'; import { LoggerService } from '../../../shared/services/logger.service'; -import * as LNDActions from '../../store/lnd.actions'; -import * as RTLActions from '../../../store/rtl.actions'; -import * as fromApp from '../../../store/rtl.reducers'; +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', @@ -24,9 +24,9 @@ export class ChannelClosedComponent implements OnInit, OnDestroy { public flgLoading: Array = [true]; public selectedFilter = ''; public flgSticky = false; - private unsubs: Array> = [new Subject(), new Subject(), new Subject(), new Subject()]; + private unsub: Array> = [new Subject(), new Subject(), new Subject()]; - constructor(private logger: LoggerService, private store: Store, private actions$: Actions) { + constructor(private logger: LoggerService, private store: Store, private rtlEffects: RTLEffects, private actions$: Actions) { switch (true) { case (window.innerWidth <= 415): this.displayedColumns = ['close_type', 'chan_id', 'settled_balance']; @@ -51,29 +51,24 @@ export class ChannelClosedComponent implements OnInit, OnDestroy { } ngOnInit() { - this.store.dispatch(new LNDActions.FetchChannels({routeParam: 'closed'})); - this.actions$.pipe(takeUntil(this.unsubs[2]), filter((action) => action.type === RTLActions.RESET_STORE)).subscribe((resetStore: RTLActions.ResetStore) => { - this.store.dispatch(new LNDActions.FetchChannels({routeParam: 'closed'})); - }); - this.store.select('lnd') - .pipe(takeUntil(this.unsubs[3])) - .subscribe(lndStore => { - if (undefined !== lndStore.closedChannels) { - this.loadClosedChannelsTable(lndStore.closedChannels); - } - if (this.flgLoading[0] !== 'error') { - this.flgLoading[0] = (undefined !== lndStore.closedChannels) ? false : true; - } - this.logger.info(lndStore); + this.store.dispatch(new RTLActions.FetchChannels({routeParam: 'closed'})); + this.actions$.pipe(takeUntil(this.unsub[2]), filter((action) => action.type === RTLActions.RESET_STORE)).subscribe((resetStore: RTLActions.ResetStore) => { + this.store.dispatch(new RTLActions.FetchChannels({routeParam: 'closed'})); }); this.store.select('rtlRoot') - .pipe(takeUntil(this.unsubs[0])) - .subscribe((rtlStore: fromApp.RootState) => { + .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) { + this.loadClosedChannelsTable(rtlStore.closedChannels); + } + if (this.flgLoading[0] !== 'error') { + this.flgLoading[0] = (undefined !== rtlStore.closedChannels) ? false : true; + } this.logger.info(rtlStore); }); @@ -107,7 +102,7 @@ export class ChannelClosedComponent implements OnInit, OnDestroy { } ngOnDestroy() { - this.unsubs.forEach(completeSub => { + this.unsub.forEach(completeSub => { completeSub.next(); completeSub.complete(); }); diff --git a/src/app/lnd/channels/channel-manage/channel-manage.component.ts b/src/app/lnd/channels/channel-manage/channel-manage.component.ts index 4e747f50..9bb8a7a8 100644 --- a/src/app/lnd/channels/channel-manage/channel-manage.component.ts +++ b/src/app/lnd/channels/channel-manage/channel-manage.component.ts @@ -1,19 +1,18 @@ import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; +import { Router, NavigationStart, ActivatedRoute } from '@angular/router'; -import { Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; +import { Subject, Observable } from 'rxjs'; +import { takeUntil, filter, map, subscribeOn } 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 { LNDEffects } from '../../store/lnd.effects'; -import { RTLEffects } from '../../../store/rtl.effects'; -import * as LNDActions from '../../store/lnd.actions'; -import * as RTLActions from '../../../store/rtl.actions'; -import * as fromApp from '../../../store/rtl.reducers'; +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', @@ -41,10 +40,9 @@ export class ChannelManageComponent implements OnInit, OnDestroy { public moreOptions = false; public flgSticky = false; public redirectedWithPeer = false; - private unsubs: Array> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()]; + private unsub: Array> = [new Subject(), new Subject(), new Subject(), new Subject()]; - constructor(private logger: LoggerService, private store: Store, private rtlEffects: RTLEffects, - private lndEffects: LNDEffects, private activatedRoute: ActivatedRoute) { + constructor(private logger: LoggerService, private store: Store, private rtlEffects: RTLEffects, private activatedRoute: ActivatedRoute) { switch (true) { case (window.innerWidth <= 415): this.displayedColumns = ['close', 'update', 'active', 'chan_id', 'remote_alias']; @@ -69,35 +67,29 @@ export class ChannelManageComponent implements OnInit, OnDestroy { } ngOnInit() { - this.store.select('lnd') - .pipe(takeUntil(this.unsubs[5])) - .subscribe(lndStore => { - this.information = lndStore.information; - this.peers = lndStore.peers; + 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 = lndStore ? +lndStore.blockchainBalance.total_balance : -1; - if (undefined !== lndStore.allChannels) { - this.loadChannelsTable(lndStore.allChannels); + this.totalBalance = +rtlStore.blockchainBalance.total_balance; + if (undefined !== rtlStore.allChannels) { + this.loadChannelsTable(rtlStore.allChannels); } if (this.flgLoading[0] !== 'error') { - this.flgLoading[0] = (undefined !== lndStore.allChannels) ? false : true; + this.flgLoading[0] = (undefined !== rtlStore.allChannels) ? false : true; } - this.logger.info(lndStore); - }); - - this.store.select('rtlRoot') - .pipe(takeUntil(this.unsubs[0])) - .subscribe((rtlStore: fromApp.RootState) => { - rtlStore.effectErrors.forEach(effectsErr => { - if (effectsErr.action === 'FetchChannels/all') { - this.flgLoading[0] = 'error'; - } - }); this.logger.info(rtlStore); }); this.activatedRoute.paramMap.subscribe(() => { @@ -114,7 +106,7 @@ export class ChannelManageComponent implements OnInit, OnDestroy { } else if (this.selTransType === '2') { transTypeValue = this.transTypeValue.fees; } - this.store.dispatch(new LNDActions.SaveNewChannel({ + this.store.dispatch(new RTLActions.SaveNewChannel({ selectedPeerPubkey: this.selectedPeer, fundingAmount: this.fundingAmount, private: this.isPrivate, transType: this.selTransType, transTypeValue: transTypeValue, spendUnconfirmed: this.spendUnconfirmed })); @@ -132,22 +124,22 @@ export class ChannelManageComponent implements OnInit, OnDestroy { ] }})); this.rtlEffects.closeConfirm - .pipe(takeUntil(this.unsubs[2])) + .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 LNDActions.UpdateChannels({baseFeeMsat: base_fee, feeRate: fee_rate, timeLockDelta: time_lock_delta, chanPoint: 'all'})); + 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 LNDActions.ChannelLookup(channelToUpdate.chan_id.toString())); - this.lndEffects.setLookup - .pipe(takeUntil(this.unsubs[3])) + 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) { @@ -170,14 +162,14 @@ export class ChannelManageComponent implements OnInit, OnDestroy { }})); }); this.rtlEffects.closeConfirm - .pipe(takeUntil(this.unsubs[4])) + .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 LNDActions.UpdateChannels({baseFeeMsat: base_fee, feeRate: fee_rate, timeLockDelta: time_lock_delta, chanPoint: channelToUpdate.channel_point})); + this.store.dispatch(new RTLActions.UpdateChannels({baseFeeMsat: base_fee, feeRate: fee_rate, timeLockDelta: time_lock_delta, chanPoint: channelToUpdate.channel_point})); } }); } @@ -189,11 +181,11 @@ export class ChannelManageComponent implements OnInit, OnDestroy { width: '70%', data: { type: 'CONFIRM', titleMessage: 'Closing channel: ' + channelToClose.chan_id, noBtnText: 'Cancel', yesBtnText: 'Close Channel' }})); this.rtlEffects.closeConfirm - .pipe(takeUntil(this.unsubs[1])) + .pipe(takeUntil(this.unsub[1])) .subscribe(confirmRes => { if (confirmRes) { this.store.dispatch(new RTLActions.OpenSpinner('Closing Channel...')); - this.store.dispatch(new LNDActions.CloseChannel({channelPoint: channelToClose.channel_point, forcibly: !channelToClose.active})); + this.store.dispatch(new RTLActions.CloseChannel({channelPoint: channelToClose.channel_point, forcibly: !channelToClose.active})); } }); } @@ -263,7 +255,7 @@ export class ChannelManageComponent implements OnInit, OnDestroy { } ngOnDestroy() { - this.unsubs.forEach(completeSub => { + this.unsub.forEach(completeSub => { completeSub.next(); completeSub.complete(); }); diff --git a/src/app/lnd/channels/channel-pending/channel-pending.component.ts b/src/app/lnd/channels/channel-pending/channel-pending.component.ts index 02515803..7df35b98 100644 --- a/src/app/lnd/channels/channel-pending/channel-pending.component.ts +++ b/src/app/lnd/channels/channel-pending/channel-pending.component.ts @@ -8,8 +8,9 @@ import { Channel, GetInfo, PendingChannels } from '../../../shared/models/lndMod import { Node } from '../../../shared/models/RTLconfig'; import { LoggerService } from '../../../shared/services/logger.service'; -import * as RTLActions from '../../../store/rtl.actions'; -import * as fromApp from '../../../store/rtl.reducers'; +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', @@ -47,9 +48,9 @@ export class ChannelPendingComponent implements OnInit, OnDestroy { public pendingWaitClosingChannelsLength = 0; public pendingWaitClosingChannels: any; public flgLoading: Array = [true]; - private unsubs: Array> = [new Subject(), new Subject(), new Subject()]; + private unsub: Array> = [new Subject(), new Subject()]; - constructor(private logger: LoggerService, private store: Store) { + 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']; @@ -95,11 +96,18 @@ export class ChannelPendingComponent implements OnInit, OnDestroy { } ngOnInit() { - this.store.select('lnd') - .pipe(takeUntil(this.unsubs[2])) - .subscribe(lndStore => { - this.information = lndStore.information; - this.pendingChannels = lndStore.pendingChannels; + 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.selNode = rtlStore.selNode; + 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) { @@ -118,19 +126,6 @@ export class ChannelPendingComponent implements OnInit, OnDestroy { if (this.flgLoading[0] !== 'error') { this.flgLoading[0] = (undefined !== this.information.identity_pubkey) ? false : true; } - this.logger.info(lndStore); - }); - - this.store.select('rtlRoot') - .pipe(takeUntil(this.unsubs[0])) - .subscribe((rtlStore: fromApp.RootState) => { - rtlStore.effectErrors.forEach(effectsErr => { - if (effectsErr.action === 'FetchChannels/pending') { - this.flgLoading[0] = 'error'; - } - }); - - this.selNode = rtlStore.selNode; this.logger.info(rtlStore); }); @@ -237,7 +232,7 @@ export class ChannelPendingComponent implements OnInit, OnDestroy { } ngOnDestroy() { - this.unsubs.forEach(completeSub => { + this.unsub.forEach(completeSub => { completeSub.next(); completeSub.complete(); }); diff --git a/src/app/lnd/home/home.component.ts b/src/app/lnd/home/home.component.ts index 86ce689d..72c93602 100644 --- a/src/app/lnd/home/home.component.ts +++ b/src/app/lnd/home/home.component.ts @@ -7,7 +7,7 @@ import { LoggerService } from '../../shared/services/logger.service'; import { GetInfo, NetworkInfo, Fees, Peer } from '../../shared/models/lndModels'; import { Node } from '../../shared/models/RTLconfig'; -import * as fromApp from '../../store/rtl.reducers'; +import * as fromRTLReducer from '../../shared/store/rtl.reducers'; @Component({ selector: 'rtl-home', @@ -25,8 +25,8 @@ export class HomeComponent implements OnInit, OnDestroy { public BTCtotalBalance = ''; public BTCchannelBalance = ''; public networkInfo: NetworkInfo = {}; - public flgLoading: Array = [true, true, true, true, true, true, true, true]; - private unsubs: Array> = [new Subject(), new Subject()]; + 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; @@ -41,7 +41,7 @@ export class HomeComponent implements OnInit, OnDestroy { yAxisLabel = 'Balance'; colorScheme = {domain: ['#FFFFFF']}; - constructor(private logger: LoggerService, private store: Store) { + constructor(private logger: LoggerService, private store: Store) { switch (true) { case (window.innerWidth <= 730): this.view = [250, 352]; @@ -64,51 +64,9 @@ export class HomeComponent implements OnInit, OnDestroy { ngOnInit() { this.flgTotalCalculated = false; - this.store.select('lnd') - .pipe(takeUntil(this.unsubs[1])) - .subscribe(lndStore => { - this.information = lndStore.information; - if (this.flgLoading[0] !== 'error') { - this.flgLoading[0] = (undefined !== this.information.identity_pubkey) ? false : true; - } - this.fees = lndStore.fees; - if (this.flgLoading[1] !== 'error') { - this.flgLoading[1] = (undefined !== this.fees.day_fee_sum) ? false : true; - } - this.totalBalance = lndStore.blockchainBalance.total_balance; - this.BTCtotalBalance = lndStore.blockchainBalance.btc_total_balance; - if (this.flgLoading[2] !== 'error') { - this.flgLoading[2] = ('' !== this.totalBalance) ? false : true; - } - this.channelBalance = lndStore.channelBalance.balance; - this.BTCchannelBalance = lndStore.channelBalance.btc_balance; - if (this.flgLoading[3] !== 'error') { - this.flgLoading[3] = ('' !== this.channelBalance) ? false : true; - } - this.networkInfo = lndStore.networkInfo; - if (this.flgLoading[4] !== 'error') { - this.flgLoading[4] = (undefined !== this.networkInfo.num_nodes) ? false : true; - } - this.totalBalances = [...[{'name': 'Local Balance', 'value': +lndStore.totalLocalBalance}, {'name': 'Remote Balance', 'value': +lndStore.totalRemoteBalance}]]; - this.maxBalanceValue = (lndStore.totalLocalBalance > lndStore.totalRemoteBalance) ? lndStore.totalLocalBalance : lndStore.totalRemoteBalance; - if (lndStore.totalLocalBalance >= 0 && lndStore.totalRemoteBalance >= 0) { - this.flgTotalCalculated = true; - if (this.flgLoading[5] !== 'error') { - this.flgLoading[5] = false; - } - } - this.activeChannels = lndStore.numberOfActiveChannels; - this.inactiveChannels = lndStore.numberOfInactiveChannels; - this.pendingChannels = (undefined !== lndStore.pendingChannels.pending_open_channels) ? lndStore.pendingChannels.pending_open_channels.length : 0; - if (lndStore.totalLocalBalance >= 0 && lndStore.totalRemoteBalance >= 0 && this.flgLoading[6] !== 'error') { - this.flgLoading[6] = false; - } - this.totalPeers = (lndStore.peers !== null) ? lndStore.peers.length : 0; - this.logger.info(lndStore); - }); this.store.select('rtlRoot') - .pipe(takeUntil(this.unsubs[0])) - .subscribe((rtlStore: fromApp.RootState) => { + .pipe(takeUntil(this.unsub[0])) + .subscribe((rtlStore: fromRTLReducer.State) => { rtlStore.effectErrors.forEach(effectsErr => { if (effectsErr.action === 'FetchInfo') { this.flgLoading[0] = 'error'; @@ -131,12 +89,57 @@ export class HomeComponent implements OnInit, OnDestroy { } }); this.selNode = rtlStore.selNode; + 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 !== null) ? rtlStore.peers.length : 0; + this.logger.info(rtlStore); }); } ngOnDestroy() { - this.unsubs.forEach(completeSub => { + this.unsub.forEach(completeSub => { completeSub.next(); completeSub.complete(); }); diff --git a/src/app/lnd/invoices/invoices.component.ts b/src/app/lnd/invoices/invoices.component.ts index 01d538f8..a5037b65 100644 --- a/src/app/lnd/invoices/invoices.component.ts +++ b/src/app/lnd/invoices/invoices.component.ts @@ -1,8 +1,9 @@ import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core'; import { formatDate } from '@angular/common'; import { Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; +import { takeUntil, filter } from 'rxjs/operators'; import { Store } from '@ngrx/store'; +import { Actions } from '@ngrx/effects'; import { MatTableDataSource, MatSort } from '@angular/material'; import { Node } from '../../shared/models/RTLconfig'; @@ -10,10 +11,8 @@ import { GetInfo, Invoice } from '../../shared/models/lndModels'; import { LoggerService } from '../../shared/services/logger.service'; import { newlyAddedRowAnimation } from '../../shared/animation/row-animation'; - -import * as LNDActions from '../store/lnd.actions'; -import * as RTLActions from '../../store/rtl.actions'; -import * as fromApp from '../../store/rtl.reducers'; +import * as RTLActions from '../../shared/store/rtl.actions'; +import * as fromRTLReducer from '../../shared/store/rtl.reducers'; @Component({ selector: 'rtl-invoices', @@ -42,9 +41,9 @@ export class InvoicesComponent implements OnInit, OnDestroy { public pageSizeOptions = [5, 10, 25, 100]; private firstOffset = -1; private lastOffset = -1; - private unSubs: Array> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()]; + private unSubs: Array> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject()]; - constructor(private logger: LoggerService, private store: Store) { + constructor(private logger: LoggerService, private store: Store, private actions$: Actions) { switch (true) { case (window.innerWidth <= 415): this.displayedColumns = ['settled', 'creation_date', 'memo', 'value']; @@ -67,29 +66,24 @@ export class InvoicesComponent implements OnInit, OnDestroy { } ngOnInit() { - this.store.select('lnd') - .pipe(takeUntil(this.unSubs[5])) - .subscribe(lndStore => { - this.information = lndStore ? lndStore.information : {}; - this.totalInvoices = lndStore ? lndStore.totalInvoices : -1; - this.firstOffset = lndStore ? +lndStore.invoices.first_index_offset : -1; - this.lastOffset = lndStore ? +lndStore.invoices.last_index_offset : -1; - this.loadInvoicesTable(lndStore.invoices.invoices); - if (this.flgLoading[0] !== 'error') { - this.flgLoading[0] = (undefined !== lndStore && undefined !== lndStore.invoices) ? false : true; - } - this.logger.info(lndStore); - }); - this.store.select('rtlRoot') .pipe(takeUntil(this.unSubs[0])) - .subscribe((rtlStore: fromApp.RootState) => { + .subscribe((rtlStore: fromRTLReducer.State) => { rtlStore.effectErrors.forEach(effectsErr => { if (effectsErr.action === 'FetchInvoices') { this.flgLoading[0] = 'error'; } }); this.selNode = rtlStore.selNode; + this.information = rtlStore.information; + this.totalInvoices = rtlStore.totalInvoices; + this.firstOffset = +rtlStore.invoices.first_index_offset; + this.lastOffset = +rtlStore.invoices.last_index_offset; + this.logger.info(rtlStore); + this.loadInvoicesTable(rtlStore.invoices.invoices); + if (this.flgLoading[0] !== 'error') { + this.flgLoading[0] = (undefined !== rtlStore.invoices) ? false : true; + } }); } @@ -99,7 +93,7 @@ export class InvoicesComponent implements OnInit, OnDestroy { this.newlyAddedInvoiceMemo = this.memo; this.newlyAddedInvoiceValue = this.invoiceValue; this.store.dispatch(new RTLActions.OpenSpinner('Adding Invoice...')); - this.store.dispatch(new LNDActions.SaveNewInvoice({ + this.store.dispatch(new RTLActions.SaveNewInvoice({ memo: this.memo, invoiceValue: this.invoiceValue, private: this.private, expiry: (this.expiry ? this.expiry : 3600), pageSize: this.pageSize })); this.resetData(); @@ -157,7 +151,7 @@ export class InvoicesComponent implements OnInit, OnDestroy { reversed = true; index_offset = 0; } - this.store.dispatch(new LNDActions.FetchInvoices({num_max_invoices: event.pageSize, index_offset: index_offset, reversed: reversed})); + this.store.dispatch(new RTLActions.FetchInvoices({num_max_invoices: event.pageSize, index_offset: index_offset, reversed: reversed})); } ngOnDestroy() { diff --git a/src/app/lnd/lnd-root.component.scss b/src/app/lnd/lnd-root.component.scss index 3c613452..e69de29b 100644 --- a/src/app/lnd/lnd-root.component.scss +++ b/src/app/lnd/lnd-root.component.scss @@ -1,4 +0,0 @@ -.inline-spinner { - display: inline-flex !important; - top: 0px !important; -} diff --git a/src/app/lnd/lnd-root.component.ts b/src/app/lnd/lnd-root.component.ts index 791923c8..281be1ba 100644 --- a/src/app/lnd/lnd-root.component.ts +++ b/src/app/lnd/lnd-root.component.ts @@ -1,71 +1,166 @@ -import { Component, OnInit, OnDestroy } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { Router, ActivatedRoute } from '@angular/router'; -import { Subject } from 'rxjs'; -import { takeUntil, filter } from 'rxjs/operators'; -import { Store } from '@ngrx/store'; -import { Actions } from '@ngrx/effects'; - -import * as LNDActions from './store/lnd.actions'; -import * as fromApp from '../store/rtl.reducers'; @Component({ - selector: 'rtl-lnd-root-app', + selector: 'rtl-lnd-root', templateUrl: './lnd-root.component.html', styleUrls: ['./lnd-root.component.scss'] }) -export class LndRootComponent implements OnInit, OnDestroy { - unsubs: Array> = [new Subject(), new Subject(), new Subject()]; - - constructor(private store: Store, private router: Router, private activatedRoute: ActivatedRoute, private actions$: Actions) {} +export class LNDRootComponent implements OnInit { + + constructor(private router: Router, private activatedRoute: ActivatedRoute) {} ngOnInit() { - console.warn('LND ROOT'); - // this.store.dispatch(new LNDActions.FetchInfo()); + console.warn('LND ROOT') this.router.navigate(['./home'], {relativeTo: this.activatedRoute}); - this.store.select('lnd') - .pipe(takeUntil(this.unsubs[0])) - .subscribe(lndStore => { - console.warn(lndStore); - if (undefined !== lndStore.information.identity_pubkey) { - this.initializeRemainingData(); - } - }); - this.actions$.pipe(takeUntil(this.unsubs[2]), filter((action) => action.type === LNDActions.SET_INFO)) - .subscribe((infoData: LNDActions.SetInfo) => { - console.warn(infoData); - if (undefined !== infoData.payload.identity_pubkey) { - this.initializeRemainingData(); - } - }); - // this.actions$ - // .pipe( - // takeUntil(this.unSubs[3]), - // filter(action => action.type === RTLActions.INIT_APP_DATA || action.type === LNDActions.SET_INFO || action.type === CLActions.SET_CL_INFO) - // ).subscribe((actionPayload: RTLActions.InitAppData | LNDActions.SetInfo | CLActions.SetCLInfo) => { - // // if (actionPayload.type === RTLActions.INIT_APP_DATA) { - // if(this.information.identity_pubkey) { - // this.initializeRemainingData(); - // } - // }); - } - initializeRemainingData() { - console.warn('SOMETHING IS WRONG HERE'); - // this.store.dispatch(new LNDActions.FetchPeers()); - // this.store.dispatch(new LNDActions.FetchBalance('channels')); - // this.store.dispatch(new LNDActions.FetchFees()); - // this.store.dispatch(new LNDActions.FetchNetwork()); - // this.store.dispatch(new LNDActions.FetchChannels({routeParam: 'all'})); - // this.store.dispatch(new LNDActions.FetchChannels({routeParam: 'pending'})); - // this.store.dispatch(new LNDActions.FetchInvoices({num_max_invoices: 25, reversed: true})); - // this.store.dispatch(new LNDActions.FetchPayments()); - } + // @ViewChild('sideNavigation', { static: false }) sideNavigation: any; + // @ViewChild('settingSidenav', { static: true }) settingSidenav: any; + // public selNode: Node; + // public settings: Settings; + // public information: GetInfo = {}; + // public flgLoading: Array = [true]; // 0: Info + // public flgCopied = false; + // public appConfig: RTLConfiguration; + // public accessKey = ''; + // public smallScreen = false; + // unsubs: Array> = [new Subject(), new Subject(), new Subject()]; - ngOnDestroy() { - this.unsubs.forEach(unsub => { - unsub.next(); - unsub.complete(); - }); - } + // constructor(private logger: LoggerService, private store: Store, private actions$: Actions, + // private userIdle: UserIdleService, private router: Router) {} + + // ngOnInit() { + // this.store.dispatch(new RTLActions.FetchRTLConfig()); + // this.accessKey = this.readAccessKey(); + // this.store.select('rtlRoot') + // .pipe(takeUntil(this.unsubs[0])) + // .subscribe(rtlStore => { + // this.selNode = rtlStore.selNode; + // this.settings = this.selNode.settings; + // this.appConfig = rtlStore.appConfig; + // this.information = rtlStore.information; + // 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_RTL_CONFIG) + // ).subscribe((actionPayload: (RTLActions.InitAppData | RTLActions.SetRTLConfig)) => { + // if (actionPayload.type === RTLActions.SET_RTL_CONFIG) { + // if (!sessionStorage.getItem('token')) { + // if (+actionPayload.payload.sso.rtlSSO) { + // this.store.dispatch(new RTLActions.Signin(sha256(this.accessKey))); + // } else { + // this.router.navigate([this.appConfig.sso.logoutRedirectLink]); + // } + // } + // if ( + // this.settings.menu === 'Horizontal' || + // this.settings.menuType === 'Compact' || + // this.settings.menuType === 'Mini') { + // this.settingSidenav.toggle(); // To dynamically update the width to 100% after side nav is closed + // setTimeout(() => { this.settingSidenav.toggle(); }, 100); + // } + // } else if (actionPayload.type === RTLActions.INIT_APP_DATA) { + // this.store.dispatch(new RTLActions.FetchInfo()); + // } + // }); + // 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('access-key=') + 11).trim(); + // } + + // 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'})); + // this.store.dispatch(new RTLActions.FetchChannels({routeParam: 'pending'})); + // this.store.dispatch(new RTLActions.FetchInvoices({num_max_invoices: 25, reversed: true})); + // 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/lnd/lnd.module.ts b/src/app/lnd/lnd.module.ts index 8809ca03..8a190a3a 100644 --- a/src/app/lnd/lnd.module.ts +++ b/src/app/lnd/lnd.module.ts @@ -1,13 +1,10 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { NgxChartsModule } from '@swimlane/ngx-charts'; -import { StoreDevtoolsModule } from '@ngrx/store-devtools'; -import { environment } from '../../environments/environment'; +import { LNDRouting } from './lnd.routing'; import { SharedModule } from '../shared/shared.module'; -import { lndRouting } from './lnd.routing'; -import { LndRootComponent } from './lnd-root.component'; +import { LNDRootComponent } from './lnd-root.component'; import { HomeComponent } from './home/home.component'; import { PeersComponent } from './peers/peers.component'; import { SendReceiveTransComponent } from './transactions/send-receive/send-receive-trans.component'; @@ -26,16 +23,18 @@ import { NodeLookupComponent } from './lookups/node-lookup/node-lookup.component import { ChannelBackupComponent } from './channels/channel-backup/channel-backup.component'; import { QueryRoutesComponent } from './payments/query-routes/query-routes.component'; +import { CommonService } from '../shared/services/common.service'; +import { LoggerService, ConsoleLoggerService } from '../shared/services/logger.service'; +import { LNDUnlockedGuard } from '../shared/services/auth.guard'; + @NgModule({ imports: [ CommonModule, SharedModule, - lndRouting, - NgxChartsModule, - !environment.production ? StoreDevtoolsModule.instrument() : [] + LNDRouting ], declarations: [ - LndRootComponent, + LNDRootComponent, HomeComponent, PeersComponent, SendReceiveTransComponent, @@ -54,7 +53,11 @@ import { QueryRoutesComponent } from './payments/query-routes/query-routes.compo ChannelBackupComponent, QueryRoutesComponent ], - providers: [], - bootstrap: [LndRootComponent] + providers: [ + { provide: LoggerService, useClass: ConsoleLoggerService }, + LNDUnlockedGuard, + CommonService + ], + bootstrap: [LNDRootComponent] }) -export class LndModule {} +export class LNDModule {} diff --git a/src/app/lnd/lnd.routing.ts b/src/app/lnd/lnd.routing.ts index a6cff842..fbd6cea6 100644 --- a/src/app/lnd/lnd.routing.ts +++ b/src/app/lnd/lnd.routing.ts @@ -1,10 +1,7 @@ import { Routes, RouterModule } from '@angular/router'; import { ModuleWithProviders } from '@angular/core'; -import { AuthGuard, LNDUnlockedGuard } from '../shared/services/auth.guard'; -import { NotFoundComponent } from '../shared/components/not-found/not-found.component'; - -import { LndRootComponent } from './lnd-root.component'; +import { LNDRootComponent } from './lnd-root.component'; import { HomeComponent } from './home/home.component'; import { UnlockLNDComponent } from './unlock-lnd/unlock-lnd.component'; import { ChannelClosedComponent } from './channels/channel-closed/channel-closed.component'; @@ -21,27 +18,29 @@ import { ForwardingHistoryComponent } from './switch/forwarding-history.componen import { RoutingPeersComponent } from './routing-peers/routing-peers.component'; import { ChannelBackupComponent } from './channels/channel-backup/channel-backup.component'; -export const lndRoutes: Routes = [ - { path: '', component: LndRootComponent, +import { LNDUnlockedGuard } from '../shared/services/auth.guard'; +import { NotFoundComponent } from '../shared/components/not-found/not-found.component'; + +export const LndRoutes: Routes = [ + { path: '', component: LNDRootComponent, children: [ - { path: 'home', component: HomeComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, - { path: 'unlocklnd', component: UnlockLNDComponent, canActivate: [AuthGuard] }, - { 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: 'chnlbackup', component: ChannelBackupComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, - { path: 'transsendreceive', component: SendReceiveTransComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, - { path: 'translist', component: ListTransactionsComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, - { path: 'paymentsend', component: PaymentsComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, - { path: 'queryroutes', component: QueryRoutesComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, - { path: 'invoices', component: InvoicesComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, - { path: 'switch', component: ForwardingHistoryComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, - { path: 'routingpeers', component: RoutingPeersComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, - { path: 'lookups', component: LookupsComponent, canActivate: [AuthGuard, LNDUnlockedGuard] }, - { path: '**', component: NotFoundComponent } - ] - } + { path: 'unlocklnd', component: UnlockLNDComponent }, + { path: 'home', component: HomeComponent, canActivate: [LNDUnlockedGuard] }, + { path: 'peers', component: PeersComponent, canActivate: [LNDUnlockedGuard] }, + { path: 'chnlclosed', component: ChannelClosedComponent, canActivate: [LNDUnlockedGuard] }, + { path: 'chnlmanage', component: ChannelManageComponent, canActivate: [LNDUnlockedGuard] }, + { path: 'chnlpending', component: ChannelPendingComponent, canActivate: [LNDUnlockedGuard] }, + { path: 'chnlbackup', component: ChannelBackupComponent, canActivate: [LNDUnlockedGuard] }, + { path: 'transsendreceive', component: SendReceiveTransComponent, canActivate: [LNDUnlockedGuard] }, + { path: 'translist', component: ListTransactionsComponent, canActivate: [LNDUnlockedGuard] }, + { path: 'paymentsend', component: PaymentsComponent, canActivate: [LNDUnlockedGuard] }, + { path: 'queryroutes', component: QueryRoutesComponent, canActivate: [LNDUnlockedGuard] }, + { path: 'invoices', component: InvoicesComponent, canActivate: [LNDUnlockedGuard] }, + { path: 'switch', component: ForwardingHistoryComponent, canActivate: [LNDUnlockedGuard] }, + { path: 'routingpeers', component: RoutingPeersComponent, canActivate: [LNDUnlockedGuard] }, + { path: 'lookups', component: LookupsComponent, canActivate: [LNDUnlockedGuard] }, + { path: '**', component: NotFoundComponent } + ]} ]; -export const lndRouting: ModuleWithProviders = RouterModule.forChild(lndRoutes); +export const LNDRouting: ModuleWithProviders = RouterModule.forChild(LndRoutes); diff --git a/src/app/lnd/lookups/channel-lookup/channel-lookup.component.ts b/src/app/lnd/lookups/channel-lookup/channel-lookup.component.ts index 1384566c..8e39ff24 100644 --- a/src/app/lnd/lookups/channel-lookup/channel-lookup.component.ts +++ b/src/app/lnd/lookups/channel-lookup/channel-lookup.component.ts @@ -1,47 +1,40 @@ -import { Component, OnInit, Input, OnDestroy } from '@angular/core'; +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 fromLNDReducer from '../../store/lnd.reducers'; +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, OnDestroy { +export class ChannelLookupComponent implements OnInit { @Input() lookupResult: ChannelEdge; public node1_match = false; public node2_match = false; - private unSubs: Array> = [new Subject(), new Subject()]; + private unSubs: Array> = [new Subject(), new Subject(), new Subject(), new Subject()]; - constructor(private lndStore: Store) { } + 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.lndStore.select('lnd') - .pipe(takeUntil(this.unSubs[1])) - .subscribe(lndStore => { - if (this.lookupResult.node1_pub === lndStore.information.identity_pubkey) { + 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 === lndStore.information.identity_pubkey) { + if (this.lookupResult.node2_pub === rtlStore.information.identity_pubkey) { this.node2_match = true; } }); } - ngOnDestroy() { - this.unSubs.forEach(unsub => { - unsub.next(); - unsub.complete(); - }); - } - } diff --git a/src/app/lnd/lookups/lookups.component.ts b/src/app/lnd/lookups/lookups.component.ts index 99412446..79ae3cd9 100644 --- a/src/app/lnd/lookups/lookups.component.ts +++ b/src/app/lnd/lookups/lookups.component.ts @@ -6,9 +6,8 @@ import { Actions } from '@ngrx/effects'; import { LoggerService } from '../../shared/services/logger.service'; -import * as LNDActions from '../store/lnd.actions'; -import * as RTLActions from '../../store/rtl.actions'; -import * as fromApp from '../../store/rtl.reducers'; +import * as RTLActions from '../../shared/store/rtl.actions'; +import * as fromRTLReducer from '../../shared/store/rtl.reducers'; @Component({ selector: 'rtl-lookups', @@ -29,14 +28,14 @@ export class LookupsComponent implements OnInit, OnDestroy { public flgLoading: Array = [true]; private unSubs: Array> = [new Subject()]; - constructor(private logger: LoggerService, private store: Store, private actions$: Actions) {} + constructor(private logger: LoggerService, private store: Store, private actions$: Actions) {} ngOnInit() { this.actions$ .pipe( takeUntil(this.unSubs[0]), - filter((action) => (action.type === LNDActions.SET_LOOKUP || action.type === RTLActions.EFFECT_ERROR)) - ).subscribe((resLookup: LNDActions.SetLookup) => { + 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 { @@ -54,10 +53,10 @@ export class LookupsComponent implements OnInit, OnDestroy { this.store.dispatch(new RTLActions.OpenSpinner('Searching ' + this.selectedField.name + '...')); switch (this.selectedField.id) { case '0': - this.store.dispatch(new LNDActions.PeerLookup(this.lookupKey.trim())); + this.store.dispatch(new RTLActions.PeerLookup(this.lookupKey.trim())); break; case '1': - this.store.dispatch(new LNDActions.ChannelLookup(this.lookupKey.trim())); + this.store.dispatch(new RTLActions.ChannelLookup(this.lookupKey.trim())); break; default: break; diff --git a/src/app/lnd/payments/query-routes/query-routes.component.ts b/src/app/lnd/payments/query-routes/query-routes.component.ts index 10fd4054..8ec09760 100644 --- a/src/app/lnd/payments/query-routes/query-routes.component.ts +++ b/src/app/lnd/payments/query-routes/query-routes.component.ts @@ -9,10 +9,9 @@ import { MatTableDataSource, MatSort } from '@angular/material'; import { Hop } from '../../../shared/models/lndModels'; import { LoggerService } from '../../../shared/services/logger.service'; - import { LNDEffects } from '../../store/lnd.effects'; -import * as LNDActions from '../../store/lnd.actions'; -import * as RTLActions from '../../../store/rtl.actions'; -import * as fromApp from '../../../store/rtl.reducers'; +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-query-routes', @@ -26,10 +25,10 @@ export class QueryRoutesComponent implements OnInit, OnDestroy { public qrHops: any; public flgSticky = false; public displayedColumns = []; - public flgLoading: Array = [false]; + public flgLoading: Array = [false]; // 0: peers private unSubs: Array> = [new Subject(), new Subject()]; - constructor(private logger: LoggerService, private store: Store, private lndEffects: LNDEffects, private actions$: Actions) { + constructor(private logger: LoggerService, private store: Store, private rtlEffects: RTLEffects, private actions$: Actions) { switch (true) { case (window.innerWidth <= 415): this.displayedColumns = ['hop_sequence', 'pubkey_alias', 'fee_msat']; @@ -54,10 +53,10 @@ export class QueryRoutesComponent implements OnInit, OnDestroy { ngOnInit() { this.store.select('rtlRoot') .pipe(takeUntil(this.unSubs[0])) - .subscribe((rtlStore: fromApp.RootState) => { + .subscribe((rtlStore: fromRTLReducer.State) => { this.logger.info(rtlStore); }); - this.lndEffects.setQueryRoutes + this.rtlEffects.setQueryRoutes .pipe(takeUntil(this.unSubs[1])) .subscribe(queryRoute => { this.qrHops = new MatTableDataSource([]); @@ -75,7 +74,7 @@ export class QueryRoutesComponent implements OnInit, OnDestroy { onQueryRoutes() { this.flgLoading[0] = true; - this.store.dispatch(new LNDActions.GetQueryRoutes({destPubkey: this.destinationPubkey, amount: this.amount})); + this.store.dispatch(new RTLActions.GetQueryRoutes({destPubkey: this.destinationPubkey, amount: this.amount})); } resetData() { diff --git a/src/app/lnd/payments/send-receive/payments.component.ts b/src/app/lnd/payments/send-receive/payments.component.ts index 210d2575..e35af829 100644 --- a/src/app/lnd/payments/send-receive/payments.component.ts +++ b/src/app/lnd/payments/send-receive/payments.component.ts @@ -10,12 +10,9 @@ import { GetInfo, Payment, PayRequest } from '../../../shared/models/lndModels'; import { LoggerService } from '../../../shared/services/logger.service'; import { newlyAddedRowAnimation } from '../../../shared/animation/row-animation'; - -import { LNDEffects } from '../../store/lnd.effects'; -import { RTLEffects } from '../../../store/rtl.effects'; -import * as LNDActions from '../../store/lnd.actions'; -import * as RTLActions from '../../../store/rtl.actions'; -import * as fromApp from '../../../store/rtl.reducers'; +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', @@ -37,9 +34,9 @@ export class PaymentsComponent implements OnInit, OnDestroy { public paymentDecoded: PayRequest = {}; public paymentRequest = ''; public flgSticky = false; - private unsubs: Array> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject()]; + private unsub: Array> = [new Subject(), new Subject(), new Subject(), new Subject()]; - constructor(private logger: LoggerService, private store: Store, private rtlEffects: RTLEffects, private lndEffects: LNDEffects) { + constructor(private logger: LoggerService, private store: Store, private rtlEffects: RTLEffects) { switch (true) { case (window.innerWidth <= 415): this.displayedColumns = ['creation_date', 'fee', 'value']; @@ -62,13 +59,18 @@ export class PaymentsComponent implements OnInit, OnDestroy { } ngOnInit() { - this.store.select('lnd') - .pipe(takeUntil(this.unsubs[4])) - .subscribe(lndStore => { - this.information = lndStore.information; - this.paymentJSONArr = (null !== lndStore.payments && lndStore.payments.length > 0) ? lndStore.payments : []; - this.payments = (undefined === lndStore.payments || null == lndStore.payments) ? - new MatTableDataSource([]) : new MatTableDataSource([...this.paymentJSONArr]); + 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.selNode = rtlStore.selNode; + this.information = rtlStore.information; + this.paymentJSONArr = (null !== rtlStore.payments && rtlStore.payments.length > 0) ? rtlStore.payments : []; + this.payments = (undefined === rtlStore.payments || null == rtlStore.payments) ? new MatTableDataSource([]) : new MatTableDataSource([...this.paymentJSONArr]); this.payments.data = this.paymentJSONArr; this.payments.sort = this.sort; this.payments.data.forEach(payment => { @@ -78,18 +80,6 @@ export class PaymentsComponent implements OnInit, OnDestroy { if (this.flgLoading[0] !== 'error') { this.flgLoading[0] = (undefined !== this.paymentJSONArr) ? false : true; } - this.logger.info(lndStore); - }); - - this.store.select('rtlRoot') - .pipe(takeUntil(this.unsubs[0])) - .subscribe((rtlStore: fromApp.RootState) => { - rtlStore.effectErrors.forEach(effectsErr => { - if (effectsErr.action === 'FetchPayments') { - this.flgLoading[0] = 'error'; - } - }); - this.selNode = rtlStore.selNode; this.logger.info(rtlStore); }); @@ -100,8 +90,8 @@ export class PaymentsComponent implements OnInit, OnDestroy { this.sendPayment(); } else { this.store.dispatch(new RTLActions.OpenSpinner('Decoding Payment...')); - this.store.dispatch(new LNDActions.DecodePayment(this.paymentRequest)); - this.lndEffects.setDecodedPayment + this.store.dispatch(new RTLActions.DecodePayment(this.paymentRequest)); + this.rtlEffects.setDecodedPayment .pipe(take(1)) .subscribe(decodedPayment => { this.paymentDecoded = decodedPayment; @@ -136,7 +126,7 @@ export class PaymentsComponent implements OnInit, OnDestroy { if (confirmRes) { this.paymentDecoded.num_satoshis = confirmRes[0].inputValue; this.store.dispatch(new RTLActions.OpenSpinner('Sending Payment...')); - this.store.dispatch(new LNDActions.SendPayment([this.paymentRequest, this.paymentDecoded, true])); + this.store.dispatch(new RTLActions.SendPayment([this.paymentRequest, this.paymentDecoded, true])); this.resetData(); } }); @@ -149,7 +139,7 @@ export class PaymentsComponent implements OnInit, OnDestroy { .subscribe(confirmRes => { if (confirmRes) { this.store.dispatch(new RTLActions.OpenSpinner('Sending Payment...')); - this.store.dispatch(new LNDActions.SendPayment([this.paymentRequest, this.paymentDecoded, false])); + this.store.dispatch(new RTLActions.SendPayment([this.paymentRequest, this.paymentDecoded, false])); this.resetData(); } }); @@ -158,8 +148,8 @@ export class PaymentsComponent implements OnInit, OnDestroy { onVerifyPayment() { this.store.dispatch(new RTLActions.OpenSpinner('Decoding Payment...')); - this.store.dispatch(new LNDActions.DecodePayment(this.paymentRequest)); - this.lndEffects.setDecodedPayment.subscribe(decodedPayment => { + 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 === '') ? '' : @@ -197,7 +187,7 @@ export class PaymentsComponent implements OnInit, OnDestroy { } ngOnDestroy() { - this.unsubs.forEach(completeSub => { + this.unsub.forEach(completeSub => { completeSub.next(); completeSub.complete(); }); diff --git a/src/app/lnd/peers/peers.component.ts b/src/app/lnd/peers/peers.component.ts index b99f625d..3eeaed1b 100644 --- a/src/app/lnd/peers/peers.component.ts +++ b/src/app/lnd/peers/peers.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core'; -import { Router, ActivatedRoute } from '@angular/router'; +import { Router } from '@angular/router'; import { Subject } from 'rxjs'; import { takeUntil, filter, take } from 'rxjs/operators'; @@ -11,12 +11,9 @@ import { Peer, GetInfo } from '../../shared/models/lndModels'; import { LoggerService } from '../../shared/services/logger.service'; import { newlyAddedRowAnimation } from '../../shared/animation/row-animation'; - -import { LNDEffects } from '../store/lnd.effects'; -import { RTLEffects } from '../../store/rtl.effects'; -import * as LNDActions from '../store/lnd.actions'; -import * as RTLActions from '../../store/rtl.actions'; -import * as fromApp from '../../store/rtl.reducers'; +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', @@ -32,12 +29,11 @@ export class PeersComponent implements OnInit, OnDestroy { public peerAddress = ''; public peers: any; public information: GetInfo = {}; - public flgLoading: Array = [true]; + public flgLoading: Array = [true]; // 0: peers public flgSticky = false; - private unSubs: Array> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject()]; + private unSubs: Array> = [new Subject(), new Subject(), new Subject(), new Subject()]; - constructor(private logger: LoggerService, private store: Store, private rtlEffects: RTLEffects, - private lndEffects: LNDEffects, private actions$: Actions, private router: Router, private activatedRoute: ActivatedRoute) { + constructor(private logger: LoggerService, private store: Store, private rtlEffects: RTLEffects, private actions$: Actions, private router: Router) { switch (true) { case (window.innerWidth <= 415): this.displayedColumns = ['detach', 'pub_key', 'alias']; @@ -60,39 +56,33 @@ export class PeersComponent implements OnInit, OnDestroy { } ngOnInit() { - this.store.select('lnd') - .pipe(takeUntil(this.unSubs[4])) - .subscribe(lndStore => { - this.information = lndStore.information; + 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 !== lndStore.peers) { - this.peers = new MatTableDataSource([...lndStore.peers]); - this.peers.data = lndStore.peers; + if (undefined !== rtlStore.peers) { + this.peers = new MatTableDataSource([...rtlStore.peers]); + this.peers.data = rtlStore.peers; setTimeout(() => { this.flgAnimate = false; }, 3000); } this.peers.sort = this.sort; if (this.flgLoading[0] !== 'error') { this.flgLoading[0] = false; } - this.logger.info(lndStore); - }); - - this.store.select('rtlRoot') - .pipe(takeUntil(this.unSubs[0])) - .subscribe((rtlStore: fromApp.RootState) => { - rtlStore.effectErrors.forEach(effectsErr => { - if (effectsErr.action === 'FetchPeers') { - this.flgLoading[0] = 'error'; - } - }); this.logger.info(rtlStore); }); this.actions$ .pipe( takeUntil(this.unSubs[1]), - filter((action) => action.type === LNDActions.SET_PEERS) - ).subscribe((setPeers: LNDActions.SetPeers) => { + filter((action) => action.type === RTLActions.SET_PEERS) + ).subscribe((setPeers: RTLActions.SetPeers) => { this.peerAddress = undefined; }); } @@ -111,8 +101,8 @@ export class PeersComponent implements OnInit, OnDestroy { } else { pubkey = (deviderIndex > -1) ? this.peerAddress.substring(0, deviderIndex) : this.peerAddress; this.store.dispatch(new RTLActions.OpenSpinner('Getting Node Address...')); - this.store.dispatch(new LNDActions.FetchGraphNode(pubkey)); - this.lndEffects.setGraphNode + 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; @@ -124,7 +114,7 @@ export class PeersComponent implements OnInit, OnDestroy { connectPeerWithParams(pubkey: string, host: string) { this.newlyAddedPeer = pubkey; this.store.dispatch(new RTLActions.OpenSpinner('Adding Peer...')); - this.store.dispatch(new LNDActions.SaveNewPeer({pubkey: pubkey, host: host, perm: false})); + this.store.dispatch(new RTLActions.SaveNewPeer({pubkey: pubkey, host: host, perm: false})); } onPeerClick(selRow: Peer, event: any) { @@ -146,7 +136,7 @@ export class PeersComponent implements OnInit, OnDestroy { } onOpenChannel(peerToAddChannel: Peer) { - this.router.navigate(['chnlmanage'], { relativeTo: this.activatedRoute, state: { peer: peerToAddChannel.pub_key }}); + this.router.navigate(['lnd/chnlmanage'], { state: { peer: peerToAddChannel.pub_key }}); } onPeerDetach(peerToDetach: Peer) { @@ -158,7 +148,7 @@ export class PeersComponent implements OnInit, OnDestroy { .subscribe(confirmRes => { if (confirmRes) { this.store.dispatch(new RTLActions.OpenSpinner('Detaching Peer...')); - this.store.dispatch(new LNDActions.DetachPeer({pubkey: peerToDetach.pub_key})); + this.store.dispatch(new RTLActions.DetachPeer({pubkey: peerToDetach.pub_key})); } }); } diff --git a/src/app/lnd/routing-peers/routing-peers.component.ts b/src/app/lnd/routing-peers/routing-peers.component.ts index 565adba1..2bef613a 100644 --- a/src/app/lnd/routing-peers/routing-peers.component.ts +++ b/src/app/lnd/routing-peers/routing-peers.component.ts @@ -9,9 +9,8 @@ import { ForwardingEvent, RoutingPeers } from '../../shared/models/lndModels'; import { LoggerService } from '../../shared/services/logger.service'; import { CommonService } from '../../shared/services/common.service'; -import * as LNDActions from '../store/lnd.actions'; -import * as RTLActions from '../../store/rtl.actions'; -import * as fromApp from '../../store/rtl.reducers'; +import * as RTLActions from '../../shared/store/rtl.actions'; +import * as fromRTLReducer from '../../shared/store/rtl.reducers'; @Component({ selector: 'rtl-routing-peers', @@ -34,9 +33,9 @@ export class RoutingPeersComponent implements OnInit, OnDestroy { public endDate = this.today; public startDate = this.lastMonthDay; public flgSticky = false; - private unsubs: Array> = [new Subject(), new Subject(), new Subject(), new Subject()]; + private unsub: Array> = [new Subject(), new Subject(), new Subject()]; - constructor(private logger: LoggerService, private commonService: CommonService, private store: Store, private actions$: Actions) { + constructor(private logger: LoggerService, private commonService: CommonService, private store: Store, private actions$: Actions) { switch (true) { case (window.innerWidth <= 415): this.displayedColumns = ['chan_id', 'events', 'total_amount']; @@ -60,30 +59,26 @@ export class RoutingPeersComponent implements OnInit, OnDestroy { ngOnInit() { this.onRoutingPeersFetch(); - this.actions$.pipe(takeUntil(this.unsubs[2]), filter((action) => action.type === RTLActions.RESET_STORE)).subscribe((resetStore: RTLActions.ResetStore) => { + this.actions$.pipe(takeUntil(this.unsub[2]), filter((action) => action.type === RTLActions.RESET_STORE)).subscribe((resetStore: RTLActions.ResetStore) => { this.onRoutingPeersFetch(); }); - this.store.select('lnd') - .pipe(takeUntil(this.unsubs[3])) - .subscribe(lndStore => { - if (undefined !== lndStore.forwardingHistory && undefined !== lndStore.forwardingHistory.forwarding_events) { - this.loadRoutingPeersTable(lndStore.forwardingHistory.forwarding_events); - } else { - this.loadRoutingPeersTable([]); - } - if (this.flgLoading[0] !== 'error') { - this.flgLoading[0] = (undefined !== lndStore.forwardingHistory) ? false : true; - } - this.logger.info(lndStore); - }); this.store.select('rtlRoot') - .pipe(takeUntil(this.unsubs[0])) - .subscribe((rtlStore: fromApp.RootState) => { + .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.loadRoutingPeersTable(rtlStore.forwardingHistory.forwarding_events); + } else { + // To reset table after other Forwarding history calls + this.loadRoutingPeersTable([]); + } + if (this.flgLoading[0] !== 'error') { + this.flgLoading[0] = (undefined !== rtlStore.forwardingHistory) ? false : true; + } this.logger.info(rtlStore); }); @@ -117,6 +112,7 @@ export class RoutingPeersComponent implements OnInit, OnDestroy { this.RoutingPeersOutgoing.sort = this.sortOut; this.logger.info(this.RoutingPeersOutgoing); } else { + // To reset table after other Forwarding history calls this.RoutingPeersIncoming = new MatTableDataSource([]); this.RoutingPeersOutgoing = new MatTableDataSource([]); } @@ -151,7 +147,7 @@ export class RoutingPeersComponent implements OnInit, OnDestroy { if (undefined === this.startDate || this.startDate == null) { this.startDate = new Date(this.endDate.getFullYear(), this.endDate.getMonth(), this.endDate.getDate() - 30); } - this.store.dispatch(new LNDActions.GetForwardingHistory({ + this.store.dispatch(new RTLActions.GetForwardingHistory({ end_time: Math.round(this.endDate.getTime() / 1000).toString(), start_time: Math.round(this.startDate.getTime() / 1000).toString() })); @@ -170,7 +166,7 @@ export class RoutingPeersComponent implements OnInit, OnDestroy { ngOnDestroy() { this.resetData(); - this.unsubs.forEach(completeSub => { + this.unsub.forEach(completeSub => { completeSub.next(); completeSub.complete(); }); diff --git a/src/app/lnd/switch/forwarding-history.component.ts b/src/app/lnd/switch/forwarding-history.component.ts index f6e87373..e6ac9d60 100644 --- a/src/app/lnd/switch/forwarding-history.component.ts +++ b/src/app/lnd/switch/forwarding-history.component.ts @@ -9,9 +9,8 @@ import { MatTableDataSource, MatSort } from '@angular/material'; import { ForwardingEvent } from '../../shared/models/lndModels'; import { LoggerService } from '../../shared/services/logger.service'; -import * as LNDActions from '../store/lnd.actions'; -import * as RTLActions from '../../store/rtl.actions'; -import * as fromApp from '../../store/rtl.reducers'; +import * as RTLActions from '../../shared/store/rtl.actions'; +import * as fromRTLReducer from '../../shared/store/rtl.reducers'; @Component({ selector: 'rtl-forwarding-history', @@ -29,9 +28,9 @@ export class ForwardingHistoryComponent implements OnInit, OnDestroy { public endDate = this.today; public startDate = this.yesterday; public flgSticky = false; - private unsubs: Array> = [new Subject(), new Subject(), new Subject(), new Subject()]; + private unsub: Array> = [new Subject(), new Subject(), new Subject()]; - constructor(private logger: LoggerService, private store: Store, private actions$: Actions) { + constructor(private logger: LoggerService, private store: Store, private actions$: Actions) { switch (true) { case (window.innerWidth <= 415): this.displayedColumns = ['timestamp', 'amt_out', 'amt_in']; @@ -55,32 +54,29 @@ export class ForwardingHistoryComponent implements OnInit, OnDestroy { ngOnInit() { this.onForwardingHistoryFetch(); - this.actions$.pipe(takeUntil(this.unsubs[2]), filter((action) => action.type === RTLActions.RESET_STORE)).subscribe((resetStore: RTLActions.ResetStore) => { + this.actions$.pipe(takeUntil(this.unsub[2]), filter((action) => action.type === RTLActions.RESET_STORE)).subscribe((resetStore: RTLActions.ResetStore) => { this.onForwardingHistoryFetch(); }); - this.store.select('lnd') - .pipe(takeUntil(this.unsubs[3])) - .subscribe(lndStore => { - if (undefined !== lndStore.forwardingHistory && undefined !== lndStore.forwardingHistory.forwarding_events) { - this.lastOffsetIndex = lndStore.forwardingHistory.last_offset_index; - this.loadForwardingEventsTable(lndStore.forwardingHistory.forwarding_events); - } else { - this.lastOffsetIndex = 0; - this.loadForwardingEventsTable([]); - } - if (this.flgLoading[0] !== 'error') { - this.flgLoading[0] = (undefined !== lndStore.forwardingHistory) ? false : true; - } - this.logger.info(lndStore); - }); + this.store.select('rtlRoot') - .pipe(takeUntil(this.unsubs[0])) - .subscribe((rtlStore: fromApp.RootState) => { + .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); + } else { + // To reset table after other Forwarding history calls + this.lastOffsetIndex = 0; + this.loadForwardingEventsTable([]); + } + if (this.flgLoading[0] !== 'error') { + this.flgLoading[0] = (undefined !== rtlStore.forwardingHistory) ? false : true; + } this.logger.info(rtlStore); }); @@ -115,7 +111,7 @@ export class ForwardingHistoryComponent implements OnInit, OnDestroy { 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 LNDActions.GetForwardingHistory({ + this.store.dispatch(new RTLActions.GetForwardingHistory({ end_time: Math.round(this.endDate.getTime() / 1000).toString(), start_time: Math.round(this.startDate.getTime() / 1000).toString() })); @@ -131,7 +127,7 @@ export class ForwardingHistoryComponent implements OnInit, OnDestroy { ngOnDestroy() { this.resetData(); - this.unsubs.forEach(completeSub => { + this.unsub.forEach(completeSub => { completeSub.next(); completeSub.complete(); }); diff --git a/src/app/lnd/transactions/list-transactions/list-transactions.component.ts b/src/app/lnd/transactions/list-transactions/list-transactions.component.ts index 9d3cf2b8..b26a9215 100644 --- a/src/app/lnd/transactions/list-transactions/list-transactions.component.ts +++ b/src/app/lnd/transactions/list-transactions/list-transactions.component.ts @@ -9,9 +9,9 @@ import { MatTableDataSource, MatSort } from '@angular/material'; import { Transaction } from '../../../shared/models/lndModels'; import { LoggerService } from '../../../shared/services/logger.service'; -import * as LNDActions from '../../store/lnd.actions'; -import * as RTLActions from '../../../store/rtl.actions'; -import * as fromApp from '../../../store/rtl.reducers'; +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', @@ -24,9 +24,9 @@ export class ListTransactionsComponent implements OnInit, OnDestroy { public listTransactions: any; public flgLoading: Array = [true]; public flgSticky = false; - private unsubs: Array> = [new Subject(), new Subject(), new Subject(), new Subject()]; + private unsub: Array> = [new Subject(), new Subject(), new Subject()]; - constructor(private logger: LoggerService, private store: Store, private actions$: Actions) { + constructor(private logger: LoggerService, private store: Store, private rtlEffects: RTLEffects, private actions$: Actions) { switch (true) { case (window.innerWidth <= 415): this.displayedColumns = ['dest_addresses', 'total_fees', 'amount']; @@ -49,29 +49,25 @@ export class ListTransactionsComponent implements OnInit, OnDestroy { } ngOnInit() { - this.store.dispatch(new LNDActions.FetchTransactions()); - this.actions$.pipe(takeUntil(this.unsubs[2]), filter((action) => action.type === RTLActions.RESET_STORE)).subscribe((resetStore: RTLActions.ResetStore) => { - this.store.dispatch(new LNDActions.FetchTransactions()); - }); - this.store.select('lnd') - .pipe(takeUntil(this.unsubs[3])) - .subscribe(lndStore => { - if (undefined !== lndStore.transactions) { - this.loadTransactionsTable(lndStore.transactions); - } - if (this.flgLoading[0] !== 'error') { - this.flgLoading[0] = (undefined !== lndStore.transactions) ? false : true; - } - this.logger.info(lndStore); + this.store.dispatch(new RTLActions.FetchTransactions()); + this.actions$.pipe(takeUntil(this.unsub[2]), filter((action) => action.type === RTLActions.RESET_STORE)).subscribe((resetStore: RTLActions.ResetStore) => { + this.store.dispatch(new RTLActions.FetchTransactions()); }); + this.store.select('rtlRoot') - .pipe(takeUntil(this.unsubs[0])) - .subscribe((rtlStore: fromApp.RootState) => { + .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) { + this.loadTransactionsTable(rtlStore.transactions); + } + if (this.flgLoading[0] !== 'error') { + this.flgLoading[0] = (undefined !== rtlStore.transactions) ? false : true; + } this.logger.info(rtlStore); }); @@ -113,7 +109,7 @@ export class ListTransactionsComponent implements OnInit, OnDestroy { } ngOnDestroy() { - this.unsubs.forEach(completeSub => { + this.unsub.forEach(completeSub => { completeSub.next(); completeSub.complete(); }); diff --git a/src/app/lnd/transactions/send-receive/send-receive-trans.component.html b/src/app/lnd/transactions/send-receive/send-receive-trans.component.html index 470e3fae..2a984ac6 100644 --- a/src/app/lnd/transactions/send-receive/send-receive-trans.component.html +++ b/src/app/lnd/transactions/send-receive/send-receive-trans.component.html @@ -98,7 +98,7 @@
-
+
diff --git a/src/app/lnd/transactions/send-receive/send-receive-trans.component.ts b/src/app/lnd/transactions/send-receive/send-receive-trans.component.ts index 2313f6cd..96b2236b 100644 --- a/src/app/lnd/transactions/send-receive/send-receive-trans.component.ts +++ b/src/app/lnd/transactions/send-receive/send-receive-trans.component.ts @@ -9,11 +9,9 @@ import { RTLConfiguration } from '../../../shared/models/RTLconfig'; import { LoggerService } from '../../../shared/services/logger.service'; import * as sha256 from 'sha256'; -import { LNDEffects } from '../../store/lnd.effects'; -import { RTLEffects } from '../../../store/rtl.effects'; -import * as LNDActions from '../../store/lnd.actions'; -import * as RTLActions from '../../../store/rtl.actions'; -import * as fromApp from '../../../store/rtl.reducers'; +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', @@ -33,18 +31,25 @@ export class SendReceiveTransComponent implements OnInit, OnDestroy { public transTypes = [{id: '1', name: 'Target Confirmation Blocks'}, {id: '2', name: 'Fee'}]; public selTransType = '1'; public flgCustomAmount = '1'; - private unsubs: Array> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()]; + private unsub: Array> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject()]; - constructor(private logger: LoggerService, private store: Store, private rtlEffects: RTLEffects, private lndEffects: LNDEffects) {} + constructor(private logger: LoggerService, private store: Store, private rtlEffects: RTLEffects) {} ngOnInit() { - this.store.select('lnd') - .pipe(takeUntil(this.unsubs[5])) - .subscribe(lndStore => { - this.information = lndStore.information; - this.addressTypes = lndStore.addressTypes; + 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.selNode = rtlStore.selNode; + this.appConfig = rtlStore.appConfig; + this.information = rtlStore.information; + this.addressTypes = rtlStore.addressTypes; - this.blockchainBalance = lndStore.blockchainBalance; + this.blockchainBalance = rtlStore.blockchainBalance; if (undefined === this.blockchainBalance.total_balance) { this.blockchainBalance.total_balance = '0'; } @@ -57,19 +62,7 @@ export class SendReceiveTransComponent implements OnInit, OnDestroy { if (this.flgLoadingWallet !== 'error') { this.flgLoadingWallet = false; } - this.logger.info(lndStore); - }); - this.store.select('rtlRoot') - .pipe(takeUntil(this.unsubs[0])) - .subscribe((rtlStore: fromApp.RootState) => { - rtlStore.effectErrors.forEach(effectsErr => { - if (effectsErr.action === 'FetchBalance/blockchain') { - this.flgLoadingWallet = 'error'; - } - }); - this.selNode = rtlStore.selNode; - this.appConfig = rtlStore.appConfig; this.logger.info(rtlStore); }); @@ -77,9 +70,9 @@ export class SendReceiveTransComponent implements OnInit, OnDestroy { onGenerateAddress() { this.store.dispatch(new RTLActions.OpenSpinner('Getting New Address...')); - this.store.dispatch(new LNDActions.GetNewAddress(this.selectedAddress)); - this.lndEffects.setNewAddress - .pipe(takeUntil(this.unsubs[1])) + this.store.dispatch(new RTLActions.GetNewAddress(this.selectedAddress)); + this.rtlEffects.setNewAddress + .pipe(takeUntil(this.unsub[1])) .subscribe(newAddress => { this.newAddress = newAddress; }); @@ -108,7 +101,7 @@ export class SendReceiveTransComponent implements OnInit, OnDestroy { })); this.rtlEffects.closeConfirm - .pipe(takeUntil(this.unsubs[2])) + .pipe(takeUntil(this.unsub[2])) .subscribe(confirmRes => { if (confirmRes) { if (this.transaction.sendAll && !+this.appConfig.sso.rtlSSO) { @@ -118,7 +111,7 @@ export class SendReceiveTransComponent implements OnInit, OnDestroy { ]} })); this.rtlEffects.closeConfirm - .pipe(takeUntil(this.unsubs[3])) + .pipe(takeUntil(this.unsub[3])) .subscribe(pwdConfirmRes => { if (pwdConfirmRes) { const pwd = pwdConfirmRes[0].inputValue; @@ -141,7 +134,7 @@ export class SendReceiveTransComponent implements OnInit, OnDestroy { dispatchToSendFunds() { this.store.dispatch(new RTLActions.OpenSpinner('Sending Funds...')); - this.store.dispatch(new LNDActions.SetChannelTransaction(this.transaction)); + this.store.dispatch(new RTLActions.SetChannelTransaction(this.transaction)); this.transaction = {address: '', amount: 0, blocks: 0, fees: 0}; } @@ -175,7 +168,7 @@ export class SendReceiveTransComponent implements OnInit, OnDestroy { } ngOnDestroy() { - this.unsubs.forEach(completeSub => { + this.unsub.forEach(completeSub => { completeSub.next(); completeSub.complete(); }); diff --git a/src/app/lnd/unlock-lnd/unlock-lnd.component.ts b/src/app/lnd/unlock-lnd/unlock-lnd.component.ts index 95cee1f1..b3276d23 100644 --- a/src/app/lnd/unlock-lnd/unlock-lnd.component.ts +++ b/src/app/lnd/unlock-lnd/unlock-lnd.component.ts @@ -1,17 +1,15 @@ import { Component, OnInit, OnDestroy, ViewChild } from '@angular/core'; -import { Router, ActivatedRoute } from '@angular/router'; +import { Router } from '@angular/router'; import { Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; +import { takeUntil, take } from 'rxjs/operators'; import { Store } from '@ngrx/store'; -import { FormBuilder, FormGroup, Validators, ValidatorFn, ValidationErrors } from '@angular/forms'; +import { FormBuilder, FormGroup, Validators, ValidatorFn, AbstractControl, ValidationErrors } from '@angular/forms'; import { STEPPER_GLOBAL_OPTIONS } from '@angular/cdk/stepper'; import { MatStepper } from '@angular/material'; -import { LNDEffects } from '../store/lnd.effects'; -import { RTLEffects } from '../../store/rtl.effects'; -import * as LNDActions from '../store/lnd.actions'; -import * as RTLActions from '../../store/rtl.actions'; -import * as fromApp from '../../store/rtl.reducers'; +import { RTLEffects } from '../../shared/store/rtl.effects'; +import * as RTLActions from '../../shared/store/rtl.actions'; +import * as fromRTLReducer from '../../shared/store/rtl.reducers'; export const matchedPasswords: ValidatorFn = (control: FormGroup): ValidationErrors | null => { const initWalletPassword = control.get('initWalletPassword'); @@ -48,8 +46,7 @@ export class UnlockLNDComponent implements OnInit, OnDestroy { warnRes = true; private unsubs = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject()]; - constructor(private store: Store, private formBuilder: FormBuilder, private rtlEffects: RTLEffects, - private lndEffects: LNDEffects, private router: Router, private activatedRoute: ActivatedRoute) {} + constructor(private store: Store, private formBuilder: FormBuilder, private rtlEffects: RTLEffects, private router: Router) {} ngOnInit() { this.walletPassword = ''; @@ -88,13 +85,13 @@ export class UnlockLNDComponent implements OnInit, OnDestroy { this.insecureLND = !window.location.protocol.includes('https://'); - this.lndEffects.initWalletRes + this.rtlEffects.initWalletRes .pipe(takeUntil(this.unsubs[2])) .subscribe(initWalletResponse => { this.initWalletResponse = initWalletResponse; }); - this.lndEffects.genSeedResponse + this.rtlEffects.genSeedResponse .pipe(takeUntil(this.unsubs[3])) .subscribe(genSeedRes => { this.genSeedResponse = genSeedRes; @@ -105,7 +102,7 @@ export class UnlockLNDComponent implements OnInit, OnDestroy { // passphrase: window.btoa(this.passphraseFormGroup.controls.passphrase.value) // })); // } else { - this.store.dispatch(new LNDActions.InitWallet({ + this.store.dispatch(new RTLActions.InitWallet({ pwd: window.btoa(this.passwordFormGroup.controls.initWalletPassword.value), cipher: this.genSeedResponse })); @@ -116,7 +113,7 @@ export class UnlockLNDComponent implements OnInit, OnDestroy { onOperateWallet() { this.store.dispatch(new RTLActions.OpenSpinner('Unlocking...')); - this.store.dispatch(new LNDActions.UnlockWallet({pwd: window.btoa(this.walletPassword)})); + this.store.dispatch(new RTLActions.UnlockWallet({pwd: window.btoa(this.walletPassword)})); } onInitWallet() { @@ -124,22 +121,22 @@ export class UnlockLNDComponent implements OnInit, OnDestroy { if (this.cipherFormGroup.controls.existingCipher.value) { const cipherArr = this.cipherFormGroup.controls.cipherSeed.value.toString().trim().split(','); if (this.passphraseFormGroup.controls.enterPassphrase.value) { - this.store.dispatch(new LNDActions.InitWallet({ + this.store.dispatch(new RTLActions.InitWallet({ pwd: window.btoa(this.passwordFormGroup.controls.initWalletPassword.value), cipher: cipherArr, passphrase: window.btoa(this.passphraseFormGroup.controls.passphrase.value) })); } else { - this.store.dispatch(new LNDActions.InitWallet({ + this.store.dispatch(new RTLActions.InitWallet({ pwd: window.btoa(this.passwordFormGroup.controls.initWalletPassword.value), cipher: cipherArr })); } } else { if (this.passphraseFormGroup.controls.enterPassphrase.value) { - this.store.dispatch(new LNDActions.GenSeed(window.btoa(this.passphraseFormGroup.controls.passphrase.value))); + this.store.dispatch(new RTLActions.GenSeed(window.btoa(this.passphraseFormGroup.controls.passphrase.value))); } else { - this.store.dispatch(new LNDActions.GenSeed('')); + this.store.dispatch(new RTLActions.GenSeed('')); } } } @@ -147,7 +144,7 @@ export class UnlockLNDComponent implements OnInit, OnDestroy { onGoToHome() { setTimeout(() => { this.store.dispatch(new RTLActions.InitAppData()); - this.router.navigate(['../'], { relativeTo: this.activatedRoute }); + this.router.navigate(['/lnd/']); }, 1000 * 1); } diff --git a/src/app/shared/components/confirmation-message/confirmation-message.component.ts b/src/app/shared/components/confirmation-message/confirmation-message.component.ts index 548bb704..f6a3e5f1 100644 --- a/src/app/shared/components/confirmation-message/confirmation-message.component.ts +++ b/src/app/shared/components/confirmation-message/confirmation-message.component.ts @@ -5,8 +5,8 @@ import { Store } from '@ngrx/store'; import { LoggerService } from '../../../shared/services/logger.service'; import { AlertData, InputData } from '../../../shared/models/alertData'; -import * as RTLActions from '../../../store/rtl.actions'; -import * as fromApp from '../../../store/rtl.reducers'; +import * as RTLActions from '../../../shared/store/rtl.actions'; +import * as fromRTLReducer from '../../../shared/store/rtl.reducers'; @Component({ selector: 'rtl-confirmation-message', @@ -24,7 +24,7 @@ export class ConfirmationMessageComponent implements OnInit { public getInputs: Array = [{placeholder: '', inputType: 'text', inputValue: ''}]; constructor(public dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: AlertData, private logger: LoggerService, - private store: Store) { } + private store: Store) { } ngOnInit() { this.flgShowInput = this.data.flgShowInput; diff --git a/src/app/shared/components/help/help.component.ts b/src/app/shared/components/help/help.component.ts index 54e59029..3ba67079 100644 --- a/src/app/shared/components/help/help.component.ts +++ b/src/app/shared/components/help/help.component.ts @@ -21,6 +21,8 @@ export class HelpComponent implements OnInit { 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/shared/components/navigation/horizontal-navigation/horizontal-navigation.component.html b/src/app/shared/components/navigation/horizontal-navigation/horizontal-navigation.component.html index b7ec659b..816d2551 100644 --- a/src/app/shared/components/navigation/horizontal-navigation/horizontal-navigation.component.html +++ b/src/app/shared/components/navigation/horizontal-navigation/horizontal-navigation.component.html @@ -1,6 +1,6 @@
-
@@ -9,7 +9,7 @@
-
diff --git a/src/app/shared/components/navigation/horizontal-navigation/horizontal-navigation.component.ts b/src/app/shared/components/navigation/horizontal-navigation/horizontal-navigation.component.ts index 367d3bd4..98609ecf 100644 --- a/src/app/shared/components/navigation/horizontal-navigation/horizontal-navigation.component.ts +++ b/src/app/shared/components/navigation/horizontal-navigation/horizontal-navigation.component.ts @@ -7,9 +7,9 @@ import { Actions } from '@ngrx/effects'; import { LoggerService } from '../../../services/logger.service'; import { MENU_DATA } from '../../../models/navMenu'; -import { RTLEffects } from '../../../../store/rtl.effects'; -import * as RTLActions from '../../../../store/rtl.actions'; -import * as fromApp from '../../../../store/rtl.reducers'; +import { RTLEffects } from '../../../store/rtl.effects'; +import * as RTLActions from '../../../store/rtl.actions'; +import * as fromRTLReducer from '../../../store/rtl.reducers'; @Component({ selector: 'rtl-horizontal-navigation', @@ -23,16 +23,19 @@ export class HorizontalNavigationComponent implements OnInit { 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; + constructor(private logger: LoggerService, private store: Store, private actions$: Actions, private rtlEffects: RTLEffects) { } ngOnInit() { - this.store.select('lnd') + this.store.select('rtlRoot') .pipe(takeUntil(this.unSubs[0])) - .subscribe(lndStore => { - this.numPendingChannels = lndStore.numberOfPendingChannels; - this.logger.info(lndStore); + .subscribe((rtlStore: fromRTLReducer.State) => { + this.numPendingChannels = rtlStore.numberOfPendingChannels; + if(+rtlStore.selNode.index === 1) { + this.menuNodes = MENU_DATA.LNDChildren; + } else { + this.menuNodes = MENU_DATA.LNDChildren; + } }); this.actions$ .pipe( @@ -41,14 +44,14 @@ export class HorizontalNavigationComponent implements OnInit { ).subscribe((action) => { this.logger.warn(action); if (action.type === RTLActions.SIGNIN) { - this.menuNodes.push({id: 100, parentId: 0, name: 'Logout', icon: 'eject'}); + this.menuNodes.push({id: 200, 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'}); + this.menuNodes.push({id: 200, parentId: 0, name: 'Logout', icon: 'eject'}); } } diff --git a/src/app/shared/components/navigation/side-navigation/side-navigation.component.html b/src/app/shared/components/navigation/side-navigation/side-navigation.component.html index 7da1730b..94fc560b 100644 --- a/src/app/shared/components/navigation/side-navigation/side-navigation.component.html +++ b/src/app/shared/components/navigation/side-navigation/side-navigation.component.html @@ -1,6 +1,6 @@ - - + + @@ -16,7 +16,7 @@
- + {{node.icon}} {{node.name}} @@ -40,7 +40,7 @@ - + {{node.icon}} {{node.name}} diff --git a/src/app/shared/components/navigation/side-navigation/side-navigation.component.ts b/src/app/shared/components/navigation/side-navigation/side-navigation.component.ts index 2aa00611..9a9d9eda 100644 --- a/src/app/shared/components/navigation/side-navigation/side-navigation.component.ts +++ b/src/app/shared/components/navigation/side-navigation/side-navigation.component.ts @@ -9,14 +9,14 @@ import { environment } from '../../../../../environments/environment'; import { FlatTreeControl } from '@angular/cdk/tree'; import { MatTreeFlatDataSource, MatTreeFlattener } from '@angular/material/tree'; -import { GetInfo, GetInfoChain } from '../../../models/lndModels'; import { Node, Settings } from '../../../models/RTLconfig'; import { LoggerService } from '../../../services/logger.service'; -import { MenuNode, FlatMenuNode, MENU_DATA } from '../../../models/navMenu'; +import { GetInfo, GetInfoChain } from '../../../models/lndModels'; +import { MenuChildNode, FlatMenuNode, MENU_DATA } from '../../../models/navMenu'; -import { RTLEffects } from '../../../../store/rtl.effects'; -import * as RTLActions from '../../../../store/rtl.actions'; -import * as fromApp from '../../../../store/rtl.reducers'; +import { RTLEffects } from '../../../store/rtl.effects'; +import * as RTLActions from '../../../store/rtl.actions'; +import * as fromRTLReducer from '../../../store/rtl.reducers'; @Component({ selector: 'rtl-side-navigation', @@ -29,29 +29,30 @@ export class SideNavigationComponent implements OnInit, OnDestroy { public settings: Settings; public version = ''; public information: GetInfo = {}; - public informationChain: GetInfoChain = {}; + public informationChain: GetInfoChain = {}; public flgLoading = true; - public logoutNode = [{id: 100, parentId: 0, name: 'Logout', icon: 'eject'}]; + public logoutNode = [{id: 200, parentId: 0, name: 'Logout', icon: 'eject'}]; public showLogout = false; public numPendingChannels = 0; public smallScreen = false; - private unSubs = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()]; + public childRootRoute = ''; + private unSubs = [new Subject(), new Subject(), new Subject()]; treeControl: FlatTreeControl; treeControlLogout: FlatTreeControl; - treeFlattener: MatTreeFlattener; - treeFlattenerLogout: MatTreeFlattener; - navMenus: MatTreeFlatDataSource; - navMenusLogout: MatTreeFlatDataSource; + treeFlattener: MatTreeFlattener; + treeFlattenerLogout: MatTreeFlattener; + navMenus: MatTreeFlatDataSource; + navMenusLogout: MatTreeFlatDataSource; - constructor(private logger: LoggerService, private store: Store, private actions$: Actions, private rtlEffects: RTLEffects, private router: Router, private activatedRoute: ActivatedRoute) { + constructor(private logger: LoggerService, private store: Store, private actions$: Actions, private rtlEffects: RTLEffects, private router: Router, private activatedRoute: ActivatedRoute) { this.version = environment.VERSION; - if (MENU_DATA.children[MENU_DATA.children.length - 1].id === 100) { - MENU_DATA.children.pop(); + if (MENU_DATA.LNDChildren[MENU_DATA.LNDChildren.length - 1].id === 200) { + MENU_DATA.LNDChildren.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.navMenus.data = MENU_DATA.LNDChildren; this.treeFlattenerLogout = new MatTreeFlattener(this.transformer, this.getLevel, this.isExpandable, this.getChildren); this.treeControlLogout = new FlatTreeControl(this.getLevel, this.isExpandable); @@ -60,39 +61,41 @@ export class SideNavigationComponent implements OnInit, OnDestroy { } ngOnInit() { - this.store.select('lnd') - .pipe(takeUntil(this.unSubs[3])) - .subscribe(lndStore => { - this.numPendingChannels = lndStore ? lndStore.numberOfPendingChannels : -1; - this.logger.info(lndStore); - }); this.store.select('rtlRoot') .pipe(takeUntil(this.unSubs[0])) - .subscribe((rtlStore: fromApp.RootState) => { + .subscribe((rtlStore: fromRTLReducer.State) => { this.selNode = rtlStore.selNode; this.settings = this.selNode.settings; - this.showLogout = (sessionStorage.getItem('token')) ? true : false; - if (this.selNode.lnImplementation.toLowerCase() === 'clightning') { - this.store.select('cl') - .pipe(takeUntil(this.unSubs[4])) - .subscribe((clStore) => { - this.information = clStore.information; - this.readInformation(); - }); + 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.store.select('lnd') - .pipe(takeUntil(this.unSubs[5])) - .subscribe((lndStore) => { - this.information = lndStore.information; - this.readInformation(); - }); + 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; } + if(+this.selNode.index === 1) { + this.navMenus.data = MENU_DATA.LNDChildren; + } else { + this.navMenus.data = MENU_DATA.CLChildren; + } this.logger.info(rtlStore); }); this.actions$ @@ -104,30 +107,13 @@ export class SideNavigationComponent implements OnInit, OnDestroy { }); } - private readInformation() { - 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; - } - - private transformer(node: MenuNode, level: number) { return new FlatMenuNode(!!node.children, level, node.id, node.parentId, node.name, node.icon, node.link); } + private transformer(node: MenuChildNode, 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); } + private getChildren(node: MenuChildNode): Observable { return of(node.children); } hasChild(_: number, _nodeData: FlatMenuNode) { return _nodeData.expandable; } @@ -144,7 +130,7 @@ export class SideNavigationComponent implements OnInit, OnDestroy { } } - onClick(node: MenuNode) { + onClick(node: MenuChildNode) { if (node.name === 'Logout') { this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data: { type: 'CONFIRM', titleMessage: 'Logout from this device?', noBtnText: 'Cancel', yesBtnText: 'Logout' diff --git a/src/app/shared/components/navigation/top-menu/top-menu.component.ts b/src/app/shared/components/navigation/top-menu/top-menu.component.ts index 1f2f3980..52dcafc1 100644 --- a/src/app/shared/components/navigation/top-menu/top-menu.component.ts +++ b/src/app/shared/components/navigation/top-menu/top-menu.component.ts @@ -9,9 +9,9 @@ import { LoggerService } from '../../../services/logger.service'; import { GetInfo, GetInfoChain } from '../../../models/lndModels'; import { environment } from '../../../../../environments/environment'; -import { RTLEffects } from '../../../../store/rtl.effects'; -import * as fromApp from '../../../../store/rtl.reducers'; -import * as RTLActions from '../../../../store/rtl.actions'; +import { RTLEffects } from '../../../store/rtl.effects'; +import * as fromRTLReducer from '../../../store/rtl.reducers'; +import * as RTLActions from '../../../store/rtl.actions'; @Component({ selector: 'rtl-top-menu', @@ -25,17 +25,19 @@ export class TopMenuComponent implements OnInit, OnDestroy { public informationChain: GetInfoChain = {}; public flgLoading = true; public showLogout = false; - private unSubs = [new Subject(), new Subject(), new Subject(), new Subject()]; + private unSubs = [new Subject(), new Subject(), new Subject()]; - constructor(private logger: LoggerService, private store: Store, private rtlEffects: RTLEffects, private actions$: Actions) { + constructor(private logger: LoggerService, private store: Store, private rtlEffects: RTLEffects, private actions$: Actions) { this.version = environment.VERSION; } ngOnInit() { - this.store.select('lnd') - .pipe(takeUntil(this.unSubs[3])) - .subscribe(lndStore => { - this.information = lndStore ? lndStore.information : {}; + this.store.select('rtlRoot') + .pipe(takeUntil(this.unSubs[0])) + .subscribe((rtlStore: fromRTLReducer.State) => { + this.selNode = rtlStore.selNode; + + this.information = rtlStore.information; this.flgLoading = (undefined !== this.information.identity_pubkey) ? false : true; if (undefined !== this.information.identity_pubkey) { @@ -51,13 +53,8 @@ export class TopMenuComponent implements OnInit, OnDestroy { this.informationChain.chain = ''; this.informationChain.network = ''; } - this.logger.info(lndStore); - }); - this.store.select('rtlRoot') - .pipe(takeUntil(this.unSubs[0])) - .subscribe((rtlStore: fromApp.RootState) => { - this.selNode = rtlStore.selNode; this.showLogout = (sessionStorage.getItem('token')) ? true : false; + this.logger.info(rtlStore); if (!sessionStorage.getItem('token')) { this.flgLoading = false; diff --git a/src/app/shared/components/not-found/not-found.component.html b/src/app/shared/components/not-found/not-found.component.html index d82353af..de7e470a 100644 --- a/src/app/shared/components/not-found/not-found.component.html +++ b/src/app/shared/components/not-found/not-found.component.html @@ -9,6 +9,7 @@
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 index 17a2f75d..b2d93e1c 100644 --- a/src/app/shared/components/not-found/not-found.component.ts +++ b/src/app/shared/components/not-found/not-found.component.ts @@ -1,7 +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 {} +export class NotFoundComponent { + + constructor(public router: Router) {} + + goToHelp(): void { + this.router.navigate(['/help']); + } + +} diff --git a/src/app/shared/components/server-config/server-config.component.ts b/src/app/shared/components/server-config/server-config.component.ts index a78eefa5..479aa6e0 100644 --- a/src/app/shared/components/server-config/server-config.component.ts +++ b/src/app/shared/components/server-config/server-config.component.ts @@ -4,11 +4,9 @@ import { takeUntil } from 'rxjs/operators'; import { Store } from '@ngrx/store'; import { Node } from '../../models/RTLconfig'; - -import { LNDEffects } from '../../../lnd/store/lnd.effects'; -import * as LNDActions from '../../../lnd/store/lnd.actions'; -import * as RTLActions from '../../../store/rtl.actions'; -import * as fromApp from '../../../store/rtl.reducers'; +import { RTLEffects } from '../../store/rtl.effects'; +import * as RTLActions from '../../store/rtl.actions'; +import * as fromRTLReducer from '../../store/rtl.reducers'; @Component({ selector: 'rtl-server-config', @@ -24,12 +22,12 @@ export class ServerConfigComponent implements OnInit, OnDestroy { public fileFormat = 'INI'; private unsubs: Array> = [new Subject(), new Subject()]; - constructor(private store: Store, private lndEffects: LNDEffects) {} + constructor(private store: Store, private rtlEffects: RTLEffects) {} ngOnInit() { this.store.select('rtlRoot') .pipe(takeUntil(this.unsubs[0])) - .subscribe((rtlStore: fromApp.RootState) => { + .subscribe((rtlStore: fromRTLReducer.State) => { rtlStore.effectErrors.forEach(effectsErr => { if (effectsErr.action === 'fetchConfig') { this.resetData(); @@ -61,8 +59,8 @@ export class ServerConfigComponent implements OnInit, OnDestroy { onShowConfig() { this.store.dispatch(new RTLActions.OpenSpinner('Opening Config File...')); - this.store.dispatch(new LNDActions.FetchConfig(this.selectedNodeType)); - this.lndEffects.showLNDConfig + this.store.dispatch(new RTLActions.FetchConfig(this.selectedNodeType)); + this.rtlEffects.showLNDConfig .pipe(takeUntil(this.unsubs[1])) .subscribe((config: any) => { const configFile = config.data; diff --git a/src/app/shared/components/settings-nav/settings-nav.component.ts b/src/app/shared/components/settings-nav/settings-nav.component.ts index 7123cd82..4cfb58a5 100644 --- a/src/app/shared/components/settings-nav/settings-nav.component.ts +++ b/src/app/shared/components/settings-nav/settings-nav.component.ts @@ -7,8 +7,8 @@ import { Node, RTLConfiguration } from '../../models/RTLconfig'; import { GetInfo } from '../../models/lndModels'; import { LoggerService } from '../../services/logger.service'; -import * as RTLActions from '../../../store/rtl.actions'; -import * as fromApp from '../../../store/rtl.reducers'; +import * as RTLActions from '../../store/rtl.actions'; +import * as fromRTLReducer from '../../store/rtl.reducers'; @Component({ selector: 'rtl-settings-nav', @@ -26,22 +26,15 @@ export class SettingsNavComponent implements OnInit, OnDestroy { public showSettingOption = true; public appConfig: RTLConfiguration; - unsubs: Array> = [new Subject(), new Subject(), new Subject()]; - @Output() done: EventEmitter = new EventEmitter(); + unsubs: Array> = [new Subject(), new Subject()]; + @Output('done') done: EventEmitter = new EventEmitter(); - constructor(private logger: LoggerService, private store: Store) {} + constructor(private logger: LoggerService, private store: Store) {} ngOnInit() { - this.store.select('lnd') - .pipe(takeUntil(this.unsubs[2])) - .subscribe(lndStore => { - this.information = lndStore ? lndStore.information : {}; - this.currencyUnit = (undefined !== this.information && undefined !== this.information.currency_unit) ? this.information.currency_unit : 'BTC'; - this.logger.info(lndStore); - }); this.store.select('rtlRoot') .pipe(takeUntil(this.unsubs[0])) - .subscribe((rtlStore: fromApp.RootState) => { + .subscribe((rtlStore: fromRTLReducer.State) => { this.appConfig = rtlStore.appConfig; this.selNode = rtlStore.selNode; this.selectedMenu = this.selNode.settings.menu; @@ -52,6 +45,8 @@ export class SettingsNavComponent implements OnInit, OnDestroy { this.selNode.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); }); } diff --git a/src/app/shared/components/signin/signin.component.ts b/src/app/shared/components/signin/signin.component.ts index 8b027c4b..70e81422 100644 --- a/src/app/shared/components/signin/signin.component.ts +++ b/src/app/shared/components/signin/signin.component.ts @@ -6,8 +6,8 @@ import { Store } from '@ngrx/store'; import { Node } from '../../models/RTLconfig'; import { LoggerService } from '../../services/logger.service'; -import * as fromApp from '../../../store/rtl.reducers'; -import * as RTLActions from '../../../store/rtl.actions'; +import * as fromRTLReducer from '../../store/rtl.reducers'; +import * as RTLActions from '../../store/rtl.actions'; @Component({ selector: 'rtl-signin', @@ -25,12 +25,12 @@ export class SigninComponent implements OnInit, OnDestroy { private unsub: Array> = [new Subject(), new Subject(), new Subject()]; - constructor(private logger: LoggerService, private store: Store) { } + constructor(private logger: LoggerService, private store: Store) { } ngOnInit() { this.store.select('rtlRoot') .pipe(takeUntil(this.unsub[0])) - .subscribe((rtlStore: fromApp.RootState) => { + .subscribe((rtlStore: fromRTLReducer.State) => { rtlStore.effectErrors.forEach(effectsErr => { this.logger.error(effectsErr); }); @@ -40,7 +40,7 @@ export class SigninComponent implements OnInit, OnDestroy { if (this.nodeAuthType.toUpperCase() === 'DEFAULT') { this.hintStr = 'Enter RPC password'; } else { - this.hintStr = ''; + this.hintStr = ''; // Do not remove, initial passowrd 'DEFAULT' is initilizing its value } }); } diff --git a/src/app/shared/models/clModels.ts b/src/app/shared/models/clModels.ts deleted file mode 100644 index e0764702..00000000 --- a/src/app/shared/models/clModels.ts +++ /dev/null @@ -1,43 +0,0 @@ -// export interface GetInfoAddress { -// type?: string; -// address?: string; -// port?: number; -// } - -// export interface GetInfo { -// id?: string; -// alias?: string; -// color?: string; -// num_peers?: number; -// num_pending_channels?: number; -// num_active_channels?: number; -// num_inactive_channels?: number; -// address?: GetInfoAddress[]; -// binding?: GetInfoAddress[]; -// version?: string; -// blockheight?: number; -// network?: string; -// msatoshi_fees_collected?: number; -// fees_collected_msat?: string; -// } - -export interface GetInfoChain { - chain?: string; - network?: string; -} - -export interface GetInfo { - identity_pubkey?: string; - alias?: string; - num_pending_channels?: number; - num_active_channels?: number; - num_inactive_channels?: number; - num_peers?: number; - block_height?: number; - synced_to_chain?: boolean; - testnet?: boolean; - chains?: GetInfoChain[]; - version?: string; - currency_unit?: string; - smaller_currency_unit?: string; -} diff --git a/src/app/shared/models/lndModels.ts b/src/app/shared/models/lndModels.ts index 4bd1c893..977958b5 100644 --- a/src/app/shared/models/lndModels.ts +++ b/src/app/shared/models/lndModels.ts @@ -5,16 +5,16 @@ export interface AddressType { } export interface Balance { - btc_balance?: string; - balance?: string; - btc_pending_open_balance?: string; - pending_open_balance?: string; - btc_total_balance?: string; - total_balance?: string; - btc_confirmed_balance?: string; - confirmed_balance?: string; - btc_unconfirmed_balance?: string; - unconfirmed_balance?: string; + 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 { @@ -271,7 +271,7 @@ export interface PayRequest { export interface Peer { pub_key?: string; alias?: string; - address?: string; + address?: string; // host bytes_sent?: number; bytes_recv?: number; sat_sent?: string; diff --git a/src/app/shared/models/navMenu.ts b/src/app/shared/models/navMenu.ts index ac710708..6dcc9a7e 100644 --- a/src/app/shared/models/navMenu.ts +++ b/src/app/shared/models/navMenu.ts @@ -1,42 +1,47 @@ -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'}, +export const MENU_DATA: MenuRootNode = { + LNDChildren: [ + {id: 1, parentId: 0, name: 'Home', icon: 'home', link: '/lnd/home'}, + {id: 2, parentId: 0, name: 'LND Wallet', icon: 'account_balance_wallet', link: '/lnd/transsendreceive', children: [ + {id: 21, parentId: 2, name: 'Send/Receive', icon: 'compare_arrows', link: '/lnd/transsendreceive'}, + {id: 22, parentId: 2, name: 'List Transactions', icon: 'list_alt', link: '/lnd/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: 44, parentId: 4, name: 'Backup', icon: 'cloud_circle', link: 'chnlbackup'} + {id: 3, parentId: 0, name: 'Peers', icon: 'group', link: '/lnd/peers'}, + {id: 4, parentId: 0, name: 'Channels', icon: 'settings_ethernet', link: '/lnd/chnlmanage', children: [ + {id: 41, parentId: 4, name: 'Management', icon: 'subtitles', link: '/lnd/chnlmanage'}, + {id: 42, parentId: 4, name: 'Pending', icon: 'watch', link: '/lnd/chnlpending'}, + {id: 43, parentId: 4, name: 'Closed', icon: 'watch_later', link: '/lnd/chnlclosed'}, + {id: 44, parentId: 4, name: 'Backup', icon: 'cloud_circle', link: '/lnd/chnlbackup'} ]}, - {id: 5, parentId: 0, name: 'Payments', icon: 'payment', link: 'paymentsend', children: [ - {id: 51, parentId: 5, name: 'Send', icon: 'send', link: 'paymentsend'}, - {id: 52, parentId: 5, name: 'Query Routes', icon: 'explore', link: 'queryroutes'} + {id: 5, parentId: 0, name: 'Payments', icon: 'payment', link: '/lnd/paymentsend', children: [ + {id: 51, parentId: 5, name: 'Send', icon: 'send', link: '/lnd/paymentsend'}, + {id: 52, parentId: 5, name: 'Query Routes', icon: 'explore', link: '/lnd/queryroutes'} ]}, - {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: 'Routing Peers', icon: 'group_work', link: 'routingpeers'}, - {id: 9, parentId: 0, name: 'Lookups', icon: 'search', link: 'lookups'}, - {id: 10, parentId: 0, name: 'Node Config', icon: 'perm_data_setting', link: 'sconfig'}, - {id: 11, parentId: 0, name: 'Help', icon: 'help', link: 'help'} + {id: 6, parentId: 0, name: 'Invoices', icon: 'receipt', link: '/lnd/invoices'}, + {id: 7, parentId: 0, name: 'Forwarding History', icon: 'timeline', link: '/lnd/switch'}, + {id: 8, parentId: 0, name: 'Routing Peers', icon: 'group_work', link: '/lnd/routingpeers'}, + {id: 9, parentId: 0, name: 'Lookups', icon: 'search', link: '/lnd/lookups'}, + {id: 10, parentId: 0, name: 'Node Config', icon: 'perm_data_setting', link: '../sconfig'}, + {id: 11, parentId: 0, name: 'Help', icon: 'help', link: '../help'} + ], + CLChildren: [ + {id: 1, parentId: 0, name: 'Home', icon: 'home', link: '/cl/home'}, + {id: 10, parentId: 0, name: 'Node Config', icon: 'perm_data_setting', link: '../sconfig'}, + {id: 11, parentId: 0, name: 'Help', icon: 'help', link: '../help'} ] }; -export class MenuNode { +export class MenuRootNode { + LNDChildren?: MenuChildNode[]; + CLChildren?: MenuChildNode[]; +} + +export class MenuChildNode { id: number; parentId: number; name?: string; icon?: string; link?: any; - children?: MenuNode[]; + children?: MenuChildNode[]; } export class FlatMenuNode { diff --git a/src/app/shared/services/auth.guard.ts b/src/app/shared/services/auth.guard.ts index a3f12af5..7a17b6c3 100644 --- a/src/app/shared/services/auth.guard.ts +++ b/src/app/shared/services/auth.guard.ts @@ -27,3 +27,17 @@ export class LNDUnlockedGuard implements CanActivate { } } } + +@Injectable() +export class CLUnlockedGuard implements CanActivate { + constructor() {} + + canActivate(): boolean | Observable | Promise { + return true; + if (!sessionStorage.getItem('clUnlocked')) { + return false; + } else { + return true; + } + } +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 2b9dad85..d9205a2d 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -1,7 +1,8 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { RouterModule } from '@angular/router'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { HttpClientModule } from '@angular/common/http'; import { FlexLayoutModule } from '@angular/flex-layout'; import { MatButtonModule, MatButtonToggleModule, MatCardModule, MatCheckboxModule, MatDialogModule, MatExpansionModule, MatGridListModule, MatDatepickerModule, @@ -9,21 +10,23 @@ import { MatSelectModule, MatSidenavModule, MatSlideToggleModule, MatSortModule, MatTableModule, MatToolbarModule, MatTooltipModule, MAT_DIALOG_DEFAULT_OPTIONS, MatBadgeModule, MatPaginatorModule, MatStepperModule } from '@angular/material'; + import { QRCodeModule } from 'angularx-qrcode'; +import { NgxChartsModule } from '@swimlane/ngx-charts'; -import { SideNavigationComponent } from './components/navigation/side-navigation/side-navigation.component'; -import { TopMenuComponent } from './components/navigation/top-menu/top-menu.component'; -import { HorizontalNavigationComponent } from './components/navigation/horizontal-navigation/horizontal-navigation.component'; 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 { ServerConfigComponent } from './components/server-config/server-config.component'; -import { HelpComponent } from './components/help/help.component'; -import { SigninComponent } from './components/signin/signin.component'; import { NotFoundComponent } from './components/not-found/not-found.component'; +import { SigninComponent } from './components/signin/signin.component'; +import { HelpComponent } from './components/help/help.component'; +import { SideNavigationComponent } from './components/navigation/side-navigation/side-navigation.component'; +import { TopMenuComponent } from './components/navigation/top-menu/top-menu.component'; +import { HorizontalNavigationComponent } from './components/navigation/horizontal-navigation/horizontal-navigation.component'; import { SettingsNavComponent } from './components/settings-nav/settings-nav.component'; -import { ClipboardDirective } from './directive/clipboard.directive'; +import { ServerConfigComponent } from './components/server-config/server-config.component'; import { SsoFailedComponent } from './components/sso-failed/sso-failed.component'; +import { ClipboardDirective } from './directive/clipboard.directive'; import { RemoveLeadingZerosPipe } from './pipes/remove-leading-zero.pipe'; @NgModule({ @@ -31,7 +34,6 @@ import { RemoveLeadingZerosPipe } from './pipes/remove-leading-zero.pipe'; CommonModule, FormsModule, ReactiveFormsModule, - RouterModule, FlexLayoutModule, MatButtonModule, MatButtonToggleModule, @@ -60,7 +62,11 @@ import { RemoveLeadingZerosPipe } from './pipes/remove-leading-zero.pipe'; MatBadgeModule, MatPaginatorModule, MatStepperModule, - QRCodeModule + QRCodeModule, + NgxChartsModule, + RouterModule, + HttpClientModule, + NgxChartsModule ], exports: [ FormsModule, @@ -97,32 +103,33 @@ import { RemoveLeadingZerosPipe } from './pipes/remove-leading-zero.pipe'; ConfirmationMessageComponent, SpinnerDialogComponent, NotFoundComponent, - ServerConfigComponent, - HelpComponent, - SigninComponent, SettingsNavComponent, - ClipboardDirective, - QRCodeModule, - RemoveLeadingZerosPipe, SideNavigationComponent, TopMenuComponent, - HorizontalNavigationComponent + HorizontalNavigationComponent, + SigninComponent, + HelpComponent, + ServerConfigComponent, + ClipboardDirective, + QRCodeModule, + NgxChartsModule, + RemoveLeadingZerosPipe ], declarations: [ AlertMessageComponent, ConfirmationMessageComponent, SpinnerDialogComponent, NotFoundComponent, - ServerConfigComponent, - HelpComponent, - SigninComponent, SettingsNavComponent, - ClipboardDirective, - SsoFailedComponent, - RemoveLeadingZerosPipe, SideNavigationComponent, TopMenuComponent, - HorizontalNavigationComponent + HorizontalNavigationComponent, + SigninComponent, + HelpComponent, + ServerConfigComponent, + ClipboardDirective, + SsoFailedComponent, + RemoveLeadingZerosPipe ], entryComponents: [ AlertMessageComponent, diff --git a/src/app/lnd/store/lnd.actions.ts b/src/app/shared/store/rtl.actions.ts similarity index 75% rename from src/app/lnd/store/lnd.actions.ts rename to src/app/shared/store/rtl.actions.ts index 02cdbdb8..f06c4e0d 100644 --- a/src/app/lnd/store/lnd.actions.ts +++ b/src/app/shared/store/rtl.actions.ts @@ -1,10 +1,27 @@ import { Action } from '@ngrx/store'; +import { RTLConfiguration, Settings, Node } from '../models/RTLconfig'; +import { ErrorPayload } from '../models/errorPayload'; import { GetInfo, Peer, Balance, NetworkInfo, Fees, Channel, Invoice, ListInvoices, Payment, GraphNode, AddressType, PayRequest, ChannelsTransaction, PendingChannels, ClosedChannel, Transaction, SwitchReq, SwitchRes, QueryRoutes -} from '../../shared/models/lndModels'; - -export const RESET_LND_STORE = 'RESET_LND_STORE'; +} from '../models/lndModels'; +import { MatDialogConfig } from '@angular/material'; + +export const RESET_STORE = 'RESET_STORE'; +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_RTL_CONFIG = 'FETCH_RTL_CONFIG'; +export const SET_RTL_CONFIG = 'SET_RTL_CONFIG'; +export const SAVE_SETTINGS = 'SAVE_SETTINGS'; +export const SET_SELECTED_NODE = 'SET_SELECTED_NODE'; export const FETCH_INFO = 'FETCH_INFO'; export const SET_INFO = 'SET_INFO'; export const FETCH_PEERS = 'FETCH_PEERS'; @@ -55,6 +72,11 @@ export const INIT_WALLET_RESPONSE = 'INIT_WALLET_RESPONSE'; export const UNLOCK_WALLET = 'UNLOCK_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'; @@ -64,8 +86,66 @@ export const SET_FORWARDING_HISTORY = 'SET_FORWARDING_HISTORY'; export const GET_QUERY_ROUTES = 'GET_QUERY_ROUTES'; export const SET_QUERY_ROUTES = 'SET_QUERY_ROUTES'; -export class ResetLNDStore implements Action { - readonly type = RESET_LND_STORE; +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 ResetStore implements Action { + readonly type = RESET_STORE; + constructor(public payload: Node) {} +} + +export class FetchRTLConfig implements Action { + readonly type = FETCH_RTL_CONFIG; +} + +export class SetRTLConfig implements Action { + readonly type = SET_RTL_CONFIG; + constructor(public payload: RTLConfiguration) {} +} + +export class SaveSettings implements Action { + readonly type = SAVE_SETTINGS; + constructor(public payload: Settings) {} +} + +export class SetSelelectedNode implements Action { + readonly type = SET_SELECTED_NODE; + constructor(public payload: Node) {} } export class FetchInfo implements Action { @@ -352,11 +432,40 @@ export class SetQueryRoutes implements Action { constructor(public payload: QueryRoutes) {} } -export type LNDActions = - ResetLNDStore | FetchInfo | SetInfo | FetchPeers | SetPeers | AddPeer | - DetachPeer | SaveNewPeer | RemovePeer | AddInvoice | SaveNewInvoice | - GetForwardingHistory | SetForwardingHistory | FetchFees | SetFees | - FetchBalance | SetBalance | FetchNetwork | SetNetwork | +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 | + FetchRTLConfig | SetRTLConfig | SaveSettings | + OpenAlert | CloseAlert | OpenConfirmation | CloseConfirmation | + ResetStore | SetSelelectedNode | 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 | BackupChannels | VerifyChannels | BackupChannelsRes | VerifyChannelsRes | @@ -367,4 +476,5 @@ export type LNDActions = FetchGraphNode | SetGraphNode | GetQueryRoutes | SetQueryRoutes | GetNewAddress | SetNewAddress | SetChannelTransaction | GenSeed | GenSeedResponse | InitWallet | InitWalletResponse | UnlockWallet | - FetchConfig | ShowConfig | PeerLookup | ChannelLookup | InvoiceLookup | SetLookup; + FetchConfig | ShowConfig | PeerLookup | ChannelLookup | InvoiceLookup | SetLookup | + IsAuthorized | IsAuthorizedRes | Signin | Signout | InitAppData; diff --git a/src/app/lnd/store/lnd.effects.ts b/src/app/shared/store/rtl.effects.ts similarity index 69% rename from src/app/lnd/store/lnd.effects.ts rename to src/app/shared/store/rtl.effects.ts index cbbb3e62..0e8dc37c 100644 --- a/src/app/lnd/store/lnd.effects.ts +++ b/src/app/shared/store/rtl.effects.ts @@ -1,41 +1,124 @@ import { Injectable, OnDestroy } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; -import { Router, ActivatedRoute } from '@angular/router'; +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, withLatestFrom } from 'rxjs/operators'; +import { map, mergeMap, catchError, take, withLatestFrom } from 'rxjs/operators'; import { MatDialog } from '@angular/material'; import { environment } from '../../../environments/environment'; -import { LoggerService } from '../../shared/services/logger.service'; -import { GetInfo, Fees, Balance, NetworkInfo, Payment, GraphNode, Transaction, SwitchReq, ListInvoices } from '../../shared/models/lndModels'; +import { LoggerService } from '../services/logger.service'; +import { Settings } from '../models/RTLconfig'; +import { GetInfo, Fees, Balance, NetworkInfo, Payment, GraphNode, Transaction, SwitchReq, ListInvoices } from '../models/lndModels'; -import * as RTLActions from '../../store/rtl.actions'; -import * as LNDActions from './lnd.actions'; -import * as fromLNDReducer from './lnd.reducers'; -import * as fromApp from '../../store/rtl.reducers'; +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 LNDEffects implements OnDestroy { +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 store: Store, private logger: LoggerService, public dialog: MatDialog, - private router: Router, - private activatedRoute: ActivatedRoute) { } + 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) => { + if (this.dialogRef) { 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) => { + if (this.dialogRef) { 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() + appConfigFetch = this.actions$.pipe( + ofType(RTLActions.FETCH_RTL_CONFIG), + mergeMap((action: RTLActions.FetchRTLConfig) => { + this.store.dispatch(new RTLActions.ClearEffectError('FetchRTLConfig')); + return this.httpClient.get(environment.CONF_API + '/rtlconf'); + }), + map((rtlConfig: any) => { + this.logger.info(rtlConfig); + if (+rtlConfig.sso.rtlSSO) { this.store.dispatch(new RTLActions.Signout()); } + return { + type: RTLActions.SET_RTL_CONFIG, + payload: rtlConfig + }; + }, + catchError((err) => { + this.logger.error(err); + this.store.dispatch(new RTLActions.EffectError({ action: 'FetchRTLConfig', 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(LNDActions.FETCH_INFO), + ofType(RTLActions.FETCH_INFO), withLatestFrom(this.store.select('rtlRoot')), - mergeMap(([action, store]: [LNDActions.FetchInfo, fromApp.RootState]) => { + mergeMap(([action, store]: [RTLActions.FetchInfo, fromRTLReducer.State]) => { this.store.dispatch(new RTLActions.ClearEffectError('FetchInfo')); return this.httpClient.get(environment.GETINFO_API) .pipe( @@ -44,15 +127,15 @@ export class LNDEffects implements OnDestroy { if (undefined === info.identity_pubkey) { sessionStorage.removeItem('lndUnlocked'); this.logger.info('Redirecting to Unlock'); - this.router.navigate(['../unlocklnd'], { relativeTo: this.activatedRoute }); + this.router.navigate(['/lnd/unlocklnd']); return { - type: LNDActions.SET_INFO, + type: RTLActions.SET_INFO, payload: {} }; } else { sessionStorage.setItem('lndUnlocked', 'true'); return { - type: LNDActions.SET_INFO, + type: RTLActions.SET_INFO, payload: (undefined !== info) ? info : {} }; } @@ -61,15 +144,15 @@ export class LNDEffects implements OnDestroy { this.logger.error(err); this.store.dispatch(new RTLActions.EffectError({ action: 'FetchInfo', code: err.status, message: err.error.error })); if (+store.appConfig.sso.rtlSSO) { - this.router.navigate(['../ssoerror'], { relativeTo: this.activatedRoute }); + this.router.navigate(['/ssoerror']); } else { if (err.status === 401) { this.logger.info('Redirecting to Signin'); - this.router.navigate([store.appConfig.sso.logoutRedirectLink], { relativeTo: this.activatedRoute }); + this.router.navigate([store.appConfig.sso.logoutRedirectLink]); return of(); } else { this.logger.info('Redirecting to Unlock'); - this.router.navigate(['../unlocklnd'], { relativeTo: this.activatedRoute }); + this.router.navigate(['/lnd/unlocklnd']); return of(); } } @@ -80,15 +163,15 @@ export class LNDEffects implements OnDestroy { @Effect() peersFetch = this.actions$.pipe( - ofType(LNDActions.FETCH_PEERS), - mergeMap((action: LNDActions.FetchPeers) => { + 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: LNDActions.SET_PEERS, + type: RTLActions.SET_PEERS, payload: (undefined !== peers) ? peers : [] }; }), @@ -103,8 +186,8 @@ export class LNDEffects implements OnDestroy { @Effect() saveNewPeer = this.actions$.pipe( - ofType(LNDActions.SAVE_NEW_PEER), - mergeMap((action: LNDActions.SaveNewPeer) => { + 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) => { @@ -112,7 +195,7 @@ export class LNDEffects implements OnDestroy { this.store.dispatch(new RTLActions.CloseSpinner()); this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', data: { type: 'SUCCESS', titleMessage: 'Peer Added Successfully!'}})); return { - type: LNDActions.SET_PEERS, + type: RTLActions.SET_PEERS, payload: (undefined !== postRes && postRes.length > 0) ? postRes : [] }; }), @@ -134,8 +217,8 @@ export class LNDEffects implements OnDestroy { @Effect() detachPeer = this.actions$.pipe( - ofType(LNDActions.DETACH_PEER), - mergeMap((action: LNDActions.DetachPeer) => { + ofType(RTLActions.DETACH_PEER), + mergeMap((action: RTLActions.DetachPeer) => { return this.httpClient.delete(environment.PEERS_API + '/' + action.payload.pubkey) .pipe( map((postRes: any) => { @@ -143,7 +226,7 @@ export class LNDEffects implements OnDestroy { this.store.dispatch(new RTLActions.CloseSpinner()); this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', data: {type: 'SUCCESS', titleMessage: 'Peer Detached Successfully!'}})); return { - type: LNDActions.REMOVE_PEER, + type: RTLActions.REMOVE_PEER, payload: { pubkey: action.payload.pubkey } }; }), @@ -165,8 +248,8 @@ export class LNDEffects implements OnDestroy { @Effect() saveNewInvoice = this.actions$.pipe( - ofType(LNDActions.SAVE_NEW_INVOICE), - mergeMap((action: LNDActions.SaveNewInvoice) => { + ofType(RTLActions.SAVE_NEW_INVOICE), + mergeMap((action: RTLActions.SaveNewInvoice) => { return this.httpClient.post(environment.INVOICES_API, { memo: action.payload.memo, amount: action.payload.invoiceValue, private: action.payload.private, expiry: action.payload.expiry }) @@ -184,7 +267,7 @@ export class LNDEffects implements OnDestroy { this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', data: { type: 'SUCCESS', titleMessage: 'Invoice Added Successfully!', message: JSON.stringify(msg) }})); return { - type: LNDActions.FETCH_INVOICES, + type: RTLActions.FETCH_INVOICES, payload: {num_max_invoices: action.payload.pageSize, reversed: true} }; }), @@ -206,8 +289,8 @@ export class LNDEffects implements OnDestroy { @Effect() openNewChannel = this.actions$.pipe( - ofType(LNDActions.SAVE_NEW_CHANNEL), - mergeMap((action: LNDActions.SaveNewChannel) => { + 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, private: action.payload.private, trans_type: action.payload.transType, trans_type_value: action.payload.transTypeValue, spend_unconfirmed: action.payload.spendUnconfirmed @@ -216,11 +299,11 @@ export class LNDEffects implements OnDestroy { map((postRes: any) => { this.logger.info(postRes); this.store.dispatch(new RTLActions.CloseSpinner()); - this.store.dispatch(new LNDActions.FetchBalance('blockchain')); - this.store.dispatch(new LNDActions.FetchChannels({routeParam: 'all'})); - this.store.dispatch(new LNDActions.BackupChannels({channelPoint: 'ALL', showMessage: 'Channel Added Successfully!'})); + this.store.dispatch(new RTLActions.FetchBalance('blockchain')); + this.store.dispatch(new RTLActions.FetchChannels({routeParam: 'all'})); + this.store.dispatch(new RTLActions.BackupChannels({channelPoint: 'ALL', showMessage: 'Channel Added Successfully!'})); return { - type: LNDActions.FETCH_CHANNELS, + type: RTLActions.FETCH_CHANNELS, payload: {routeParam: 'pending', channelStatus: ''} }; }), @@ -242,8 +325,8 @@ export class LNDEffects implements OnDestroy { @Effect() updateChannel = this.actions$.pipe( - ofType(LNDActions.UPDATE_CHANNELS), - mergeMap((action: LNDActions.UpdateChannels) => { + 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( @@ -252,7 +335,7 @@ export class LNDEffects implements OnDestroy { this.store.dispatch(new RTLActions.CloseSpinner()); this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', data: {type: 'SUCCESS', titleMessage: 'Channel Updated Successfully!'}})); return { - type: LNDActions.FETCH_CHANNELS, + type: RTLActions.FETCH_CHANNELS, payload: {routeParam: 'all', channelStatus: ''} }; }), @@ -274,24 +357,24 @@ export class LNDEffects implements OnDestroy { @Effect() closeChannel = this.actions$.pipe( - ofType(LNDActions.CLOSE_CHANNEL), - mergeMap((action: LNDActions.CloseChannel) => { + 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 LNDActions.FetchBalance('channels')); - this.store.dispatch(new LNDActions.FetchBalance('blockchain')); - this.store.dispatch(new LNDActions.FetchChannels({routeParam: 'all'})); + this.store.dispatch(new RTLActions.FetchBalance('channels')); + this.store.dispatch(new RTLActions.FetchBalance('blockchain')); + this.store.dispatch(new RTLActions.FetchChannels({routeParam: 'all'})); if (action.payload.forcibly) { - this.store.dispatch(new LNDActions.FetchChannels({routeParam: 'pending'})); + this.store.dispatch(new RTLActions.FetchChannels({routeParam: 'pending'})); } else { - this.store.dispatch(new LNDActions.FetchChannels({routeParam: 'closed'})); + this.store.dispatch(new RTLActions.FetchChannels({routeParam: 'closed'})); } - this.store.dispatch(new LNDActions.BackupChannels({channelPoint: 'ALL', showMessage: 'Channel Closed Successfully!'})); + this.store.dispatch(new RTLActions.BackupChannels({channelPoint: 'ALL', showMessage: 'Channel Closed Successfully!'})); return { - type: LNDActions.REMOVE_CHANNEL, + type: RTLActions.REMOVE_CHANNEL, payload: { channelPoint: action.payload.channelPoint } }; }), @@ -312,8 +395,8 @@ export class LNDEffects implements OnDestroy { @Effect() backupChannels = this.actions$.pipe( - ofType(LNDActions.BACKUP_CHANNELS), - mergeMap((action: LNDActions.BackupChannels) => { + ofType(RTLActions.BACKUP_CHANNELS), + mergeMap((action: RTLActions.BackupChannels) => { this.store.dispatch(new RTLActions.ClearEffectError('BackupChannels')); return this.httpClient.get(environment.CHANNELS_BACKUP_API + '/' + action.payload.channelPoint) .pipe( @@ -322,7 +405,7 @@ export class LNDEffects implements OnDestroy { this.store.dispatch(new RTLActions.CloseSpinner()); this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', data: {type: 'SUCCESS', titleMessage: action.payload.showMessage + ' ' + postRes.message}})); return { - type: LNDActions.BACKUP_CHANNELS_RES, + type: RTLActions.BACKUP_CHANNELS_RES, payload: postRes.message }; }), @@ -344,8 +427,8 @@ export class LNDEffects implements OnDestroy { @Effect() verifyChannels = this.actions$.pipe( - ofType(LNDActions.VERIFY_CHANNELS), - mergeMap((action: LNDActions.VerifyChannels) => { + ofType(RTLActions.VERIFY_CHANNELS), + mergeMap((action: RTLActions.VerifyChannels) => { this.store.dispatch(new RTLActions.ClearEffectError('VerifyChannels')); return this.httpClient.post(environment.CHANNELS_BACKUP_API + '/verify/' + action.payload.channelPoint, {}) .pipe( @@ -354,7 +437,7 @@ export class LNDEffects implements OnDestroy { this.store.dispatch(new RTLActions.CloseSpinner()); this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', data: {type: 'SUCCESS', titleMessage: postRes.message}})); return { - type: LNDActions.VERIFY_CHANNELS_RES, + type: RTLActions.VERIFY_CHANNELS_RES, payload: postRes.message }; }), @@ -376,15 +459,15 @@ export class LNDEffects implements OnDestroy { @Effect() fetchFees = this.actions$.pipe( - ofType(LNDActions.FETCH_FEES), - mergeMap((action: LNDActions.FetchFees) => { + 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: LNDActions.SET_FEES, + type: RTLActions.SET_FEES, payload: (undefined !== fees) ? fees : {} }; }), @@ -397,19 +480,19 @@ export class LNDEffects implements OnDestroy { @Effect() balanceFetch = this.actions$.pipe( - ofType(LNDActions.FETCH_BALANCE), - mergeMap((action: LNDActions.FetchBalance) => { + 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 LNDActions.FetchBalance('blockchain')); + 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: LNDActions.SET_BALANCE, + type: RTLActions.SET_BALANCE, payload: (undefined !== res) ? { target: action.payload, balance: res } : { target: action.payload, balance: emptyRes } }; }), @@ -424,15 +507,15 @@ export class LNDEffects implements OnDestroy { @Effect() networkInfoFetch = this.actions$.pipe( - ofType(LNDActions.FETCH_NETWORK), - mergeMap((action: LNDActions.FetchNetwork) => { + 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: LNDActions.SET_NETWORK, + type: RTLActions.SET_NETWORK, payload: (undefined !== networkInfo) ? networkInfo : {} }; }), @@ -445,25 +528,25 @@ export class LNDEffects implements OnDestroy { @Effect() channelsFetch = this.actions$.pipe( - ofType(LNDActions.FETCH_CHANNELS), - mergeMap((action: LNDActions.FetchChannels) => { + ofType(RTLActions.FETCH_CHANNELS), + mergeMap((action: RTLActions.FetchChannels) => { return this.httpClient.get(environment.CHANNELS_API + '/' + action.payload.routeParam) .pipe( map((channels: any) => { this.logger.info(channels); if (action.payload.routeParam === 'pending') { return { - type: LNDActions.SET_PENDING_CHANNELS, + type: RTLActions.SET_PENDING_CHANNELS, payload: (undefined !== channels) ? channels : {} }; } else if (action.payload.routeParam === 'closed') { return { - type: LNDActions.SET_CLOSED_CHANNELS, + 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: LNDActions.SET_CHANNELS, + type: RTLActions.SET_CHANNELS, payload: (undefined !== channels && undefined !== channels.channels && channels.channels.length > 0) ? channels.channels : [] }; } @@ -479,8 +562,8 @@ export class LNDEffects implements OnDestroy { @Effect() invoicesFetch = this.actions$.pipe( - ofType(LNDActions.FETCH_INVOICES), - mergeMap((action: LNDActions.FetchInvoices) => { + ofType(RTLActions.FETCH_INVOICES), + mergeMap((action: RTLActions.FetchInvoices) => { this.store.dispatch(new RTLActions.ClearEffectError('FetchInvoices')); const num_max_invoices = (action.payload.num_max_invoices) ? action.payload.num_max_invoices : 100; const index_offset = (action.payload.index_offset) ? action.payload.index_offset : 0; @@ -489,10 +572,10 @@ export class LNDEffects implements OnDestroy { .pipe(map((res: ListInvoices) => { this.logger.info(res); if (action.payload.reversed && !action.payload.index_offset) { - this.store.dispatch(new LNDActions.SetTotalInvoices(+res.last_index_offset)); + this.store.dispatch(new RTLActions.SetTotalInvoices(+res.last_index_offset)); } return { - type: LNDActions.SET_INVOICES, + type: RTLActions.SET_INVOICES, payload: res }; }), @@ -506,15 +589,15 @@ export class LNDEffects implements OnDestroy { @Effect() transactionsFetch = this.actions$.pipe( - ofType(LNDActions.FETCH_TRANSACTIONS), - mergeMap((action: LNDActions.FetchTransactions) => { + 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: LNDActions.SET_TRANSACTIONS, + type: RTLActions.SET_TRANSACTIONS, payload: (undefined !== transactions && transactions.length > 0) ? transactions : [] }; }), @@ -527,15 +610,15 @@ export class LNDEffects implements OnDestroy { @Effect() paymentsFetch = this.actions$.pipe( - ofType(LNDActions.FETCH_PAYMENTS), - mergeMap((action: LNDActions.FetchPayments) => { + 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: LNDActions.SET_PAYMENTS, + type: RTLActions.SET_PAYMENTS, payload: (undefined !== payments && null != payments) ? payments : [] }; }), @@ -548,15 +631,15 @@ export class LNDEffects implements OnDestroy { @Effect() decodePayment = this.actions$.pipe( - ofType(LNDActions.DECODE_PAYMENT), - mergeMap((action: LNDActions.DecodePayment) => { + 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: LNDActions.SET_DECODED_PAYMENT, + type: RTLActions.SET_DECODED_PAYMENT, payload: (undefined !== decodedPayment) ? decodedPayment : {} }; }), @@ -577,8 +660,8 @@ export class LNDEffects implements OnDestroy { @Effect({ dispatch: false }) setDecodedPayment = this.actions$.pipe( - ofType(LNDActions.SET_DECODED_PAYMENT), - map((action: LNDActions.SetDecodedPayment) => { + ofType(RTLActions.SET_DECODED_PAYMENT), + map((action: RTLActions.SetDecodedPayment) => { this.logger.info(action.payload); return action.payload; }) @@ -586,9 +669,9 @@ export class LNDEffects implements OnDestroy { @Effect() sendPayment = this.actions$.pipe( - ofType(LNDActions.SEND_PAYMENT), - withLatestFrom(this.store.select('lnd')), - mergeMap(([action, store]: [LNDActions.SendPayment, fromLNDReducer.LNDState]) => { + 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]}; @@ -620,11 +703,11 @@ export class LNDEffects implements OnDestroy { 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 LNDActions.FetchChannels({routeParam: 'all'})); - this.store.dispatch(new LNDActions.FetchBalance('channels')); - this.store.dispatch(new LNDActions.FetchPayments()); + this.store.dispatch(new RTLActions.FetchChannels({routeParam: 'all'})); + this.store.dispatch(new RTLActions.FetchBalance('channels')); + this.store.dispatch(new RTLActions.FetchPayments()); return { - type: LNDActions.SET_DECODED_PAYMENT, + type: RTLActions.SET_DECODED_PAYMENT, payload: {} }; } @@ -646,14 +729,14 @@ export class LNDEffects implements OnDestroy { @Effect() graphNodeFetch = this.actions$.pipe( - ofType(LNDActions.FETCH_GRAPH_NODE), - mergeMap((action: LNDActions.FetchGraphNode) => { + 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: LNDActions.SET_GRAPH_NODE, + type: RTLActions.SET_GRAPH_NODE, payload: (undefined !== graphNode) ? graphNode : {} }; }), @@ -673,8 +756,8 @@ export class LNDEffects implements OnDestroy { @Effect({ dispatch: false }) setGraphNode = this.actions$.pipe( - ofType(LNDActions.SET_GRAPH_NODE), - map((action: LNDActions.SetGraphNode) => { + ofType(RTLActions.SET_GRAPH_NODE), + map((action: RTLActions.SetGraphNode) => { this.logger.info(action.payload); return action.payload; }) @@ -682,14 +765,14 @@ export class LNDEffects implements OnDestroy { @Effect() getNewAddress = this.actions$.pipe( - ofType(LNDActions.GET_NEW_ADDRESS), - mergeMap((action: LNDActions.GetNewAddress) => { + 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: LNDActions.SET_NEW_ADDRESS, + type: RTLActions.SET_NEW_ADDRESS, payload: (undefined !== newAddress && undefined !== newAddress.address) ? newAddress.address : {} }; }), @@ -709,8 +792,8 @@ export class LNDEffects implements OnDestroy { @Effect({ dispatch: false }) setNewAddress = this.actions$.pipe( - ofType(LNDActions.SET_NEW_ADDRESS), - map((action: LNDActions.SetNewAddress) => { + ofType(RTLActions.SET_NEW_ADDRESS), + map((action: RTLActions.SetNewAddress) => { this.logger.info(action.payload); return action.payload; }) @@ -718,15 +801,15 @@ export class LNDEffects implements OnDestroy { @Effect() configFetch = this.actions$.pipe( - ofType(LNDActions.FETCH_CONFIG), - mergeMap((action: LNDActions.FetchConfig) => { + 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: LNDActions.SHOW_CONFIG, + type: RTLActions.SHOW_CONFIG, payload: configFile }; }), @@ -748,16 +831,16 @@ export class LNDEffects implements OnDestroy { @Effect({ dispatch: false }) showLNDConfig = this.actions$.pipe( - ofType(LNDActions.SHOW_CONFIG), - map((action: LNDActions.ShowConfig) => { + ofType(RTLActions.SHOW_CONFIG), + map((action: RTLActions.ShowConfig) => { return action.payload; }) ); @Effect() SetChannelTransaction = this.actions$.pipe( - ofType(LNDActions.SET_CHANNEL_TRANSACTION), - mergeMap((action: LNDActions.SetChannelTransaction) => { + 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 } @@ -766,7 +849,7 @@ export class LNDEffects implements OnDestroy { map((postRes: any) => { this.logger.info(postRes); this.store.dispatch(new RTLActions.CloseSpinner()); - this.store.dispatch(new LNDActions.FetchBalance('blockchain')); + this.store.dispatch(new RTLActions.FetchBalance('blockchain')); return { type: RTLActions.OPEN_ALERT, payload: { data: {type: 'SUCCESS', titleMessage: 'Fund Sent Successfully!'} } @@ -789,8 +872,8 @@ export class LNDEffects implements OnDestroy { @Effect() fetchForwardingHistory = this.actions$.pipe( - ofType(LNDActions.GET_FORWARDING_HISTORY), - mergeMap((action: LNDActions.GetForwardingHistory) => { + 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 @@ -800,7 +883,7 @@ export class LNDEffects implements OnDestroy { map((fhRes: any) => { this.logger.info(fhRes); return { - type: LNDActions.SET_FORWARDING_HISTORY, + type: RTLActions.SET_FORWARDING_HISTORY, payload: fhRes }; }), @@ -821,19 +904,19 @@ export class LNDEffects implements OnDestroy { @Effect() queryRoutesFetch = this.actions$.pipe( - ofType(LNDActions.GET_QUERY_ROUTES), - mergeMap((action: LNDActions.GetQueryRoutes) => { + ofType(RTLActions.GET_QUERY_ROUTES), + mergeMap((action: RTLActions.GetQueryRoutes) => { return this.httpClient.get(environment.NETWORK_API + '/routes/' + action.payload.destPubkey + '/' + action.payload.amount) .pipe( map((qrRes: any) => { this.logger.info(qrRes); return { - type: LNDActions.SET_QUERY_ROUTES, + type: RTLActions.SET_QUERY_ROUTES, payload: qrRes }; }), catchError((err: any) => { - this.store.dispatch(new LNDActions.SetQueryRoutes({})); + this.store.dispatch(new RTLActions.SetQueryRoutes({})); this.logger.error(err); return of( { @@ -849,16 +932,16 @@ export class LNDEffects implements OnDestroy { @Effect({ dispatch: false }) setQueryRoutes = this.actions$.pipe( - ofType(LNDActions.SET_QUERY_ROUTES), - map((action: LNDActions.SetQueryRoutes) => { + ofType(RTLActions.SET_QUERY_ROUTES), + map((action: RTLActions.SetQueryRoutes) => { return action.payload; }) ); @Effect() genSeed = this.actions$.pipe( - ofType(LNDActions.GEN_SEED), - mergeMap((action: LNDActions.GenSeed) => { + ofType(RTLActions.GEN_SEED), + mergeMap((action: RTLActions.GenSeed) => { return this.httpClient.get(environment.WALLET_API + '/genseed/' + action.payload) .pipe( map((postRes: any) => { @@ -866,7 +949,7 @@ export class LNDEffects implements OnDestroy { this.logger.info(postRes); this.store.dispatch(new RTLActions.CloseSpinner()); return { - type: LNDActions.GEN_SEED_RESPONSE, + type: RTLActions.GEN_SEED_RESPONSE, payload: postRes.cipher_seed_mnemonic }; }), @@ -882,24 +965,24 @@ export class LNDEffects implements OnDestroy { @Effect({ dispatch: false }) genSeedResponse = this.actions$.pipe( - ofType(LNDActions.GEN_SEED_RESPONSE), - map((action: LNDActions.GenSeedResponse) => { + ofType(RTLActions.GEN_SEED_RESPONSE), + map((action: RTLActions.GenSeedResponse) => { return action.payload; }) ); @Effect({ dispatch: false }) initWalletRes = this.actions$.pipe( - ofType(LNDActions.INIT_WALLET_RESPONSE), - map((action: LNDActions.InitWalletResponse) => { + ofType(RTLActions.INIT_WALLET_RESPONSE), + map((action: RTLActions.InitWalletResponse) => { return action.payload; }) ); @Effect() initWallet = this.actions$.pipe( - ofType(LNDActions.INIT_WALLET), - mergeMap((action: LNDActions.InitWallet) => { + ofType(RTLActions.INIT_WALLET), + mergeMap((action: RTLActions.InitWallet) => { return this.httpClient.post(environment.WALLET_API + '/initwallet', { wallet_password: action.payload.pwd, cipher_seed_mnemonic: action.payload.cipher ? action.payload.cipher : '', @@ -909,7 +992,7 @@ export class LNDEffects implements OnDestroy { this.logger.info(postRes); this.store.dispatch(new RTLActions.CloseSpinner()); return { - type: LNDActions.INIT_WALLET_RESPONSE, + type: RTLActions.INIT_WALLET_RESPONSE, payload: postRes }; }), @@ -925,8 +1008,8 @@ export class LNDEffects implements OnDestroy { @Effect({ dispatch : false }) unlockWallet = this.actions$.pipe( - ofType(LNDActions.UNLOCK_WALLET), - mergeMap((action: LNDActions.UnlockWallet) => { + ofType(RTLActions.UNLOCK_WALLET), + mergeMap((action: RTLActions.UnlockWallet) => { return this.httpClient.post(environment.WALLET_API + '/unlockwallet', { wallet_password: action.payload.pwd }) .pipe( map((postRes) => { @@ -939,7 +1022,7 @@ export class LNDEffects implements OnDestroy { this.store.dispatch(new RTLActions.CloseSpinner()); this.logger.info('Successfully Initialized!'); this.store.dispatch(new RTLActions.InitAppData()); - this.router.navigate(['/'], { relativeTo: this.activatedRoute }); + this.router.navigate(['/lnd/']); }, 1000 * 90); return of({}); }), @@ -953,10 +1036,92 @@ export class LNDEffects implements OnDestroy { } )); + @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(['/lnd/']); + }), + 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.appConfig.sso.rtlSSO) { + this.router.navigate(['/ssoerror']); + } else { + this.router.navigate([store.appConfig.sso.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.appConfig.sso.rtlSSO) { + window.location.href = store.appConfig.sso.logoutRedirectLink; + } else { + this.router.navigate([store.appConfig.sso.logoutRedirectLink]); + } + sessionStorage.removeItem('lndUnlocked'); + sessionStorage.removeItem('token'); + this.logger.warn('LOGGED OUT'); + return of(); + })); + @Effect() peerLookup = this.actions$.pipe( - ofType(LNDActions.PEER_LOOKUP), - mergeMap((action: LNDActions.PeerLookup) => { + 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( @@ -964,7 +1129,7 @@ export class LNDEffects implements OnDestroy { this.logger.info(resPeer); this.store.dispatch(new RTLActions.CloseSpinner()); return { - type: LNDActions.SET_LOOKUP, + type: RTLActions.SET_LOOKUP, payload: resPeer }; }), @@ -986,8 +1151,8 @@ export class LNDEffects implements OnDestroy { @Effect() channelLookup = this.actions$.pipe( - ofType(LNDActions.CHANNEL_LOOKUP), - mergeMap((action: LNDActions.ChannelLookup) => { + 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( @@ -995,7 +1160,7 @@ export class LNDEffects implements OnDestroy { this.logger.info(resChannel); this.store.dispatch(new RTLActions.CloseSpinner()); return { - type: LNDActions.SET_LOOKUP, + type: RTLActions.SET_LOOKUP, payload: resChannel }; }), @@ -1017,8 +1182,8 @@ export class LNDEffects implements OnDestroy { @Effect() invoiceLookup = this.actions$.pipe( - ofType(LNDActions.INVOICE_LOOKUP), - mergeMap((action: LNDActions.InvoiceLookup) => { + 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( @@ -1026,7 +1191,7 @@ export class LNDEffects implements OnDestroy { this.logger.info(resInvoice); this.store.dispatch(new RTLActions.CloseSpinner()); return { - type: LNDActions.SET_LOOKUP, + type: RTLActions.SET_LOOKUP, payload: resInvoice }; }), @@ -1048,13 +1213,66 @@ export class LNDEffects implements OnDestroy { @Effect({ dispatch: false }) setLookup = this.actions$.pipe( - ofType(LNDActions.SET_LOOKUP), - map((action: LNDActions.SetLookup) => { + ofType(RTLActions.SET_LOOKUP), + map((action: RTLActions.SetLookup) => { this.logger.info(action.payload); return action.payload; }) ); + @Effect() + setSelectedNode = this.actions$.pipe( + ofType(RTLActions.SET_SELECTED_NODE), + mergeMap((action: RTLActions.SetSelelectedNode) => { + this.store.dispatch(new RTLActions.ClearEffectError('UpdateSelNode')); + return this.httpClient.post(environment.CONF_API + '/updateSelNode', { selNodeIndex: action.payload.index }) + .pipe( + map((postRes: any) => { + this.logger.info(postRes); + this.store.dispatch(new RTLActions.CloseSpinner()); + if (sessionStorage.getItem('token')) { + if(+action.payload.index === 1) { + this.router.navigate(['/lnd/home']); + } else { + this.router.navigate(['/cl/home']); + } + this.store.dispatch(new RTLActions.ResetStore(action.payload)); + return { type: RTLActions.FETCH_INFO }; + } else { + return { + type: RTLActions.OPEN_ALERT, + payload: { width: '70%', data: {type: 'WARN', titleMessage: 'Authorization required to get the data from the node!' }} + }; + } + }), + catchError((err: any) => { + this.store.dispatch(new RTLActions.CloseSpinner()); + this.store.dispatch(new RTLActions.EffectError({ action: 'UpdateSelNode', code: err.status, message: err.error.message })); + this.logger.error(err); + return of( + { + type: RTLActions.OPEN_ALERT, + payload: { width: '70%', data: {type: 'ERROR', titleMessage: 'Update Selected Node Failed!', + message: JSON.stringify({code: err.status, Message: err.error.error}) + }} + } + ); + }) + ); + } + )); + + 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(); diff --git a/src/app/lnd/store/lnd.reducers.ts b/src/app/shared/store/rtl.reducers.ts similarity index 72% rename from src/app/lnd/store/lnd.reducers.ts rename to src/app/shared/store/rtl.reducers.ts index 67f881e0..802ce793 100644 --- a/src/app/lnd/store/lnd.reducers.ts +++ b/src/app/shared/store/rtl.reducers.ts @@ -1,10 +1,15 @@ -import * as LNDActions from './lnd.actions'; +import * as RTLActions from './rtl.actions'; + +import { ErrorPayload } from '../models/errorPayload'; +import { RTLConfiguration, Node } from '../models/RTLconfig'; import { - GetInfo, GetInfoChain, Peer, AddressType, Fees, NetworkInfo, Balance, Channel, - Payment, ListInvoices, PendingChannels, ClosedChannel, Transaction, SwitchRes, QueryRoutes -} from '../../shared/models/lndModels'; + GetInfo, GetInfoChain, Peer, AddressType, Fees, NetworkInfo, Balance, Channel, Payment, ListInvoices, PendingChannels, ClosedChannel, Transaction, SwitchRes, QueryRoutes +} from '../models/lndModels'; -export interface LNDState { +export interface State { + effectErrors: ErrorPayload[]; + selNode: Node; + appConfig: RTLConfiguration; information: GetInfo; peers: Peer[]; fees: Fees; @@ -27,7 +32,17 @@ export interface LNDState { addressTypes: AddressType[]; } -const LNDInitialState: LNDState = { +const initNodeSettings = { flgSidenavOpened: true, flgSidenavPinned: true, menu: 'Vertical', menuType: 'Regular', theme: 'dark-blue', satsToBTC: false }; +const initNodeAuthentication = { nodeAuthType: 'CUSTOM', lndConfigPath: '', bitcoindConfigPath: '' }; + +const initialState: State = { + effectErrors: [], + selNode: {settings: initNodeSettings, authentication: initNodeAuthentication}, + appConfig: { + selectedNodeIndex: -1, + sso: { rtlSSO: 0, logoutRedirectLink: '/login' }, + nodes: [{ settings: initNodeSettings, authentication: initNodeAuthentication}] + }, information: {}, peers: [], fees: {}, @@ -53,13 +68,43 @@ const LNDInitialState: LNDState = { ] }; -export function LNDReducer(state = LNDInitialState, action: LNDActions.LNDActions) { +export function RTLRootReducer(state = initialState, action: RTLActions.RTLActions) { switch (action.type) { - case LNDActions.RESET_LND_STORE: + 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.RESET_STORE: + return { + ...initialState, + appConfig: state.appConfig, + selNode: action.payload + }; + case RTLActions.SET_SELECTED_NODE: return { - ...LNDInitialState + ...state, + selNode: action.payload + }; + case RTLActions.SET_RTL_CONFIG: + return { + ...state, + selNode: action.payload.nodes.find(node => +node.index === action.payload.selectedNodeIndex), + appConfig: action.payload }; - case LNDActions.SET_INFO: + 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'; @@ -79,17 +124,17 @@ export function LNDReducer(state = LNDInitialState, action: LNDActions.LNDAction ...state, information: action.payload }; - case LNDActions.SET_PEERS: + case RTLActions.SET_PEERS: return { ...state, peers: action.payload }; - case LNDActions.ADD_PEER: + case RTLActions.ADD_PEER: return { ...state, peers: [...state.peers, action.payload] }; - case LNDActions.REMOVE_PEER: + case RTLActions.REMOVE_PEER: const modifiedPeers = [...state.peers]; const removePeerIdx = state.peers.findIndex(peer => { return peer.pub_key === action.payload.pubkey; @@ -101,24 +146,24 @@ export function LNDReducer(state = LNDInitialState, action: LNDActions.LNDAction ...state, peers: modifiedPeers }; - case LNDActions.ADD_INVOICE: + case RTLActions.ADD_INVOICE: const newInvoices = state.invoices; newInvoices.invoices.unshift(action.payload); return { ...state, invoices: newInvoices }; - case LNDActions.SET_FEES: + case RTLActions.SET_FEES: return { ...state, fees: action.payload }; - case LNDActions.SET_CLOSED_CHANNELS: + case RTLActions.SET_CLOSED_CHANNELS: return { ...state, closedChannels: action.payload, }; - case LNDActions.SET_PENDING_CHANNELS: + case RTLActions.SET_PENDING_CHANNELS: let pendingChannels = -1; if (action.payload) { pendingChannels = 0; @@ -140,7 +185,7 @@ export function LNDReducer(state = LNDInitialState, action: LNDActions.LNDAction pendingChannels: action.payload, numberOfPendingChannels: pendingChannels, }; - case LNDActions.SET_CHANNELS: + case RTLActions.SET_CHANNELS: let localBal = 0, remoteBal = 0, activeChannels = 0, inactiveChannels = 0; if (action.payload) { action.payload.filter(channel => { @@ -165,7 +210,7 @@ export function LNDReducer(state = LNDInitialState, action: LNDActions.LNDAction totalLocalBalance: localBal, totalRemoteBalance: remoteBal }; - case LNDActions.REMOVE_CHANNEL: + case RTLActions.REMOVE_CHANNEL: const modifiedChannels = [...state.allChannels]; const removeChannelIdx = state.allChannels.findIndex(channel => { return channel.channel_point === action.payload.channelPoint; @@ -177,7 +222,7 @@ export function LNDReducer(state = LNDInitialState, action: LNDActions.LNDAction ...state, allChannels: modifiedChannels }; - case LNDActions.SET_BALANCE: + case RTLActions.SET_BALANCE: if (action.payload.target === 'channels') { return { ...state, @@ -189,32 +234,32 @@ export function LNDReducer(state = LNDInitialState, action: LNDActions.LNDAction blockchainBalance: action.payload.balance }; } - case LNDActions.SET_NETWORK: + case RTLActions.SET_NETWORK: return { ...state, networkInfo: action.payload }; - case LNDActions.SET_INVOICES: + case RTLActions.SET_INVOICES: return { ...state, invoices: action.payload }; - case LNDActions.SET_TOTAL_INVOICES: + case RTLActions.SET_TOTAL_INVOICES: return { ...state, totalInvoices: action.payload }; - case LNDActions.SET_TRANSACTIONS: + case RTLActions.SET_TRANSACTIONS: return { ...state, transactions: action.payload }; - case LNDActions.SET_PAYMENTS: + case RTLActions.SET_PAYMENTS: return { ...state, payments: action.payload }; - case LNDActions.SET_FORWARDING_HISTORY: + case RTLActions.SET_FORWARDING_HISTORY: if (action.payload.forwarding_events) { const storedChannels = [...state.allChannels]; action.payload.forwarding_events.forEach(event => { diff --git a/src/app/shared/theme/styles/change-theme.scss b/src/app/shared/theme/styles/change-theme.scss index 551d6dcc..37bf4e15 100644 --- a/src/app/shared/theme/styles/change-theme.scss +++ b/src/app/shared/theme/styles/change-theme.scss @@ -43,7 +43,7 @@ .active-link { background: mat-color($primary); - color: white; + color: white; // mat-color($foreground, text); for dark theme but for light theme the foreground text color is black } .h-active-link { @@ -58,6 +58,10 @@ } } + .mat-primary .mat-select, .mat-primary .mat-select-trigger, .mat-primary .mat-select-value, .mat-primary .mat-select-arrow { + // color: white !important; + } + .mat-primary .mat-select-panel .mat-option.mat-selected:not(.mat-option-multiple), .mat-primary .mat-option.mat-selected:not(.mat-option-multiple):not(.mat-option-disabled) { background: none; diff --git a/src/app/shared/theme/styles/root.scss b/src/app/shared/theme/styles/root.scss index 1fb0188a..a32bc925 100644 --- a/src/app/shared/theme/styles/root.scss +++ b/src/app/shared/theme/styles/root.scss @@ -61,6 +61,24 @@ html, body { overflow: hidden; } +.material-icons { + font-family: 'Material Icons'; + font-weight: normal; + font-style: normal; + font-size: 24px; + display: inline-block; + line-height: 1; + text-transform: none; + letter-spacing: normal; + word-wrap: normal; + white-space: nowrap; + direction: ltr; + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; + -moz-osx-font-smoothing: grayscale; + font-feature-settings: 'liga'; +} + .font-9px { font-size: 9px !important; } diff --git a/src/app/shared/theme/styles/styles.scss b/src/app/shared/theme/styles/styles.scss index abe37aeb..e2d5f8fe 100644 --- a/src/app/shared/theme/styles/styles.scss +++ b/src/app/shared/theme/styles/styles.scss @@ -1,5 +1,5 @@ -@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 '~material-design-icons/iconfont/material-icons.css'; +@import '~roboto-fontface/css/roboto/roboto-fontface.css'; @import "/root"; @import "/perfect-scrollbar"; diff --git a/src/app/store/rtl.actions.ts b/src/app/store/rtl.actions.ts deleted file mode 100644 index 63300006..00000000 --- a/src/app/store/rtl.actions.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { Action } from '@ngrx/store'; -import { RTLConfiguration, Settings, Node } from '../shared/models/RTLconfig'; -import { ErrorPayload } from '../shared/models/errorPayload'; -import { MatDialogConfig } from '@angular/material'; - -export const RESET_STORE = 'RESET_STORE'; -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_RTL_CONFIG = 'FETCH_RTL_CONFIG'; -export const SET_RTL_CONFIG = 'SET_RTL_CONFIG'; -export const SAVE_SETTINGS = 'SAVE_SETTINGS'; -export const SET_SELECTED_NODE = 'SET_SELECTED_NODE'; -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 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 ResetStore implements Action { - readonly type = RESET_STORE; - constructor(public payload: Node) {} -} - -export class FetchRTLConfig implements Action { - readonly type = FETCH_RTL_CONFIG; -} - -export class SetRTLConfig implements Action { - readonly type = SET_RTL_CONFIG; - constructor(public payload: RTLConfiguration) {} -} - -export class SaveSettings implements Action { - readonly type = SAVE_SETTINGS; - constructor(public payload: Settings) {} -} - -export class SetSelelectedNode implements Action { - readonly type = SET_SELECTED_NODE; - constructor(public payload: Node) {} -} - -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 | - FetchRTLConfig | SetRTLConfig | SaveSettings | - OpenAlert | CloseAlert | OpenConfirmation | CloseConfirmation | - ResetStore | SetSelelectedNode | - IsAuthorized | IsAuthorizedRes | Signin | Signout | InitAppData; diff --git a/src/app/store/rtl.effects.ts b/src/app/store/rtl.effects.ts deleted file mode 100644 index b1c0212e..00000000 --- a/src/app/store/rtl.effects.ts +++ /dev/null @@ -1,261 +0,0 @@ -import { Injectable, OnDestroy } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; -import { Router, ActivatedRoute } 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 '../shared/services/logger.service'; -import { Settings } from '../shared/models/RTLconfig'; - -import { SpinnerDialogComponent } from '../shared/components/spinner-dialog/spinner-dialog.component'; -import { AlertMessageComponent } from '../shared/components/alert-message/alert-message.component'; -import { ConfirmationMessageComponent } from '../shared/components/confirmation-message/confirmation-message.component'; - -import * as CLActions from '../c-lightning/store/cl.actions'; -import * as LNDActions from '../lnd/store/lnd.actions'; -import * as RTLActions from './rtl.actions'; -import * as fromApp 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, - private activatedRoute: ActivatedRoute) { } - - @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) => { - if (this.dialogRef) { 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) => { - if (this.dialogRef) { 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() - appConfigFetch = this.actions$.pipe( - ofType(RTLActions.FETCH_RTL_CONFIG), - mergeMap((action: RTLActions.FetchRTLConfig) => { - this.store.dispatch(new RTLActions.ClearEffectError('FetchRTLConfig')); - return this.httpClient.get(environment.CONF_API + '/rtlconf'); - }), - map((rtlConfig: any) => { - this.logger.info(rtlConfig); - if (+rtlConfig.sso.rtlSSO) { this.store.dispatch(new RTLActions.Signout()); } - return { - type: RTLActions.SET_RTL_CONFIG, - payload: rtlConfig - }; - }, - catchError((err) => { - this.logger.error(err); - this.store.dispatch(new RTLActions.EffectError({ action: 'FetchRTLConfig', 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() - isAuthorized = this.actions$.pipe( - ofType(RTLActions.IS_AUTHORIZED), - withLatestFrom(this.store.select('rtlRoot')), - mergeMap(([action, store]: [RTLActions.IsAuthorized, fromApp.RootState]) => { - 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, fromApp.RootState]) => { - 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(['/'], { relativeTo: this.activatedRoute }); - }), - 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.appConfig.sso.rtlSSO) { - this.router.navigate(['/ssoerror'], { relativeTo: this.activatedRoute }); - } else { - this.router.navigate([store.appConfig.sso.logoutRedirectLink], { relativeTo: this.activatedRoute }); - } - return of(); - }) - ); - })); - - @Effect({ dispatch: false }) - signOut = this.actions$.pipe( - ofType(RTLActions.SIGNOUT), - withLatestFrom(this.store.select('rtlRoot')), - mergeMap(([action, store]: [RTLActions.Signout, fromApp.RootState]) => { - if (+store.appConfig.sso.rtlSSO) { - window.location.href = store.appConfig.sso.logoutRedirectLink; - } else { - this.router.navigate([store.appConfig.sso.logoutRedirectLink], { relativeTo: this.activatedRoute }); - } - sessionStorage.removeItem('lndUnlocked'); - sessionStorage.removeItem('token'); - this.logger.warn('LOGGED OUT'); - return of(); - })); - - @Effect() - setSelectedNode = this.actions$.pipe( - ofType(RTLActions.SET_SELECTED_NODE), - mergeMap((action: RTLActions.SetSelelectedNode) => { - this.store.dispatch(new RTLActions.ClearEffectError('UpdateSelNode')); - return this.httpClient.post(environment.CONF_API + '/updateSelNode', { selNodeIndex: action.payload.index }) - .pipe( - map((postRes: any) => { - this.logger.info(postRes); - this.store.dispatch(new RTLActions.CloseSpinner()); - if (sessionStorage.getItem('token')) { - this.store.dispatch(new RTLActions.ResetStore(action.payload)); - if (action.payload.lnImplementation.toLowerCase() === 'clightning') { - this.router.navigate(['./cl'], { relativeTo: this.activatedRoute }); - return { type: CLActions.FETCH_CL_INFO }; - } else { - this.router.navigate(['./lnd'], { relativeTo: this.activatedRoute }); - return { type: LNDActions.FETCH_INFO }; - } - } else { - return { - type: RTLActions.OPEN_ALERT, - payload: { width: '70%', data: {type: 'WARN', titleMessage: 'Authorization required to get the data from the node!' }} - }; - } - }), - catchError((err: any) => { - this.store.dispatch(new RTLActions.CloseSpinner()); - this.store.dispatch(new RTLActions.EffectError({ action: 'UpdateSelNode', code: err.status, message: err.error.message })); - this.logger.error(err); - return of( - { - type: RTLActions.OPEN_ALERT, - payload: { width: '70%', data: {type: 'ERROR', titleMessage: 'Update Selected Node Failed!', - message: JSON.stringify({code: err.status, Message: err.error.error}) - }} - } - ); - }) - ); - } - )); - - 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/store/rtl.reducers.ts b/src/app/store/rtl.reducers.ts deleted file mode 100644 index b5823ec3..00000000 --- a/src/app/store/rtl.reducers.ts +++ /dev/null @@ -1,82 +0,0 @@ -import * as RTLActions from './rtl.actions'; -import { ErrorPayload } from '../shared/models/errorPayload'; -import { RTLConfiguration, Node } from '../shared/models/RTLconfig'; - -import { ActionReducerMap } from '@ngrx/store'; - -import * as fromLND from '../lnd/store/lnd.reducers'; -import * as fromCL from '../c-lightning/store/cl.reducers'; - -export interface AppState { - rtlRoot: RootState; - lnd: fromLND.LNDState; - cl: fromCL.CLState; -} - -export interface RootState { - effectErrors: ErrorPayload[]; - selNode: Node; - appConfig: RTLConfiguration; -} - -const initNodeSettings = { flgSidenavOpened: true, flgSidenavPinned: true, menu: 'Vertical', menuType: 'Regular', theme: 'dark-blue', satsToBTC: false }; -const initNodeAuthentication = { nodeAuthType: 'CUSTOM', lndConfigPath: '', bitcoindConfigPath: '' }; - -const initialState: RootState = { - effectErrors: [], - selNode: {settings: initNodeSettings, authentication: initNodeAuthentication}, - appConfig: { - selectedNodeIndex: -1, - sso: { rtlSSO: 0, logoutRedirectLink: '/login' }, - nodes: [{ settings: initNodeSettings, authentication: initNodeAuthentication}] - } -}; - -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.RESET_STORE: - return { - ...initialState, - appConfig: state.appConfig, - selNode: action.payload - }; - case RTLActions.SET_SELECTED_NODE: - return { - ...state, - selNode: action.payload - }; - case RTLActions.SET_RTL_CONFIG: - return { - ...state, - selNode: action.payload.nodes.find(node => +node.index === action.payload.selectedNodeIndex), - appConfig: action.payload - }; - default: - return state; - } - -} - -export const appReducer: ActionReducerMap = { - rtlRoot: RTLRootReducer, - lnd: fromLND.LNDReducer, - cl: fromCL.CLReducer -}; - diff --git a/src/app/super-user-dashboard/super-user-dashboard.component.html b/src/app/super-user-dashboard/super-user-dashboard.component.html deleted file mode 100644 index 6a164d69..00000000 --- a/src/app/super-user-dashboard/super-user-dashboard.component.html +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/src/app/super-user-dashboard/super-user-dashboard.component.scss b/src/app/super-user-dashboard/super-user-dashboard.component.scss deleted file mode 100644 index e69de29b..00000000 diff --git a/src/app/super-user-dashboard/super-user-dashboard.component.spec.ts b/src/app/super-user-dashboard/super-user-dashboard.component.spec.ts deleted file mode 100644 index cec67da2..00000000 --- a/src/app/super-user-dashboard/super-user-dashboard.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { SuperUserDashboardComponent } from './super-user-dashboard.component'; - -describe('SuperUserDashboardComponent', () => { - let component: SuperUserDashboardComponent; - let fixture: ComponentFixture; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ SuperUserDashboardComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(SuperUserDashboardComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/super-user-dashboard/super-user-dashboard.component.ts b/src/app/super-user-dashboard/super-user-dashboard.component.ts deleted file mode 100644 index 9298bc17..00000000 --- a/src/app/super-user-dashboard/super-user-dashboard.component.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { Component, OnInit, OnDestroy } from '@angular/core'; -import { Router, ActivatedRoute } 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 { RTLConfiguration, Settings, Node } from '../shared/models/RTLconfig'; -import { GetInfo } from '../shared/models/lndModels'; - -import * as LNDActions from '../lnd/store/lnd.actions'; -import * as CLActions from '../c-lightning/store/cl.actions'; -import * as RTLActions from '../store/rtl.actions'; -import * as fromApp from '../store/rtl.reducers'; - -@Component({ - selector: 'rtl-super-user-dashboard', - templateUrl: './super-user-dashboard.component.html', - styleUrls: ['./super-user-dashboard.component.scss'] -}) -export class SuperUserDashboardComponent implements OnInit, OnDestroy { - public selNode: Node; - public settings: Settings; - public information: GetInfo = {}; - public flgLoading: Array = [true]; - public flgCopied = false; - public appConfig: RTLConfiguration; - public accessKey = ''; - public smallScreen = false; - unSubs: Array> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject()]; - - constructor(private logger: LoggerService, private store: Store, private actions$: Actions, private userIdle: UserIdleService, private router: Router, private activatedRoute: ActivatedRoute) {} - - ngOnInit() { - this.actions$.pipe(takeUntil(this.unSubs[3]), filter(action => action.type === RTLActions.SET_RTL_CONFIG)) - .subscribe((setConfigAction: RTLActions.SetRTLConfig) => { - console.warn(setConfigAction); - this.selNode = setConfigAction.payload.nodes.find(node => +node.index === setConfigAction.payload.selectedNodeIndex) - if (this.selNode.lnImplementation.toLowerCase() === 'clightning') { - this.store.dispatch(new CLActions.FetchCLInfo()); - this.router.navigate(['../cl'], { relativeTo: this.activatedRoute }); - } else { - this.store.dispatch(new LNDActions.FetchInfo()); - this.router.navigate(['../lnd'], { relativeTo: this.activatedRoute }); - } - }); - // this.store.select('rtlRoot') - // .pipe(takeUntil(this.unSubs[0])) - // .subscribe(rtlStore => { - // this.selNode = rtlStore.selNode; - // if (this.selNode.lnImplementation.toLowerCase() === 'clightning') { - // this.store.dispatch(new CLActions.FetchCLInfo()); - // this.router.navigate(['./cl'], { relativeTo: this.activatedRoute }); - // } else { - // this.store.dispatch(new LNDActions.FetchInfo()); - // this.router.navigate(['./lnd'], { relativeTo: this.activatedRoute }); - // } - // }); - } - - ngOnDestroy() { - this.unSubs.forEach(unsub => { - unsub.next(); - unsub.complete(); - }); - } - -} diff --git a/src/environments/version.ts b/src/environments/version.ts index 37a50bcd..c76b21b9 100644 --- a/src/environments/version.ts +++ b/src/environments/version.ts @@ -1 +1 @@ -export const VERSION = '0.4.7-beta'; \ No newline at end of file +export const VERSION = '0.4.8-beta'; \ No newline at end of file