Compare commits

...

189 Commits

Author SHA1 Message Date
Eugene Pankov
f6d4a51239 proper xdg category 2021-03-14 11:51:27 +01:00
Eugene Pankov
36f77c5b63 added hex serial input/output modes 2021-03-14 11:34:58 +01:00
Eugene Pankov
3676b90c9f build fix 2021-03-13 22:09:05 +01:00
Eugene Pankov
c4204167cd make tab close button not take up extra space - fixes #3502 2021-03-13 22:08:20 +01:00
Eugene Pankov
604d7c464f fixed cycling tab reordering via hotkeys - fixes #3510 2021-03-13 21:43:36 +01:00
Eugene Pankov
e42bd11725 made progress detection optional - fixes #3472 2021-03-13 21:38:03 +01:00
Eugene Pankov
864932d663 settings ui tweak 2021-03-13 21:30:22 +01:00
Eugene Pankov
9e68c735dc added scrolling to typeahead - fixes #1178 2021-03-13 21:28:21 +01:00
Eugene Pankov
be43f8b50d disallow disabling core plugins - fixes #1990 2021-03-13 21:25:25 +01:00
Eugene Pankov
c290633e7e detect user@domain style usernames in ssh quick connect - fixes #3026 2021-03-13 21:02:49 +01:00
Eugene Pankov
d03211631a fixed #2600 2021-03-13 20:09:45 +01:00
Eugene Pankov
ca27c05f0f bumped electron 2021-03-13 20:06:42 +01:00
Eugene Pankov
62a21b03ea duplicate tab title and color when duplicating a tab - fixes #3588 2021-03-13 20:06:37 +01:00
Eugene Pankov
6236ee95c3 Update app.module.ts 2021-03-10 22:25:02 +01:00
Eugene Pankov
836014c270 shorter notification for copying 2021-03-10 22:08:11 +01:00
Eugene Pankov
0bf870738e option to disable dynamic tab title in profiles - fixes #3574 2021-03-10 21:36:12 +01:00
Eugene Pankov
7c1697b9cb Revert "Bump electron-is-dev from 1.2.0 to 2.0.0 in /app"
This reverts commit a241144827.
2021-03-10 21:17:42 +01:00
Eugene Pankov
c800dd6e44 Merge branch 'master' of github.com:Eugeny/terminus 2021-03-10 20:54:44 +01:00
Eugene
68e9a1f66b Merge pull request #3320 from Eugeny/dependabot/npm_and_yarn/terminus-core/ngx-perfect-scrollbar-10.1.0
Bump ngx-perfect-scrollbar from 8.0.0 to 10.1.0 in /terminus-core
2021-03-10 20:54:36 +01:00
Eugene Pankov
f925d63fb0 Merge branch 'master' of github.com:Eugeny/terminus 2021-03-10 20:51:53 +01:00
Eugene Pankov
e79fc13de9 bumped plugins 2021-03-10 20:51:50 +01:00
Eugene Pankov
0c963dcbcc expose sessionChanged$ 2021-03-10 20:51:44 +01:00
Eugene
b7b672ce9b Merge pull request #3548 from Eugeny/dependabot/npm_and_yarn/electron-builder-22.10.5
Bump electron-builder from 22.10.4 to 22.10.5
2021-03-10 20:50:33 +01:00
Eugene
4c8bb45d01 Merge pull request #3544 from Eugeny/dependabot/npm_and_yarn/graceful-fs-4.2.6 2021-03-10 20:49:11 +01:00
Eugene
d4f8a88451 Merge pull request #3525 from Eugeny/dependabot/npm_and_yarn/terminus-core/core-js-3.9.1 2021-03-10 20:49:01 +01:00
dependabot-preview[bot]
fac8fafa36 Bump electron-builder from 22.10.4 to 22.10.5
Bumps [electron-builder](https://github.com/electron-userland/electron-builder) from 22.10.4 to 22.10.5.
- [Release notes](https://github.com/electron-userland/electron-builder/releases)
- [Changelog](https://github.com/electron-userland/electron-builder/blob/master/CHANGELOG.md)
- [Commits](https://github.com/electron-userland/electron-builder/compare/v22.10.4...v22.10.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-10 19:48:54 +00:00
dependabot-preview[bot]
bc854fcfff Bump graceful-fs from 4.2.4 to 4.2.6
Bumps [graceful-fs](https://github.com/isaacs/node-graceful-fs) from 4.2.4 to 4.2.6.
- [Release notes](https://github.com/isaacs/node-graceful-fs/releases)
- [Commits](https://github.com/isaacs/node-graceful-fs/compare/v4.2.4...v4.2.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-10 19:48:51 +00:00
Eugene
ebc83b8064 Merge pull request #3375 from Eugeny/dependabot/npm_and_yarn/app/ngx-toastr-13.2.0 2021-03-10 20:48:50 +01:00
dependabot-preview[bot]
6757deab67 Bump core-js from 3.8.2 to 3.9.1 in /terminus-core
Bumps [core-js](https://github.com/zloirock/core-js/tree/HEAD/packages/core-js) from 3.8.2 to 3.9.1.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/commits/v3.9.1/packages/core-js)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-10 19:48:28 +00:00
dependabot-preview[bot]
fe68d9a34e Bump ngx-toastr from 12.1.0 to 13.2.0 in /app
Bumps [ngx-toastr](https://github.com/scttcper/ngx-toastr) from 12.1.0 to 13.2.0.
- [Release notes](https://github.com/scttcper/ngx-toastr/releases)
- [Commits](https://github.com/scttcper/ngx-toastr/compare/v12.1.0...v13.2.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-10 19:48:26 +00:00
Eugene
2840ae2aa7 Merge pull request #3546 from Eugeny/dependabot/npm_and_yarn/pug-3.0.2
Bump pug from 3.0.1 to 3.0.2
2021-03-10 20:47:19 +01:00
Eugene
b275f5311d Merge pull request #3530 from Eugeny/dependabot/npm_and_yarn/core-js-3.9.1
Bump core-js from 3.8.3 to 3.9.1
2021-03-10 20:47:09 +01:00
Eugene
4e084cdc93 Merge pull request #3559 from Eugeny/dependabot/npm_and_yarn/app/node-abi-2.21.0
Bump node-abi from 2.20.0 to 2.21.0 in /app
2021-03-10 20:46:47 +01:00
Eugene
910b207160 Merge pull request #3572 from Eugeny/dependabot/npm_and_yarn/html-loader-2.1.2
Bump html-loader from 1.3.2 to 2.1.2
2021-03-10 20:46:23 +01:00
Eugene
f54ff37010 Merge pull request #3560 from Eugeny/dependabot/npm_and_yarn/typescript-eslint/parser-4.17.0
Bump @typescript-eslint/parser from 4.14.1 to 4.17.0
2021-03-10 20:42:50 +01:00
Eugene
03d9d46a8c Merge pull request #3423 from Eugeny/dependabot/npm_and_yarn/webpack-cli-4.5.0
Bump webpack-cli from 4.4.0 to 4.5.0
2021-03-10 20:42:41 +01:00
Eugene
7111f35268 Merge pull request #3550 from Eugeny/dependabot/npm_and_yarn/sentry/electron-2.4.0
Bump @sentry/electron from 2.2.0 to 2.4.0
2021-03-10 20:42:12 +01:00
Eugene
44427ac3b6 Merge pull request #3568 from Eugeny/dependabot/npm_and_yarn/terminus-terminal/xterm-4.11.0
Bump xterm from 4.10.0 to 4.11.0 in /terminus-terminal
2021-03-10 20:42:04 +01:00
Eugene
8816910e43 Merge pull request #3567 from Eugeny/dependabot/npm_and_yarn/terminus-terminal/xterm-addon-serialize-0.5.0
Bump xterm-addon-serialize from 0.4.0 to 0.5.0 in /terminus-terminal
2021-03-10 20:41:01 +01:00
Eugene
31464ee37a Merge pull request #3566 from Eugeny/dependabot/npm_and_yarn/terminus-terminal/xterm-addon-webgl-0.10.0
Bump xterm-addon-webgl from 0.9.0 to 0.10.0 in /terminus-terminal
2021-03-10 20:40:54 +01:00
dependabot-preview[bot]
4bdb72021b Bump html-loader from 1.3.2 to 2.1.2
Bumps [html-loader](https://github.com/webpack-contrib/html-loader) from 1.3.2 to 2.1.2.
- [Release notes](https://github.com/webpack-contrib/html-loader/releases)
- [Changelog](https://github.com/webpack-contrib/html-loader/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack-contrib/html-loader/compare/v1.3.2...v2.1.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-10 04:21:47 +00:00
dependabot-preview[bot]
7d5e70c718 Bump xterm from 4.10.0 to 4.11.0 in /terminus-terminal
Bumps [xterm](https://github.com/xtermjs/xterm.js) from 4.10.0 to 4.11.0.
- [Release notes](https://github.com/xtermjs/xterm.js/releases)
- [Commits](https://github.com/xtermjs/xterm.js/compare/4.10.0...4.11.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-10 04:18:43 +00:00
dependabot-preview[bot]
6af92c9f95 Bump xterm-addon-serialize from 0.4.0 to 0.5.0 in /terminus-terminal
Bumps xterm-addon-serialize from 0.4.0 to 0.5.0.

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-10 04:18:16 +00:00
dependabot-preview[bot]
4a8fe78b07 Bump xterm-addon-webgl from 0.9.0 to 0.10.0 in /terminus-terminal
Bumps [xterm-addon-webgl](https://github.com/xtermjs/xterm.js) from 0.9.0 to 0.10.0.
- [Release notes](https://github.com/xtermjs/xterm.js/releases)
- [Commits](https://github.com/xtermjs/xterm.js/compare/0.9...0.10)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-10 04:17:54 +00:00
dependabot-preview[bot]
1aa6bc3c10 Bump @typescript-eslint/parser from 4.14.1 to 4.17.0
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 4.14.1 to 4.17.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.17.0/packages/parser)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-09 04:18:01 +00:00
dependabot-preview[bot]
93d74bf3cb Bump node-abi from 2.20.0 to 2.21.0 in /app
Bumps [node-abi](https://github.com/lgeiger/node-abi) from 2.20.0 to 2.21.0.
- [Release notes](https://github.com/lgeiger/node-abi/releases)
- [Commits](https://github.com/lgeiger/node-abi/compare/v2.20.0...v2.21.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-08 04:21:17 +00:00
Eugene
9e16ef5a57 Merge pull request #3555 from Eugeny/all-contributors/add-iamchating 2021-03-05 17:18:41 +03:00
allcontributors[bot]
741c77506c docs: update .all-contributorsrc [skip ci] 2021-03-05 14:17:23 +00:00
allcontributors[bot]
507cc16190 docs: update README.md [skip ci] 2021-03-05 14:17:22 +00:00
Eugene
bfeb353858 Merge pull request #3554 from iamchating/master
FIX: #3520
2021-03-05 17:17:06 +03:00
Tan, Tian
806bfef8bf FIX: #3520 2021-03-05 21:19:43 +08:00
Eugene Pankov
975b5a117d build typings before docs 2021-03-04 09:42:46 +01:00
dependabot-preview[bot]
46e4832a66 Bump @sentry/electron from 2.2.0 to 2.4.0
Bumps [@sentry/electron](https://github.com/getsentry/sentry-electron) from 2.2.0 to 2.4.0.
- [Release notes](https://github.com/getsentry/sentry-electron/releases)
- [Changelog](https://github.com/getsentry/sentry-electron/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-electron/compare/2.2.0...2.4.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-04 04:22:48 +00:00
dependabot-preview[bot]
6ab7093cc6 Bump pug from 3.0.1 to 3.0.2
Bumps [pug](https://github.com/pugjs/pug) from 3.0.1 to 3.0.2.
- [Release notes](https://github.com/pugjs/pug/releases)
- [Commits](https://github.com/pugjs/pug/compare/pug@3.0.1...pug@3.0.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-04 04:20:52 +00:00
dependabot-preview[bot]
00cc2474cc Bump core-js from 3.8.3 to 3.9.1
Bumps [core-js](https://github.com/zloirock/core-js/tree/HEAD/packages/core-js) from 3.8.3 to 3.9.1.
- [Release notes](https://github.com/zloirock/core-js/releases)
- [Changelog](https://github.com/zloirock/core-js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/zloirock/core-js/commits/v3.9.1/packages/core-js)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-03 20:42:25 +00:00
dependabot-preview[bot]
4e4d02041a Bump webpack-cli from 4.4.0 to 4.5.0
Bumps [webpack-cli](https://github.com/webpack/webpack-cli) from 4.4.0 to 4.5.0.
- [Release notes](https://github.com/webpack/webpack-cli/releases)
- [Changelog](https://github.com/webpack/webpack-cli/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack/webpack-cli/compare/webpack-cli@4.4.0...webpack-cli@4.5.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-03 20:41:22 +00:00
Eugene
09ac506dd3 Merge pull request #3504 from Eugeny/dependabot/npm_and_yarn/terminus-settings/utils-decorators-1.8.1
Bump utils-decorators from 1.8.0 to 1.8.1 in /terminus-settings
2021-03-03 23:40:26 +03:00
Eugene
769ce6bc0b Merge pull request #3527 from Eugeny/dependabot/npm_and_yarn/app/rxjs-6.6.6
Bump rxjs from 6.6.3 to 6.6.6 in /app
2021-03-03 23:40:14 +03:00
Eugene
26605124c1 Merge pull request #3172 from Eugeny/dependabot/npm_and_yarn/terminus-plugin-manager/semver-7.3.4
Bump semver from 7.2.2 to 7.3.4 in /terminus-plugin-manager
2021-03-03 23:40:07 +03:00
Eugene
7465c32645 Merge pull request #3380 from Eugeny/dependabot/npm_and_yarn/tslib-2.1.0
Bump tslib from 2.0.3 to 2.1.0
2021-03-03 23:39:56 +03:00
Eugene
846ac62a7f Merge pull request #3541 from Eugeny/dependabot/npm_and_yarn/pug-code-gen-2.0.3
Bump pug-code-gen from 2.0.2 to 2.0.3
2021-03-03 23:39:49 +03:00
Eugene
eae2c5ee16 Merge pull request #3529 from Eugeny/dependabot/npm_and_yarn/typescript-3.9.9
Bump typescript from 3.9.7 to 3.9.9
2021-03-03 23:39:05 +03:00
Eugene
4fd89105e5 Merge pull request #3483 from Eugeny/dependabot/npm_and_yarn/terminus-ssh/types/node-14.14.31
Bump @types/node from 14.14.14 to 14.14.31 in /terminus-ssh
2021-03-03 23:38:56 +03:00
dependabot[bot]
87c1bef16e Bump pug-code-gen from 2.0.2 to 2.0.3
Bumps [pug-code-gen](https://github.com/pugjs/pug) from 2.0.2 to 2.0.3.
- [Release notes](https://github.com/pugjs/pug/releases)
- [Commits](https://github.com/pugjs/pug/compare/pug-code-gen@2.0.2...pug@2.0.3)

Signed-off-by: dependabot[bot] <support@github.com>
2021-03-03 20:38:54 +00:00
Eugene
eed35c2613 Merge pull request #3484 from Eugeny/dependabot/npm_and_yarn/app/types/node-14.14.31
Bump @types/node from 14.14.14 to 14.14.31 in /app
2021-03-03 23:38:44 +03:00
dependabot-preview[bot]
678f2f7a85 Bump @types/node from 14.14.14 to 14.14.31 in /app
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.14 to 14.14.31.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-03 20:37:35 +00:00
Eugene
0b1bacaf0d Merge pull request #3542 from Eugeny/dependabot/npm_and_yarn/pug-3.0.1
[Security] Bump pug from 3.0.0 to 3.0.1
2021-03-03 23:37:31 +03:00
dependabot-preview[bot]
98b5a27382 Bump @types/node from 14.14.14 to 14.14.31 in /terminus-ssh
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.14 to 14.14.31.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-03 20:37:11 +00:00
dependabot-preview[bot]
76a81b9402 Bump typescript from 3.9.7 to 3.9.9
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 3.9.7 to 3.9.9.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v3.9.7...v3.9.9)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-03 20:36:37 +00:00
dependabot-preview[bot]
634b221aa3 Bump tslib from 2.0.3 to 2.1.0
Bumps [tslib](https://github.com/Microsoft/tslib) from 2.0.3 to 2.1.0.
- [Release notes](https://github.com/Microsoft/tslib/releases)
- [Commits](https://github.com/Microsoft/tslib/compare/2.0.3...2.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-03 20:36:17 +00:00
dependabot-preview[bot]
ffcb3e72c2 [Security] Bump pug from 3.0.0 to 3.0.1
Bumps [pug](https://github.com/pugjs/pug) from 3.0.0 to 3.0.1. **This update includes a security fix.**
- [Release notes](https://github.com/pugjs/pug/releases)
- [Commits](https://github.com/pugjs/pug/compare/pug@3.0.0...pug@3.0.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-03 20:36:17 +00:00
dependabot-preview[bot]
b4b7bdeb16 Bump semver from 7.2.2 to 7.3.4 in /terminus-plugin-manager
Bumps [semver](https://github.com/npm/node-semver) from 7.2.2 to 7.3.4.
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/master/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v7.2.2...v7.3.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-03 20:36:04 +00:00
Eugene
21daa4aa18 Merge pull request #3486 from Eugeny/dependabot/npm_and_yarn/types/node-14.14.31
Bump @types/node from 14.14.14 to 14.14.31
2021-03-03 23:35:51 +03:00
Eugene
867dbcddcc Merge pull request #3482 from Eugeny/dependabot/npm_and_yarn/terminus-terminal/slugify-1.4.7
Bump slugify from 1.4.6 to 1.4.7 in /terminus-terminal
2021-03-03 23:35:08 +03:00
Eugene
b906dbd8d6 Merge pull request #3189 from Eugeny/dependabot/npm_and_yarn/terminus-core/uuid-8.3.2
Bump uuid from 8.2.0 to 8.3.2 in /terminus-core
2021-03-03 23:34:59 +03:00
Eugene
e5c7d0649f Merge pull request #3347 from Eugeny/dependabot/npm_and_yarn/terminus-ssh/run-script-os-1.1.5
Bump run-script-os from 1.1.3 to 1.1.5 in /terminus-ssh
2021-03-03 23:34:48 +03:00
Eugene
55286bc7e7 Merge pull request #3429 from Eugeny/dependabot/npm_and_yarn/sass-loader-11.0.1
Bump sass-loader from 10.1.1 to 11.0.1
2021-03-03 23:34:40 +03:00
Eugene Pankov
359e41f884 Merge branch 'dependabot/npm_and_yarn/typedoc-0.20.28' 2021-03-03 21:33:49 +01:00
Eugene Pankov
cc93578ada typedoc fixes 2021-03-03 21:33:37 +01:00
dependabot-preview[bot]
2e54fa317c Bump @types/node from 14.14.14 to 14.14.31
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.14 to 14.14.31.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-03 20:26:55 +00:00
dependabot-preview[bot]
c3bd725ce8 Bump ngx-perfect-scrollbar from 8.0.0 to 10.1.0 in /terminus-core
Bumps [ngx-perfect-scrollbar](https://github.com/zefoy/ngx-perfect-scrollbar) from 8.0.0 to 10.1.0.
- [Release notes](https://github.com/zefoy/ngx-perfect-scrollbar/releases)
- [Commits](https://github.com/zefoy/ngx-perfect-scrollbar/compare/v8.0.0...v10.1.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-03 20:25:49 +00:00
Eugene
18f69c5527 Merge pull request #3485 from Eugeny/dependabot/npm_and_yarn/app/serialport-9.0.7
Bump serialport from 9.0.4 to 9.0.7 in /app
2021-03-03 23:24:38 +03:00
Eugene
0102a2a61b Merge pull request #3301 from Eugeny/dependabot/npm_and_yarn/terminus-core/types/js-yaml-4.0.0
Bump @types/js-yaml from 3.12.5 to 4.0.0 in /terminus-core
2021-03-03 23:24:31 +03:00
Eugene
1de709561c Merge pull request #3381 from Eugeny/dependabot/npm_and_yarn/types/js-yaml-4.0.0
Bump @types/js-yaml from 3.12.5 to 4.0.0
2021-03-03 23:24:26 +03:00
Eugene
9f985ee8f0 Merge pull request #3287 from Eugeny/dependabot/npm_and_yarn/terminus-core/js-yaml-4.0.0
Bump js-yaml from 3.14.0 to 4.0.0 in /terminus-core
2021-03-03 23:24:20 +03:00
Eugene
1a35ed3c73 Merge pull request #3528 from Eugeny/dependabot/npm_and_yarn/app/electron-is-dev-2.0.0
Bump electron-is-dev from 1.2.0 to 2.0.0 in /app
2021-03-03 23:23:53 +03:00
dependabot-preview[bot]
a241144827 Bump electron-is-dev from 1.2.0 to 2.0.0 in /app
Bumps [electron-is-dev](https://github.com/sindresorhus/electron-is-dev) from 1.2.0 to 2.0.0.
- [Release notes](https://github.com/sindresorhus/electron-is-dev/releases)
- [Commits](https://github.com/sindresorhus/electron-is-dev/compare/v1.2.0...v2.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-03 20:04:32 +00:00
dependabot-preview[bot]
18e341f886 Bump js-yaml from 3.14.0 to 4.0.0 in /terminus-core
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 3.14.0 to 4.0.0.
- [Release notes](https://github.com/nodeca/js-yaml/releases)
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/3.14.0...4.0.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-03 20:03:52 +00:00
Eugene
3182d4428d Merge pull request #3321 from Eugeny/dependabot/npm_and_yarn/app/glasstron-0.0.7
Bump glasstron from 0.0.6 to 0.0.7 in /app
2021-03-03 23:02:28 +03:00
Eugene
6dfcb9422a Merge pull request #3379 from Eugeny/dependabot/npm_and_yarn/fortawesome/fontawesome-free-5.15.2
Bump @fortawesome/fontawesome-free from 5.15.1 to 5.15.2
2021-03-03 22:59:20 +03:00
Eugene Pankov
ad5993b94f bumepd node-abi 2021-03-03 20:58:33 +01:00
Eugene Pankov
eb9826fb2a macos: only query default shell once 2021-03-02 22:55:06 +01:00
Eugene Pankov
1c81baa6f2 added docking space adjustment - fixes #3524 2021-03-02 22:53:26 +01:00
Eugene Pankov
e07c5db0a8 let themes specify macos titlebar buttons offset - fixes #3507 2021-03-02 22:41:17 +01:00
Eugene Pankov
b93989d02b remove titlebar padding in fullscreen - fixes #3532 2021-03-02 22:12:15 +01:00
Eugene Pankov
15bfde6077 Update linux.yml 2021-03-02 22:01:42 +01:00
Eugene Pankov
4243e79a11 patch node-abi in linux builds 2021-03-02 21:58:15 +01:00
Eugene Pankov
eb49001614 node-abi patches 2021-03-02 15:58:36 +01:00
Eugene
3aaa670400 Merge pull request #3535 from Eugeny/all-contributors/add-clarkwang 2021-03-02 13:03:25 +03:00
allcontributors[bot]
5371b2d1a6 docs: update .all-contributorsrc [skip ci] 2021-03-02 09:13:12 +00:00
allcontributors[bot]
e46281a9a7 docs: update README.md [skip ci] 2021-03-02 09:13:11 +00:00
Eugene
9d4aa179a0 Merge pull request #3534 from clarkwang/hotkeys-for-tab-11-20
fixes #3500: add hotkey support for Tabs 11~20
2021-03-02 12:12:59 +03:00
Clark Wang
20118afd1f fixes #3500: add hotkey support for Tabs 11~20 2021-03-02 16:57:40 +08:00
dependabot-preview[bot]
b29daac3c6 Bump @types/js-yaml from 3.12.5 to 4.0.0
Bumps [@types/js-yaml](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/js-yaml) from 3.12.5 to 4.0.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/js-yaml)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-02 08:56:51 +00:00
dependabot-preview[bot]
8ba9e8b210 Bump @types/js-yaml from 3.12.5 to 4.0.0 in /terminus-core
Bumps [@types/js-yaml](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/js-yaml) from 3.12.5 to 4.0.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/js-yaml)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-02 08:55:39 +00:00
Eugene
f3f3edfbb6 Merge pull request #3526 from Eugeny/dependabot/npm_and_yarn/terminus-core/electron-updater-4.3.8
Bump electron-updater from 4.3.5 to 4.3.8 in /terminus-core
2021-03-02 11:54:23 +03:00
Eugene Pankov
472cb18a16 Merge branch 'master' of github.com:Eugeny/terminus 2021-03-02 09:52:51 +01:00
Eugene Pankov
7c8d8ebc81 ui tweaks 2021-03-02 09:52:48 +01:00
Eugene Pankov
18fc0fa886 bumped electron to stable 2021-03-02 09:52:41 +01:00
dependabot-preview[bot]
5a90c246b9 Bump rxjs from 6.6.3 to 6.6.6 in /app
Bumps [rxjs](https://github.com/reactivex/rxjs) from 6.6.3 to 6.6.6.
- [Release notes](https://github.com/reactivex/rxjs/releases)
- [Changelog](https://github.com/ReactiveX/rxjs/blob/6.6.6/CHANGELOG.md)
- [Commits](https://github.com/reactivex/rxjs/compare/6.6.3...6.6.6)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-02 04:16:46 +00:00
dependabot-preview[bot]
9bc31556f2 Bump electron-updater from 4.3.5 to 4.3.8 in /terminus-core
Bumps [electron-updater](https://github.com/electron-userland/electron-builder) from 4.3.5 to 4.3.8.
- [Release notes](https://github.com/electron-userland/electron-builder/releases)
- [Changelog](https://github.com/electron-userland/electron-builder/blob/master/CHANGELOG.md)
- [Commits](https://github.com/electron-userland/electron-builder/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-02 04:16:22 +00:00
dependabot-preview[bot]
2c81491825 Bump @fortawesome/fontawesome-free from 5.15.1 to 5.15.2
Bumps [@fortawesome/fontawesome-free](https://github.com/FortAwesome/Font-Awesome) from 5.15.1 to 5.15.2.
- [Release notes](https://github.com/FortAwesome/Font-Awesome/releases)
- [Changelog](https://github.com/FortAwesome/Font-Awesome/blob/master/CHANGELOG.md)
- [Commits](https://github.com/FortAwesome/Font-Awesome/compare/5.15.1...5.15.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-01 20:16:43 +00:00
dependabot-preview[bot]
9ed18d965c Bump glasstron from 0.0.6 to 0.0.7 in /app
Bumps [glasstron](https://github.com/AryToNeX/Glasstron) from 0.0.6 to 0.0.7.
- [Release notes](https://github.com/AryToNeX/Glasstron/releases)
- [Commits](https://github.com/AryToNeX/Glasstron/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-03-01 20:15:11 +00:00
Eugene
b4f76847bf Merge pull request #3425 from Eugeny/dependabot/npm_and_yarn/electron-rebuild-2.3.5
Bump electron-rebuild from 2.3.4 to 2.3.5
2021-03-01 23:03:26 +03:00
Eugene
b9bcb14dd7 Merge pull request #3466 from Eugeny/dependabot/npm_and_yarn/app/keytar-7.4.0
Bump keytar from 7.3.0 to 7.4.0 in /app
2021-03-01 23:03:05 +03:00
Eugene
ee3e17981b Merge pull request #3503 from Eugeny/dependabot/npm_and_yarn/app/zone.js-0.11.4
Bump zone.js from 0.11.3 to 0.11.4 in /app
2021-03-01 23:02:37 +03:00
Eugene
415d833ae6 Merge pull request #3515 from Eugeny/dependabot/npm_and_yarn/sentry/cli-1.63.0
Bump @sentry/cli from 1.61.0 to 1.63.0
2021-03-01 23:02:13 +03:00
Eugene Pankov
ed9117670e split fpm options 2021-02-28 12:34:49 +01:00
Eugene Pankov
0ecd47346d Merge branch 'master' of github.com:Eugeny/terminus 2021-02-28 12:15:27 +01:00
Eugene Pankov
bc0024ec06 disable packaging build-id links - fixes #3523 2021-02-28 12:15:25 +01:00
dependabot-preview[bot]
bdec20f7c7 Bump @sentry/cli from 1.61.0 to 1.63.0
Bumps [@sentry/cli](https://github.com/getsentry/sentry-cli) from 1.61.0 to 1.63.0.
- [Release notes](https://github.com/getsentry/sentry-cli/releases)
- [Changelog](https://github.com/getsentry/sentry-cli/blob/master/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-cli/compare/1.61.0...1.63.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-26 04:22:23 +00:00
dependabot-preview[bot]
45ebe3caf9 Bump utils-decorators from 1.8.0 to 1.8.1 in /terminus-settings
Bumps [utils-decorators](https://github.com/vlio20/utils-decorators) from 1.8.0 to 1.8.1.
- [Release notes](https://github.com/vlio20/utils-decorators/releases)
- [Commits](https://github.com/vlio20/utils-decorators/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-24 04:17:51 +00:00
dependabot-preview[bot]
7315bc8d8b Bump zone.js from 0.11.3 to 0.11.4 in /app
Bumps [zone.js](https://github.com/angular/angular/tree/HEAD/packages/zone.js) from 0.11.3 to 0.11.4.
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/master/packages/zone.js/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/zone.js-0.11.4/packages/zone.js)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-24 04:17:15 +00:00
Eugene
a969dc1ea4 use yarn in HACKING.md 2021-02-23 13:51:48 +01:00
dependabot-preview[bot]
2733dc69be Bump typedoc from 0.18.0 to 0.20.28
Bumps [typedoc](https://github.com/TypeStrong/TypeDoc) from 0.18.0 to 0.20.28.
- [Release notes](https://github.com/TypeStrong/TypeDoc/releases)
- [Commits](https://github.com/TypeStrong/TypeDoc/compare/v0.18.0...v0.20.28)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-23 04:24:34 +00:00
Eugene Pankov
bb86848cd3 Merge branch 'master' of github.com:Eugeny/terminus 2021-02-22 11:22:25 +01:00
Eugene
e844ad6063 Merge pull request #3491 from Eugeny/all-contributors/add-VectorKappa 2021-02-22 12:58:48 +03:00
allcontributors[bot]
a096a691cc docs: update .all-contributorsrc [skip ci] 2021-02-22 09:58:08 +00:00
allcontributors[bot]
a28e25e96a docs: update README.md [skip ci] 2021-02-22 09:58:07 +00:00
Eugene
a09ce13709 Merge pull request #3489 from VectorKappa/master
Add Nord theme
2021-02-22 12:57:28 +03:00
VectorKappa
123d8ceb5f Add Nord theme 2021-02-22 09:34:36 +01:00
dependabot-preview[bot]
c0155c8d4e Bump serialport from 9.0.4 to 9.0.7 in /app
Bumps [serialport](https://github.com/serialport/node-serialport) from 9.0.4 to 9.0.7.
- [Release notes](https://github.com/serialport/node-serialport/releases)
- [Changelog](https://github.com/serialport/node-serialport/blob/master/CHANGELOG.md)
- [Commits](https://github.com/serialport/node-serialport/compare/@serialport/bindings@9.0.4...v9.0.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-22 04:18:38 +00:00
dependabot-preview[bot]
fcda35b02e Bump slugify from 1.4.6 to 1.4.7 in /terminus-terminal
Bumps [slugify](https://github.com/simov/slugify) from 1.4.6 to 1.4.7.
- [Release notes](https://github.com/simov/slugify/releases)
- [Commits](https://github.com/simov/slugify/compare/v1.4.6...v1.4.7)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-22 04:16:20 +00:00
Eugene Pankov
9d6a1031da more responsive css editing 2021-02-20 19:53:27 +01:00
Eugene Pankov
c119d3283e fixed #3464 2021-02-20 19:43:21 +01:00
dependabot-preview[bot]
3667fb45ee Bump keytar from 7.3.0 to 7.4.0 in /app
Bumps [keytar](https://github.com/atom/node-keytar) from 7.3.0 to 7.4.0.
- [Release notes](https://github.com/atom/node-keytar/releases)
- [Commits](https://github.com/atom/node-keytar/compare/v7.3.0...v7.4.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-16 04:16:55 +00:00
Eugene Pankov
92d34343f1 fixed missing serial settings tab 2021-02-15 16:08:55 +01:00
Eugene Pankov
8afad944b7 Merge branch 'master' of https://github.com/Eugeny/terminus 2021-02-14 13:07:56 +01:00
Eugene Pankov
707d077eb2 fixed winpty input - fixes #3397 2021-02-13 15:05:29 +01:00
Eugene Pankov
92eabab509 cleanup 2021-02-13 14:53:19 +01:00
Eugene Pankov
888cfc6548 fixed windows build 2021-02-13 14:10:56 +01:00
Eugene Pankov
9cb10c3e21 tweaked plugins ui 2021-02-13 13:53:25 +01:00
Eugene Pankov
661d5af9ba casing 2021-02-13 13:40:05 +01:00
Eugene Pankov
26429bf209 removed toolbar buttons from touchbar 2021-02-13 13:25:46 +01:00
Eugene Pankov
4779c41f48 bumped electron 2021-02-13 13:16:55 +01:00
Eugene Pankov
b11eda8653 bumped electron 2021-02-13 13:04:41 +01:00
Eugene Pankov
23bff8750c added static/dynamic tab size setting - fixes #3426 2021-02-13 12:55:55 +01:00
Eugene Pankov
aab1ae3ceb reconnect hotkey - fixes #3344 2021-02-13 12:49:07 +01:00
Eugene Pankov
9b5b5a9d00 re-fixed session restarting 2021-02-13 12:47:21 +01:00
Eugene Pankov
9c87cf3f3a fixed tabs on side with compact theme 2021-02-13 12:42:23 +01:00
Eugene Pankov
a8c7134218 fixed SSH reconnection behaviour - fixed #3446, fixed #3442 2021-02-13 12:42:15 +01:00
Eugene Pankov
9734830a74 web demo fixes 2021-02-13 12:14:14 +01:00
Eugene Pankov
5fa056751d bumped angular 2021-02-13 12:14:09 +01:00
Eugene Pankov
6fdccd0a02 cleanup webpack configs 2021-02-13 12:11:38 +01:00
dependabot-preview[bot]
41ee7b7bbf Bump sass-loader from 10.1.1 to 11.0.1
Bumps [sass-loader](https://github.com/webpack-contrib/sass-loader) from 10.1.1 to 11.0.1.
- [Release notes](https://github.com/webpack-contrib/sass-loader/releases)
- [Changelog](https://github.com/webpack-contrib/sass-loader/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack-contrib/sass-loader/compare/v10.1.1...v11.0.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-09 04:22:04 +00:00
dependabot-preview[bot]
a755fdaa4e Bump electron-rebuild from 2.3.4 to 2.3.5
Bumps [electron-rebuild](https://github.com/electron/electron-rebuild) from 2.3.4 to 2.3.5.
- [Release notes](https://github.com/electron/electron-rebuild/releases)
- [Changelog](https://github.com/electron/electron-rebuild/blob/master/.releaserc.json)
- [Commits](https://github.com/electron/electron-rebuild/compare/v2.3.4...v2.3.5)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-08 04:25:07 +00:00
Eugene
1149d68d1c Merge pull request #3243 from Eugeny/dependabot/npm_and_yarn/https-proxy-agent-2.2.4
[Security] Bump https-proxy-agent from 2.0.0 to 2.2.4
2021-02-07 16:33:41 +01:00
Eugene
1d92a3f89d Merge pull request #3242 from Eugeny/dependabot/npm_and_yarn/tar-2.2.2
[Security] Bump tar from 2.2.1 to 2.2.2
2021-02-07 16:33:25 +01:00
Eugene
3557345d70 Merge pull request #3222 from Eugeny/dependabot/npm_and_yarn/terminus-plugin-manager/axios-0.21.1
[Security] Bump axios from 0.19.2 to 0.21.1 in /terminus-plugin-manager
2021-02-07 16:33:06 +01:00
Eugene
86ebdd92b4 Merge pull request #3221 from Eugeny/dependabot/npm_and_yarn/terminus-core/axios-0.21.1
[Security] Bump axios from 0.19.2 to 0.21.1 in /terminus-core
2021-02-07 16:32:59 +01:00
Eugene
4764ec8249 Merge pull request #3239 from Eugeny/dependabot/npm_and_yarn/tough-cookie-2.3.4
[Security] Bump tough-cookie from 2.3.2 to 2.3.4
2021-02-07 16:32:49 +01:00
Eugene Pankov
b1752bd0b4 updated cwd settings UI 2021-02-07 13:44:17 +01:00
Eugene Pankov
1e697a952a upgraded xterm.js 2021-02-07 13:44:08 +01:00
Eugene Pankov
6bad2a2167 cache dscl output 2021-02-07 13:43:58 +01:00
Eugene Pankov
61a46e3b4a lint 2021-02-07 13:15:24 +01:00
Eugene Pankov
cba90cec0a better error messages for X11 forwarding issues 2021-02-07 12:49:34 +01:00
Eugene Pankov
7583d92747 set terminus to use built-in graphics by default - fixes #657 2021-02-07 12:49:22 +01:00
Eugene Pankov
e2b99d71ad lint 2021-02-06 17:47:17 +01:00
dependabot-preview[bot]
c829daac41 [Security] Bump tar from 2.2.1 to 2.2.2
Bumps [tar](https://github.com/npm/node-tar) from 2.2.1 to 2.2.2. **This update includes a security fix.**
- [Release notes](https://github.com/npm/node-tar/releases)
- [Changelog](https://github.com/npm/node-tar/blob/master/CHANGELOG.md)
- [Commits](https://github.com/npm/node-tar/compare/v2.2.1...v2.2.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-02-06 15:47:12 +00:00
Eugene Pankov
aac38fa190 CWD detection on windows where possible 2021-02-06 16:45:38 +01:00
Eugene Pankov
7098622c8f bumped electron 2021-02-06 11:20:34 +01:00
Eugene Pankov
8695003c74 lint 2021-02-01 11:40:49 +01:00
Eugene Pankov
43a27a7b7c serial newline modes 2021-01-31 20:07:26 +01:00
Eugene Pankov
dd2d2ce20d Update tsconfig.json 2021-01-31 19:33:33 +01:00
Eugene Pankov
73574374f0 readline input mode for serial terminals - #3099, #2661 2021-01-31 19:33:30 +01:00
Eugene Pankov
5bd1bfd565 better editor ts support 2021-01-31 18:20:58 +01:00
Eugene Pankov
0611afa8b5 better session handlers behaviour, added serial auto-reconnection logic - #3099 2021-01-31 18:20:39 +01:00
Eugene Pankov
91c9e8affd bumped angular 2021-01-28 22:01:42 +01:00
Eugene Pankov
322ffc5847 margin fix 2021-01-28 21:55:29 +01:00
Eugene Pankov
21084b5d24 bumped js-yaml 2021-01-28 21:52:11 +01:00
dependabot-preview[bot]
4c840a0db1 [Security] Bump https-proxy-agent from 2.0.0 to 2.2.4
Bumps [https-proxy-agent](https://github.com/TooTallNate/node-https-proxy-agent) from 2.0.0 to 2.2.4. **This update includes security fixes.**
- [Release notes](https://github.com/TooTallNate/node-https-proxy-agent/releases)
- [Commits](https://github.com/TooTallNate/node-https-proxy-agent/compare/2.0.0...2.2.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-28 20:48:14 +00:00
dependabot-preview[bot]
3b69172f62 Bump uuid from 8.2.0 to 8.3.2 in /terminus-core
Bumps [uuid](https://github.com/uuidjs/uuid) from 8.2.0 to 8.3.2.
- [Release notes](https://github.com/uuidjs/uuid/releases)
- [Changelog](https://github.com/uuidjs/uuid/blob/master/CHANGELOG.md)
- [Commits](https://github.com/uuidjs/uuid/compare/v8.2.0...v8.3.2)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-28 20:48:05 +00:00
Eugene Pankov
e0efb4073a bumped eslint 2021-01-28 21:46:31 +01:00
Eugene Pankov
c42b62afe6 bumped deps 2021-01-28 21:11:53 +01:00
Eugene Pankov
e2b11c83d5 fixed cli args handling 2021-01-28 21:11:47 +01:00
dependabot-preview[bot]
6545a2fda6 Bump run-script-os from 1.1.3 to 1.1.5 in /terminus-ssh
Bumps [run-script-os](https://github.com/charlesguse/run-script-os) from 1.1.3 to 1.1.5.
- [Release notes](https://github.com/charlesguse/run-script-os/releases)
- [Commits](https://github.com/charlesguse/run-script-os/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-18 04:31:15 +00:00
dependabot-preview[bot]
ceb638e08d [Security] Bump tough-cookie from 2.3.2 to 2.3.4
Bumps [tough-cookie](https://github.com/salesforce/tough-cookie) from 2.3.2 to 2.3.4. **This update includes security fixes.**
- [Release notes](https://github.com/salesforce/tough-cookie/releases)
- [Changelog](https://github.com/salesforce/tough-cookie/blob/master/CHANGELOG.md)
- [Commits](https://github.com/salesforce/tough-cookie/compare/v2.3.2...v2.3.4)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-02 09:43:15 +00:00
dependabot-preview[bot]
040098050d Bump axios from 0.19.2 to 0.21.1 in /terminus-plugin-manager
Bumps [axios](https://github.com/axios/axios) from 0.19.2 to 0.21.1.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v0.21.1/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v0.19.2...v0.21.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-02 09:43:10 +00:00
dependabot-preview[bot]
00de7c148f Bump axios from 0.19.2 to 0.21.1 in /terminus-core
Bumps [axios](https://github.com/axios/axios) from 0.19.2 to 0.21.1.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v0.21.1/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v0.19.2...v0.21.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-01-02 09:43:06 +00:00
107 changed files with 2619 additions and 2012 deletions

View File

@@ -343,6 +343,33 @@
"contributions": [ "contributions": [
"code" "code"
] ]
},
{
"login": "VectorKappa",
"name": "Piotr Patalong",
"avatar_url": "https://avatars.githubusercontent.com/u/29167842?v=4",
"profile": "http://patalong.pl",
"contributions": [
"design"
]
},
{
"login": "clarkwang",
"name": "Clark Wang",
"avatar_url": "https://avatars.githubusercontent.com/u/157076?v=4",
"profile": "https://github.com/clarkwang",
"contributions": [
"code"
]
},
{
"login": "iamchating",
"name": "iamchating",
"avatar_url": "https://avatars.githubusercontent.com/u/7088153?v=4",
"profile": "https://github.com/iamchating",
"contributions": [
"code"
]
} }
], ],
"contributorsPerLine": 7, "contributorsPerLine": 7,

View File

@@ -1,6 +1,8 @@
parser: '@typescript-eslint/parser' parser: '@typescript-eslint/parser'
parserOptions: parserOptions:
project: tsconfig.json project:
- tsconfig.json
- '*/tsconfig.typings.json'
extends: extends:
- 'plugin:@typescript-eslint/all' - 'plugin:@typescript-eslint/all'
plugins: plugins:
@@ -37,6 +39,7 @@ rules:
'@typescript-eslint/no-misused-promises': off '@typescript-eslint/no-misused-promises': off
'@typescript-eslint/typedef': off '@typescript-eslint/typedef': off
'@typescript-eslint/consistent-type-imports': off '@typescript-eslint/consistent-type-imports': off
'@typescript-eslint/sort-type-union-intersection-members': off
'@typescript-eslint/no-use-before-define': '@typescript-eslint/no-use-before-define':
- error - error
- classes: false - classes: false
@@ -81,7 +84,8 @@ rules:
argsIgnorePattern: ^_ argsIgnorePattern: ^_
no-undef: error no-undef: error
no-var: error no-var: error
object-curly-spacing: object-curly-spacing: off
'@typescript-eslint/object-curly-spacing':
- error - error
- always - always
quote-props: quote-props:

View File

@@ -23,6 +23,7 @@ jobs:
cd .. cd ..
rm app/node_modules/.yarn-integrity rm app/node_modules/.yarn-integrity
yarn yarn
yarn run build:typings
yarn run docs yarn run docs
rsync -e "ssh -o StrictHostKeyChecking=no" -arv docs/api/ root@ajenti.org:/srv/terminus-docs/ rsync -e "ssh -o StrictHostKeyChecking=no" -arv docs/api/ root@ajenti.org:/srv/terminus-docs/

View File

@@ -21,6 +21,10 @@ jobs:
cd .. cd ..
rm app/node_modules/.yarn-integrity rm app/node_modules/.yarn-integrity
yarn yarn
./node_modules/.bin/patch-package
cd app
../node_modules/.bin/patch-package
cd ..
- name: Build native deps - name: Build native deps
run: scripts/build-native.js run: scripts/build-native.js

View File

@@ -10,27 +10,25 @@ First, install the dependencies:
``` ```
# macOS/Linux: # macOS/Linux:
npm install yarn
./scripts/install-deps.js
./scripts/build-native.js ./scripts/build-native.js
# Windows: # Windows:
npm -g install windows-build-tools npm -g install windows-build-tools
npm install yarn
node scripts\install-deps.js
node scripts\build-native.js node scripts\build-native.js
``` ```
Now, check if your build is working: Now, check if your build is working:
``` ```
npm run build yarn run build
``` ```
Start Terminus with Start Terminus with
``` ```
npm start yarn start
``` ```
# Project layout # Project layout

View File

@@ -121,6 +121,9 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<tr> <tr>
<td align="center"><a href="https://github.com/TakuroOnoda"><img src="https://avatars0.githubusercontent.com/u/1407926?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Takuro Onoda</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=TakuroOnoda" title="Code">💻</a></td> <td align="center"><a href="https://github.com/TakuroOnoda"><img src="https://avatars0.githubusercontent.com/u/1407926?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Takuro Onoda</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=TakuroOnoda" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/frauhottelmann"><img src="https://avatars2.githubusercontent.com/u/902705?v=4?s=100" width="100px;" alt=""/><br /><sub><b>frauhottelmann</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=frauhottelmann" title="Code">💻</a></td> <td align="center"><a href="https://github.com/frauhottelmann"><img src="https://avatars2.githubusercontent.com/u/902705?v=4?s=100" width="100px;" alt=""/><br /><sub><b>frauhottelmann</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=frauhottelmann" title="Code">💻</a></td>
<td align="center"><a href="http://patalong.pl"><img src="https://avatars.githubusercontent.com/u/29167842?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Piotr Patalong</b></sub></a><br /><a href="#design-VectorKappa" title="Design">🎨</a></td>
<td align="center"><a href="https://github.com/clarkwang"><img src="https://avatars.githubusercontent.com/u/157076?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Clark Wang</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=clarkwang" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/iamchating"><img src="https://avatars.githubusercontent.com/u/7088153?v=4?s=100" width="100px;" alt=""/><br /><sub><b>iamchating</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=iamchating" title="Code">💻</a></td>
</tr> </tr>
</table> </table>

View File

@@ -6,7 +6,7 @@ import { app } from 'electron'
export function loadConfig (): any { export function loadConfig (): any {
const configPath = path.join(app.getPath('userData'), 'config.yaml') const configPath = path.join(app.getPath('userData'), 'config.yaml')
if (fs.existsSync(configPath)) { if (fs.existsSync(configPath)) {
return yaml.safeLoad(fs.readFileSync(configPath, 'utf8')) return yaml.load(fs.readFileSync(configPath, 'utf8'))
} else { } else {
return {} return {}
} }

View File

@@ -36,7 +36,7 @@ export class Window {
private windowConfig: ElectronConfig private windowConfig: ElectronConfig
private windowBounds?: Rectangle private windowBounds?: Rectangle
private closing = false private closing = false
private lastVibrancy: {enabled: boolean, type?: string} | null = null private lastVibrancy: { enabled: boolean, type?: string } | null = null
private disableVibrancyWhileDragging = false private disableVibrancyWhileDragging = false
private configStore: any private configStore: any
@@ -88,7 +88,7 @@ export class Window {
bwOptions.frame = true bwOptions.frame = true
} else { } else {
if (process.platform === 'darwin') { if (process.platform === 'darwin') {
bwOptions.titleBarStyle = 'hiddenInset' bwOptions.titleBarStyle = 'hidden'
} }
} }

View File

@@ -1,6 +1,7 @@
{ {
"name": "terminus", "name": "terminus",
"description": "A terminal for a modern age", "description": "A terminal for a modern age",
"private": true,
"repository": "https://github.com/eugeny/terminus", "repository": "https://github.com/eugeny/terminus",
"author": { "author": {
"name": "Eugene Pankov", "name": "Eugene Pankov",
@@ -13,42 +14,43 @@
"watch": "webpack --progress --color --watch" "watch": "webpack --progress --color --watch"
}, },
"dependencies": { "dependencies": {
"@angular/animations": "^9.1.9", "@angular/animations": "^11.1.1",
"@angular/common": "^9.1.11", "@angular/common": "^11.1.1",
"@angular/compiler": "^9.1.9", "@angular/compiler": "^11.1.1",
"@angular/core": "^9.1.9", "@angular/core": "^11.1.1",
"@angular/forms": "^9.1.11", "@angular/forms": "^11.1.1",
"@angular/platform-browser": "^9.1.9", "@angular/platform-browser": "^11.1.1",
"@angular/platform-browser-dynamic": "^9.1.9", "@angular/platform-browser-dynamic": "^11.1.1",
"@ng-bootstrap/ng-bootstrap": "^6.1.0", "@ng-bootstrap/ng-bootstrap": "^6.1.0",
"@terminus-term/node-pty": "0.10.0-beta10", "@terminus-term/node-pty": "0.10.0-terminus.3",
"electron-config": "2.0.0", "electron-config": "2.0.0",
"electron-debug": "^3.0.1", "electron-debug": "^3.2.0",
"electron-is-dev": "1.1.0", "electron-is-dev": "1.2.0",
"electron-promise-ipc": "^2.2.4", "electron-promise-ipc": "^2.2.4",
"fontmanager-redux": "1.0.0", "fontmanager-redux": "1.0.0",
"glasstron": "0.0.6", "glasstron": "0.0.7",
"js-yaml": "3.14.0", "js-yaml": "4.0.0",
"keytar": "^7.2.0", "keytar": "^7.4.0",
"mz": "^2.7.0", "mz": "^2.7.0",
"ngx-toastr": "^12.0.1", "native-process-working-directory": "^1.0.2",
"ngx-toastr": "^13.2.0",
"npm": "6", "npm": "6",
"path": "0.12.7", "path": "0.12.7",
"rxjs": "^6.5.5", "rxjs": "^6.6.6",
"yargs": "^15.4.1", "yargs": "^15.4.1",
"zone.js": "^0.11.3" "zone.js": "^0.11.4"
}, },
"optionalDependencies": { "optionalDependencies": {
"macos-native-processlist": "^2.0.0", "macos-native-processlist": "^2.0.0",
"serialport": "^9.0.4", "serialport": "^9.0.7",
"windows-blurbehind": "^1.0.1", "windows-blurbehind": "^1.0.1",
"windows-native-registry": "^3.0.0", "windows-native-registry": "^3.0.0",
"windows-process-tree": "^0.2.4" "windows-process-tree": "^0.2.4"
}, },
"devDependencies": { "devDependencies": {
"@types/mz": "0.0.32", "@types/mz": "0.0.32",
"@types/node": "14.14.14", "@types/node": "14.14.31",
"node-abi": "2.19.3", "node-abi": "^2.21.0",
"source-map-support": "^0.5.19" "source-map-support": "^0.5.19"
}, },
"peerDependencies": { "peerDependencies": {
@@ -59,5 +61,8 @@
"terminus-settings": "*", "terminus-settings": "*",
"terminus-ssh": "*", "terminus-ssh": "*",
"terminus-terminal": "*" "terminus-terminal": "*"
},
"resolutions": {
"*/node-abi": "^2.20.0"
} }
} }

View File

@@ -1,12 +0,0 @@
diff --git a/node_modules/node-abi/abi_registry.json b/node_modules/node-abi/abi_registry.json
index bc1436d..630c1b7 100644
--- a/node_modules/node-abi/abi_registry.json
+++ b/node_modules/node-abi/abi_registry.json
@@ -94,6 +94,6 @@
"future": true,
"lts": false,
"runtime": "electron",
- "target": "12.0.0-nightly.20201013"
+ "target": "12.0.0-beta.16"
}
]

View File

@@ -13,7 +13,7 @@ export function getRootModule (plugins: any[]) {
positionClass: 'toast-bottom-center', positionClass: 'toast-bottom-center',
toastClass: 'toast', toastClass: 'toast',
preventDuplicates: true, preventDuplicates: true,
extendedTimeOut: 5000, extendedTimeOut: 1000,
}), }),
] ]
const bootstrap = [ const bootstrap = [

View File

@@ -95,3 +95,12 @@ input[type=range] {
&::-moz-range-track { @include track(); } &::-moz-range-track { @include track(); }
&::-ms-track { @include track(); } &::-ms-track { @include track(); }
} }
a[ngbdropdownitem] {
cursor: pointer;
}
ngb-typeahead-window {
max-height: 60vh;
overflow: auto;
}

View File

@@ -2,14 +2,16 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
padding: 20px; padding: 20px 0 50px;
.toast { .toast {
box-shadow: 0 1px 0 rgba(0,0,0,.25); box-shadow: 0 1px 0 rgba(0,0,0,.25);
padding: 10px; padding: 7px 12px;
background-image: none; background-image: none;
width: auto; width: auto;
flex-basis: auto; flex-basis: auto;
border-radius: 0.5rem;
font-size: 0.75rem;
&.toast-error { &.toast-error {
background-color: #BD362F; background-color: #BD362F;

View File

@@ -2,40 +2,54 @@
# yarn lockfile v1 # yarn lockfile v1
"@angular/animations@^9.1.9": "@angular/animations@^11.1.1":
version "9.1.13" version "11.2.0"
resolved "https://registry.npmjs.org/@angular/animations/-/animations-9.1.13.tgz" resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-11.2.0.tgz#383438758c61d98f43c5ea1078d8388eb8784387"
integrity sha512-ane1eeQmsP7fcAiLgRhle7YIDgE88WDMMvzqJYhSxwLzXNF/hwqNeskmNcjo8bLt9h/yTIjrCQbycLCHJfU8UQ== integrity sha512-orYrBPNAsF8VpvuOaXTtPltwK2nsje5R8sWJnRC2dh1RCRdyIqHwmRIU0Mi6qLMiEaLNrFPGEMyQ9gB+sC/vYg==
dependencies:
tslib "^2.0.0"
"@angular/common@^9.1.11": "@angular/common@^11.1.1":
version "9.1.13" version "11.2.0"
resolved "https://registry.npmjs.org/@angular/common/-/common-9.1.13.tgz" resolved "https://registry.yarnpkg.com/@angular/common/-/common-11.2.0.tgz#90d602c0e33bb95a4d0c4c597f08255d78ed580f"
integrity sha512-QACUhJWlly/nfHUmjopVS1p6ayxxa/NqjyftdCeBJaoyM2YohqWixP/n/keu1K/srJ96aFpUNsZQgmgoRv5SOQ== integrity sha512-wsWI5F6Y2DNxne2D5uk8e9U/vn95UYZLMNBW+QXI9U/I9kDSXoa8yEvNcn1x0XfNXBMst5pi4iSF5M8mIck1eg==
dependencies:
tslib "^2.0.0"
"@angular/compiler@^9.1.9": "@angular/compiler@^11.1.1":
version "9.1.13" version "11.2.0"
resolved "https://registry.npmjs.org/@angular/compiler/-/compiler-9.1.13.tgz" resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-11.2.0.tgz#130bee57dd1daa1326d37bef4b63c02aa7309cc2"
integrity sha512-9MLB1Xx7odKuxDoybVwiOB1ZEUZpL8FurYm4RVuW39ntsUt0IMC9Hb8UagZLTAWhaWSHydkD/KBQVVobGqd0lA== integrity sha512-EW6LM/kUYhQkuFqGt03c/eRKZAYr0LLEdMOn//j1uIh+wSq9KLffBGpky6b63xdfWxsXi8OucXUOydTQBckNEQ==
dependencies:
tslib "^2.0.0"
"@angular/core@^9.1.9": "@angular/core@^11.1.1":
version "9.1.13" version "11.2.0"
resolved "https://registry.npmjs.org/@angular/core/-/core-9.1.13.tgz" resolved "https://registry.yarnpkg.com/@angular/core/-/core-11.2.0.tgz#309ae61d55b21fca0b644a6571109741d64b2467"
integrity sha512-mBm24Q9GjkAsxMAzqQ86U1078+yTEpr0+syMEruUtJ0HUH6Fzn3J+6xTLb+BVcGb9RkCkFaV9T5mcn6ZM0f++g== integrity sha512-jnbnJTW2GwfkRoXG8J4zs5FMcahMZwo6jrZGe9FiXjCYG9cLEuOXy4h99Z1s/o0vc/VXyWgym7SmeEgv+urf8g==
dependencies:
tslib "^2.0.0"
"@angular/forms@^9.1.11": "@angular/forms@^11.1.1":
version "9.1.13" version "11.2.0"
resolved "https://registry.npmjs.org/@angular/forms/-/forms-9.1.13.tgz" resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-11.2.0.tgz#8ba7a98efdd464a4a6b901ba1f220162dd80c1ed"
integrity sha512-soGVZmPq2bzkxvtTyeJB8p3ejzm4xxt+43hJw6Ag8NxpwUFPVa30oJge3JV+u8Y4yBtl5SbOZ4bBX3EkMxLcGQ== integrity sha512-FgIG9ou27FbmyFv0n6pF95cQEz412/+iyY9OSlDnezD/7yU4fwk4NNPgP6Z/b1k7ClLYxP/YKC00WVhi1i8HdA==
dependencies:
tslib "^2.0.0"
"@angular/platform-browser-dynamic@^9.1.9": "@angular/platform-browser-dynamic@^11.1.1":
version "9.1.13" version "11.2.0"
resolved "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-9.1.13.tgz" resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-11.2.0.tgz#647fe6d8dfa7651d38564240cbf75f97f11754b7"
integrity sha512-jCeHyAZ4Nap1/FOqAlKEg9UxQaSkHrxnQr6hYtWwC4ZDVUn3zLWQf6J+mbeYNOXN5yQxEiIqqhORYeOCLLqf1w== integrity sha512-bBCtgtL87mvDT0K3HNBS19UC0BzIJUTGnYKJS9IugyfTEqlldB4juMmh/3FPjk30kxxJ8IB/ydaN2uVhBAxPVQ==
dependencies:
tslib "^2.0.0"
"@angular/platform-browser@^9.1.9": "@angular/platform-browser@^11.1.1":
version "9.1.13" version "11.2.0"
resolved "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-9.1.13.tgz" resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-11.2.0.tgz#d1bbafd394ebfb600043060ec2d8543763041403"
integrity sha512-F3iTz1zNbtrs7KFKUxbj8qmTsd/fiuTNcpBExjE5TtatRiE6J8vNvN1+Z/1FgPe0UXBSdTzSwZ8/RxWKw20RMw== integrity sha512-xd3O4svQ95BN/KpzQUFkSWfvwiCURuLJhLlDkxzLA58ElA0qodHOjQmQz/1vRFh/nXQQoWg8z9ixbmcRGzWTow==
dependencies:
tslib "^2.0.0"
"@iarna/cli@^1.2.0": "@iarna/cli@^1.2.0":
version "1.2.0" version "1.2.0"
@@ -51,76 +65,81 @@
resolved "https://registry.yarnpkg.com/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-6.2.0.tgz#0506d612ca6002bd8fa398d006fa2641013e11d4" resolved "https://registry.yarnpkg.com/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-6.2.0.tgz#0506d612ca6002bd8fa398d006fa2641013e11d4"
integrity sha512-wqwhnJFyEwvzWQJjXrEt+7oBTSvu2qPbdYvUFYhDVzOJLWB5M7YEhDAkMrfHQJ0pZNBMGr580FqYue+XiURY0Q== integrity sha512-wqwhnJFyEwvzWQJjXrEt+7oBTSvu2qPbdYvUFYhDVzOJLWB5M7YEhDAkMrfHQJ0pZNBMGr580FqYue+XiURY0Q==
"@serialport/binding-abstract@^9.0.2": "@serialport/binding-abstract@^9.0.7":
version "9.0.2" version "9.0.7"
resolved "https://registry.npmjs.org/@serialport/binding-abstract/-/binding-abstract-9.0.2.tgz" resolved "https://registry.yarnpkg.com/@serialport/binding-abstract/-/binding-abstract-9.0.7.tgz#d2c7ecea0f100bdf20187bfc0d34ba90f5504e1e"
integrity sha512-kyMX6usn+VLpidt0YsDq5JwztIan9TPCX6skr0XcalOxI8I7w+/2qVZJzjgo2fSqDnPRcU2jMWTytwzEXFODvQ== integrity sha512-g1ncCMIG9rMsxo/28ObYmXZcHThlvtZygsCANmyMUuFS7SwXY4+PhcEnt2+ZcMkEDNRiOklT+ngtIVx5GGpt/A==
dependencies: dependencies:
debug "^4.1.1" debug "^4.3.1"
"@serialport/binding-mock@^9.0.2": "@serialport/binding-mock@^9.0.7":
version "9.0.2" version "9.0.7"
resolved "https://registry.npmjs.org/@serialport/binding-mock/-/binding-mock-9.0.2.tgz" resolved "https://registry.yarnpkg.com/@serialport/binding-mock/-/binding-mock-9.0.7.tgz#2fda427adc113320461f33f7426dfca73e8ad1de"
integrity sha512-HfrvJ/LXULHk8w63CGxwDNiDidFgDX8BnadY+cgVS6yHMHikbhLCLjCmUKsKBWaGKRqOznl0w+iUl7TMi1lkXQ== integrity sha512-aR8H+htZwwZZkVb1MdbnNvGWw8eXVRqQ2qPhkbKyx0N/LY5aVIgCgT98Kt1YylLsG7SzNG+Jbhd4wzwEuPVT5Q==
dependencies: dependencies:
"@serialport/binding-abstract" "^9.0.2" "@serialport/binding-abstract" "^9.0.7"
debug "^4.1.1" debug "^4.3.1"
"@serialport/bindings@^9.0.4": "@serialport/bindings@^9.0.7":
version "9.0.4" version "9.0.7"
resolved "https://registry.npmjs.org/@serialport/bindings/-/bindings-9.0.4.tgz" resolved "https://registry.yarnpkg.com/@serialport/bindings/-/bindings-9.0.7.tgz#8f53fb56eb866d5a1021a19ced1ddc20a60916d7"
integrity sha512-6dlE1vm5c1xk667f1Zm7D+msbHJ9jdnUr9l8DResKpj2iCBzbCNsW+yCYq26WxzXWc1L2HUaS3/aL+k0wm5amg== integrity sha512-cNWaxnEbbpLoSJ6GMb0ZeCpaciczm8XRE4jgBqe/BflWZb+wyiTYIocbsySxpS40WT3kJ0sNTFag77uSmQ6ftg==
dependencies: dependencies:
"@serialport/binding-abstract" "^9.0.2" "@serialport/binding-abstract" "^9.0.7"
"@serialport/parser-readline" "^9.0.1" "@serialport/parser-readline" "^9.0.7"
bindings "^1.5.0" bindings "^1.5.0"
debug "^4.3.1" debug "^4.3.1"
nan "^2.14.2" nan "^2.14.2"
prebuild-install "^6.0.0" prebuild-install "^6.0.1"
"@serialport/parser-byte-length@^9.0.1": "@serialport/parser-byte-length@^9.0.7":
version "9.0.1" version "9.0.7"
resolved "https://registry.npmjs.org/@serialport/parser-byte-length/-/parser-byte-length-9.0.1.tgz" resolved "https://registry.yarnpkg.com/@serialport/parser-byte-length/-/parser-byte-length-9.0.7.tgz#9e362bba70eeffcd2eb0804afeca4bb1dee59d5f"
integrity sha512-1Ikv4lgCNw8OMf35yCpgzjHwkpgBEkhBuXFXIdWZk+ixaHFLlAtp03QxGPZBmzHMK58WDmEQoBHC1V5BkkAKSQ== integrity sha512-evf7oOOSBMBn2AZZbgBFMRIyEzlsyQkhqaPm7IBCPTxMDXRf4tKkFYJHYZB0/6d1W4eI0meH079UqmSsh/uoDA==
"@serialport/parser-cctalk@^9.0.1": "@serialport/parser-cctalk@^9.0.7":
version "9.0.1" version "9.0.7"
resolved "https://registry.npmjs.org/@serialport/parser-cctalk/-/parser-cctalk-9.0.1.tgz" resolved "https://registry.yarnpkg.com/@serialport/parser-cctalk/-/parser-cctalk-9.0.7.tgz#fa0e1539f067aced22a5ef7d64fdac14f1a6a4d3"
integrity sha512-GtMda2DeJ+23bNqOc79JYV06dax2n3FLLFM3zA7nfReCOi98QbuDj4TUbFESMOnp4DB0oMO0GYHCR9gHOedTkg== integrity sha512-ert5jhMkeiTfr44TkbdySC09J8UwAsf/RxBucVN5Mz5enG509RggnkfFi4mfj3UCG2vZ7qsmM6gtZ62DshY02Q==
"@serialport/parser-delimiter@^9.0.1": "@serialport/parser-delimiter@^9.0.7":
version "9.0.1" version "9.0.7"
resolved "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-9.0.1.tgz" resolved "https://registry.yarnpkg.com/@serialport/parser-delimiter/-/parser-delimiter-9.0.7.tgz#7bef2447d4282dd00dc659719b310edeb30ff294"
integrity sha512-+oaSl5zEu47OlrRiF5p5tn2qgGqYuhVcE+NI+Pv4E1xsNB/A0fFxxMv/8XUw466CRLEJ5IESIB9qbFvKE6ltaQ== integrity sha512-Vb2NPeXPZ/28M4m5x4OAHFd8jRAeddNCgvL+Q+H/hqFPY1w47JcMLchC7pigRW8Cnt1fklmzfwdNQ8Fb+kMkxQ==
"@serialport/parser-readline@^9.0.1": "@serialport/parser-inter-byte-timeout@^9.0.7":
version "9.0.1" version "9.0.7"
resolved "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-9.0.1.tgz" resolved "https://registry.yarnpkg.com/@serialport/parser-inter-byte-timeout/-/parser-inter-byte-timeout-9.0.7.tgz#55b315b49d8ad37f981ba69bb9443f25c96aec17"
integrity sha512-38058gxvyfgdeLpg3aUyD98NuWkVB9yyTLpcSdeQ3GYiupivwH6Tdy/SKPmxlHIw3Ml2qil5MR2mtW2fLPB5CQ== integrity sha512-lUZ3cwgUluBvJ1jf+0LQsqoiPYAokDO6+fRCw9HCfnrF/OS60Gm4rxuyo2uQIueqZkJ7NIFP+ibKsULrA47AEA==
"@serialport/parser-readline@^9.0.7":
version "9.0.7"
resolved "https://registry.yarnpkg.com/@serialport/parser-readline/-/parser-readline-9.0.7.tgz#8b096028170fb2644bcf0f997d534a344cfd00e6"
integrity sha512-ydoLbgVQQPxWrwbe3Fhh4XnZexbkEQAC6M/qgRTzjnKvTjrD61CJNxLc3vyDaAPI9bJIhTiI7eTX3JB5jJv8Hg==
dependencies: dependencies:
"@serialport/parser-delimiter" "^9.0.1" "@serialport/parser-delimiter" "^9.0.7"
"@serialport/parser-ready@^9.0.1": "@serialport/parser-ready@^9.0.7":
version "9.0.1" version "9.0.7"
resolved "https://registry.npmjs.org/@serialport/parser-ready/-/parser-ready-9.0.1.tgz" resolved "https://registry.yarnpkg.com/@serialport/parser-ready/-/parser-ready-9.0.7.tgz#d9eb9801c6003fdb1450c557f3e256a188a9f3be"
integrity sha512-lgzGkVJaaV1rJVx26WwI2UKyPxc0vu1rsOeldzA3VVbF+ABrblUQA06+cRPpT6k96GY+X4+1fB1rWuPpt8HbgQ== integrity sha512-3qYhI4cNUPAYqVYvdwV57Y+PVRl4dJf1fPBtMoWtwDgwopsAXTR93WCs49WuUq9JCyNW+8Hrfqv8x8eNAD5Dqg==
"@serialport/parser-regex@^9.0.1": "@serialport/parser-regex@^9.0.7":
version "9.0.1" version "9.0.7"
resolved "https://registry.npmjs.org/@serialport/parser-regex/-/parser-regex-9.0.1.tgz" resolved "https://registry.yarnpkg.com/@serialport/parser-regex/-/parser-regex-9.0.7.tgz#d8a02e3a169faa2f6604e8293832cc676b865f48"
integrity sha512-BHTV+Lkl+J8hSecFtDRENaR4fgA6tw44J+dmA1vEKEyum0iDN4bihbu8yvztYyo4PhBGUKDfm/PnD5EkJm0dPA== integrity sha512-5XF+FXbhqQ/5bVKM4NaGs1m+E9KjfmeCx/obwsKaUZognQF67jwoTfjJJWNP/21jKfxdl8XoCYjZjASl3XKRAw==
"@serialport/stream@^9.0.2": "@serialport/stream@^9.0.7":
version "9.0.2" version "9.0.7"
resolved "https://registry.npmjs.org/@serialport/stream/-/stream-9.0.2.tgz" resolved "https://registry.yarnpkg.com/@serialport/stream/-/stream-9.0.7.tgz#0bf023eb0233a714fcc5a86de09e381e466d9882"
integrity sha512-0RkVe+gvwZu/PPfbb7ExQ+euGoCTGKD/B8TQ5fuhe+eKk1sh73RwjKmu9gp6veSNqx9Zljnh1dF6mhdEKWZpSA== integrity sha512-c/h7HPAeFiryD9iTGlaSvPqHFHSZ0NMQHxC4rcmKS2Vu3qJuEtkBdTLABwsMp7iWEiSnI4KC3s7bHapaXP06FQ==
dependencies: dependencies:
debug "^4.1.1" debug "^4.3.1"
"@terminus-term/node-pty@0.10.0-beta10": "@terminus-term/node-pty@0.10.0-terminus.3":
version "0.10.0-beta10" version "0.10.0-terminus.3"
resolved "https://registry.yarnpkg.com/@terminus-term/node-pty/-/node-pty-0.10.0-beta10.tgz#de9dade3d7549d44b0906ec0d0b9e1bb411f1f21" resolved "https://registry.yarnpkg.com/@terminus-term/node-pty/-/node-pty-0.10.0-terminus.3.tgz#9dbd64d52afda5079e66265a89d313fe42affab7"
integrity sha512-j9RJk7sD/es4vR6+AR5M/p3SicVxY6kZEeE0UQKhHNcaAla90/mcGeBNicAWPaAkjO1uQZVbYh5cJMMu5unQgA== integrity sha512-HvIOts22dnoBXhRfLiK9DyPasuixYVgEUvgqZmOr0B0Ki9tF8e074oYPUtzLRll6Y553QiUzTWhriCS99MChNQ==
dependencies: dependencies:
nan "^2.14.0" nan "^2.14.0"
@@ -131,10 +150,10 @@
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/node@*", "@types/node@14.14.14": "@types/node@*", "@types/node@14.14.31":
version "14.14.14" version "14.14.31"
resolved "https://registry.npmjs.org/@types/node/-/node-14.14.14.tgz" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.31.tgz#72286bd33d137aa0d152d47ec7c1762563d34055"
integrity sha512-UHnOPWVWV1z+VV8k6L1HhG7UbGBgIdghqF3l9Ny9ApPghbjICXkUJSd/b9gOgQfjM1r+37cipdw/HJ3F6ICEnQ== integrity sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==
JSONStream@^1.3.4, JSONStream@^1.3.5: JSONStream@^1.3.4, JSONStream@^1.3.5:
version "1.3.5" version "1.3.5"
@@ -259,12 +278,10 @@ are-we-there-yet@~1.1.2:
delegates "^1.0.0" delegates "^1.0.0"
readable-stream "^2.0.6" readable-stream "^2.0.6"
argparse@^1.0.7: argparse@^2.0.1:
version "1.0.10" version "2.0.1"
resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
dependencies:
sprintf-js "~1.0.2"
asap@^2.0.0: asap@^2.0.0:
version "2.0.6" version "2.0.6"
@@ -709,7 +726,7 @@ debug@^3.1.0:
dependencies: dependencies:
ms "^2.1.1" ms "^2.1.1"
debug@^4.0.1, debug@^4.1.1, debug@^4.3.1: debug@^4.0.1, debug@^4.3.1:
version "4.3.1" version "4.3.1"
resolved "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz" resolved "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz"
integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
@@ -837,10 +854,10 @@ electron-config@2.0.0:
dependencies: dependencies:
conf "^1.0.0" conf "^1.0.0"
electron-debug@^3.0.1: electron-debug@^3.2.0:
version "3.1.0" version "3.2.0"
resolved "https://registry.npmjs.org/electron-debug/-/electron-debug-3.1.0.tgz" resolved "https://registry.yarnpkg.com/electron-debug/-/electron-debug-3.2.0.tgz#46a15b555c3b11872218c65ea01d058aa0814920"
integrity sha512-SWEqLj4MgfV3tGuO5eBLQ5/Nr6M+KPxsnE0bUJZvQebGJus6RAcdmvd7L+l0Ji31h2mmrN23l2tHFtCa2FvurA== integrity sha512-7xZh+LfUvJ52M9rn6N+tPuDw6oRAjxUj9SoxAZfJ0hVCXhZCsdkrSt7TgXOiWiEOBgEV8qwUIO/ScxllsPS7ow==
dependencies: dependencies:
electron-is-dev "^1.1.0" electron-is-dev "^1.1.0"
electron-localshortcut "^3.1.0" electron-localshortcut "^3.1.0"
@@ -850,7 +867,12 @@ electron-is-accelerator@^0.1.0:
resolved "https://registry.npmjs.org/electron-is-accelerator/-/electron-is-accelerator-0.1.2.tgz" resolved "https://registry.npmjs.org/electron-is-accelerator/-/electron-is-accelerator-0.1.2.tgz"
integrity sha1-UJ5RDCala1Xhf4Y6SwThEYRqsns= integrity sha1-UJ5RDCala1Xhf4Y6SwThEYRqsns=
electron-is-dev@1.1.0, electron-is-dev@^1.1.0: electron-is-dev@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/electron-is-dev/-/electron-is-dev-1.2.0.tgz#2e5cea0a1b3ccf1c86f577cee77363ef55deb05e"
integrity sha512-R1oD5gMBPS7PVU8gJwH6CtT0e6VSoD0+SzSnYpNm+dBkcijgA+K7VAMHDfnRq/lkKPZArpzplTW6jfiMYosdzw==
electron-is-dev@^1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-1.1.0.tgz" resolved "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-1.1.0.tgz"
integrity sha512-Z1qA/1oHNowGtSBIcWk0pcLEqYT/j+13xUw/MYOrBUOL4X7VN0i0KCTf5SqyvMPmW5pSPKbo28wkxMxzZ20YnQ== integrity sha512-Z1qA/1oHNowGtSBIcWk0pcLEqYT/j+13xUw/MYOrBUOL4X7VN0i0KCTf5SqyvMPmW5pSPKbo28wkxMxzZ20YnQ==
@@ -972,11 +994,6 @@ escape-string-regexp@^1.0.5:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
esprima@^4.0.0:
version "4.0.1"
resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz"
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
execa@^0.7.0: execa@^0.7.0:
version "0.7.0" version "0.7.0"
resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777"
@@ -1217,10 +1234,10 @@ github-from-package@0.0.0:
resolved "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz" resolved "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz"
integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=
glasstron@0.0.6: glasstron@0.0.7:
version "0.0.6" version "0.0.7"
resolved "https://registry.yarnpkg.com/glasstron/-/glasstron-0.0.6.tgz#1438899cd49a1cda1999290be2165310b759fd62" resolved "https://registry.yarnpkg.com/glasstron/-/glasstron-0.0.7.tgz#d0f3e8344351bbcb89a39323282b4ddb06b03ba0"
integrity sha512-WBE1zH3ZcYhLlfKATfKzuN05Anno2WYlVfImWteU5RM+gqdFLHGIxxM3VR16JvFF5oIYah01MBGQ2+3xTq44iQ== integrity sha512-zeqfC0E153yBKWHB8ZBA5rT1o1dCCQcPECBryzWLX3uy6VTX3CUcy7kjk/4BlVztEIbpV2plEetpOxSAOe5cqw==
dependencies: dependencies:
node-addon-api "^3.0.0" node-addon-api "^3.0.0"
x11 "^2.3.0" x11 "^2.3.0"
@@ -1581,13 +1598,12 @@ isstream@~0.1.2:
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz"
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
js-yaml@3.14.0: js-yaml@4.0.0:
version "3.14.0" version "4.0.0"
resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.0.0.tgz#f426bc0ff4b4051926cd588c71113183409a121f"
integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== integrity sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==
dependencies: dependencies:
argparse "^1.0.7" argparse "^2.0.1"
esprima "^4.0.0"
jsbn@~0.1.0: jsbn@~0.1.0:
version "0.1.1" version "0.1.1"
@@ -1644,10 +1660,10 @@ keyboardevents-areequal@^0.2.1:
resolved "https://registry.npmjs.org/keyboardevents-areequal/-/keyboardevents-areequal-0.2.2.tgz" resolved "https://registry.npmjs.org/keyboardevents-areequal/-/keyboardevents-areequal-0.2.2.tgz"
integrity sha512-Nv+Kr33T0mEjxR500q+I6IWisOQ0lK1GGOncV0kWE6n4KFmpcu7RUX5/2B0EUtX51Cb0HjZ9VJsSY3u4cBa0kw== integrity sha512-Nv+Kr33T0mEjxR500q+I6IWisOQ0lK1GGOncV0kWE6n4KFmpcu7RUX5/2B0EUtX51Cb0HjZ9VJsSY3u4cBa0kw==
keytar@^7.2.0: keytar@^7.4.0:
version "7.3.0" version "7.4.0"
resolved "https://registry.npmjs.org/keytar/-/keytar-7.3.0.tgz" resolved "https://registry.yarnpkg.com/keytar/-/keytar-7.4.0.tgz#0a508d64850ca05aa3ba4127818037d13ca3219f"
integrity sha512-t8YD0ETO5AeRxCaaN4N/hzj3JusIH0ugjVooE724+ozaVG9+l16Mau62T+U8tEhCv7SozY/g69BWF1U+o47qJg== integrity sha512-nELmc35YjSE4ZNSFaID/743CgDt/MdV4JLX7rRewAh9mKvU72RtF3uJMY0MdMpwdDYZhmD8FSdRCD1J97lEyVg==
dependencies: dependencies:
node-addon-api "^3.0.0" node-addon-api "^3.0.0"
prebuild-install "^6.0.0" prebuild-install "^6.0.0"
@@ -2083,17 +2099,24 @@ napi-build-utils@^1.0.1:
resolved "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz" resolved "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz"
integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==
ngx-toastr@^12.0.1: native-process-working-directory@^1.0.2:
version "12.1.0" version "1.0.2"
resolved "https://registry.npmjs.org/ngx-toastr/-/ngx-toastr-12.1.0.tgz" resolved "https://registry.yarnpkg.com/native-process-working-directory/-/native-process-working-directory-1.0.2.tgz#7843e2fa1490f53cf8d2c7d1913de8b275e8b89a"
integrity sha512-rytCRBhvuudj614Kfj9GoIVQDrFuLvHSMP1YrMwTmR1SNkNJZOpGKmaSDCCBrNDkSrGouzMWBlFbl1UDBBsiqw== integrity sha512-3a67QQV8r3YMUTSOgvtMOCjPDgCpb/8xjv93L8Cqb8bv3hOKsWis4/+8HCu3bgj8ADQV75SCYFSsAGM5G0cXmQ==
dependencies: dependencies:
tslib "^1.10.0" node-addon-api "^3.1.0"
node-abi@2.19.3, node-abi@^2.7.0: ngx-toastr@^13.2.0:
version "2.19.3" version "13.2.0"
resolved "https://registry.npmjs.org/node-abi/-/node-abi-2.19.3.tgz" resolved "https://registry.yarnpkg.com/ngx-toastr/-/ngx-toastr-13.2.0.tgz#3ef047c977a7d0fb67fed9338b8f5add3c87b356"
integrity sha512-9xZrlyfvKhWme2EXFKQhZRp1yNWT/uI1luYPr3sFl+H4keYY4xR+1jO7mvTTijIsHf1M+QDe9uWuKeEpLInIlg== integrity sha512-XU+wACX5hxwOJ4BtPMAUExQmYbjfvH3C/R4vcC9QK/dX2Zw+2w9tS9m4W6TUFyR92xZ/tGLBtsqRdrDRn3fJCw==
dependencies:
tslib "^2.0.0"
node-abi@^2.20.0, node-abi@^2.21.0, node-abi@^2.7.0:
version "2.21.0"
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.21.0.tgz#c2dc9ebad6f4f53d6ea9b531e7b8faad81041d48"
integrity sha512-smhrivuPqEM3H5LmnY3KU6HfYv0u4QklgAxfFyRNujKUzbUcYZ+Jc2EhukB9SRcD2VpqhxM7n/MIcp1Ua1/JMg==
dependencies: dependencies:
semver "^5.4.1" semver "^5.4.1"
@@ -2102,7 +2125,7 @@ node-addon-api@3.0.0:
resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.0.0.tgz" resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.0.0.tgz"
integrity sha512-sSHCgWfJ+Lui/u+0msF3oyCgvdkhxDbkCS6Q8uiJquzOimkJBvX6hl5aSSA7DR1XbMpdM8r7phjcF63sF4rkKg== integrity sha512-sSHCgWfJ+Lui/u+0msF3oyCgvdkhxDbkCS6Q8uiJquzOimkJBvX6hl5aSSA7DR1XbMpdM8r7phjcF63sF4rkKg==
node-addon-api@^3.0.0, node-addon-api@^3.0.2: node-addon-api@^3.0.0, node-addon-api@^3.0.2, node-addon-api@^3.1.0:
version "3.1.0" version "3.1.0"
resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.1.0.tgz" resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.1.0.tgz"
integrity sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw== integrity sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw==
@@ -2693,6 +2716,27 @@ prebuild-install@^6.0.0:
tunnel-agent "^0.6.0" tunnel-agent "^0.6.0"
which-pm-runs "^1.0.0" which-pm-runs "^1.0.0"
prebuild-install@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-6.0.1.tgz#5902172f7a40eb67305b96c2a695db32636ee26d"
integrity sha512-7GOJrLuow8yeiyv75rmvZyeMGzl8mdEX5gY69d6a6bHWmiPevwqFw+tQavhK0EYMaSg3/KD24cWqeQv1EWsqDQ==
dependencies:
detect-libc "^1.0.3"
expand-template "^2.0.3"
github-from-package "0.0.0"
minimist "^1.2.3"
mkdirp-classic "^0.5.3"
napi-build-utils "^1.0.1"
node-abi "^2.7.0"
noop-logger "^0.1.1"
npmlog "^4.0.1"
pump "^3.0.0"
rc "^1.2.7"
simple-get "^3.0.3"
tar-fs "^2.0.0"
tunnel-agent "^0.6.0"
which-pm-runs "^1.0.0"
prepend-http@^1.0.1: prepend-http@^1.0.1:
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
@@ -3018,10 +3062,10 @@ run-queue@^1.0.0, run-queue@^1.0.3:
dependencies: dependencies:
aproba "^1.1.1" aproba "^1.1.1"
rxjs@^6.5.5: rxjs@^6.6.6:
version "6.6.3" version "6.6.6"
resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.6.tgz#14d8417aa5a07c5e633995b525e1e3c0dec03b70"
integrity sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ== integrity sha512-/oTwee4N4iWzAMAL9xdGKjkEHmIwupR3oXbQjCKywF1BeFohswF3vZdogbmEF6pZkOsXTzWkrZszrWpQTByYVg==
dependencies: dependencies:
tslib "^1.9.0" tslib "^1.9.0"
@@ -3059,21 +3103,22 @@ serialize-error@^5.0.0:
dependencies: dependencies:
type-fest "^0.8.0" type-fest "^0.8.0"
serialport@^9.0.4: serialport@^9.0.7:
version "9.0.4" version "9.0.7"
resolved "https://registry.npmjs.org/serialport/-/serialport-9.0.4.tgz" resolved "https://registry.yarnpkg.com/serialport/-/serialport-9.0.7.tgz#bd116a70bd7acbfd587491acd3ee03e02a0df71c"
integrity sha512-Wtl6sxciHKNdJKW8jUZm+f5KRXt0J0UP25ksM8N31l08KTdAhZ5MmKNUFpoO/YYG6TvHFOu+07PUX35m+TUw7g== integrity sha512-NeDfVks3JAJ7s8cXDopx1iUUgC/7TaltE7iQGiSewIWMZaK7oStiz3VJzcuKgor7F+U/y6zbAnj4i6eHq0on+g==
dependencies: dependencies:
"@serialport/binding-mock" "^9.0.2" "@serialport/binding-mock" "^9.0.7"
"@serialport/bindings" "^9.0.4" "@serialport/bindings" "^9.0.7"
"@serialport/parser-byte-length" "^9.0.1" "@serialport/parser-byte-length" "^9.0.7"
"@serialport/parser-cctalk" "^9.0.1" "@serialport/parser-cctalk" "^9.0.7"
"@serialport/parser-delimiter" "^9.0.1" "@serialport/parser-delimiter" "^9.0.7"
"@serialport/parser-readline" "^9.0.1" "@serialport/parser-inter-byte-timeout" "^9.0.7"
"@serialport/parser-ready" "^9.0.1" "@serialport/parser-readline" "^9.0.7"
"@serialport/parser-regex" "^9.0.1" "@serialport/parser-ready" "^9.0.7"
"@serialport/stream" "^9.0.2" "@serialport/parser-regex" "^9.0.7"
debug "^4.1.1" "@serialport/stream" "^9.0.7"
debug "^4.3.1"
set-blocking@^2.0.0, set-blocking@~2.0.0: set-blocking@^2.0.0, set-blocking@~2.0.0:
version "2.0.0" version "2.0.0"
@@ -3201,11 +3246,6 @@ split-on-first@^1.0.0:
resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f"
integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==
sprintf-js@~1.0.2:
version "1.0.3"
resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz"
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
sshpk@^1.7.0: sshpk@^1.7.0:
version "1.16.1" version "1.16.1"
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz"
@@ -3463,15 +3503,15 @@ tough-cookie@~2.5.0:
psl "^1.1.28" psl "^1.1.28"
punycode "^2.1.1" punycode "^2.1.1"
tslib@^1.10.0, tslib@^1.9.0: tslib@^1.9.0:
version "1.14.1" version "1.14.1"
resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
tslib@^2.0.0: tslib@^2.0.0:
version "2.0.3" version "2.1.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a"
integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ== integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==
tunnel-agent@^0.6.0: tunnel-agent@^0.6.0:
version "0.6.0" version "0.6.0"
@@ -3836,9 +3876,9 @@ yargs@^8.0.2:
y18n "^3.2.1" y18n "^3.2.1"
yargs-parser "^7.0.0" yargs-parser "^7.0.0"
zone.js@^0.11.3: zone.js@^0.11.4:
version "0.11.3" version "0.11.4"
resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.11.3.tgz#255a6313174731cc014d63233ef04fd9858da375" resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.11.4.tgz#0f70dcf6aba80f698af5735cbb257969396e8025"
integrity sha512-Y4hTHoh4VcxU5BDGAqEoOnOiyT254w6CiHtpQxAJUSMZPyVgdbKf+5R7Mwz6xsPhMIeBXk5rTopRZDpjssTCUg== integrity sha512-DDh2Ab+A/B+9mJyajPjHFPWfYU1H+pdun4wnnk0OcQTNjem1XQSZ2CDW+rfZEUDjv5M19SBqAkjZi0x5wuB5Qw==
dependencies: dependencies:
tslib "^2.0.0" tslib "^2.0.0"

View File

@@ -63,7 +63,7 @@ mac:
NSRemovableVolumesUsageDescription: 'A subprocess requests access to files on a removable volume.' NSRemovableVolumesUsageDescription: 'A subprocess requests access to files on a removable volume.'
linux: linux:
category: Utilities category: Utility
icon: "./build/icons" icon: "./build/icons"
artifactName: terminus-${version}-linux.${ext} artifactName: terminus-${version}-linux.${ext}
executableArgs: executableArgs:
@@ -88,3 +88,6 @@ rpm:
depends: depends:
- screen - screen
- gnome-keyring - gnome-keyring
fpm:
- '--rpm-rpmbuild-define'
- '_build_id_links none'

View File

@@ -1,33 +1,34 @@
{ {
"devDependencies": { "devDependencies": {
"@fortawesome/fontawesome-free": "^5.13.0", "@fortawesome/fontawesome-free": "^5.15.2",
"@sentry/cli": "^1.61.0", "@sentry/cli": "^1.63.0",
"@sentry/electron": "^2.0.4", "@sentry/electron": "^2.4.0",
"@terminus-term/to-string-loader": "1.1.7-beta.1",
"@types/electron-config": "^3.2.2", "@types/electron-config": "^3.2.2",
"@types/electron-debug": "^2.1.0", "@types/electron-debug": "^2.1.0",
"@types/fs-extra": "^8.1.1", "@types/fs-extra": "^8.1.1",
"@types/js-yaml": "^3.12.5", "@types/js-yaml": "^4.0.0",
"@types/node": "14.14.14", "@types/node": "14.14.31",
"@types/webpack-env": "^1.16.0", "@types/webpack-env": "^1.16.0",
"@typescript-eslint/eslint-plugin": "^4.11.0", "@typescript-eslint/eslint-plugin": "^4.14.1",
"@typescript-eslint/parser": "^4.11.0", "@typescript-eslint/parser": "^4.17.0",
"apply-loader": "2.0.0", "apply-loader": "2.0.0",
"awesome-typescript-loader": "^5.2.1", "awesome-typescript-loader": "^5.2.1",
"compare-versions": "^3.6.0", "compare-versions": "^3.6.0",
"core-js": "^3.8.1", "core-js": "^3.9.1",
"cross-env": "7.0.2", "cross-env": "7.0.3",
"css-loader": "3.4.2", "css-loader": "5.0.1",
"electron": "12.0.0-beta.16", "electron": "12.0.1",
"electron-builder": "22.10.4", "electron-builder": "22.10.5",
"electron-download": "^4.1.1", "electron-download": "^4.1.1",
"electron-installer-snap": "^5.1.0", "electron-installer-snap": "^5.1.0",
"electron-notarize": "^1.0.0", "electron-notarize": "^1.0.0",
"electron-rebuild": "^2.3.4", "electron-rebuild": "^2.3.5",
"eslint": "^7.6.0", "eslint": "^7.18.0",
"eslint-plugin-import": "^2.21.1", "eslint-plugin-import": "^2.21.1",
"file-loader": "^5.1.0", "file-loader": "^6.2.0",
"graceful-fs": "^4.2.4", "graceful-fs": "^4.2.6",
"html-loader": "0.5.5", "html-loader": "2.1.2",
"json-loader": "0.5.7", "json-loader": "0.5.7",
"lru-cache": "^6.0.0", "lru-cache": "^6.0.0",
"macos-release": "^2.4.1", "macos-release": "^2.4.1",
@@ -37,31 +38,30 @@
"npmlog": "4.1.2", "npmlog": "4.1.2",
"npx": "^10.2.2", "npx": "^10.2.2",
"patch-package": "^6.2.2", "patch-package": "^6.2.2",
"pug": "^2.0.4", "pug": "^3.0.2",
"pug-html-loader": "1.1.5", "pug-html-loader": "1.1.5",
"pug-lint": "^2.6.0", "pug-lint": "^2.6.0",
"pug-loader": "^2.4.0", "pug-loader": "^2.4.0",
"pug-static-loader": "2.0.0", "pug-static-loader": "2.0.0",
"raw-loader": "4.0.1", "raw-loader": "4.0.2",
"sass-loader": "^10.1.0", "sass-loader": "^11.0.1",
"shelljs": "0.8.4", "shelljs": "0.8.4",
"source-code-pro": "^2.30.2", "source-code-pro": "^2.30.2",
"source-sans-pro": "3.6.0", "source-sans-pro": "3.6.0",
"ssh2-streams": "^0.4.10", "ssh2-streams": "^0.4.10",
"style-loader": "^2.0.0", "style-loader": "^2.0.0",
"svg-inline-loader": "^0.8.2", "svg-inline-loader": "^0.8.2",
"to-string-loader": "1.1.6", "tslib": "^2.1.0",
"tslib": "^2.0.3", "typedoc": "^0.20.28",
"typedoc": "^0.18.0", "typescript": "^3.9.9",
"typescript": "^3.9.7", "url-loader": "^4.1.1",
"url-loader": "^3.0.0", "val-loader": "3.0.0",
"val-loader": "2.1.1", "webpack": "^5.18.0",
"webpack": "^5.11.0", "webpack-cli": "^4.5.0",
"webpack-cli": "^4.2.0",
"yaml-loader": "0.6.0" "yaml-loader": "0.6.0"
}, },
"resolutions": { "resolutions": {
"*/node-abi": "^2.19.3", "*/node-abi": "^2.20.0",
"**/graceful-fs": "^4.2.4" "**/graceful-fs": "^4.2.4"
}, },
"scripts": { "scripts": {
@@ -71,11 +71,9 @@
"start": "cross-env TERMINUS_DEV=1 electron app --debug", "start": "cross-env TERMINUS_DEV=1 electron app --debug",
"start:prod": "electron app --debug", "start:prod": "electron app --debug",
"prod": "cross-env TERMINUS_DEV=1 electron app", "prod": "cross-env TERMINUS_DEV=1 electron app",
"docs": "typedoc --out docs/api terminus-core/src && typedoc --out docs/api/terminal --tsconfig terminus-terminal/tsconfig.typings.json terminus-terminal/src && typedoc --out docs/api/settings --tsconfig terminus-settings/tsconfig.typings.json terminus-settings/src", "docs": "typedoc --out docs/api --tsconfig terminus-core/src/tsconfig.typings.json terminus-core/src/index.ts && typedoc --out docs/api/terminal --tsconfig terminus-terminal/tsconfig.typings.json terminus-terminal/src/index.ts && typedoc --out docs/api/settings --tsconfig terminus-settings/tsconfig.typings.json terminus-settings/src/index.ts",
"lint": "eslint --ext ts */src */lib", "lint": "eslint --ext ts */src */lib",
"postinstall": "node ./scripts/install-deps.js" "postinstall": "node ./scripts/install-deps.js"
}, },
"repository": "eugeny/terminus", "private": true
"author": "Eugene Pankov",
"license": "MIT"
} }

View File

@@ -1,12 +0,0 @@
diff --git a/node_modules/node-abi/abi_registry.json b/node_modules/node-abi/abi_registry.json
index bc1436d..630c1b7 100644
--- a/node_modules/node-abi/abi_registry.json
+++ b/node_modules/node-abi/abi_registry.json
@@ -94,6 +94,6 @@
"future": true,
"lts": false,
"runtime": "electron",
- "target": "12.0.0-nightly.20201013"
+ "target": "12.0.0-beta.16"
}
]

View File

@@ -1,6 +1,6 @@
{ {
"name": "terminus-community-color-schemes", "name": "terminus-community-color-schemes",
"version": "1.0.123-nightly.0", "version": "1.0.135-nightly.0",
"description": "Community color schemes for Terminus", "description": "Community color schemes for Terminus",
"keywords": [ "keywords": [
"terminus-builtin-plugin" "terminus-builtin-plugin"

View File

@@ -0,0 +1,42 @@
!
!
*.foreground: #d8dee9
*.background: #2e3440
*.cursorColor: #d8dee9
!
! Black
*.color0: #3b4252
*.color8: #373e4d
!
! Red
*.color1: #bf616a
*.color9: #94545d
!
! Green
*.color2: #a3be8c
*.color10: #809575
!
! Yellow
*.color3: #ebcb8b
*.color11: #b29e75
!
! Blue
*.color4: #81a1c1
*.color12: #68809a
!
! Magenta
*.color5: #b48ead
*.color13: #8c738c
!
! Cyan
*.color6: #88c0d0
*.color14: #6d96a5
!
! White
*.color7: #e5e9f0
*.color15: #aeb3bb
!
! Bold, Italic, Underline
*.colorBD: #a5abb6
!*.colorIT:
!*.colorUL:

View File

@@ -1,51 +1,6 @@
const path = require('path') const config = require('../webpack.plugin.config')
module.exports = config({
module.exports = { name: 'community-color-schemes',
target: 'node', dirname: __dirname,
entry: 'src/index.ts', })
context: __dirname, module.exports.module.rules.push({ test: /[\\\/]schemes[\\\/]/, use: 'raw-loader' })
devtool: 'cheap-module-source-map',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
pathinfo: true,
libraryTarget: 'umd',
devtoolModuleFilenameTemplate: 'webpack-terminus-community-color-schemes:///[resource-path]',
},
mode: process.env.TERMINUS_DEV ? 'development' : 'production',
optimization:{
minimize: false,
},
resolve: {
modules: ['.', 'src', 'node_modules', '../app/node_modules'].map(x => path.join(__dirname, x)),
extensions: ['.ts', '.js'],
},
module: {
rules: [
{
test: /\.ts$/,
use: {
loader: 'awesome-typescript-loader',
options: {
configFileName: path.resolve(__dirname, 'tsconfig.json'),
typeRoots: [
path.resolve(__dirname, 'node_modules/@types'),
path.resolve(__dirname, '../node_modules/@types'),
],
paths: {
"terminus-*": [path.resolve(__dirname, '../terminus-*')],
"*": [path.resolve(__dirname, '../app/node_modules/*')],
},
},
},
},
{ test: /[\\\/]schemes[\\\/]/, use: "raw-loader" },
],
},
externals: [
/^rxjs/,
/^@angular/,
/^@ng-bootstrap/,
/^terminus-/,
],
}

View File

@@ -1,6 +1,6 @@
{ {
"name": "terminus-core", "name": "terminus-core",
"version": "1.0.123-nightly.0", "version": "1.0.135-nightly.0",
"description": "Terminus core", "description": "Terminus core",
"keywords": [ "keywords": [
"terminus-builtin-plugin" "terminus-builtin-plugin"
@@ -17,18 +17,18 @@
"author": "Eugene Pankov", "author": "Eugene Pankov",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@types/js-yaml": "^3.9.0", "@types/js-yaml": "^4.0.0",
"@types/shell-escape": "^0.2.0", "@types/shell-escape": "^0.2.0",
"@types/winston": "^2.3.6", "@types/winston": "^2.3.6",
"axios": "^0.19.0", "axios": "^0.21.1",
"bootstrap": "^4.1.3", "bootstrap": "^4.1.3",
"core-js": "^3.1.2", "core-js": "^3.1.2",
"deepmerge": "^4.1.1", "deepmerge": "^4.1.1",
"electron-updater": "^4.0.6", "electron-updater": "^4.0.6",
"js-yaml": "^3.9.0", "js-yaml": "^4.0.0",
"mixpanel": "^0.10.2", "mixpanel": "^0.10.2",
"ng2-dnd": "^5.0.2", "ng2-dnd": "^5.0.2",
"ngx-perfect-scrollbar": "^8.0.0", "ngx-perfect-scrollbar": "^10.1.0",
"readable-stream": "2.3.7", "readable-stream": "2.3.7",
"shell-escape": "^0.2.0", "shell-escape": "^0.2.0",
"uuid": "^8.0.0", "uuid": "^8.0.0",

View File

@@ -17,6 +17,7 @@ export { Logger, LogService } from '../services/log.service'
export { HomeBaseService } from '../services/homeBase.service' export { HomeBaseService } from '../services/homeBase.service'
export { HotkeysService } from '../services/hotkeys.service' export { HotkeysService } from '../services/hotkeys.service'
export { HostAppService, Platform } from '../services/hostApp.service' export { HostAppService, Platform } from '../services/hostApp.service'
export { NotificationsService } from '../services/notifications.service'
export { ShellIntegrationService } from '../services/shellIntegration.service' export { ShellIntegrationService } from '../services/shellIntegration.service'
export { ThemesService } from '../services/themes.service' export { ThemesService } from '../services/themes.service'
export { TabsService } from '../services/tabs.service' export { TabsService } from '../services/tabs.service'

View File

@@ -10,4 +10,7 @@ export abstract class Theme {
css: string css: string
terminalBackground: string terminalBackground: string
macOSWindowButtonsInsetX?: number
macOSWindowButtonsInsetY?: number
} }

View File

@@ -1,6 +1,6 @@
title-bar( title-bar(
*ngIf='!hostApp.isFullScreen && config.store.appearance.frame == "full" && config.store.appearance.dock == "off"', *ngIf='!hostApp.isFullScreen && config.store.appearance.frame == "full" && config.store.appearance.dock == "off"',
[class.inset]='hostApp.platform == Platform.macOS' [class.inset]='hostApp.platform == Platform.macOS && !hostApp.isFullScreen'
) )
.content( .content(
@@ -9,6 +9,7 @@ title-bar(
) )
.tab-bar .tab-bar
.inset.background(*ngIf='hostApp.platform == Platform.macOS \ .inset.background(*ngIf='hostApp.platform == Platform.macOS \
&& !hostApp.isFullScreen \
&& config.store.appearance.frame == "thin" \ && config.store.appearance.frame == "thin" \
&& (config.store.appearance.tabsLocation == "top" || config.store.appearance.tabsLocation == "left")') && (config.store.appearance.tabsLocation == "top" || config.store.appearance.tabsLocation == "left")')
.tabs( .tabs(

View File

@@ -85,6 +85,7 @@ $side-tab-width: 200px;
cursor: pointer; cursor: pointer;
display: flex; display: flex;
align-items: center;
padding: 0 15px; padding: 0 15px;
flex: 0 0 auto; flex: 0 0 auto;
border-bottom: 2px solid transparent; border-bottom: 2px solid transparent;

View File

@@ -142,6 +142,8 @@ export class AppRootComponent {
this.touchbar.update() this.touchbar.update()
this.hostApp.useBuiltinGraphics()
config.changed$.subscribe(() => this.updateVibrancy()) config.changed$.subscribe(() => this.updateVibrancy())
this.updateVibrancy() this.updateVibrancy()

View File

@@ -17,7 +17,7 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'
}) })
export class CheckboxComponent implements ControlValueAccessor { export class CheckboxComponent implements ControlValueAccessor {
@HostBinding('class.active') @Input() model: boolean @HostBinding('class.active') @Input() model: boolean
@Input() disabled: boolean @HostBinding('class.disabled') @Input() disabled: boolean
@Input() text: string @Input() text: string
private changed = new Array<(val: boolean) => void>() private changed = new Array<(val: boolean) => void>()

View File

@@ -7,7 +7,7 @@
(ngModelChange)='onFilterChange()' (ngModelChange)='onFilterChange()'
) )
.list-group.mt-3(*ngIf='filteredOptions.length') .list-group(*ngIf='filteredOptions.length')
a.list-group-item.list-group-item-action.d-flex.align-items-center( a.list-group-item.list-group-item-action.d-flex.align-items-center(
#item, #item,
(click)='selectOption(option)', (click)='selectOption(option)',

View File

@@ -1,6 +1,12 @@
.modal-body {
padding: 0;
}
.list-group { .list-group {
max-height: 70vh; max-height: 70vh;
overflow: auto; overflow: auto;
border-top-left-radius: 0;
border-top-right-radius: 0;
} }
.icon { .icon {

View File

@@ -1,9 +1,10 @@
import { Component, Input, HostListener, ViewChildren, QueryList, ElementRef } from '@angular/core' import { Component, Input, HostListener, ViewChildren, QueryList, ElementRef } from '@angular/core' // eslint-disable-line @typescript-eslint/no-unused-vars
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap' import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
import { SelectorOption } from '../api/selector' import { SelectorOption } from '../api/selector'
/** @hidden */ /** @hidden */
@Component({ @Component({
selector: 'selector-modal',
template: require('./selectorModal.component.pug'), template: require('./selectorModal.component.pug'),
styles: [require('./selectorModal.component.scss')], styles: [require('./selectorModal.component.scss')],
}) })

View File

@@ -6,6 +6,12 @@ $tabs-height: 38px;
flex: 1000 1 200px; flex: 1000 1 200px;
width: 200px; width: 200px;
padding: 0 10px;
&.flex-width {
flex: 1000 1 auto;
width: auto;
}
display: flex; display: flex;
flex-direction: row; flex-direction: row;
@@ -24,7 +30,6 @@ $tabs-height: 38px;
-webkit-app-region: no-drag; -webkit-app-region: no-drag;
cursor: -webkit-grab; cursor: -webkit-grab;
margin-left: 10px;
width: 22px; width: 22px;
border-radius: 10px; border-radius: 10px;
text-align: center; text-align: center;
@@ -34,7 +39,7 @@ $tabs-height: 38px;
.name { .name {
flex: auto; flex: auto;
margin: 0 1px 0 10px; margin-top: 1px;
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
@@ -42,6 +47,10 @@ $tabs-height: 38px;
align-self: center; align-self: center;
} }
.index + .name {
margin-left: 10px;
}
button { button {
display: block; display: block;
flex: none; flex: none;
@@ -49,13 +58,15 @@ $tabs-height: 38px;
opacity: 0; opacity: 0;
-webkit-app-region: no-drag; -webkit-app-region: no-drag;
position: absolute;
right: 0;
$button-size: 26px; $button-size: 26px;
width: $button-size; width: $button-size;
height: $button-size; height: $button-size;
border-radius: $button-size / 2; border-radius: $button-size / 2;
line-height: $button-size; line-height: $button-size;
align-self: center; align-self: center;
margin-right: 10px;
text-align: center; text-align: center;
font-size: 20px; font-size: 20px;
@@ -65,6 +76,13 @@ $tabs-height: 38px;
} }
} }
&:hover .name {
-webkit-mask-image: linear-gradient(black 0 0), linear-gradient(to left, transparent 0%, black 100%);
-webkit-mask-size: calc(100% - 60px) auto, 60px auto;
-webkit-mask-repeat: no-repeat;
-webkit-mask-position: left, right;
}
&:hover button { &:hover button {
transition: 0.25s opacity; transition: 0.25s opacity;
display: block; display: block;

View File

@@ -29,7 +29,7 @@ export class TabHeaderComponent {
@Input() @HostBinding('class.has-activity') hasActivity: boolean @Input() @HostBinding('class.has-activity') hasActivity: boolean
@Input() tab: BaseTabComponent @Input() tab: BaseTabComponent
@Input() progress: number|null @Input() progress: number|null
@ViewChild('handle') handle: ElementRef @ViewChild('handle') handle?: ElementRef
private constructor ( private constructor (
public app: AppService, public app: AppService,
@@ -58,7 +58,7 @@ export class TabHeaderComponent {
} }
ngAfterViewInit () { ngAfterViewInit () {
if (this.hostApp.platform === Platform.macOS) { if (this.handle && this.hostApp.platform === Platform.macOS) {
this.parentDraggable.setDragHandle(this.handle.nativeElement) this.parentDraggable.setDragHandle(this.handle.nativeElement)
} }
} }
@@ -81,6 +81,10 @@ export class TabHeaderComponent {
return items.slice(1) return items.slice(1)
} }
@HostBinding('class.flex-width') get isFlexWidthEnabled (): boolean {
return this.config.store.appearance.flexTabs
}
@HostListener('dblclick') onDoubleClick (): void { @HostListener('dblclick') onDoubleClick (): void {
this.showRenameTabModal() this.showRenameTabModal()
} }

View File

@@ -3,7 +3,6 @@
$toggle-size: 18px; $toggle-size: 18px;
$height: 30px; $height: 30px;
$padding: 2px; $padding: 2px;
cursor: pointer;
display: inline-flex; display: inline-flex;
overflow: visible; overflow: visible;
border-radius: 3px; border-radius: 3px;
@@ -16,8 +15,11 @@
padding-left: 10px; padding-left: 10px;
margin-left: -10px; margin-left: -10px;
&[disabled] { &.disabled {
opacity: 0.5; opacity: 0.5;
} }
* {
cursor: pointer;
}
} }

View File

@@ -42,6 +42,16 @@ hotkeys:
- 'Alt-9' - 'Alt-9'
tab-10: tab-10:
- 'Alt-0' - 'Alt-0'
tab-11: []
tab-12: []
tab-13: []
tab-14: []
tab-15: []
tab-16: []
tab-17: []
tab-18: []
tab-19: []
tab-20: []
split-right: split-right:
- 'Ctrl-Shift-E' - 'Ctrl-Shift-E'
split-bottom: split-bottom:

View File

@@ -40,6 +40,16 @@ hotkeys:
- '⌘-9' - '⌘-9'
tab-10: tab-10:
- '⌘-0' - '⌘-0'
tab-11: []
tab-12: []
tab-13: []
tab-14: []
tab-15: []
tab-16: []
tab-17: []
tab-18: []
tab-19: []
tab-20: []
split-right: split-right:
- '⌘-Shift-D' - '⌘-Shift-D'
split-bottom: split-bottom:

View File

@@ -43,6 +43,16 @@ hotkeys:
- 'Alt-9' - 'Alt-9'
tab-10: tab-10:
- 'Alt-0' - 'Alt-0'
tab-11: []
tab-12: []
tab-13: []
tab-14: []
tab-15: []
tab-16: []
tab-17: []
tab-18: []
tab-19: []
tab-20: []
split-right: split-right:
- 'Ctrl-Shift-E' - 'Ctrl-Shift-E'
split-bottom: split-bottom:

View File

@@ -2,8 +2,10 @@ appearance:
dock: off dock: off
dockScreen: current dockScreen: current
dockFill: 0.5 dockFill: 0.5
dockSpace: 1
dockHideOnBlur: false dockHideOnBlur: false
dockAlwaysOnTop: true dockAlwaysOnTop: true
flexTabs: false
tabsLocation: top tabsLocation: top
cycleTabs: true cycleTabs: true
theme: Standard theme: Standard

View File

@@ -89,6 +89,46 @@ export class AppHotkeyProvider extends HotkeyProvider {
id: 'tab-10', id: 'tab-10',
name: 'Tab 10', name: 'Tab 10',
}, },
{
id: 'tab-11',
name: 'Tab 11',
},
{
id: 'tab-12',
name: 'Tab 12',
},
{
id: 'tab-13',
name: 'Tab 13',
},
{
id: 'tab-14',
name: 'Tab 14',
},
{
id: 'tab-15',
name: 'Tab 15',
},
{
id: 'tab-16',
name: 'Tab 16',
},
{
id: 'tab-17',
name: 'Tab 17',
},
{
id: 'tab-18',
name: 'Tab 18',
},
{
id: 'tab-19',
name: 'Tab 19',
},
{
id: 'tab-20',
name: 'Tab 20',
},
{ {
id: 'split-right', id: 'split-right',
name: 'Split to the right', name: 'Split to the right',

View File

@@ -44,8 +44,11 @@ import 'ng2-dnd/bundles/style.css'
// PerfectScrollbar fix // PerfectScrollbar fix
import { fromEvent } from 'rxjs/internal/observable/fromEvent' import { fromEvent } from 'rxjs/internal/observable/fromEvent'
import { merge } from 'rxjs/internal/observable/merge' import { merge } from 'rxjs/internal/observable/merge'
require('rxjs').fromEvent = fromEvent
require('rxjs').merge = merge try {
require('rxjs').fromEvent = fromEvent
require('rxjs').merge = merge
} catch {}
const PROVIDERS = [ const PROVIDERS = [
{ provide: HotkeyProvider, useClass: AppHotkeyProvider, multi: true }, { provide: HotkeyProvider, useClass: AppHotkeyProvider, multi: true },
@@ -110,7 +113,7 @@ export default class AppModule { // eslint-disable-line @typescript-eslint/no-ex
}) })
} }
static forRoot (): ModuleWithProviders { static forRoot (): ModuleWithProviders<AppModule> {
return { return {
ngModule: AppModule, ngModule: AppModule,
providers: PROVIDERS, providers: PROVIDERS,

View File

@@ -100,7 +100,7 @@ export class AppService {
hostApp.windowFocused$.subscribe(() => this._activeTab?.emitFocused()) hostApp.windowFocused$.subscribe(() => this._activeTab?.emitFocused())
this.tabClosed$.subscribe(async tab => { this.tabClosed$.subscribe(async tab => {
const token = await tab.getRecoveryToken() const token = await tabRecovery.getFullRecoveryToken(tab)
if (token) { if (token) {
this.closedTabsStack.push(token) this.closedTabsStack.push(token)
} }
@@ -263,7 +263,7 @@ export class AppService {
if (tabIndex > 0) { if (tabIndex > 0) {
this.swapTabs(this._activeTab, this.tabs[tabIndex - 1]) this.swapTabs(this._activeTab, this.tabs[tabIndex - 1])
} else if (this.config.store.appearance.cycleTabs) { } else if (this.config.store.appearance.cycleTabs) {
this.swapTabs(this._activeTab, this.tabs[this.tabs.length - 1]) this.tabs.push(this.tabs.shift()!)
} }
} }
} }
@@ -277,7 +277,7 @@ export class AppService {
if (tabIndex < this.tabs.length - 1) { if (tabIndex < this.tabs.length - 1) {
this.swapTabs(this._activeTab, this.tabs[tabIndex + 1]) this.swapTabs(this._activeTab, this.tabs[tabIndex + 1])
} else if (this.config.store.appearance.cycleTabs) { } else if (this.config.store.appearance.cycleTabs) {
this.swapTabs(this._activeTab, this.tabs[0]) this.tabs.unshift(this.tabs.pop()!)
} }
} }
} }

View File

@@ -144,7 +144,7 @@ export class ConfigService {
load (): void { load (): void {
if (fs.existsSync(this.path)) { if (fs.existsSync(this.path)) {
this._store = yaml.safeLoad(fs.readFileSync(this.path, 'utf8')) this._store = yaml.load(fs.readFileSync(this.path, 'utf8'))
} else { } else {
this._store = {} this._store = {}
} }
@@ -154,7 +154,7 @@ export class ConfigService {
save (): void { save (): void {
// Scrub undefined values // Scrub undefined values
this._store = JSON.parse(JSON.stringify(this._store)) this._store = JSON.parse(JSON.stringify(this._store))
fs.writeFileSync(this.path, yaml.safeDump(this._store), 'utf8') fs.writeFileSync(this.path, yaml.dump(this._store), 'utf8')
this.emitChange() this.emitChange()
this.hostApp.broadcastConfigChange(JSON.parse(JSON.stringify(this.store))) this.hostApp.broadcastConfigChange(JSON.parse(JSON.stringify(this.store)))
} }
@@ -163,14 +163,14 @@ export class ConfigService {
* Reads config YAML as string * Reads config YAML as string
*/ */
readRaw (): string { readRaw (): string {
return yaml.safeDump(this._store) return yaml.dump(this._store)
} }
/** /**
* Writes config YAML as string * Writes config YAML as string
*/ */
writeRaw (data: string): void { writeRaw (data: string): void {
this._store = yaml.safeLoad(data) this._store = yaml.load(data)
this.save() this.save()
this.load() this.load()
this.emitChange() this.emitChange()

View File

@@ -34,25 +34,30 @@ export class DockingService {
const newBounds: Bounds = { x: 0, y: 0, width: 0, height: 0 } const newBounds: Bounds = { x: 0, y: 0, width: 0, height: 0 }
const fill = this.config.store.appearance.dockFill <= 1 ? this.config.store.appearance.dockFill : 1 const fill = this.config.store.appearance.dockFill <= 1 ? this.config.store.appearance.dockFill : 1
const space = this.config.store.appearance.dockSpace <= 1 ? this.config.store.appearance.dockSpace : 1
const [minWidth, minHeight] = this.hostApp.getWindow().getMinimumSize() const [minWidth, minHeight] = this.hostApp.getWindow().getMinimumSize()
if (dockSide === 'left' || dockSide === 'right') { if (dockSide === 'left' || dockSide === 'right') {
newBounds.width = Math.max(minWidth, Math.round(fill * display.bounds.width)) newBounds.width = Math.max(minWidth, Math.round(fill * display.bounds.width))
newBounds.height = display.bounds.height newBounds.height = Math.round(display.bounds.height * space)
} }
if (dockSide === 'top' || dockSide === 'bottom') { if (dockSide === 'top' || dockSide === 'bottom') {
newBounds.width = display.bounds.width newBounds.width = Math.round(display.bounds.width * space)
newBounds.height = Math.max(minHeight, Math.round(fill * display.bounds.height)) newBounds.height = Math.max(minHeight, Math.round(fill * display.bounds.height))
} }
if (dockSide === 'right') { if (dockSide === 'right') {
newBounds.x = display.bounds.x + display.bounds.width - newBounds.width newBounds.x = display.bounds.x + display.bounds.width - newBounds.width
} else { } else if (dockSide === 'left') {
newBounds.x = display.bounds.x newBounds.x = display.bounds.x
} else {
newBounds.x = display.bounds.x + Math.round(display.bounds.width / 2 * (1 - space))
} }
if (dockSide === 'bottom') { if (dockSide === 'bottom') {
newBounds.y = display.bounds.y + display.bounds.height - newBounds.height newBounds.y = display.bounds.y + display.bounds.height - newBounds.height
} else { } else if (dockSide === 'top') {
newBounds.y = display.bounds.y newBounds.y = display.bounds.y
} else {
newBounds.y = display.bounds.y + Math.round(display.bounds.height / 2 * (1 - space))
} }
const alwaysOnTop = this.config.store.appearance.dockAlwaysOnTop const alwaysOnTop = this.config.store.appearance.dockAlwaysOnTop

View File

@@ -8,6 +8,12 @@ import { ElectronService } from './electron.service'
import { Logger, LogService } from './log.service' import { Logger, LogService } from './log.service'
import { isWindowsBuild, WIN_BUILD_FLUENT_BG_SUPPORTED } from '../utils' import { isWindowsBuild, WIN_BUILD_FLUENT_BG_SUPPORTED } from '../utils'
/* eslint-disable block-scoped-var */
try {
var wnr = require('windows-native-registry') // eslint-disable-line @typescript-eslint/no-var-requires, no-var
} catch (_) { }
export enum Platform { export enum Platform {
Linux = 'Linux', Linux = 'Linux',
macOS = 'macOS', macOS = 'macOS',
@@ -154,7 +160,7 @@ export class HostAppService {
electron.ipcRenderer.on('cli', (_$event, argv: any, cwd: string, secondInstance: boolean) => this.zone.run(async () => { electron.ipcRenderer.on('cli', (_$event, argv: any, cwd: string, secondInstance: boolean) => this.zone.run(async () => {
this.logger.info('Second instance', argv) this.logger.info('Second instance', argv)
const op = argv._[0] const op = argv._[0]
const opAsPath = path.resolve(cwd, op) const opAsPath = op ? path.resolve(cwd, op) : null
if (op === 'open') { if (op === 'open') {
this.cliOpenDirectory.next(path.resolve(cwd, argv.directory)) this.cliOpenDirectory.next(path.resolve(cwd, argv.directory))
} else if (op === 'run') { } else if (op === 'run') {
@@ -167,9 +173,9 @@ export class HostAppService {
this.cliPaste.next(text) this.cliPaste.next(text)
} else if (op === 'profile') { } else if (op === 'profile') {
this.cliOpenProfile.next(argv.profileName) this.cliOpenProfile.next(argv.profileName)
} else if (op === undefined) { } else if (secondInstance && op === undefined) {
this.newWindow() this.newWindow()
} else if ((await fs.lstat(opAsPath)).isDirectory()) { } else if (opAsPath && (await fs.lstat(opAsPath)).isDirectory()) {
this.cliOpenDirectory.next(opAsPath) this.cliOpenDirectory.next(opAsPath)
} }
@@ -283,6 +289,20 @@ export class HostAppService {
this.electron.ipcRenderer.send('app:register-global-hotkey', specs) this.electron.ipcRenderer.send('app:register-global-hotkey', specs)
} }
useBuiltinGraphics (): void {
const keyPath = 'SOFTWARE\\Microsoft\\DirectX\\UserGpuPreferences'
const valueName = this.electron.app.getPath('exe')
if (this.platform === Platform.Windows) {
if (!wnr.getRegistryValue(wnr.HK.CU, keyPath, valueName)) {
wnr.setRegistryValue(wnr.HK.CU, keyPath, valueName, wnr.REG.SZ, 'GpuPreference=1;')
}
}
}
setTrafficLightInset (x: number, y: number): void {
this.getWindow().setTrafficLightPosition({ x, y })
}
relaunch (): void { relaunch (): void {
if (this.isPortable) { if (this.isPortable) {
this.electron.app.relaunch({ execPath: process.env.PORTABLE_EXECUTABLE_FILE }) this.electron.app.relaunch({ execPath: process.env.PORTABLE_EXECUTABLE_FILE })

View File

@@ -1,11 +1,13 @@
import { Injectable } from '@angular/core' import { Injectable } from '@angular/core'
import { ElectronService } from './electron.service' import { ElectronService } from './electron.service'
import * as winston from 'winston' import type * as winston from 'winston'
import * as fs from 'fs' import * as fs from 'fs'
import * as path from 'path' import * as path from 'path'
const initializeWinston = (electron: ElectronService) => { const initializeWinston = (electron: ElectronService) => {
const logDirectory = electron.app.getPath('userData') const logDirectory = electron.app.getPath('userData')
// eslint-disable-next-line
const winston = require('winston')
if (!fs.existsSync(logDirectory)) { if (!fs.existsSync(logDirectory)) {
fs.mkdirSync(logDirectory) fs.mkdirSync(logDirectory)
@@ -64,7 +66,11 @@ export class LogService {
/** @hidden */ /** @hidden */
private constructor (electron: ElectronService) { private constructor (electron: ElectronService) {
this.log = initializeWinston(electron) if (!process.env.XWEB) {
this.log = initializeWinston(electron)
} else {
this.log = console as any
}
} }
create (name: string): Logger { create (name: string): Logger {

View File

@@ -0,0 +1,23 @@
import { Injectable } from '@angular/core'
import { ToastrService } from 'ngx-toastr'
@Injectable({ providedIn: 'root' })
export class NotificationsService {
private constructor (
private toastr: ToastrService,
) { }
notice (text: string): void {
this.toastr.info(text, undefined, {
timeOut: 1000,
})
}
info (text: string, details?: string): void {
this.toastr.info(text, details)
}
error (text: string, details?: string): void {
this.toastr.error(text, details)
}
}

View File

@@ -24,20 +24,22 @@ export class TabRecoveryService {
} }
window.localStorage.tabsRecovery = JSON.stringify( window.localStorage.tabsRecovery = JSON.stringify(
(await Promise.all( (await Promise.all(
tabs tabs.map(async tab => this.getFullRecoveryToken(tab))
.map(async tab => tab.getRecoveryToken().then(r => {
if (r) {
r.tabTitle = tab.title
if (tab.color) {
r.tabColor = tab.color
}
}
return r
}))
)).filter(token => !!token) )).filter(token => !!token)
) )
} }
async getFullRecoveryToken (tab: BaseTabComponent): Promise<RecoveryToken|null> {
const token = await tab.getRecoveryToken()
if (token) {
token.tabTitle = tab.title
if (tab.color) {
token.tabColor = tab.color
}
}
return token
}
async recoverTab (token: RecoveryToken): Promise<RecoveredTab|null> { async recoverTab (token: RecoveryToken): Promise<RecoveredTab|null> {
for (const provider of this.config.enabledServices(this.tabRecoveryProviders ?? [])) { for (const provider of this.config.enabledServices(this.tabRecoveryProviders ?? [])) {
try { try {

View File

@@ -30,7 +30,7 @@ export class TabsService {
* Duplicates an existing tab instance (using the tab recovery system) * Duplicates an existing tab instance (using the tab recovery system)
*/ */
async duplicate (tab: BaseTabComponent): Promise<BaseTabComponent|null> { async duplicate (tab: BaseTabComponent): Promise<BaseTabComponent|null> {
const token = await tab.getRecoveryToken() const token = await this.tabRecovery.getFullRecoveryToken(tab)
if (!token) { if (!token) {
return null return null
} }

View File

@@ -1,6 +1,7 @@
import { Inject, Injectable } from '@angular/core' import { Inject, Injectable } from '@angular/core'
import { ConfigService } from '../services/config.service' import { ConfigService } from '../services/config.service'
import { Theme } from '../api/theme' import { Theme } from '../api/theme'
import { HostAppService, Platform } from './hostApp.service'
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class ThemesService { export class ThemesService {
@@ -9,6 +10,7 @@ export class ThemesService {
/** @hidden */ /** @hidden */
private constructor ( private constructor (
private config: ConfigService, private config: ConfigService,
private hostApp: HostAppService,
@Inject(Theme) private themes: Theme[], @Inject(Theme) private themes: Theme[],
) { ) {
this.applyCurrentTheme() this.applyCurrentTheme()
@@ -33,6 +35,12 @@ export class ThemesService {
} }
this.styleElement.textContent = theme.css this.styleElement.textContent = theme.css
document.querySelector('style#custom-css')!.innerHTML = this.config.store.appearance.css document.querySelector('style#custom-css')!.innerHTML = this.config.store.appearance.css
if (this.hostApp.platform === Platform.macOS) {
this.hostApp.setTrafficLightInset(
theme.macOSWindowButtonsInsetX ?? 14,
theme.macOSWindowButtonsInsetY ?? 22,
)
}
} }
private applyCurrentTheme (): void { private applyCurrentTheme (): void {

View File

@@ -1,24 +1,18 @@
import { NativeImage, SegmentedControlSegment, TouchBarSegmentedControl } from 'electron' import { SegmentedControlSegment, TouchBarSegmentedControl } from 'electron'
import { Injectable, Inject, NgZone } from '@angular/core' import { Injectable, NgZone } from '@angular/core'
import { AppService } from './app.service' import { AppService } from './app.service'
import { ConfigService } from './config.service'
import { ElectronService } from './electron.service' import { ElectronService } from './electron.service'
import { HostAppService, Platform } from './hostApp.service' import { HostAppService, Platform } from './hostApp.service'
import { ToolbarButton, ToolbarButtonProvider } from '../api'
/** @hidden */ /** @hidden */
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class TouchbarService { export class TouchbarService {
private tabsSegmentedControl: TouchBarSegmentedControl private tabsSegmentedControl: TouchBarSegmentedControl
private buttonsSegmentedControl: TouchBarSegmentedControl
private tabSegments: SegmentedControlSegment[] = [] private tabSegments: SegmentedControlSegment[] = []
private nsImageCache: Record<string, NativeImage> = {}
private constructor ( private constructor (
private app: AppService, private app: AppService,
private hostApp: HostAppService, private hostApp: HostAppService,
@Inject(ToolbarButtonProvider) private toolbarButtonProviders: ToolbarButtonProvider[],
private config: ConfigService,
private electron: ElectronService, private electron: ElectronService,
private zone: NgZone, private zone: NgZone,
) { ) {
@@ -63,16 +57,6 @@ export class TouchbarService {
return return
} }
let buttons: ToolbarButton[] = []
this.config.enabledServices(this.toolbarButtonProviders).forEach(provider => {
buttons = buttons.concat(provider.provide())
})
buttons = buttons.filter(x => !!x.touchBarNSImage)
buttons.sort((a, b) => (a.weight ?? 0) - (b.weight ?? 0))
this.tabSegments = this.app.tabs.map(tab => ({
label: this.shortenTitle(tab.title),
}))
this.tabsSegmentedControl = new this.electron.TouchBar.TouchBarSegmentedControl({ this.tabsSegmentedControl = new this.electron.TouchBar.TouchBarSegmentedControl({
segments: this.tabSegments, segments: this.tabSegments,
selectedIndex: this.app.activeTab ? this.app.tabs.indexOf(this.app.activeTab) : undefined, selectedIndex: this.app.activeTab ? this.app.tabs.indexOf(this.app.activeTab) : undefined,
@@ -81,43 +65,14 @@ export class TouchbarService {
}), }),
}) })
this.buttonsSegmentedControl = new this.electron.TouchBar.TouchBarSegmentedControl({
segments: buttons.map(button => this.getButton(button)),
mode: 'buttons',
change: (selectedIndex) => this.zone.run(() => {
if (buttons[selectedIndex].click) {
buttons[selectedIndex].click!()
}
}),
})
const touchBar = new this.electron.TouchBar({ const touchBar = new this.electron.TouchBar({
items: [ items: [
this.tabsSegmentedControl, this.tabsSegmentedControl,
new this.electron.TouchBar.TouchBarSpacer({ size: 'flexible' }),
new this.electron.TouchBar.TouchBarSpacer({ size: 'small' }),
this.buttonsSegmentedControl,
], ],
}) })
this.hostApp.setTouchBar(touchBar) this.hostApp.setTouchBar(touchBar)
} }
private getButton (button: ToolbarButton): SegmentedControlSegment {
return {
label: button.touchBarNSImage ? undefined : this.shortenTitle(button.touchBarTitle ?? button.title),
icon: button.touchBarNSImage ? this.getCachedNSImage(button.touchBarNSImage) : undefined,
// click: () => this.zone.run(() => button.click()),
}
}
private getCachedNSImage (name: string) {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!this.nsImageCache[name]) {
this.nsImageCache[name] = this.electron.nativeImage.createFromNamedImage(name, [0, 0, 1])
}
return this.nsImageCache[name]
}
private shortenTitle (title: string): string { private shortenTitle (title: string): string {
if (title.length > 15) { if (title.length > 15) {
title = title.substring(0, 15) + '...' title = title.substring(0, 15) + '...'

View File

@@ -1,6 +1,10 @@
@import './theme.scss'; @import './theme.scss';
app-root { app-root {
.tabs-on-side .tab-bar {
height: 100% !important;
}
.tab-bar { .tab-bar {
height: 27px !important; height: 27px !important;
@@ -12,6 +16,10 @@ app-root {
height: 14px; height: 14px;
} }
} }
.inset {
width: 70 !important;
}
} }
terminaltab .content { terminaltab .content {

View File

@@ -66,7 +66,9 @@ app-root {
border: none; border: none;
transition: 0.25s all; transition: 0.25s all;
&:hover { background: $button-hover-bg !important; } right: 5px;
&:hover { background: $button-active-bg !important; }
&:active { background: $button-active-bg !important; } &:active { background: $button-active-bg !important; }
} }

View File

@@ -15,6 +15,8 @@ export class StandardCompactTheme extends Theme {
name = 'Compact' name = 'Compact'
css = require('./theme.compact.scss') css = require('./theme.compact.scss')
terminalBackground = '#222a33' terminalBackground = '#222a33'
macOSWindowButtonsInsetX = 8
macOSWindowButtonsInsetY = 12
} }
/** @hidden */ /** @hidden */

View File

@@ -1,60 +1,5 @@
const path = require('path') const config = require('../webpack.plugin.config')
module.exports = config({
module.exports = { name: 'core',
target: 'node', dirname: __dirname,
entry: 'src/index.ts', })
context: __dirname,
devtool: 'cheap-module-source-map',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
pathinfo: true,
libraryTarget: 'umd',
devtoolModuleFilenameTemplate: 'webpack-terminus-core:///[resource-path]',
},
mode: process.env.TERMINUS_DEV ? 'development' : 'production',
optimization:{
minimize: false,
},
resolve: {
modules: ['.', 'src', 'node_modules', '../app/node_modules'].map(x => path.join(__dirname, x)),
extensions: ['.ts', '.js'],
},
module: {
rules: [
{
test: /\.ts$/,
use: {
loader: 'awesome-typescript-loader',
options: {
configFileName: path.resolve(__dirname, 'tsconfig.json'),
typeRoots: [
path.resolve(__dirname, 'node_modules/@types'),
path.resolve(__dirname, '../node_modules/@types'),
],
paths: {
"terminus-*": [path.resolve(__dirname, '../terminus-*')],
"*": [path.resolve(__dirname, '../app/node_modules/*')],
},
},
},
},
{ test: /\.pug$/, use: ['apply-loader', 'pug-loader'] },
{ test: /\.scss$/, use: ['to-string-loader', 'css-loader', 'sass-loader'] },
{ test: /\.css$/, use: ['to-string-loader', 'css-loader'], include: /component\.css/ },
{ test: /\.css$/, use: ['style-loader', 'css-loader'], exclude: /component\.css/ },
{ test: /\.yaml$/, use: ['json-loader', 'yaml-loader'] },
{ test: /\.svg/, use: ['svg-inline-loader'] },
],
},
externals: [
'electron',
'fs',
'os',
'path',
'windows-native-registry',
/^rxjs/,
/^@angular/,
/^@ng-bootstrap/,
],
}

View File

@@ -11,12 +11,12 @@
enabled "2.0.x" enabled "2.0.x"
kuler "^2.0.0" kuler "^2.0.0"
"@types/js-yaml@^3.9.0": "@types/js-yaml@^4.0.0":
version "3.12.5" version "4.0.0"
resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-3.12.5.tgz#136d5e6a57a931e1cce6f9d8126aa98a9c92a6bb" resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.0.tgz#d1a11688112091f2c711674df3a65ea2f47b5dfb"
integrity sha512-JCcp6J0GV66Y4ZMDAQCXot4xprYB+Zfd3meK9+INSJeVZwJmHAW30BBEEkPzXswMXuiyReUGOP3GxrADc9wPww== integrity sha512-4vlpCM5KPCL5CfGmTbpjwVKbISRYhduEJvvUWsH5EB7QInhEj94XPZ3ts/9FPiLZFqYO0xoW4ZL8z2AabTGgJA==
"@types/semver@^7.3.1": "@types/semver@^7.3.4":
version "7.3.4" version "7.3.4"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.4.tgz#43d7168fec6fa0988bb1a513a697b29296721afb" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.4.tgz#43d7168fec6fa0988bb1a513a697b29296721afb"
integrity sha512-+nVsLKlcUCeMzD2ufHEYuJ9a2ovstb6Dp52A5VsoKxDXgvE051XgHI/33I1EymwkRGQkwnA0LkhnUzituGs4EQ== integrity sha512-+nVsLKlcUCeMzD2ufHEYuJ9a2ovstb6Dp52A5VsoKxDXgvE051XgHI/33I1EymwkRGQkwnA0LkhnUzituGs4EQ==
@@ -40,12 +40,10 @@ agent-base@^4.3.0:
dependencies: dependencies:
es6-promisify "^5.0.0" es6-promisify "^5.0.0"
argparse@^1.0.7: argparse@^2.0.1:
version "1.0.10" version "2.0.1"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
dependencies:
sprintf-js "~1.0.2"
async@^3.1.0: async@^3.1.0:
version "3.2.0" version "3.2.0"
@@ -57,24 +55,24 @@ at-least-node@^1.0.0:
resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2"
integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==
axios@^0.19.0: axios@^0.21.1:
version "0.19.2" version "0.21.1"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8"
integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA== integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==
dependencies: dependencies:
follow-redirects "1.5.10" follow-redirects "^1.10.0"
bootstrap@^4.1.3: bootstrap@^4.1.3:
version "4.5.3" version "4.5.3"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.5.3.tgz#c6a72b355aaf323920be800246a6e4ef30997fe6" resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.5.3.tgz#c6a72b355aaf323920be800246a6e4ef30997fe6"
integrity sha512-o9ppKQioXGqhw8Z7mah6KdTYpNQY//tipnkxppWhPbiSWdD+1raYsnhwEZjkTHYbGee4cVQ0Rx65EhOY/HNLcQ== integrity sha512-o9ppKQioXGqhw8Z7mah6KdTYpNQY//tipnkxppWhPbiSWdD+1raYsnhwEZjkTHYbGee4cVQ0Rx65EhOY/HNLcQ==
builder-util-runtime@8.7.2: builder-util-runtime@8.7.3:
version "8.7.2" version "8.7.3"
resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-8.7.2.tgz#d93afc71428a12789b437e13850e1fa7da956d72" resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-8.7.3.tgz#0aaafa52d25295c939496f62231ca9ff06c30e40"
integrity sha512-xBqv+8bg6cfnzAQK1k3OGpfaHg+QkPgIgpEkXNhouZ0WiUkyZCftuRc2LYzQrLucFywpa14Xbc6+hTbpq83yRA== integrity sha512-1Q2ReBqFblimF5g/TLg2+0M5Xzv0Ih5LxJ/BMWXvEy/e6pQKeeEpbkPMGsN6OiQgkygaZo5VXCXIjOkOQG5EoQ==
dependencies: dependencies:
debug "^4.1.1" debug "^4.3.2"
sax "^1.2.4" sax "^1.2.4"
color-convert@^1.9.1: color-convert@^1.9.1:
@@ -124,22 +122,15 @@ colorspace@1.1.x:
text-hex "1.0.x" text-hex "1.0.x"
core-js@^3.1.2: core-js@^3.1.2:
version "3.8.2" version "3.9.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.8.2.tgz#0a1fd6709246da9ca8eff5bb0cbd15fba9ac7044" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.9.1.tgz#cec8de593db8eb2a85ffb0dbdeb312cb6e5460ae"
integrity sha512-FfApuSRgrR6G5s58casCBd9M2k+4ikuu4wbW6pJyYU7bd9zvFc9qf7vr5xmrZOhT9nn+8uwlH1oRR9jTnFoA3A== integrity sha512-gSjRvzkxQc1zjM/5paAmL4idJBFzuJoo+jDjF1tStYFMV2ERfD02HhahhCGXUyHxQRG4yFKVSdO6g62eoRMcDg==
core-util-is@~1.0.0: core-util-is@~1.0.0:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
debug@=3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
dependencies:
ms "2.0.0"
debug@^3.1.0: debug@^3.1.0:
version "3.2.6" version "3.2.6"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
@@ -147,10 +138,10 @@ debug@^3.1.0:
dependencies: dependencies:
ms "^2.1.1" ms "^2.1.1"
debug@^4.1.1: debug@^4.3.2:
version "4.2.0" version "4.3.2"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b"
integrity sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg== integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==
dependencies: dependencies:
ms "2.1.2" ms "2.1.2"
@@ -160,17 +151,17 @@ deepmerge@^4.1.1:
integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==
electron-updater@^4.0.6: electron-updater@^4.0.6:
version "4.3.5" version "4.3.8"
resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-4.3.5.tgz#4fb36f593a031c87ea07ee141c9f064d5deffb15" resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-4.3.8.tgz#94f1731682a756385726183e2b04b959cb319456"
integrity sha512-5jjN7ebvfj1cLI0VZMdCnJk6aC4bP+dy7ryBf21vArR0JzpRVk0OZHA2QBD+H5rm6ZSeDYHOY6+8PrMEqJ4wlQ== integrity sha512-/tB82Ogb2LqaXrUzAD8waJC+TZV52Pr0Znfj7w+i4D+jA2GgrKFI3Pxjp+36y9FcBMQz7kYsMHcB6c5zBJao+A==
dependencies: dependencies:
"@types/semver" "^7.3.1" "@types/semver" "^7.3.4"
builder-util-runtime "8.7.2" builder-util-runtime "8.7.3"
fs-extra "^9.0.1" fs-extra "^9.1.0"
js-yaml "^3.14.0" js-yaml "^4.0.0"
lazy-val "^1.0.4" lazy-val "^1.0.4"
lodash.isequal "^4.5.0" lodash.isequal "^4.5.0"
semver "^7.3.2" semver "^7.3.4"
enabled@2.0.x: enabled@2.0.x:
version "2.0.0" version "2.0.0"
@@ -189,11 +180,6 @@ es6-promisify@^5.0.0:
dependencies: dependencies:
es6-promise "^4.0.3" es6-promise "^4.0.3"
esprima@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
fast-safe-stringify@^2.0.4: fast-safe-stringify@^2.0.4:
version "2.0.7" version "2.0.7"
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743" resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743"
@@ -209,22 +195,20 @@ fn.name@1.x.x:
resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc"
integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==
follow-redirects@1.5.10: follow-redirects@^1.10.0:
version "1.5.10" version "1.13.1"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.1.tgz#5f69b813376cee4fd0474a3aba835df04ab763b7"
integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== integrity sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==
dependencies:
debug "=3.1.0"
fs-extra@^9.0.1: fs-extra@^9.1.0:
version "9.0.1" version "9.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.0.1.tgz#910da0062437ba4c39fedd863f1675ccfefcb9fc" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d"
integrity sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ== integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==
dependencies: dependencies:
at-least-node "^1.0.0" at-least-node "^1.0.0"
graceful-fs "^4.2.0" graceful-fs "^4.2.0"
jsonfile "^6.0.1" jsonfile "^6.0.1"
universalify "^1.0.0" universalify "^2.0.0"
graceful-fs@^4.1.6, graceful-fs@^4.2.0: graceful-fs@^4.1.6, graceful-fs@^4.2.0:
version "4.2.4" version "4.2.4"
@@ -259,13 +243,12 @@ isarray@~1.0.0:
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
js-yaml@^3.14.0, js-yaml@^3.9.0: js-yaml@^4.0.0:
version "3.14.0" version "4.0.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.0.0.tgz#f426bc0ff4b4051926cd588c71113183409a121f"
integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== integrity sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==
dependencies: dependencies:
argparse "^1.0.7" argparse "^2.0.1"
esprima "^4.0.0"
jsonfile@^6.0.1: jsonfile@^6.0.1:
version "6.1.0" version "6.1.0"
@@ -302,6 +285,13 @@ logform@^2.2.0:
ms "^2.1.1" ms "^2.1.1"
triple-beam "^1.3.0" triple-beam "^1.3.0"
lru-cache@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
dependencies:
yallist "^4.0.0"
mixpanel@^0.10.2: mixpanel@^0.10.2:
version "0.10.3" version "0.10.3"
resolved "https://registry.yarnpkg.com/mixpanel/-/mixpanel-0.10.3.tgz#2dff3bc0e17b57d6365547d315cbbf3ecfdb8a00" resolved "https://registry.yarnpkg.com/mixpanel/-/mixpanel-0.10.3.tgz#2dff3bc0e17b57d6365547d315cbbf3ecfdb8a00"
@@ -309,11 +299,6 @@ mixpanel@^0.10.2:
dependencies: dependencies:
https-proxy-agent "3.0.0" https-proxy-agent "3.0.0"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
ms@2.1.2, ms@^2.1.1: ms@2.1.2, ms@^2.1.1:
version "2.1.2" version "2.1.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
@@ -324,13 +309,14 @@ ng2-dnd@^5.0.2:
resolved "https://registry.yarnpkg.com/ng2-dnd/-/ng2-dnd-5.0.2.tgz#862278ac7dedfa14f5783bbf34014d5d73dfefb4" resolved "https://registry.yarnpkg.com/ng2-dnd/-/ng2-dnd-5.0.2.tgz#862278ac7dedfa14f5783bbf34014d5d73dfefb4"
integrity sha512-5mWWBePwvEPsNd/HkdbD543Q9mPyJofL6zkNydl8/Ah3qrrvZT2DaEPbknY08OgkXpI2qUGksc01OzzVlRQ9dQ== integrity sha512-5mWWBePwvEPsNd/HkdbD543Q9mPyJofL6zkNydl8/Ah3qrrvZT2DaEPbknY08OgkXpI2qUGksc01OzzVlRQ9dQ==
ngx-perfect-scrollbar@^8.0.0: ngx-perfect-scrollbar@^10.1.0:
version "8.0.0" version "10.1.0"
resolved "https://registry.yarnpkg.com/ngx-perfect-scrollbar/-/ngx-perfect-scrollbar-8.0.0.tgz#19c1bbf9b1a36d89b00a68f7834e39427d29182f" resolved "https://registry.yarnpkg.com/ngx-perfect-scrollbar/-/ngx-perfect-scrollbar-10.1.0.tgz#6f7e2d8c849e595077b1c71992b6b544d56084d7"
integrity sha512-IXoFbULQnxyJj0gdCcKCLE/6OW9HCP9KARzMCKS1kNxTuzG4DghjM2AaCBRM5/sFwdbn6rqOKMCINtHA8W8YCA== integrity sha512-CQ4pthb+UOoccTh3dOVcmBJsUILpHNBsKMHatif6AB2jsvhH6y2O6elMaoslhQEFqpv1fJlrU25AKIUJQZIA4A==
dependencies: dependencies:
perfect-scrollbar "^1.4.0" perfect-scrollbar "1.5.0"
resize-observer-polyfill "^1.5.0" resize-observer-polyfill "^1.5.0"
tslib "^2.0.0"
one-time@^1.0.0: one-time@^1.0.0:
version "1.0.0" version "1.0.0"
@@ -339,7 +325,7 @@ one-time@^1.0.0:
dependencies: dependencies:
fn.name "1.x.x" fn.name "1.x.x"
perfect-scrollbar@^1.4.0: perfect-scrollbar@1.5.0:
version "1.5.0" version "1.5.0"
resolved "https://registry.yarnpkg.com/perfect-scrollbar/-/perfect-scrollbar-1.5.0.tgz#821d224ed8ff61990c23f26db63048cdc75b6b83" resolved "https://registry.yarnpkg.com/perfect-scrollbar/-/perfect-scrollbar-1.5.0.tgz#821d224ed8ff61990c23f26db63048cdc75b6b83"
integrity sha512-NrNHJn5mUGupSiheBTy6x+6SXCFbLlm8fVZh9moIzw/LgqElN5q4ncR4pbCBCYuCJ8Kcl9mYM0NgDxvW+b4LxA== integrity sha512-NrNHJn5mUGupSiheBTy6x+6SXCFbLlm8fVZh9moIzw/LgqElN5q4ncR4pbCBCYuCJ8Kcl9mYM0NgDxvW+b4LxA==
@@ -391,10 +377,12 @@ sax@^1.2.4:
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
semver@^7.3.2: semver@^7.3.4:
version "7.3.2" version "7.3.4"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97"
integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==
dependencies:
lru-cache "^6.0.0"
shell-escape@^0.2.0: shell-escape@^0.2.0:
version "0.2.0" version "0.2.0"
@@ -408,11 +396,6 @@ simple-swizzle@^0.2.2:
dependencies: dependencies:
is-arrayish "^0.3.1" is-arrayish "^0.3.1"
sprintf-js@~1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
stack-trace@0.0.x: stack-trace@0.0.x:
version "0.0.10" version "0.0.10"
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
@@ -442,10 +425,10 @@ triple-beam@^1.2.0, triple-beam@^1.3.0:
resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9" resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9"
integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw== integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==
universalify@^1.0.0: tslib@^2.0.0:
version "1.0.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a"
integrity sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug== integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==
universalify@^2.0.0: universalify@^2.0.0:
version "2.0.0" version "2.0.0"
@@ -458,9 +441,9 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1:
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
uuid@^8.0.0: uuid@^8.0.0:
version "8.3.1" version "8.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.1.tgz#2ba2e6ca000da60fce5a196954ab241131e05a31" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg== integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
winston-transport@^4.4.0: winston-transport@^4.4.0:
version "4.4.0" version "4.4.0"
@@ -484,3 +467,8 @@ winston@*, winston@^3.3.3:
stack-trace "0.0.x" stack-trace "0.0.x"
triple-beam "^1.3.0" triple-beam "^1.3.0"
winston-transport "^4.4.0" winston-transport "^4.4.0"
yallist@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==

View File

@@ -1,6 +1,6 @@
{ {
"name": "terminus-plugin-manager", "name": "terminus-plugin-manager",
"version": "1.0.123-nightly.0", "version": "1.0.135-nightly.0",
"description": "Terminus' plugin manager", "description": "Terminus' plugin manager",
"keywords": [ "keywords": [
"terminus-builtin-plugin" "terminus-builtin-plugin"
@@ -18,7 +18,7 @@
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@types/semver": "^7.1.0", "@types/semver": "^7.1.0",
"axios": "^0.19.0", "axios": "^0.21.1",
"electron-promise-ipc": "^2.2.4", "electron-promise-ipc": "^2.2.4",
"mz": "^2.6.0", "mz": "^2.6.0",
"semver": "^7.1.1" "semver": "^7.1.1"

View File

@@ -2,7 +2,6 @@
strong Error in {{erroredPlugin}}: strong Error in {{erroredPlugin}}:
pre {{errorMessage}} pre {{errorMessage}}
.d-flex .d-flex
h3.mb-1 Installed h3.mb-1 Installed
button.btn.btn-outline-secondary.btn-sm.ml-auto((click)='openPluginsFolder()') button.btn.btn-outline-secondary.btn-sm.ml-auto((click)='openPluginsFolder()')
@@ -11,11 +10,17 @@
.list-group.list-group-flush.mt-2 .list-group.list-group-flush.mt-2
.list-group-item.d-flex.align-items-center(*ngFor='let plugin of pluginManager.installedPlugins') .list-group-item.d-flex.align-items-center(*ngFor='let plugin of pluginManager.installedPlugins')
toggle(
[ngModel]='isPluginEnabled(plugin)',
(ngModelChange)='togglePlugin(plugin)',
[disabled]='!canDisablePlugin(plugin)'
)
.mr-auto.d-flex.flex-column .mr-auto.d-flex.flex-column
div div
strong {{plugin.name}} strong {{plugin.name}}
small.text-muted.ml-1(*ngIf='!plugin.isBuiltin') {{plugin.version}} / {{plugin.author}} small.text-muted.ml-1(*ngIf='!plugin.isBuiltin') {{plugin.version}} / {{plugin.author}}
small.text-warning.ml-1(*ngIf='config.store.pluginBlacklist.includes(plugin.name)') Disabled small.text-warning.ml-1(*ngIf='!isPluginEnabled(plugin)') Disabled
a.text-muted.mb-0((click)='showPluginInfo(plugin)') a.text-muted.mb-0((click)='showPluginInfo(plugin)')
small {{plugin.description}} small {{plugin.description}}
@@ -28,18 +33,6 @@
i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='busy.get(plugin.name) == BusyState.Installing') i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='busy.get(plugin.name) == BusyState.Installing')
span Upgrade ({{knownUpgrades[plugin.name].version}}) span Upgrade ({{knownUpgrades[plugin.name].version}})
button.btn.btn-link.text-primary.ml-2(
*ngIf='config.store.pluginBlacklist.includes(plugin.name)',
(click)='enablePlugin(plugin)'
)
i.fas.fa-fw.fa-play
button.btn.btn-link.ml-2(
*ngIf='!config.store.pluginBlacklist.includes(plugin.name)',
(click)='disablePlugin(plugin)'
)
i.fas.fa-fw.fa-pause
button.btn.btn-link.text-danger.ml-2( button.btn.btn-link.text-danger.ml-2(
(click)='uninstallPlugin(plugin)', (click)='uninstallPlugin(plugin)',
*ngIf='!plugin.isBuiltin', *ngIf='!plugin.isBuiltin',

View File

@@ -9,6 +9,8 @@ import { PluginInfo, PluginManagerService } from '../services/pluginManager.serv
enum BusyState { Installing = 'Installing', Uninstalling = 'Uninstalling' } enum BusyState { Installing = 'Installing', Uninstalling = 'Uninstalling' }
const FORCE_ENABLE = ['terminus-core', 'terminus-settings']
/** @hidden */ /** @hidden */
@Component({ @Component({
template: require('./pluginsSettingsTab.component.pug'), template: require('./pluginsSettingsTab.component.pug'),
@@ -102,6 +104,22 @@ export class PluginsSettingsTabComponent {
this.electron.shell.openExternal('https://www.npmjs.com/package/' + plugin.packageName) this.electron.shell.openExternal('https://www.npmjs.com/package/' + plugin.packageName)
} }
isPluginEnabled (plugin: PluginInfo) {
return !this.config.store.pluginBlacklist.includes(plugin.name)
}
canDisablePlugin (plugin: PluginInfo) {
return !FORCE_ENABLE.includes(plugin.packageName)
}
togglePlugin (plugin: PluginInfo) {
if (this.isPluginEnabled(plugin)) {
this.disablePlugin(plugin)
} else {
this.enablePlugin(plugin)
}
}
enablePlugin (plugin: PluginInfo) { enablePlugin (plugin: PluginInfo) {
this.config.store.pluginBlacklist = this.config.store.pluginBlacklist.filter(x => x !== plugin.name) this.config.store.pluginBlacklist = this.config.store.pluginBlacklist.filter(x => x !== plugin.name)
this.config.save() this.config.save()

View File

@@ -3,6 +3,7 @@ import { BrowserModule } from '@angular/platform-browser'
import { FormsModule } from '@angular/forms' import { FormsModule } from '@angular/forms'
import { NgbModule } from '@ng-bootstrap/ng-bootstrap' import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
import TerminusCorePlugin from 'terminus-core'
import { SettingsTabProvider } from 'terminus-settings' import { SettingsTabProvider } from 'terminus-settings'
import { PluginsSettingsTabComponent } from './components/pluginsSettingsTab.component' import { PluginsSettingsTabComponent } from './components/pluginsSettingsTab.component'
@@ -14,6 +15,7 @@ import { PluginsSettingsTabProvider } from './settings'
BrowserModule, BrowserModule,
FormsModule, FormsModule,
NgbModule, NgbModule,
TerminusCorePlugin,
], ],
providers: [ providers: [
{ provide: SettingsTabProvider, useClass: PluginsSettingsTabProvider, multi: true }, { provide: SettingsTabProvider, useClass: PluginsSettingsTabProvider, multi: true },

View File

@@ -1,56 +1,5 @@
const path = require('path') const config = require('../webpack.plugin.config')
module.exports = config({
module.exports = { name: 'plugin-manager',
target: 'node', dirname: __dirname,
entry: 'src/index.ts', })
context: __dirname,
devtool: 'cheap-module-source-map',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
pathinfo: true,
libraryTarget: 'umd',
devtoolModuleFilenameTemplate: 'webpack-terminus-plugin-manager:///[resource-path]',
},
mode: process.env.TERMINUS_DEV ? 'development' : 'production',
optimization:{
minimize: false,
},
resolve: {
modules: ['.', 'src', 'node_modules', '../app/node_modules'].map(x => path.join(__dirname, x)),
extensions: ['.ts', '.js'],
},
module: {
rules: [
{
test: /\.ts$/,
use: {
loader: 'awesome-typescript-loader',
options: {
configFileName: path.resolve(__dirname, 'tsconfig.json'),
typeRoots: [
path.resolve(__dirname, 'node_modules/@types'),
path.resolve(__dirname, '../node_modules/@types'),
],
paths: {
"terminus-*": [path.resolve(__dirname, '../terminus-*')],
"*": [path.resolve(__dirname, '../app/node_modules/*')],
},
},
},
},
{ test: /\.pug$/, use: ['apply-loader', 'pug-loader'] },
{ test: /\.scss$/, use: ['to-string-loader', 'css-loader', 'sass-loader'] },
],
},
externals: [
'fs',
'net',
'path',
'electron-promise-ipc',
/^rxjs/,
/^@angular/,
/^@ng-bootstrap/,
/^terminus-/,
],
}

View File

@@ -12,12 +12,12 @@ any-promise@^1.0.0:
resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= integrity sha1-q8av7tzqUugJzcA3au0845Y10X8=
axios@^0.19.0: axios@^0.21.1:
version "0.19.2" version "0.21.1"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8"
integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA== integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==
dependencies: dependencies:
follow-redirects "1.5.10" follow-redirects "^1.10.0"
call-bind@^1.0.0: call-bind@^1.0.0:
version "1.0.0" version "1.0.0"
@@ -27,13 +27,6 @@ call-bind@^1.0.0:
function-bind "^1.1.1" function-bind "^1.1.1"
get-intrinsic "^1.0.0" get-intrinsic "^1.0.0"
debug@=3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
dependencies:
ms "2.0.0"
define-properties@^1.1.3: define-properties@^1.1.3:
version "1.1.3" version "1.1.3"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
@@ -78,12 +71,10 @@ es-to-primitive@^1.2.1:
is-date-object "^1.0.1" is-date-object "^1.0.1"
is-symbol "^1.0.2" is-symbol "^1.0.2"
follow-redirects@1.5.10: follow-redirects@^1.10.0:
version "1.5.10" version "1.13.1"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.1.tgz#5f69b813376cee4fd0474a3aba835df04ab763b7"
integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== integrity sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==
dependencies:
debug "=3.1.0"
function-bind@^1.1.1: function-bind@^1.1.1:
version "1.1.1" version "1.1.1"
@@ -145,10 +136,12 @@ is-symbol@^1.0.2:
dependencies: dependencies:
has-symbols "^1.0.1" has-symbols "^1.0.1"
ms@2.0.0: lru-cache@^6.0.0:
version "2.0.0" version "6.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
dependencies:
yallist "^4.0.0"
mz@^2.6.0: mz@^2.6.0:
version "2.7.0" version "2.7.0"
@@ -195,9 +188,11 @@ object.entries@^1.1.3:
has "^1.0.3" has "^1.0.3"
semver@^7.1.1: semver@^7.1.1:
version "7.3.2" version "7.3.4"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97"
integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==
dependencies:
lru-cache "^6.0.0"
serialize-error@^5.0.0: serialize-error@^5.0.0:
version "5.0.0" version "5.0.0"
@@ -245,3 +240,8 @@ uuid@^3.0.1:
version "3.4.0" version "3.4.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
yallist@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==

View File

@@ -1,6 +1,6 @@
{ {
"name": "terminus-serial", "name": "terminus-serial",
"version": "1.0.123-nightly.0", "version": "1.0.135-nightly.0",
"description": "Serial connection manager for Terminus", "description": "Serial connection manager for Terminus",
"keywords": [ "keywords": [
"terminus-builtin-plugin" "terminus-builtin-plugin"
@@ -20,7 +20,10 @@
"@types/node": "14.14.14", "@types/node": "14.14.14",
"@types/ssh2": "^0.5.35", "@types/ssh2": "^0.5.35",
"ansi-colors": "^4.1.1", "ansi-colors": "^4.1.1",
"cli-spinner": "^0.2.10" "binstring": "^0.2.1",
"buffer-replace": "^1.0.0",
"cli-spinner": "^0.2.10",
"hexer": "^1.5.0"
}, },
"peerDependencies": { "peerDependencies": {
"@angular/animations": "^9.1.9", "@angular/animations": "^9.1.9",

View File

@@ -1,7 +1,15 @@
import hexdump from 'hexer'
import colors from 'ansi-colors'
import binstring from 'binstring'
import stripAnsi from 'strip-ansi'
import bufferReplace from 'buffer-replace'
import { BaseSession } from 'terminus-terminal' import { BaseSession } from 'terminus-terminal'
import { SerialPort } from 'serialport' import { SerialPort } from 'serialport'
import { Logger } from 'terminus-core' import { Logger } from 'terminus-core'
import { Subject, Observable } from 'rxjs' import { Subject, Observable, interval } from 'rxjs'
import { debounce } from 'rxjs/operators'
import { ReadLine, createInterface as createReadline, clearLine } from 'readline'
import { PassThrough, Readable, Writable } from 'stream'
export interface LoginScript { export interface LoginScript {
expect: string expect: string
@@ -23,6 +31,10 @@ export interface SerialConnection {
xany: boolean xany: boolean
scripts?: LoginScript[] scripts?: LoginScript[]
color?: string color?: string
inputMode?: InputMode
inputNewlines?: NewlineMode
outputMode?: OutputMode
outputNewlines?: NewlineMode
} }
export const BAUD_RATES = [ export const BAUD_RATES = [
@@ -34,6 +46,10 @@ export interface SerialPortInfo {
description?: string description?: string
} }
export type InputMode = null | 'readline' | 'readline-hex' // eslint-disable-line @typescript-eslint/no-type-alias
export type OutputMode = null | 'hex' // eslint-disable-line @typescript-eslint/no-type-alias
export type NewlineMode = null | 'cr' | 'lf' | 'crlf' // eslint-disable-line @typescript-eslint/no-type-alias
export class SerialSession extends BaseSession { export class SerialSession extends BaseSession {
scripts?: LoginScript[] scripts?: LoginScript[]
serial: SerialPort serial: SerialPort
@@ -41,58 +57,38 @@ export class SerialSession extends BaseSession {
get serviceMessage$ (): Observable<string> { return this.serviceMessage } get serviceMessage$ (): Observable<string> { return this.serviceMessage }
private serviceMessage = new Subject<string>() private serviceMessage = new Subject<string>()
private inputReadline: ReadLine
private inputPromptVisible = true
private inputReadlineInStream: Readable & Writable
private inputReadlineOutStream: Readable & Writable
constructor (public connection: SerialConnection) { constructor (public connection: SerialConnection) {
super() super()
this.scripts = connection.scripts ?? [] this.scripts = connection.scripts ?? []
this.inputReadlineInStream = new PassThrough()
this.inputReadlineOutStream = new PassThrough()
this.inputReadline = createReadline({
input: this.inputReadlineInStream,
output: this.inputReadlineOutStream,
terminal: true,
prompt: this.connection.inputMode === 'readline-hex' ? 'hex> ' : '> ',
} as any)
this.inputReadlineOutStream.on('data', data => {
this.emitOutput(Buffer.from(data))
})
this.inputReadline.on('line', line => {
this.onInput(new Buffer(line + '\n'))
this.resetInputPrompt()
})
this.output$.pipe(debounce(() => interval(500))).subscribe(() => this.onOutputSettled())
} }
async start (): Promise<void> { async start (): Promise<void> {
this.open = true this.open = true
this.serial.on('data', data => { this.serial.on('readable', () => {
const dataString = data.toString() this.onOutput(this.serial.read())
this.emitOutput(data)
if (this.scripts) {
let found = false
for (const script of this.scripts) {
let match = false
let cmd = ''
if (script.isRegex) {
const re = new RegExp(script.expect, 'g')
if (dataString.match(re)) {
cmd = dataString.replace(re, script.send)
match = true
found = true
}
} else {
if (dataString.includes(script.expect)) {
cmd = script.send
match = true
found = true
}
}
if (match) {
this.logger.info('Executing script: "' + cmd + '"')
this.serial.write(cmd + '\n')
this.scripts = this.scripts.filter(x => x !== script)
} else {
if (script.optional) {
this.logger.debug('Skip optional script: ' + script.expect)
found = true
this.scripts = this.scripts.filter(x => x !== script)
} else {
break
}
}
}
if (found) {
this.executeUnconditionalScripts()
}
}
}) })
this.serial.on('end', () => { this.serial.on('end', () => {
@@ -106,23 +102,33 @@ export class SerialSession extends BaseSession {
} }
write (data: Buffer): void { write (data: Buffer): void {
if (this.serial) { if (this.connection.inputMode?.startsWith('readline')) {
this.serial.write(data.toString()) this.inputReadlineInStream.write(data)
} else {
this.onInput(data)
} }
} }
async destroy (): Promise<void> { async destroy (): Promise<void> {
this.serviceMessage.complete() this.serviceMessage.complete()
this.inputReadline.close()
await super.destroy() await super.destroy()
} }
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-empty-function // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-empty-function
resize (_, __) { } resize (_, __) {
this.inputReadlineOutStream.emit('resize')
}
kill (_?: string): void { kill (_?: string): void {
this.serial.close() this.serial.close()
} }
emitServiceMessage (msg: string): void {
this.serviceMessage.next(msg)
this.logger.info(stripAnsi(msg))
}
async getChildProcesses (): Promise<any[]> { async getChildProcesses (): Promise<any[]> {
return [] return []
} }
@@ -139,6 +145,118 @@ export class SerialSession extends BaseSession {
return null return null
} }
private replaceNewlines (data: Buffer, mode?: NewlineMode): Buffer {
if (!mode) {
return data
}
data = bufferReplace(data, '\r\n', '\n')
data = bufferReplace(data, '\r', '\n')
const replacement = {
strip: '',
cr: '\r',
lf: '\n',
crlf: '\r\n',
}[mode]
return bufferReplace(data, '\n', replacement)
}
private onInput (data: Buffer) {
if (this.connection.inputMode === 'readline-hex') {
const tokens = data.toString().split(/\s/g)
data = Buffer.concat(tokens.filter(t => !!t).map(t => {
if (t.startsWith('0x')) {
t = t.substring(2)
}
return binstring(t, { 'in': 'hex' })
}))
}
data = this.replaceNewlines(data, this.connection.inputNewlines)
if (this.serial) {
this.serial.write(data.toString())
}
}
private onOutputSettled () {
if (this.connection.inputMode?.startsWith('readline') && !this.inputPromptVisible) {
this.resetInputPrompt()
}
}
private resetInputPrompt () {
this.emitOutput(new Buffer('\r\n'))
this.inputReadline.prompt(true)
this.inputPromptVisible = true
}
private onOutput (data: Buffer) {
const dataString = data.toString()
if (this.connection.inputMode?.startsWith('readline')) {
if (this.inputPromptVisible) {
clearLine(this.inputReadlineOutStream, 0)
this.inputPromptVisible = false
}
}
data = this.replaceNewlines(data, this.connection.outputNewlines)
if (this.connection.outputMode === 'hex') {
this.emitOutput(Buffer.concat([
new Buffer('\r\n'),
Buffer.from(hexdump(data, {
group: 1,
gutter: 4,
divide: colors.gray(' '),
emptyHuman: colors.gray(''),
}).replace(/\n/g, '\r\n')),
new Buffer('\r\n\n'),
]))
} else {
this.emitOutput(data)
}
if (this.scripts) {
let found = false
for (const script of this.scripts) {
let match = false
let cmd = ''
if (script.isRegex) {
const re = new RegExp(script.expect, 'g')
if (re.test(dataString)) {
cmd = dataString.replace(re, script.send)
match = true
found = true
}
} else {
if (dataString.includes(script.expect)) {
cmd = script.send
match = true
found = true
}
}
if (match) {
this.logger.info('Executing script: "' + cmd + '"')
this.serial.write(cmd + '\n')
this.scripts = this.scripts.filter(x => x !== script)
} else {
if (script.optional) {
this.logger.debug('Skip optional script: ' + script.expect)
found = true
this.scripts = this.scripts.filter(x => x !== script)
} else {
break
}
}
}
if (found) {
this.executeUnconditionalScripts()
}
}
}
private executeUnconditionalScripts () { private executeUnconditionalScripts () {
if (this.scripts) { if (this.scripts) {
for (const script of this.scripts) { for (const script of this.scripts) {

View File

@@ -11,21 +11,84 @@
[(ngModel)]='connection.name', [(ngModel)]='connection.name',
) )
.form-group .row
label Path .col-6
input.form-control( .form-group
type='text', label Path
[(ngModel)]='connection.port', input.form-control(
[ngbTypeahead]='portsAutocomplete', type='text',
[resultFormatter]='portsFormatter', [(ngModel)]='connection.port',
) [ngbTypeahead]='portsAutocomplete',
[resultFormatter]='portsFormatter',
)
.form-group .col-6
label Baud Rate .form-group
select.form-control( label Baud Rate
[(ngModel)]='connection.baudrate', select.form-control(
) [(ngModel)]='connection.baudrate',
option([value]='x', *ngFor='let x of baudRates') {{x}} )
option([value]='x', *ngFor='let x of baudRates') {{x}}
.row
.col-6
.form-line
.header
.title Input mode
.d-flex(ngbDropdown)
button.btn.btn-secondary.btn-tab-bar(
ngbDropdownToggle,
) {{getInputModeName(connection.inputMode)}}
div(ngbDropdownMenu)
a.d-flex.flex-column(
*ngFor='let mode of inputModes',
(click)='connection.inputMode = mode.key',
ngbDropdownItem
)
div {{mode.name}}
.text-muted {{mode.description}}
.col-6
.form-line
.header
.title Input newlines
select.form-control(
[(ngModel)]='connection.inputNewlines',
)
option([ngValue]='mode.key', *ngFor='let mode of newlineModes') {{mode.name}}
.row
.col-6
.form-line
.header
.title Output mode
.d-flex(ngbDropdown)
button.btn.btn-secondary.btn-tab-bar(
ngbDropdownToggle,
) {{getOutputModeName(connection.outputMode)}}
div(ngbDropdownMenu)
a.d-flex.flex-column(
*ngFor='let mode of outputModes',
(click)='connection.outputMode = mode.key',
ngbDropdownItem
)
div {{mode.name}}
.text-muted {{mode.description}}
.col-6
.form-line
.header
.title Output newlines
select.form-control(
[(ngModel)]='connection.outputNewlines',
)
option([ngValue]='mode.key', *ngFor='let mode of newlineModes') {{mode.name}}
ngb-tab(id='advanced') ngb-tab(id='advanced')
ng-template(ngbTabTitle) Advanced ng-template(ngbTabTitle) Advanced

View File

@@ -15,6 +15,22 @@ export class EditConnectionModalComponent {
connection: SerialConnection connection: SerialConnection
foundPorts: SerialPortInfo[] foundPorts: SerialPortInfo[]
baudRates = BAUD_RATES baudRates = BAUD_RATES
inputModes = [
{ key: null, name: 'Normal', description: 'Input is sent as you type' },
{ key: 'readline', name: 'Line by line', description: 'Line editor, input is sent after you press Enter' },
{ key: 'readline-hex', name: 'Hexadecimal', description: 'Send bytes by typing in hex values' },
]
outputModes = [
{ key: null, name: 'Normal', description: 'Output is shown as it is received' },
{ key: 'hex', name: 'Hexadecimal', description: 'Output is shown as a hexdump' },
]
newlineModes = [
{ key: null, name: 'Keep' },
{ key: 'strip', name: 'Strip' },
{ key: 'cr', name: 'Force CR' },
{ key: 'lf', name: 'Force LF' },
{ key: 'crlf', name: 'Force CRLF' },
]
constructor ( constructor (
private modalInstance: NgbActiveModal, private modalInstance: NgbActiveModal,
@@ -24,6 +40,14 @@ export class EditConnectionModalComponent {
) { ) {
} }
getInputModeName (key) {
return this.inputModes.find(x => x.key === key)?.name
}
getOutputModeName (key) {
return this.outputModes.find(x => x.key === key)?.name
}
portsAutocomplete = text$ => text$.pipe(map(() => { portsAutocomplete = text$ => text$.pipe(map(() => {
return this.foundPorts.map(x => x.name) return this.foundPorts.map(x => x.name)
})) }))

View File

@@ -34,6 +34,10 @@ export class SerialSettingsTabComponent {
xany: false, xany: false,
xoff: false, xoff: false,
xon: false, xon: false,
inputMode: null,
outputMode: null,
inputNewlines: null,
outputNewlines: null,
} }
const modal = this.ngbModal.open(EditConnectionModalComponent) const modal = this.ngbModal.open(EditConnectionModalComponent)

View File

@@ -1,16 +1,16 @@
.tab-toolbar .tab-toolbar([class.show]='!session || !session.open')
.btn.btn-outline-secondary.reveal-button .btn.btn-outline-secondary.reveal-button
i.fas.fa-ellipsis-h i.fas.fa-ellipsis-h
.toolbar(*ngIf='session', [class.show]='!session.open') .toolbar
i.fas.fa-circle.text-success.mr-2(*ngIf='session.open') i.fas.fa-circle.text-success.mr-2(*ngIf='session && session.open')
i.fas.fa-circle.text-danger.mr-2(*ngIf='!session.open') i.fas.fa-circle.text-danger.mr-2(*ngIf='!session || !session.open')
strong(*ngIf='session') {{session.connection.port}} ({{session.connection.baudrate}}) strong {{connection.port}} ({{connection.baudrate}})
.mr-auto .mr-auto
button.btn.btn-secondary.mr-3((click)='changeBaudRate()', *ngIf='session.open') button.btn.btn-secondary.mr-3((click)='changeBaudRate()', *ngIf='session && session.open')
span Change baud rate span Change baud rate
button.btn.btn-info((click)='reconnect()', *ngIf='!session.open') button.btn.btn-info((click)='reconnect()', *ngIf='!session || !session.open')
i.fas.fa-reload i.fas.fa-reload
span Reconnect span Reconnect

View File

@@ -11,14 +11,15 @@ import { Subscription } from 'rxjs'
/** @hidden */ /** @hidden */
@Component({ @Component({
selector: 'serial-tab', selector: 'serial-tab',
template: BaseTerminalTabComponent.template + (require('./serialTab.component.pug') as string), template: `${BaseTerminalTabComponent.template} ${require('./serialTab.component.pug')}`,
styles: [require('./serialTab.component.scss'), ...BaseTerminalTabComponent.styles], styles: [require('./serialTab.component.scss'), ...BaseTerminalTabComponent.styles],
animations: BaseTerminalTabComponent.animations, animations: BaseTerminalTabComponent.animations,
}) })
export class SerialTabComponent extends BaseTerminalTabComponent { export class SerialTabComponent extends BaseTerminalTabComponent {
connection?: SerialConnection connection?: SerialConnection
session?: SerialSession session: SerialSession|null = null
serialPort: any serialPort: any
private serialService: SerialService
private homeEndSubscription: Subscription private homeEndSubscription: Subscription
// eslint-disable-next-line @typescript-eslint/no-useless-constructor // eslint-disable-next-line @typescript-eslint/no-useless-constructor
@@ -26,6 +27,7 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
injector: Injector, injector: Injector,
) { ) {
super(injector) super(injector)
this.serialService = injector.get(SerialService)
} }
ngOnInit () { ngOnInit () {
@@ -42,6 +44,9 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
case 'end': case 'end':
this.sendInput('\x1b[F' ) this.sendInput('\x1b[F' )
break break
case 'restart-serial-session':
this.reconnect()
break
} }
}) })
@@ -62,12 +67,8 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
return return
} }
this.session = this.injector.get(SerialService).createSession(this.connection) const session = this.serialService.createSession(this.connection)
this.session.serviceMessage$.subscribe(msg => { this.setSession(session)
this.write(`\r\n${colors.black.bgWhite(' serial ')} ${msg}\r\n`)
this.session?.resize(this.size.columns, this.size.rows)
})
this.attachSessionHandlers()
this.write(`Connecting to `) this.write(`Connecting to `)
const spinner = new Spinner({ const spinner = new Spinner({
@@ -80,15 +81,32 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
spinner.start() spinner.start()
try { try {
this.serialPort = await this.injector.get(SerialService).connectSession(this.session) this.serialPort = await this.serialService.connectSession(this.session!)
spinner.stop(true) spinner.stop(true)
session.emitServiceMessage('Port opened')
} catch (e) { } catch (e) {
spinner.stop(true) spinner.stop(true)
this.write(colors.black.bgRed(' X ') + ' ' + colors.red(e.message) + '\r\n') this.write(colors.black.bgRed(' X ') + ' ' + colors.red(e.message) + '\r\n')
return return
} }
await this.session.start() await this.session!.start()
this.session.resize(this.size.columns, this.size.rows) this.session!.resize(this.size.columns, this.size.rows)
}
protected attachSessionHandlers () {
this.attachSessionHandler(this.session!.serviceMessage$.subscribe(msg => {
this.write(`\r\n${colors.black.bgWhite(' Serial ')} ${msg}\r\n`)
this.session?.resize(this.size.columns, this.size.rows)
}))
this.attachSessionHandler(this.session!.destroyed$.subscribe(() => {
this.write('Press any key to reconnect\r\n')
this.input$.pipe(first()).subscribe(() => {
if (!this.session?.open) {
this.reconnect()
}
})
}))
super.attachSessionHandlers()
} }
async getRecoveryToken (): Promise<any> { async getRecoveryToken (): Promise<any> {
@@ -99,8 +117,10 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
} }
} }
reconnect () { async reconnect (): Promise<void> {
this.initializeSession() this.session?.destroy()
await this.initializeSession()
this.session?.releaseInitialDataBuffer()
} }
async changeBaudRate () { async changeBaudRate () {

View File

@@ -12,6 +12,7 @@ export class SerialConfigProvider extends ConfigProvider {
serial: [ serial: [
'Alt-K', 'Alt-K',
], ],
'restart-serial-session': [],
}, },
} }

View File

@@ -9,6 +9,10 @@ export class SerialHotkeyProvider extends HotkeyProvider {
id: 'serial', id: 'serial',
name: 'Show Serial connections', name: 'Show Serial connections',
}, },
{
id: 'restart-serial-session',
name: 'Restart current serial session',
},
] ]
async provide (): Promise<HotkeyDescription[]> { async provide (): Promise<HotkeyDescription[]> {

View File

@@ -1,7 +1,6 @@
import { Injectable, NgZone } from '@angular/core' import { Injectable, NgZone } from '@angular/core'
import SerialPort from 'serialport' import SerialPort from 'serialport'
import { ToastrService } from 'ngx-toastr' import { LogService, AppService, SelectorOption, ConfigService, NotificationsService } from 'terminus-core'
import { LogService, AppService, SelectorOption, ConfigService } from 'terminus-core'
import { SettingsTabComponent } from 'terminus-settings' import { SettingsTabComponent } from 'terminus-settings'
import { SerialConnection, SerialSession, SerialPortInfo, BAUD_RATES } from '../api' import { SerialConnection, SerialSession, SerialPortInfo, BAUD_RATES } from '../api'
import { SerialTabComponent } from '../components/serialTab.component' import { SerialTabComponent } from '../components/serialTab.component'
@@ -11,7 +10,7 @@ export class SerialService {
private constructor ( private constructor (
private log: LogService, private log: LogService,
private zone: NgZone, private zone: NgZone,
private toastr: ToastrService, private notifications: NotificationsService,
private app: AppService, private app: AppService,
private config: ConfigService, private config: ConfigService,
) { } ) { }
@@ -30,10 +29,17 @@ export class SerialService {
} }
async connectSession (session: SerialSession): Promise<SerialPort> { async connectSession (session: SerialSession): Promise<SerialPort> {
const serial = new SerialPort(session.connection.port, { autoOpen: false, baudRate: session.connection.baudrate, const serial = new SerialPort(session.connection.port, {
dataBits: session.connection.databits, stopBits: session.connection.stopbits, parity: session.connection.parity, autoOpen: false,
rtscts: session.connection.rtscts, xon: session.connection.xon, xoff: session.connection.xoff, baudRate: parseInt(session.connection.baudrate as any),
xany: session.connection.xany }) dataBits: session.connection.databits,
stopBits: session.connection.stopbits,
parity: session.connection.parity,
rtscts: session.connection.rtscts,
xon: session.connection.xon,
xoff: session.connection.xoff,
xany: session.connection.xany,
})
session.serial = serial session.serial = serial
let connected = false let connected = false
await new Promise(async (resolve, reject) => { await new Promise(async (resolve, reject) => {
@@ -44,17 +50,21 @@ export class SerialService {
serial.on('error', error => { serial.on('error', error => {
this.zone.run(() => { this.zone.run(() => {
if (connected) { if (connected) {
this.toastr.error(error.toString()) this.notifications.error(error.toString())
} else { } else {
reject(error) reject(error)
} }
}) })
}) })
serial.on('close', () => {
session.emitServiceMessage('Port closed')
session.destroy()
})
try { try {
serial.open() serial.open()
} catch (e) { } catch (e) {
this.toastr.error(e.message) this.notifications.error(e.message)
reject(e) reject(e)
} }
}) })
@@ -103,7 +113,7 @@ export class SerialService {
options.push({ options.push({
name: 'Manage connections', name: 'Manage connections',
icon: 'cog', icon: 'cog',
callback: () => this.app.openNewTab(SettingsTabComponent, { activeTab: 'serial' }), callback: () => this.app.openNewTabRaw(SettingsTabComponent, { activeTab: 'serial' }),
}) })
options.push({ options.push({
@@ -131,7 +141,7 @@ export class SerialService {
}) })
return tab return tab
} catch (error) { } catch (error) {
this.toastr.error(`Could not connect: ${error}`) this.notifications.error(`Could not connect: ${error}`)
throw error throw error
} }
} }

View File

@@ -1,59 +1,5 @@
const path = require('path') const config = require('../webpack.plugin.config')
module.exports = config({
module.exports = { name: 'serial',
target: 'node', dirname: __dirname,
entry: 'src/index.ts', })
context: __dirname,
devtool: 'source-map',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
pathinfo: true,
libraryTarget: 'umd',
devtoolModuleFilenameTemplate: 'webpack-terminus-serial:///[resource-path]',
},
mode: process.env.TERMINUS_DEV ? 'development' : 'production',
optimization:{
minimize: false,
},
resolve: {
modules: ['.', 'src', 'node_modules', '../app/node_modules'].map(x => path.join(__dirname, x)),
extensions: ['.ts', '.js', '.node'],
},
module: {
rules: [
{
test: /\.ts$/,
use: {
loader: 'awesome-typescript-loader',
options: {
configFileName: path.resolve(__dirname, 'tsconfig.json'),
typeRoots: [
path.resolve(__dirname, 'node_modules/@types'),
path.resolve(__dirname, '../node_modules/@types'),
],
paths: {
"terminus-*": [path.resolve(__dirname, '../terminus-*')],
"*": [path.resolve(__dirname, '../app/node_modules/*')],
},
},
},
},
{ test: /\.pug$/, use: ['apply-loader', 'pug-loader'] },
{ test: /\.scss$/, use: ['to-string-loader', 'css-loader', 'sass-loader'] },
{ test: /\.svg/, use: ['svg-inline-loader'] },
],
},
externals: [
'fs',
'keytar',
'path',
'ngx-toastr',
'serialport',
'windows-process-tree/build/Release/windows_process_tree.node',
/^rxjs/,
/^@angular/,
/^@ng-bootstrap/,
/^terminus-/,
],
}

View File

@@ -27,12 +27,52 @@
"@types/node" "*" "@types/node" "*"
"@types/ssh2-streams" "*" "@types/ssh2-streams" "*"
ansi-color@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/ansi-color/-/ansi-color-0.2.1.tgz#3e75c037475217544ed763a8db5709fa9ae5bf9a"
integrity sha1-PnXAN0dSF1RO12Oo21cJ+prlv5o=
ansi-colors@^4.1.1: ansi-colors@^4.1.1:
version "4.1.1" version "4.1.1"
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
binstring@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/binstring/-/binstring-0.2.1.tgz#8a174d301f6d54efda550dd98bb4cb524eacd75d"
integrity sha1-ihdNMB9tVO/aVQ3Zi7TLUk6s110=
buffer-replace@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/buffer-replace/-/buffer-replace-1.0.0.tgz#bc427c40af4c1f06d6933dede57110acba8ade54"
integrity sha1-vEJ8QK9MHwbWkz3t5XEQrLqK3lQ=
cli-spinner@^0.2.10: cli-spinner@^0.2.10:
version "0.2.10" version "0.2.10"
resolved "https://registry.yarnpkg.com/cli-spinner/-/cli-spinner-0.2.10.tgz#f7d617a36f5c47a7bc6353c697fc9338ff782a47" resolved "https://registry.yarnpkg.com/cli-spinner/-/cli-spinner-0.2.10.tgz#f7d617a36f5c47a7bc6353c697fc9338ff782a47"
integrity sha512-U0sSQ+JJvSLi1pAYuJykwiA8Dsr15uHEy85iCJ6A+0DjVxivr3d+N2Wjvodeg89uP5K6TswFkKBfAD7B3YSn/Q== integrity sha512-U0sSQ+JJvSLi1pAYuJykwiA8Dsr15uHEy85iCJ6A+0DjVxivr3d+N2Wjvodeg89uP5K6TswFkKBfAD7B3YSn/Q==
hexer@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/hexer/-/hexer-1.5.0.tgz#b86ce808598e8a9d1892c571f3cedd86fc9f0653"
integrity sha1-uGzoCFmOip0YksVx887dhvyfBlM=
dependencies:
ansi-color "^0.2.1"
minimist "^1.1.0"
process "^0.10.0"
xtend "^4.0.0"
minimist@^1.1.0:
version "1.2.5"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
process@^0.10.0:
version "0.10.1"
resolved "https://registry.yarnpkg.com/process/-/process-0.10.1.tgz#842457cc51cfed72dc775afeeafb8c6034372725"
integrity sha1-hCRXzFHP7XLcd1r+6vuMYDQ3JyU=
xtend@^4.0.0:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==

View File

@@ -1,6 +1,6 @@
{ {
"name": "terminus-settings", "name": "terminus-settings",
"version": "1.0.123-nightly.0", "version": "1.0.135-nightly.0",
"description": "Terminus terminal settings page", "description": "Terminus terminal settings page",
"keywords": [ "keywords": [
"terminus-builtin-plugin" "terminus-builtin-plugin"
@@ -17,7 +17,8 @@
"author": "Eugene Pankov", "author": "Eugene Pankov",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@types/deep-equal": "1.0.1" "@types/deep-equal": "1.0.1",
"utils-decorators": "^1.8.0"
}, },
"peerDependencies": { "peerDependencies": {
"@angular/animations": "^9.1.9", "@angular/animations": "^9.1.9",

View File

@@ -6,26 +6,27 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
i.fas.fa-fw.fa-window-maximize.mr-2 i.fas.fa-fw.fa-window-maximize.mr-2
| Application | Application
ng-template(ngbTabContent) ng-template(ngbTabContent)
.d-flex.align-items-center.mb-4 .d-flex.align-items-center.flex-wrap.mb-4
h1.terminus-title.mb-2.mr-2 Terminus h1.terminus-title.mb-2.mr-2 Terminus
sup α sup α
.text-muted.mr-auto {{homeBase.appVersion}} .text-muted.mr-auto {{homeBase.appVersion}}
button.btn.btn-secondary.mr-3((click)='homeBase.openGitHub()') div
i.fab.fa-github button.btn.btn-secondary.mr-3((click)='homeBase.openGitHub()')
span GitHub i.fab.fa-github
span GitHub
button.btn.btn-secondary((click)='homeBase.reportBug()') button.btn.btn-secondary((click)='homeBase.reportBug()')
i.fas.fa-bug i.fas.fa-bug
span Report a problem span Report a problem
.form-line .form-line
.header .header
.title Theme .title Theme
select.form-control( select.form-control(
[(ngModel)]='config.store.appearance.theme', [(ngModel)]='config.store.appearance.theme',
(ngModelChange)='config.save()', (ngModelChange)='saveConfiguration()',
) )
option(*ngFor='let theme of themes', [ngValue]='theme.name') {{theme.name}} option(*ngFor='let theme of themes', [ngValue]='theme.name') {{theme.name}}
@@ -34,7 +35,7 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
.title Tabs location .title Tabs location
.btn-group( .btn-group(
[(ngModel)]='config.store.appearance.tabsLocation', [(ngModel)]='config.store.appearance.tabsLocation',
(ngModelChange)='config.save()', (ngModelChange)='saveConfiguration()',
ngbRadioGroup ngbRadioGroup
) )
label.btn.btn-secondary(ngbButtonLabel) label.btn.btn-secondary(ngbButtonLabel)
@@ -66,6 +67,29 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
) )
| Right | Right
.form-line
.header
.title Tabs width
.btn-group(
[(ngModel)]='config.store.appearance.flexTabs',
(ngModelChange)='saveConfiguration()',
ngbRadioGroup
)
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='true'
)
| Dynamic
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='false'
)
| Fixed
.form-line .form-line
.header .header
.title(*ngIf='hostApp.platform !== Platform.macOS') Acrylic background .title(*ngIf='hostApp.platform !== Platform.macOS') Acrylic background
@@ -74,7 +98,7 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
toggle( toggle(
[(ngModel)]='config.store.appearance.vibrancy', [(ngModel)]='config.store.appearance.vibrancy',
(ngModelChange)='config.save()' (ngModelChange)='saveConfiguration()'
) )
.form-line(*ngIf='config.store.appearance.vibrancy && isFluentVibrancySupported') .form-line(*ngIf='config.store.appearance.vibrancy && isFluentVibrancySupported')
@@ -82,7 +106,7 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
.title Background type .title Background type
.btn-group( .btn-group(
[(ngModel)]='config.store.appearance.vibrancyType', [(ngModel)]='config.store.appearance.vibrancyType',
(ngModelChange)='config.save()', (ngModelChange)='saveConfiguration()',
ngbRadioGroup ngbRadioGroup
) )
label.btn.btn-secondary(ngbButtonLabel) label.btn.btn-secondary(ngbButtonLabel)
@@ -106,7 +130,7 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
input( input(
type='range', type='range',
[(ngModel)]='config.store.appearance.opacity', [(ngModel)]='config.store.appearance.opacity',
(ngModelChange)='config.save(); (hostApp.platform === Platform.Linux && config.requestRestart())', (ngModelChange)='saveConfiguration(); (hostApp.platform === Platform.Linux && config.requestRestart())',
min='0.4', min='0.4',
max='1', max='1',
step='0.01' step='0.01'
@@ -125,7 +149,7 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
.btn-group( .btn-group(
[(ngModel)]='config.store.appearance.frame', [(ngModel)]='config.store.appearance.frame',
(ngModelChange)='config.save(); config.requestRestart()', (ngModelChange)='saveConfiguration(true)',
ngbRadioGroup ngbRadioGroup
) )
label.btn.btn-secondary(ngbButtonLabel) label.btn.btn-secondary(ngbButtonLabel)
@@ -157,7 +181,7 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
.btn-group( .btn-group(
[(ngModel)]='config.store.appearance.dock', [(ngModel)]='config.store.appearance.dock',
(ngModelChange)='config.save(); docking.dock()', (ngModelChange)='saveConfiguration(); docking.dock()',
ngbRadioGroup ngbRadioGroup
) )
label.btn.btn-secondary(ngbButtonLabel) label.btn.btn-secondary(ngbButtonLabel)
@@ -196,14 +220,14 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
) )
| Bottom | Bottom
.form-line(*ngIf='config.store.appearance.dock != "off"') .ml-5.form-line(*ngIf='config.store.appearance.dock != "off"')
.header .header
.title Display on .title Display on
.description Snaps the window to a side of the screen .description Snaps the window to a side of the screen
div( div(
[(ngModel)]='config.store.appearance.dockScreen', [(ngModel)]='config.store.appearance.dockScreen',
(ngModelChange)='config.save(); docking.dock()', (ngModelChange)='saveConfiguration(); docking.dock()',
ngbRadioGroup ngbRadioGroup
) )
label.btn.btn-secondary(ngbButtonLabel) label.btn.btn-secondary(ngbButtonLabel)
@@ -221,34 +245,46 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
) )
| {{screen.name}} | {{screen.name}}
.form-line(*ngIf='config.store.appearance.dock != "off"') .ml-5.form-line(*ngIf='config.store.appearance.dock != "off"')
.header .header
.title Dock always on top .title Dock always on top
.description Keep docked terminal always on top .description Keep docked terminal always on top
toggle( toggle(
[(ngModel)]='config.store.appearance.dockAlwaysOnTop', [(ngModel)]='config.store.appearance.dockAlwaysOnTop',
(ngModelChange)='config.save(); docking.dock()', (ngModelChange)='saveConfiguration(); docking.dock()',
) )
.form-line(*ngIf='config.store.appearance.dock != "off"') .ml-5.form-line(*ngIf='config.store.appearance.dock != "off"')
.header .header
.title Docked terminal size .title Docked terminal size
input( input(
type='range', type='range',
[(ngModel)]='config.store.appearance.dockFill', [(ngModel)]='config.store.appearance.dockFill',
(mouseup)='config.save(); docking.dock()', (mouseup)='saveConfiguration(); docking.dock()',
min='0.05', min='0.05',
max='1', max='1',
step='0.01' step='0.01'
) )
.form-line(*ngIf='config.store.appearance.dock != "off"') .ml-5.form-line(*ngIf='config.store.appearance.dock != "off"')
.header
.title Docked terminal space
input(
type='range',
[(ngModel)]='config.store.appearance.dockSpace',
(mouseup)='saveConfiguration(); docking.dock()',
min='0.2',
max='1',
step='0.01'
)
.ml-5.form-line(*ngIf='config.store.appearance.dock != "off"')
.header .header
.title Hide dock on blur .title Hide dock on blur
.description Hides the docked terminal when you click away. .description Hides the docked terminal when you click away.
toggle( toggle(
[(ngModel)]='config.store.appearance.dockHideOnBlur', [(ngModel)]='config.store.appearance.dockHideOnBlur',
(ngModelChange)='config.save(); ', (ngModelChange)='saveConfiguration(); ',
) )
.form-line .form-line
@@ -265,21 +301,21 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
.description We're only tracking your Terminus and OS versions. .description We're only tracking your Terminus and OS versions.
toggle( toggle(
[(ngModel)]='config.store.enableAnalytics', [(ngModel)]='config.store.enableAnalytics',
(ngModelChange)='config.save(); config.requestRestart()', (ngModelChange)='saveConfiguration(true)',
) )
.form-line .form-line
.header .header
.title Automatic Updates .title Automatic Updates
.description Enable automatic installation of updates when they become available. .description Enable automatic installation of updates when they become available.
toggle([(ngModel)]='config.store.enableAutomaticUpdates', (ngModelChange)='config.save()') toggle([(ngModel)]='config.store.enableAutomaticUpdates', (ngModelChange)='saveConfiguration()')
.form-line .form-line
.header .header
.title Custom CSS .title Custom CSS
textarea.form-control( textarea.form-control(
[(ngModel)]='config.store.appearance.css', [(ngModel)]='config.store.appearance.css',
(ngModelChange)='config.save()', (ngModelChange)='saveConfiguration()',
) )
ngb-tab(id='hotkeys') ngb-tab(id='hotkeys')
@@ -308,7 +344,7 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
td.pr-5 td.pr-5
multi-hotkey-input( multi-hotkey-input(
[model]='getHotkey(hotkey.id) || []', [model]='getHotkey(hotkey.id) || []',
(modelChange)='setHotkey(hotkey.id, $event); config.save(); docking.dock()' (modelChange)='setHotkey(hotkey.id, $event); saveConfiguration(); docking.dock()'
) )
ngb-tab(*ngFor='let provider of settingsProviders', [id]='provider.id') ngb-tab(*ngFor='let provider of settingsProviders', [id]='provider.id')
@@ -327,7 +363,7 @@ ngb-tabset.vertical(type='pills', [activeId]='activeTab')
.d-flex.flex-column.w-100.h-100 .d-flex.flex-column.w-100.h-100
.h-100.d-flex .h-100.d-flex
.w-100.d-flex.flex-column .w-100.d-flex.flex-column
h3 Config file h3 Config File
textarea.form-control.h-100( textarea.form-control.h-100(
[(ngModel)]='configFile' [(ngModel)]='configFile'
) )

View File

@@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import * as yaml from 'js-yaml' import * as yaml from 'js-yaml'
import { debounce } from 'utils-decorators/dist/cjs'
import { Subscription } from 'rxjs' import { Subscription } from 'rxjs'
import { Component, Inject, Input, HostBinding, NgZone } from '@angular/core' import { Component, Inject, Input, HostBinding, NgZone } from '@angular/core'
import { import {
@@ -60,7 +61,7 @@ export class SettingsTabComponent extends BaseTabComponent {
this.settingsProviders = config.enabledServices(this.settingsProviders) this.settingsProviders = config.enabledServices(this.settingsProviders)
this.themes = config.enabledServices(this.themes) this.themes = config.enabledServices(this.themes)
this.configDefaults = yaml.safeDump(config.getDefaults()) this.configDefaults = yaml.dump(config.getDefaults())
const onConfigChange = () => { const onConfigChange = () => {
this.configFile = config.readRaw() this.configFile = config.readRaw()
@@ -104,6 +105,14 @@ export class SettingsTabComponent extends BaseTabComponent {
this.hostApp.relaunch() this.hostApp.relaunch()
} }
@debounce(500)
saveConfiguration (requireRestart?: boolean) {
this.config.save()
if (requireRestart) {
this.config.requestRestart()
}
}
saveConfigFile () { saveConfigFile () {
if (this.isConfigFileValid()) { if (this.isConfigFileValid()) {
this.config.writeRaw(this.configFile) this.config.writeRaw(this.configFile)
@@ -116,7 +125,7 @@ export class SettingsTabComponent extends BaseTabComponent {
isConfigFileValid () { isConfigFileValid () {
try { try {
yaml.safeLoad(this.configFile) yaml.load(this.configFile)
return true return true
} catch (_) { } catch (_) {
return false return false

View File

@@ -1,57 +1,5 @@
const path = require('path') const config = require('../webpack.plugin.config')
module.exports = config({
module.exports = { name: 'settings',
target: 'node', dirname: __dirname,
entry: 'src/index.ts', })
context: __dirname,
devtool: 'cheap-module-source-map',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
pathinfo: true,
libraryTarget: 'umd',
devtoolModuleFilenameTemplate: 'webpack-terminus-settings:///[resource-path]',
},
mode: process.env.TERMINUS_DEV ? 'development' : 'production',
optimization:{
minimize: false,
},
resolve: {
modules: ['.', 'src', 'node_modules', '../app/node_modules'].map(x => path.join(__dirname, x)),
extensions: ['.ts', '.js'],
},
module: {
rules: [
{
test: /\.ts$/,
use: {
loader: 'awesome-typescript-loader',
options: {
configFileName: path.resolve(__dirname, 'tsconfig.json'),
typeRoots: [
path.resolve(__dirname, 'node_modules/@types'),
path.resolve(__dirname, '../node_modules/@types'),
],
paths: {
"terminus-*": [path.resolve(__dirname, '../terminus-*')],
"*": [path.resolve(__dirname, '../app/node_modules/*')],
},
},
},
},
{ test: /\.pug$/, use: ['apply-loader', 'pug-loader'] },
{ test: /\.scss$/, use: ['to-string-loader', 'css-loader', 'sass-loader'] },
{ test: /\.css$/, use: ['to-string-loader', 'css-loader', 'sass-loader'] },
{ test: /\.svg/, use: ['svg-inline-loader'] },
],
},
externals: [
'fs',
'path',
'os',
/^rxjs/,
/^@angular/,
/^@ng-bootstrap/,
/^terminus-/,
],
}

View File

@@ -6,3 +6,15 @@
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/@types/deep-equal/-/deep-equal-1.0.1.tgz#71cfabb247c22bcc16d536111f50c0ed12476b03" resolved "https://registry.yarnpkg.com/@types/deep-equal/-/deep-equal-1.0.1.tgz#71cfabb247c22bcc16d536111f50c0ed12476b03"
integrity sha512-mMUu4nWHLBlHtxXY17Fg6+ucS/MnndyOWyOe7MmwkoMYxvfQU2ajtRaEvqSUv+aVkMqH/C0NCI8UoVfRNQ10yg== integrity sha512-mMUu4nWHLBlHtxXY17Fg6+ucS/MnndyOWyOe7MmwkoMYxvfQU2ajtRaEvqSUv+aVkMqH/C0NCI8UoVfRNQ10yg==
tinyqueue@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/tinyqueue/-/tinyqueue-2.0.3.tgz#64d8492ebf39e7801d7bd34062e29b45b2035f08"
integrity sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==
utils-decorators@^1.8.0:
version "1.8.1"
resolved "https://registry.yarnpkg.com/utils-decorators/-/utils-decorators-1.8.1.tgz#6e7e2cf46c05a9554c05f004e5235696142bd5f7"
integrity sha512-UpqzJj40jdTknZpxdeYL7p+8Ynl3bpHP6yoxoY+RmuDCOaelTiOz4GcDpScPvfZhv/ivHTV1bPJZeQd8tlxczA==
dependencies:
tinyqueue "^2.0.3"

View File

@@ -1,6 +1,6 @@
{ {
"name": "terminus-ssh", "name": "terminus-ssh",
"version": "1.0.123-nightly.0", "version": "1.0.135-nightly.1",
"description": "SSH connection manager for Terminus", "description": "SSH connection manager for Terminus",
"keywords": [ "keywords": [
"terminus-builtin-plugin" "terminus-builtin-plugin"
@@ -21,11 +21,10 @@
"author": "Eugene Pankov", "author": "Eugene Pankov",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@types/node": "14.14.14", "@types/node": "14.14.31",
"@types/ssh2": "^0.5.35", "@types/ssh2": "^0.5.35",
"ansi-colors": "^4.1.1", "ansi-colors": "^4.1.1",
"cli-spinner": "^0.2.10", "cli-spinner": "^0.2.10",
"run-script-os": "^1.1.3",
"ssh2": "^0.8.9", "ssh2": "^0.8.9",
"ssh2-streams": "Eugeny/ssh2-streams#75f6d3425d071ac73a18fd46e2f5e738bfe897c5", "ssh2-streams": "Eugeny/ssh2-streams#75f6d3425d071ac73a18fd46e2f5e738bfe897c5",
"sshpk": "^1.16.1", "sshpk": "^1.16.1",
@@ -33,6 +32,7 @@
"temp": "^0.9.1" "temp": "^0.9.1"
}, },
"dependencies": { "dependencies": {
"run-script-os": "^1.1.3",
"socksv5": "^0.0.6" "socksv5": "^0.0.6"
}, },
"peerDependencies": { "peerDependencies": {

View File

@@ -140,6 +140,9 @@ export class SSHSession extends BaseSession {
this.shell = await this.openShellChannel({ x11: this.connection.x11 }) this.shell = await this.openShellChannel({ x11: this.connection.x11 })
} catch (err) { } catch (err) {
this.emitServiceMessage(colors.bgRed.black(' X ') + ` Remote rejected opening a shell channel: ${err}`) this.emitServiceMessage(colors.bgRed.black(' X ') + ` Remote rejected opening a shell channel: ${err}`)
if (err.toString().includes('Unable to request X11')) {
this.emitServiceMessage(' Make sure `xauth` is installed on the remote side')
}
return return
} }
@@ -245,7 +248,13 @@ export class SSHSession extends BaseSession {
} }
socket.on('error', e => { socket.on('error', e => {
// eslint-disable-next-line @typescript-eslint/no-base-to-string // eslint-disable-next-line @typescript-eslint/no-base-to-string
this.emitServiceMessage(colors.bgRed.black(' X ') + ` Could not connect to the X server ${xHost}:${xPort}: ${e}`) this.emitServiceMessage(colors.bgRed.black(' X ') + ` Could not connect to the X server: ${e}`)
this.emitServiceMessage(` Terminus tried to connect to ${xHost}:${xPort} based on the DISPLAY environment var (${displaySpec})`)
if (process.platform === 'win32') {
this.emitServiceMessage(' To use X forwarding, you need a local X server, e.g.:')
this.emitServiceMessage(' * VcXsrv: https://sourceforge.net/projects/vcxsrv/')
this.emitServiceMessage(' * Xming: https://sourceforge.net/projects/xming/')
}
reject() reject()
}) })
socket.on('connect', () => { socket.on('connect', () => {

View File

@@ -1,14 +1,14 @@
.tab-toolbar .tab-toolbar([class.show]='!session || !session.open')
.btn.btn-outline-secondary.reveal-button .btn.btn-outline-secondary.reveal-button
i.fas.fa-ellipsis-h i.fas.fa-ellipsis-h
.toolbar(*ngIf='session', [class.show]='!session.open') .toolbar
i.fas.fa-circle.text-success.mr-2(*ngIf='session.open') i.fas.fa-circle.text-success.mr-2(*ngIf='session && session.open')
i.fas.fa-circle.text-danger.mr-2(*ngIf='!session.open') i.fas.fa-circle.text-danger.mr-2(*ngIf='!session || !session.open')
strong.mr-auto(*ngIf='session') {{session.connection.user}}@{{session.connection.host}}:{{session.connection.port}} strong.mr-auto {{connection.user}}@{{connection.host}}:{{connection.port}}
button.btn.btn-secondary.mr-2((click)='reconnect()', [class.btn-info]='!session.open') button.btn.btn-secondary.mr-2((click)='reconnect()', [class.btn-info]='!session || !session.open')
span Reconnect span Reconnect
button.btn.btn-secondary((click)='showPortForwarding()', *ngIf='session.open') button.btn.btn-secondary((click)='showPortForwarding()', *ngIf='session && session.open')
i.fas.fa-plug i.fas.fa-plug
span Ports span Ports

View File

@@ -14,18 +14,17 @@ import { Subscription } from 'rxjs'
/** @hidden */ /** @hidden */
@Component({ @Component({
selector: 'ssh-tab', selector: 'ssh-tab',
template: BaseTerminalTabComponent.template + (require('./sshTab.component.pug') as string), template: `${BaseTerminalTabComponent.template} ${require('./sshTab.component.pug')}`,
styles: [require('./sshTab.component.scss'), ...BaseTerminalTabComponent.styles], styles: [require('./sshTab.component.scss'), ...BaseTerminalTabComponent.styles],
animations: BaseTerminalTabComponent.animations, animations: BaseTerminalTabComponent.animations,
}) })
export class SSHTabComponent extends BaseTerminalTabComponent { export class SSHTabComponent extends BaseTerminalTabComponent {
connection?: SSHConnection connection?: SSHConnection
session?: SSHSession session: SSHSession|null = null
private sessionStack: SSHSession[] = [] private sessionStack: SSHSession[] = []
private homeEndSubscription: Subscription private homeEndSubscription: Subscription
private recentInputs = '' private recentInputs = ''
private reconnectOffered = false private reconnectOffered = false
private sessionHandlers: Subscription[] = []
constructor ( constructor (
injector: Injector, injector: Injector,
@@ -55,6 +54,9 @@ export class SSHTabComponent extends BaseTerminalTabComponent {
case 'end': case 'end':
this.sendInput('\x1b[F' ) this.sendInput('\x1b[F' )
break break
case 'restart-ssh-session':
this.reconnect()
break
} }
}) })
@@ -85,8 +87,12 @@ export class SSHTabComponent extends BaseTerminalTabComponent {
await this.setupOneSession(jumpSession) await this.setupOneSession(jumpSession)
this.sessionHandlers.push( this.attachSessionHandler(
jumpSession.destroyed$.subscribe(() => session.destroy()) jumpSession.destroyed$.subscribe(() => {
if (session.open) {
session.destroy()
}
})
) )
session.jumpStream = await new Promise((resolve, reject) => jumpSession.ssh.forwardOut( session.jumpStream = await new Promise((resolve, reject) => jumpSession.ssh.forwardOut(
@@ -107,31 +113,11 @@ export class SSHTabComponent extends BaseTerminalTabComponent {
this.sessionStack.push(session) this.sessionStack.push(session)
} }
this.sessionHandlers.push(session.serviceMessage$.subscribe(msg => { this.attachSessionHandler(session.serviceMessage$.subscribe(msg => {
this.write(`\r\n${colors.black.bgWhite(' SSH ')} ${msg}\r\n`) this.write(`\r\n${colors.black.bgWhite(' SSH ')} ${msg}\r\n`)
session.resize(this.size.columns, this.size.rows) session.resize(this.size.columns, this.size.rows)
})) }))
this.sessionHandlers.push(session.destroyed$.subscribe(() => {
if (
// Ctrl-D
this.recentInputs.charCodeAt(this.recentInputs.length - 1) === 4 ||
this.recentInputs.endsWith('exit\r')
) {
// User closed the session
this.destroy()
} else {
// Session was closed abruptly
this.write('\r\n' + colors.black.bgCyan(' SSH ') + ` ${session.connection.host}: session closed\r\n`)
if (!this.reconnectOffered) {
this.reconnectOffered = true
this.write('Press any key to reconnect\r\n')
this.input$.pipe(first()).subscribe(() => {
this.reconnect()
})
}
}
}))
this.write('\r\n' + colors.black.bgCyan(' SSH ') + ` Connecting to ${session.connection.host}\r\n`) this.write('\r\n' + colors.black.bgCyan(' SSH ') + ` Connecting to ${session.connection.host}\r\n`)
@@ -158,6 +144,33 @@ export class SSHTabComponent extends BaseTerminalTabComponent {
} }
} }
protected attachSessionHandlers (): void {
const session = this.session!
this.attachSessionHandler(session.destroyed$.subscribe(() => {
if (
// Ctrl-D
this.recentInputs.charCodeAt(this.recentInputs.length - 1) === 4 ||
this.recentInputs.endsWith('exit\r')
) {
// User closed the session
this.destroy()
} else {
// Session was closed abruptly
this.write('\r\n' + colors.black.bgCyan(' SSH ') + ` ${session.connection.host}: session closed\r\n`)
if (!this.reconnectOffered) {
this.reconnectOffered = true
this.write('Press any key to reconnect\r\n')
this.input$.pipe(first()).subscribe(() => {
if (!this.session?.open) {
this.reconnect()
}
})
}
}
}))
super.attachSessionHandlers()
}
async initializeSession (): Promise<void> { async initializeSession (): Promise<void> {
this.reconnectOffered = false this.reconnectOffered = false
if (!this.connection) { if (!this.connection) {
@@ -165,18 +178,17 @@ export class SSHTabComponent extends BaseTerminalTabComponent {
return return
} }
this.session = this.ssh.createSession(this.connection) const session = this.ssh.createSession(this.connection)
this.setSession(session)
try { try {
await this.setupOneSession(this.session) await this.setupOneSession(session)
} catch (e) { } catch (e) {
this.write(colors.black.bgRed(' X ') + ' ' + colors.red(e.message) + '\r\n') this.write(colors.black.bgRed(' X ') + ' ' + colors.red(e.message) + '\r\n')
} }
this.attachSessionHandlers() await this.session!.start()
this.session!.resize(this.size.columns, this.size.rows)
await this.session.start()
this.session.resize(this.size.columns, this.size.rows)
} }
async getRecoveryToken (): Promise<RecoveryToken> { async getRecoveryToken (): Promise<RecoveryToken> {
@@ -193,10 +205,6 @@ export class SSHTabComponent extends BaseTerminalTabComponent {
} }
async reconnect (): Promise<void> { async reconnect (): Promise<void> {
for (const s of this.sessionHandlers) {
s.unsubscribe()
}
this.sessionHandlers = []
this.session?.destroy() this.session?.destroy()
await this.initializeSession() await this.initializeSession()
this.session?.releaseInitialDataBuffer() this.session?.releaseInitialDataBuffer()

View File

@@ -13,6 +13,7 @@ export class SSHConfigProvider extends ConfigProvider {
ssh: [ ssh: [
'Alt-S', 'Alt-S',
], ],
'restart-ssh-session': [],
}, },
} }

View File

@@ -9,6 +9,10 @@ export class SSHHotkeyProvider extends HotkeyProvider {
id: 'ssh', id: 'ssh',
name: 'Show SSH connections', name: 'Show SSH connections',
}, },
{
id: 'restart-ssh-session',
name: 'Restart current SSH session',
},
] ]
async provide (): Promise<HotkeyDescription[]> { async provide (): Promise<HotkeyDescription[]> {

View File

@@ -5,14 +5,26 @@ import * as keytar from 'keytar'
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class PasswordStorageService { export class PasswordStorageService {
async savePassword (connection: SSHConnection, password: string): Promise<void> { async savePassword (connection: SSHConnection, password: string): Promise<void> {
return keytar.setPassword(`ssh@${connection.host}`, connection.user, password) let key = `ssh@${connection.host}`
if (connection.port) {
key = `ssh@${connection.host}:${connection.port}`
}
return keytar.setPassword(key, connection.user, password)
} }
async deletePassword (connection: SSHConnection): Promise<void> { async deletePassword (connection: SSHConnection): Promise<void> {
await keytar.deletePassword(`ssh@${connection.host}`, connection.user) let key = `ssh@${connection.host}`
if (connection.port) {
key = `ssh@${connection.host}:${connection.port}`
}
await keytar.deletePassword(key, connection.user)
} }
async loadPassword (connection: SSHConnection): Promise<string|null> { async loadPassword (connection: SSHConnection): Promise<string|null> {
return keytar.getPassword(`ssh@${connection.host}`, connection.user) let key = `ssh@${connection.host}`
if (connection.port) {
key = `ssh@${connection.host}:${connection.port}`
}
return keytar.getPassword(key, connection.user)
} }
} }

View File

@@ -9,8 +9,7 @@ import * as fs from 'mz/fs'
import { execFile } from 'mz/child_process' import { execFile } from 'mz/child_process'
import * as path from 'path' import * as path from 'path'
import * as sshpk from 'sshpk' import * as sshpk from 'sshpk'
import { ToastrService } from 'ngx-toastr' import { HostAppService, Platform, Logger, LogService, ElectronService, AppService, SelectorOption, ConfigService, NotificationsService } from 'terminus-core'
import { HostAppService, Platform, Logger, LogService, ElectronService, AppService, SelectorOption, ConfigService } from 'terminus-core'
import { SettingsTabComponent } from 'terminus-settings' import { SettingsTabComponent } from 'terminus-settings'
import { ALGORITHM_BLACKLIST, SSHConnection, SSHSession } from '../api' import { ALGORITHM_BLACKLIST, SSHConnection, SSHSession } from '../api'
import { PromptModalComponent } from '../components/promptModal.component' import { PromptModalComponent } from '../components/promptModal.component'
@@ -39,7 +38,7 @@ export class SSHService {
private ngbModal: NgbModal, private ngbModal: NgbModal,
private hostApp: HostAppService, private hostApp: HostAppService,
private passwordStorage: PasswordStorageService, private passwordStorage: PasswordStorageService,
private toastr: ToastrService, private notifications: NotificationsService,
private app: AppService, private app: AppService,
private config: ConfigService, private config: ConfigService,
) { ) {
@@ -70,7 +69,7 @@ export class SSHService {
privateKey = (await fs.readFile(privateKeyPath)).toString() privateKey = (await fs.readFile(privateKeyPath)).toString()
} catch (error) { } catch (error) {
logCallback?.(colors.bgRed.black(' X ') + 'Could not read the private key file') logCallback?.(colors.bgRed.black(' X ') + 'Could not read the private key file')
this.toastr.error('Could not read the private key file') this.notifications.error('Could not read the private key file')
} }
if (privateKey) { if (privateKey) {
@@ -166,7 +165,7 @@ export class SSHService {
this.zone.run(() => { this.zone.run(() => {
if (connected) { if (connected) {
// eslint-disable-next-line @typescript-eslint/no-base-to-string // eslint-disable-next-line @typescript-eslint/no-base-to-string
this.toastr.error(error.toString()) this.notifications.error(error.toString())
} else { } else {
reject(error) reject(error)
} }
@@ -289,7 +288,7 @@ export class SSHService {
}, },
} as any) } as any)
} catch (e) { } catch (e) {
this.toastr.error(e.message) this.notifications.error(e.message)
return reject(e) return reject(e)
} }
@@ -383,7 +382,7 @@ export class SSHService {
options.push({ options.push({
name: 'Manage connections', name: 'Manage connections',
icon: 'cog', icon: 'cog',
callback: () => this.app.openNewTab(SettingsTabComponent, { activeTab: 'ssh' }), callback: () => this.app.openNewTabRaw(SettingsTabComponent, { activeTab: 'ssh' }),
}) })
options.push({ options.push({
@@ -411,7 +410,7 @@ export class SSHService {
return tab return tab
} catch (error) { } catch (error) {
this.toastr.error(`Could not connect: ${error}`) this.notifications.error(`Could not connect: ${error}`)
throw error throw error
} }
} }
@@ -421,7 +420,9 @@ export class SSHService {
let host = query let host = query
let port = 22 let port = 22
if (host.includes('@')) { if (host.includes('@')) {
[user, host] = host.split('@') const parts = host.split(/@/g)
host = parts[parts.length - 1]
user = parts.slice(0, parts.length - 1).join('@')
} }
if (host.includes(':')) { if (host.includes(':')) {
port = parseInt(host.split(':')[1]) port = parseInt(host.split(':')[1])

View File

@@ -1,61 +1,5 @@
const path = require('path') const config = require('../webpack.plugin.config')
module.exports = config({
module.exports = { name: 'ssh',
target: 'node', dirname: __dirname,
entry: 'src/index.ts', })
context: __dirname,
devtool: 'cheap-module-source-map',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
pathinfo: true,
libraryTarget: 'umd',
devtoolModuleFilenameTemplate: 'webpack-terminus-ssh:///[resource-path]',
},
mode: process.env.TERMINUS_DEV ? 'development' : 'production',
optimization:{
minimize: false,
},
resolve: {
modules: ['.', 'src', 'node_modules', '../app/node_modules'].map(x => path.join(__dirname, x)),
extensions: ['.ts', '.js'],
},
module: {
rules: [
{
test: /\.ts$/,
use: {
loader: 'awesome-typescript-loader',
options: {
configFileName: path.resolve(__dirname, 'tsconfig.json'),
typeRoots: [
path.resolve(__dirname, 'node_modules/@types'),
path.resolve(__dirname, '../node_modules/@types'),
],
paths: {
"terminus-*": [path.resolve(__dirname, '../terminus-*')],
"*": [path.resolve(__dirname, '../app/node_modules/*')],
},
},
},
},
{ test: /\.pug$/, use: ['apply-loader', 'pug-loader'] },
{ test: /\.scss$/, use: ['to-string-loader', 'css-loader', 'sass-loader'] },
{ test: /\.svg/, use: ['svg-inline-loader'] },
],
},
externals: [
'child_process',
'fs',
'keytar',
'path',
'ngx-toastr',
'socksv5',
'windows-native-registry',
'windows-process-tree/build/Release/windows_process_tree.node',
/^rxjs/,
/^@angular/,
/^@ng-bootstrap/,
/^terminus-/,
],
}

View File

@@ -2,10 +2,10 @@
# yarn lockfile v1 # yarn lockfile v1
"@types/node@*", "@types/node@14.14.14": "@types/node@*", "@types/node@14.14.31":
version "14.14.14" version "14.14.31"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.14.tgz#f7fd5f3cc8521301119f63910f0fb965c7d761ae" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.31.tgz#72286bd33d137aa0d152d47ec7c1762563d34055"
integrity sha512-UHnOPWVWV1z+VV8k6L1HhG7UbGBgIdghqF3l9Ny9ApPghbjICXkUJSd/b9gOgQfjM1r+37cipdw/HJ3F6ICEnQ== integrity sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==
"@types/ssh2-streams@*": "@types/ssh2-streams@*":
version "0.1.7" version "0.1.7"
@@ -230,9 +230,9 @@ rimraf@~2.6.2:
glob "^7.1.3" glob "^7.1.3"
run-script-os@^1.1.3: run-script-os@^1.1.3:
version "1.1.3" version "1.1.5"
resolved "https://registry.yarnpkg.com/run-script-os/-/run-script-os-1.1.3.tgz#1069b418307f4fd36ff056b5eda309c273fca8b0" resolved "https://registry.yarnpkg.com/run-script-os/-/run-script-os-1.1.5.tgz#6038a92b370a1cbca5fa2fa73d1c740b0037b6ff"
integrity sha512-xPlzE6533nvWVea5z7e5J7+JAIepfpxTu/HLGxcjJYlemVukOCWJBaRCod/DWXJFRIWEFOgSGbjd2m1QWTJi5w== integrity sha512-kLvUnf1SM1+gSH2bY1P41MNFaWdXaG2nkhoJS9WQNQxk6g9KNuncKderBLG7vOsp77GtQqNs0bEazxip/I6wfg==
safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
version "2.1.2" version "2.1.2"

View File

@@ -1,6 +1,6 @@
{ {
"name": "terminus-terminal", "name": "terminus-terminal",
"version": "1.0.123-nightly.0", "version": "1.0.135-nightly.0",
"description": "Terminus' terminal emulation core", "description": "Terminus' terminal emulation core",
"keywords": [ "keywords": [
"terminus-builtin-plugin" "terminus-builtin-plugin"
@@ -27,12 +27,12 @@
"runes": "^0.4.2", "runes": "^0.4.2",
"slugify": "^1.4.0", "slugify": "^1.4.0",
"xterm": "^4.9.0-beta.7", "xterm": "^4.9.0-beta.7",
"xterm-addon-fit": "^0.4.0-beta.8", "xterm-addon-fit": "^0.5.0",
"xterm-addon-ligatures": "^0.4.0-beta.5", "xterm-addon-ligatures": "^0.4.0",
"xterm-addon-search": "^0.7.0-beta.2", "xterm-addon-search": "^0.8.0",
"xterm-addon-serialize": "^0.3.0", "xterm-addon-serialize": "^0.5.0",
"xterm-addon-unicode11": "^0.2.0", "xterm-addon-unicode11": "^0.2.0",
"xterm-addon-webgl": "^0.8.0", "xterm-addon-webgl": "^0.10.0",
"zmodem.js": "^0.1.9" "zmodem.js": "^0.1.9"
}, },
"peerDependencies": { "peerDependencies": {

View File

@@ -1,11 +1,10 @@
import type { MenuItemConstructorOptions } from 'electron' import type { MenuItemConstructorOptions } from 'electron'
import { Observable, Subject, Subscription } from 'rxjs' import { Observable, Subject, Subscription } from 'rxjs'
import { first } from 'rxjs/operators' import { first } from 'rxjs/operators'
import { ToastrService } from 'ngx-toastr'
import colors from 'ansi-colors' import colors from 'ansi-colors'
import { NgZone, OnInit, OnDestroy, Injector, ViewChild, HostBinding, Input, ElementRef, InjectFlags } from '@angular/core' import { NgZone, OnInit, OnDestroy, Injector, ViewChild, HostBinding, Input, ElementRef, InjectFlags } from '@angular/core'
import { trigger, transition, style, animate, AnimationTriggerMetadata } from '@angular/animations' import { trigger, transition, style, animate, AnimationTriggerMetadata } from '@angular/animations'
import { AppService, ConfigService, BaseTabComponent, ElectronService, HostAppService, HotkeysService, Platform, LogService, Logger, TabContextMenuItemProvider, SplitTabComponent } from 'terminus-core' import { AppService, ConfigService, BaseTabComponent, ElectronService, HostAppService, HotkeysService, NotificationsService, Platform, LogService, Logger, TabContextMenuItemProvider, SplitTabComponent } from 'terminus-core'
import { BaseSession, SessionsService } from '../services/sessions.service' import { BaseSession, SessionsService } from '../services/sessions.service'
import { TerminalFrontendService } from '../services/terminalFrontend.service' import { TerminalFrontendService } from '../services/terminalFrontend.service'
@@ -15,11 +14,6 @@ import { ResizeEvent } from './interfaces'
import { TerminalDecorator } from './decorator' import { TerminalDecorator } from './decorator'
/** @hidden */
export interface ToastrServiceProxy {
info: (_: string) => void
error: (_: string) => void
}
/** /**
* A class to base your custom terminal tabs on * A class to base your custom terminal tabs on
*/ */
@@ -36,7 +30,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
]), ]),
])] ])]
session?: BaseSession session: BaseSession|null = null
savedState?: any savedState?: any
@Input() zoom = 0 @Input() zoom = 0
@@ -82,7 +76,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
protected sessions: SessionsService protected sessions: SessionsService
protected electron: ElectronService protected electron: ElectronService
protected terminalContainersService: TerminalFrontendService protected terminalContainersService: TerminalFrontendService
protected toastr: ToastrServiceProxy protected notifications: NotificationsService
protected log: LogService protected log: LogService
protected decorators: TerminalDecorator[] = [] protected decorators: TerminalDecorator[] = []
protected contextMenuProviders: TabContextMenuItemProvider[] protected contextMenuProviders: TabContextMenuItemProvider[]
@@ -90,11 +84,13 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
protected logger: Logger protected logger: Logger
protected output = new Subject<string>() protected output = new Subject<string>()
protected sessionChanged = new Subject<BaseSession|null>()
private sessionCloseSubscription: Subscription private sessionCloseSubscription: Subscription
private hotkeysSubscription: Subscription private hotkeysSubscription: Subscription
private bellPlayer: HTMLAudioElement private bellPlayer: HTMLAudioElement
private termContainerSubscriptions: Subscription[] = [] private termContainerSubscriptions: Subscription[] = []
private allFocusModeSubscription: Subscription|null = null private allFocusModeSubscription: Subscription|null = null
private sessionHandlers: Subscription[] = []
get input$ (): Observable<Buffer> { get input$ (): Observable<Buffer> {
if (!this.frontend) { if (!this.frontend) {
@@ -121,6 +117,8 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
get frontendReady$ (): Observable<void> { return this.frontendReady } get frontendReady$ (): Observable<void> { return this.frontendReady }
get sessionChanged$ (): Observable<BaseSession|null> { return this.sessionChanged }
constructor (protected injector: Injector) { constructor (protected injector: Injector) {
super() super()
@@ -133,7 +131,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
this.sessions = injector.get(SessionsService) this.sessions = injector.get(SessionsService)
this.electron = injector.get(ElectronService) this.electron = injector.get(ElectronService)
this.terminalContainersService = injector.get(TerminalFrontendService) this.terminalContainersService = injector.get(TerminalFrontendService)
this.toastr = injector.get(ToastrService) this.notifications = injector.get(NotificationsService)
this.log = injector.get(LogService) this.log = injector.get(LogService)
this.decorators = injector.get<any>(TerminalDecorator, null, InjectFlags.Optional) as TerminalDecorator[] this.decorators = injector.get<any>(TerminalDecorator, null, InjectFlags.Optional) as TerminalDecorator[]
this.contextMenuProviders = injector.get<any>(TabContextMenuItemProvider, null, InjectFlags.Optional) as TabContextMenuItemProvider[] this.contextMenuProviders = injector.get<any>(TabContextMenuItemProvider, null, InjectFlags.Optional) as TabContextMenuItemProvider[]
@@ -150,7 +148,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
if (this.frontend?.getSelection()) { if (this.frontend?.getSelection()) {
this.frontend.copySelection() this.frontend.copySelection()
this.frontend.clearSelection() this.frontend.clearSelection()
this.toastr.info('Copied') this.notifications.notice('Copied')
} else { } else {
this.sendInput('\x03') this.sendInput('\x03')
} }
@@ -158,7 +156,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
case 'copy': case 'copy':
this.frontend?.copySelection() this.frontend?.copySelection()
this.frontend?.clearSelection() this.frontend?.clearSelection()
this.toastr.info('Copied') this.notifications.notice('Copied')
break break
case 'paste': case 'paste':
this.paste() this.paste()
@@ -332,7 +330,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
} }
const percentageMatch = /(^|[^\d])(\d+(\.\d+)?)%([^\d]|$)/.exec(data) const percentageMatch = /(^|[^\d])(\d+(\.\d+)?)%([^\d]|$)/.exec(data)
if (!this.alternateScreenActive && percentageMatch) { if (!this.alternateScreenActive && percentageMatch && this.config.store.terminal.detectProgress) {
const percentage = percentageMatch[3] ? parseFloat(percentageMatch[2]) : parseInt(percentageMatch[2]) const percentage = percentageMatch[3] ? parseFloat(percentageMatch[2]) : parseInt(percentageMatch[2])
if (percentage > 0 && percentage <= 100) { if (percentage > 0 && percentage <= 100) {
this.setProgress(percentage) this.setProgress(percentage)
@@ -347,7 +345,7 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
async paste (): Promise<void> { async paste (): Promise<void> {
let data = this.electron.clipboard.readText() let data = this.electron.clipboard.readText()
if (this.config.store.terminal.bracketedPaste) { if (this.config.store.terminal.bracketedPaste) {
data = '\x1b[200~' + data + '\x1b[201~' data = `\x1b[200~${data}\x1b[201~`
} }
if (this.hostApp.platform === Platform.Windows) { if (this.hostApp.platform === Platform.Windows) {
data = data.replace(/\r\n/g, '\r') data = data.replace(/\r\n/g, '\r')
@@ -418,10 +416,11 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
return return
} }
if (this.parent instanceof SplitTabComponent) { if (this.parent instanceof SplitTabComponent) {
this.parent._allFocusMode = true const parent = this.parent
this.parent.layout() parent._allFocusMode = true
parent.layout()
this.allFocusModeSubscription = this.frontend?.input$.subscribe(data => { this.allFocusModeSubscription = this.frontend?.input$.subscribe(data => {
for (const tab of (this.parent as SplitTabComponent).getAllTabs()) { for (const tab of parent.getAllTabs()) {
if (tab !== this && tab instanceof BaseTerminalTabComponent) { if (tab !== this && tab instanceof BaseTerminalTabComponent) {
tab.sendInput(data) tab.sendInput(data)
} }
@@ -449,9 +448,9 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
} }
if (cwd) { if (cwd) {
this.electron.clipboard.writeText(cwd) this.electron.clipboard.writeText(cwd)
this.toastr.info('Copied') this.notifications.notice('Copied')
} else { } else {
this.toastr.error('Shell does not support current path detection') this.notifications.error('Shell does not support current path detection')
} }
} }
@@ -567,26 +566,56 @@ export class BaseTerminalTabComponent extends BaseTabComponent implements OnInit
] ]
} }
setSession (session: BaseSession|null, destroyOnSessionClose = false): void {
if (session) {
if (this.session) {
this.setSession(null)
}
this.detachSessionHandlers()
this.session = session
this.attachSessionHandlers(destroyOnSessionClose)
} else {
this.detachSessionHandlers()
this.session = null
}
this.sessionChanged.next(session)
}
protected attachSessionHandler (subscription: Subscription): void {
this.sessionHandlers.push(subscription)
}
protected attachSessionHandlers (destroyOnSessionClose = false): void { protected attachSessionHandlers (destroyOnSessionClose = false): void {
if (!this.session) { if (!this.session) {
throw new Error('Session not set') throw new Error('Session not set')
} }
// this.session.output$.bufferTime(10).subscribe((datas) => { // this.session.output$.bufferTime(10).subscribe((datas) => {
this.session.output$.subscribe(data => { this.attachSessionHandler(this.session.output$.subscribe(data => {
if (this.enablePassthrough) { if (this.enablePassthrough) {
this.zone.run(() => { this.zone.run(() => {
this.output.next(data) this.output.next(data)
this.write(data) this.write(data)
}) })
} }
}) }))
if (destroyOnSessionClose) { if (destroyOnSessionClose) {
this.sessionCloseSubscription = this.session.closed$.subscribe(() => { this.attachSessionHandler(this.sessionCloseSubscription = this.session.closed$.subscribe(() => {
this.frontend?.destroy() this.frontend?.destroy()
this.destroy() this.destroy()
}) }))
} }
this.attachSessionHandler(this.session.destroyed$.subscribe(() => {
this.setSession(null)
}))
}
protected detachSessionHandlers (): void {
for (const s of this.sessionHandlers) {
s.unsubscribe()
}
this.sessionHandlers = []
} }
} }

View File

@@ -22,6 +22,7 @@ export interface Profile {
shell?: string shell?: string
isBuiltin?: boolean isBuiltin?: boolean
icon?: string icon?: string
disableDynamicTitle?: boolean
} }
export interface TerminalColorScheme { export interface TerminalColorScheme {

View File

@@ -1,6 +1,6 @@
h3.mb-3 Appearance h3.mb-3 Appearance
.d-flex .row
.mr-5.w-100 .col-12.col-md-6
.form-line .form-line
.header .header
.title Font .title Font
@@ -30,7 +30,8 @@ h3.mb-3 Appearance
.alert.alert-info.d-flex.align-items-center(*ngIf='config.store.terminal.ligatures && config.store.terminal.frontend == "xterm-webgl"') Ligatures are not supported by the WebGL frontend .alert.alert-info.d-flex.align-items-center(*ngIf='config.store.terminal.ligatures && config.store.terminal.frontend == "xterm-webgl"') Ligatures are not supported by the WebGL frontend
color-scheme-preview([scheme]='config.store.terminal.colorScheme', [fontPreview]='true') .col-12.col-md-6
color-scheme-preview([scheme]='config.store.terminal.colorScheme', [fontPreview]='true')
.form-line .form-line
.header .header

View File

@@ -62,6 +62,12 @@
placeholder='#000000' placeholder='#000000'
) )
.form-line
.header
.title Disable dynamic tab title
.description Connection name will be used as a title instead
toggle([(ngModel)]='profile.disableDynamicTitle')
.modal-footer .modal-footer
button.btn.btn-outline-primary((click)='save()') Save button.btn.btn-outline-primary((click)='save()') Save
button.btn.btn-outline-danger((click)='cancel()') Cancel button.btn.btn-outline-danger((click)='cancel()') Cancel

View File

@@ -10,7 +10,7 @@ import { Subject } from 'rxjs'
}) })
export class EnvironmentEditorComponent { export class EnvironmentEditorComponent {
@Output() modelChange = new Subject<any>() @Output() modelChange = new Subject<any>()
vars: {key: string, value: string}[] = [] vars: { key: string, value: string }[] = []
private cachedModel: any private cachedModel: any
@Input() get model (): any { @Input() get model (): any {

View File

@@ -1,7 +1,6 @@
import { Component, Input, Output, EventEmitter } from '@angular/core' import { Component, Input, Output, EventEmitter } from '@angular/core'
import { ToastrService } from 'ngx-toastr'
import { Frontend, SearchOptions } from '../frontends/frontend' import { Frontend, SearchOptions } from '../frontends/frontend'
import { ConfigService } from 'terminus-core' import { ConfigService, NotificationsService } from 'terminus-core'
@Component({ @Component({
selector: 'search-panel', selector: 'search-panel',
@@ -20,7 +19,7 @@ export class SearchPanelComponent {
@Output() close = new EventEmitter() @Output() close = new EventEmitter()
constructor ( constructor (
private toastr: ToastrService, private notifications: NotificationsService,
public config: ConfigService, public config: ConfigService,
) { } ) { }
@@ -35,7 +34,7 @@ export class SearchPanelComponent {
} }
if (!this.frontend.findNext(this.query, { ...this.options, incremental: incremental || undefined })) { if (!this.frontend.findNext(this.query, { ...this.options, incremental: incremental || undefined })) {
this.notFound = true this.notFound = true
this.toastr.error('Not found') this.notifications.notice('Not found')
} }
} }
@@ -45,7 +44,7 @@ export class SearchPanelComponent {
} }
if (!this.frontend.findPrevious(this.query, { ...this.options, incremental: incremental || undefined })) { if (!this.frontend.findPrevious(this.query, { ...this.options, incremental: incremental || undefined })) {
this.notFound = true this.notFound = true
this.toastr.error('Not found') this.notifications.notice('Not found')
} }
} }

View File

@@ -57,15 +57,14 @@ h3.mb-3 Shell
.form-line .form-line
.header .header
.title Always Use Working Directory .title Directory for new tabs
.description
div By default, new terminals will open where the previous terminal was working.
div Enabling this option will always launch new terminals in the working directory specified above.
toggle( select.form-control(
[(ngModel)]='config.store.terminal.alwaysUseWorkingDirectory', [(ngModel)]='config.store.terminal.alwaysUseWorkingDirectory',
(ngModelChange)='config.save()' (ngModelChange)='config.save()',
) )
option([ngValue]='false') Same as active tab's directory
option([ngValue]='true') The working directory from above
.form-line.align-items-start .form-line.align-items-start
.header .header
@@ -97,7 +96,7 @@ h3.mt-3 Saved Profiles
button.btn.btn-outline-danger.ml-1((click)='$event.stopPropagation(); deleteProfile(profile)') button.btn.btn-outline-danger.ml-1((click)='$event.stopPropagation(); deleteProfile(profile)')
i.fas.fa-trash i.fas.fa-trash
div(ngbDropdown, placement='top-left') .pb-4(ngbDropdown, placement='top-left')
button.btn.btn-primary(ngbDropdownToggle) button.btn.btn-primary(ngbDropdownToggle)
i.fas.fa-fw.fa-plus i.fas.fa-fw.fa-plus
| New profile | New profile

View File

@@ -74,6 +74,7 @@ export class TerminalConfigProvider extends ConfigProvider {
wholeWord: false, wholeWord: false,
caseSensitive: false, caseSensitive: false,
}, },
detectProgress: true,
}, },
} }

View File

@@ -2,12 +2,11 @@ import * as psNode from 'ps-node'
import * as fs from 'mz/fs' import * as fs from 'mz/fs'
import * as os from 'os' import * as os from 'os'
import * as nodePTY from '@terminus-term/node-pty' import * as nodePTY from '@terminus-term/node-pty'
import { getWorkingDirectoryFromPID } from 'native-process-working-directory'
import { Observable, Subject } from 'rxjs' import { Observable, Subject } from 'rxjs'
import { first } from 'rxjs/operators' import { first } from 'rxjs/operators'
import { Injectable } from '@angular/core' import { Injectable } from '@angular/core'
import { Logger, LogService, ConfigService, WIN_BUILD_CONPTY_SUPPORTED, isWindowsBuild } from 'terminus-core' import { Logger, LogService, ConfigService, WIN_BUILD_CONPTY_SUPPORTED, isWindowsBuild } from 'terminus-core'
import { exec } from 'mz/child_process'
import { SessionOptions } from '../api/interfaces' import { SessionOptions } from '../api/interfaces'
/* eslint-disable block-scoped-var */ /* eslint-disable block-scoped-var */
@@ -20,7 +19,6 @@ try {
var windowsProcessTree = require('windows-process-tree') // eslint-disable-line @typescript-eslint/no-var-requires, no-var var windowsProcessTree = require('windows-process-tree') // eslint-disable-line @typescript-eslint/no-var-requires, no-var
} catch { } } catch { }
export interface ChildProcess { export interface ChildProcess {
pid: number pid: number
ppid: number ppid: number
@@ -28,7 +26,6 @@ export interface ChildProcess {
} }
const windowsDirectoryRegex = /([a-zA-Z]:[^\:\[\]\?\"\<\>\|]+)/mi const windowsDirectoryRegex = /([a-zA-Z]:[^\:\[\]\?\"\<\>\|]+)/mi
const catalinaDataVolumePrefix = '/System/Volumes/Data'
const OSC1337Prefix = Buffer.from('\x1b]1337;') const OSC1337Prefix = Buffer.from('\x1b]1337;')
const OSC1337Suffix = Buffer.from('\x07') const OSC1337Suffix = Buffer.from('\x07')
@@ -97,6 +94,7 @@ export class Session extends BaseSession {
private pauseAfterExit = false private pauseAfterExit = false
private guessedCWD: string|null = null private guessedCWD: string|null = null
private reportedCWD: string private reportedCWD: string
private initialCWD: string|null = null
constructor (private config: ConfigService) { constructor (private config: ConfigService) {
super() super()
@@ -154,6 +152,7 @@ export class Session extends BaseSession {
this.truePID = processes[0].pid this.truePID = processes[0].pid
processes = await this.getChildProcesses() processes = await this.getChildProcesses()
} }
this.initialCWD = await this.getWorkingDirectory()
}, 2000) }, 2000)
this.open = true this.open = true
@@ -261,13 +260,7 @@ export class Session extends BaseSession {
} }
supportsWorkingDirectory (): boolean { supportsWorkingDirectory (): boolean {
if (this.reportedCWD || this.guessedCWD) { return !!(this.truePID || this.reportedCWD || this.guessedCWD)
return true
}
if (!this.truePID) {
return false
}
return process.platform !== 'win32'
} }
async getWorkingDirectory (): Promise<string|null> { async getWorkingDirectory (): Promise<string|null> {
@@ -277,40 +270,31 @@ export class Session extends BaseSession {
if (!this.truePID) { if (!this.truePID) {
return null return null
} }
if (process.platform === 'darwin') { let cwd: string|null = null
let lines: string[] = [] try {
try { cwd = getWorkingDirectoryFromPID(this.truePID)
lines = (await exec(`lsof -p ${this.truePID} -Fn`))[0].toString().split('\n') } catch (exc) {
} catch (e) { console.error(exc)
return null
}
let cwd = lines[lines[1] === 'fcwd' ? 2 : 1].substring(1)
if (cwd.startsWith(catalinaDataVolumePrefix)) {
cwd = cwd.substring(catalinaDataVolumePrefix.length)
}
return cwd
} }
if (process.platform === 'linux') {
try { try {
const cwd = await fs.readlink(`/proc/${this.truePID}/cwd`) cwd = await fs.realpath(cwd)
return cwd } catch {}
} catch (exc) {
console.error(exc) if (process.platform === 'win32' && (cwd === this.initialCWD || cwd === process.env.WINDIR)) {
return null // shell doesn't truly change its process' CWD
} cwd = null
} }
if (process.platform === 'win32') {
if (!this.guessedCWD) { // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
return null cwd = cwd || this.guessedCWD
}
try { try {
await fs.access(this.guessedCWD) await fs.access(cwd)
} catch (e) { } catch {
return null return null
}
return this.guessedCWD
} }
return null return cwd
} }
private guessWindowsCWD (data: string) { private guessWindowsCWD (data: string) {

View File

@@ -104,6 +104,10 @@ export class TerminalService {
if (profile.color) { if (profile.color) {
(this.app.getParentTab(tab) ?? tab).color = profile.color (this.app.getParentTab(tab) ?? tab).color = profile.color
} }
if (profile.disableDynamicTitle) {
tab.enableDynamicTitle = false
tab.setTitle(profile.name)
}
return tab return tab
} }

View File

@@ -16,7 +16,7 @@ export class TerminalFrontendService {
private hotkeys: HotkeysService, private hotkeys: HotkeysService,
) { } ) { }
getFrontend (session?: BaseSession): Frontend { getFrontend (session?: BaseSession|null): Frontend {
if (!session) { if (!session) {
const frontend: Frontend = new { const frontend: Frontend = new {
xterm: XTermFrontend, xterm: XTermFrontend,

View File

@@ -8,6 +8,8 @@ import { Shell } from '../api/interfaces'
/** @hidden */ /** @hidden */
@Injectable() @Injectable()
export class MacOSDefaultShellProvider extends ShellProvider { export class MacOSDefaultShellProvider extends ShellProvider {
private cachedShell?: string
constructor ( constructor (
private hostApp: HostAppService, private hostApp: HostAppService,
) { ) {
@@ -18,14 +20,25 @@ export class MacOSDefaultShellProvider extends ShellProvider {
if (this.hostApp.platform !== Platform.macOS) { if (this.hostApp.platform !== Platform.macOS) {
return [] return []
} }
const shellEntry = (await exec(`/usr/bin/dscl . -read /Users/${process.env.LOGNAME} UserShell`))[0].toString()
return [{ return [{
id: 'default', id: 'default',
name: 'User default', name: 'User default',
command: shellEntry.split(' ')[1].trim(), command: await this.getDefaultShellCached(),
args: ['--login'], args: ['--login'],
hidden: true, hidden: true,
env: {}, env: {},
}] }]
} }
private async getDefaultShellCached () {
if (!this.cachedShell) {
this.cachedShell = await this.getDefaultShell()
}
return this.cachedShell!
}
private async getDefaultShell () {
const shellEntry = (await exec(`/usr/bin/dscl . -read /Users/${process.env.LOGNAME} UserShell`))[0].toString()
return shellEntry.split(' ')[1].trim()
}
} }

Some files were not shown because too many files have changed in this diff Show More