mirror of
https://github.com/Eugeny/tabby.git
synced 2025-08-05 17:01:57 +00:00
Compare commits
446 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
448a1a094f | ||
![]() |
788dd61a13 | ||
![]() |
467684d9ab | ||
![]() |
5069070040 | ||
![]() |
ecf5297bc3 | ||
![]() |
78bd90ac55 | ||
![]() |
712589eb93 | ||
![]() |
f103e71285 | ||
![]() |
0cf883cc4a | ||
![]() |
2b0ad0d558 | ||
![]() |
67bacb9dd3 | ||
![]() |
d0a597634d | ||
![]() |
322014c409 | ||
![]() |
c751a8725b | ||
![]() |
5417efe558 | ||
![]() |
bf356fcd19 | ||
![]() |
10ee66b9dd | ||
![]() |
763da0d80c | ||
![]() |
8d46bb2181 | ||
![]() |
fe936c7726 | ||
![]() |
2f3e32990a | ||
![]() |
22344f8d54 | ||
![]() |
f6d37a39f4 | ||
![]() |
0e4c60ad4b | ||
![]() |
e8c2171d8f | ||
![]() |
f7a5be2c67 | ||
![]() |
39fa0424a6 | ||
![]() |
bcb1b6a13b | ||
![]() |
a19f35ac44 | ||
![]() |
ea92f1a700 | ||
![]() |
b5701cf9f9 | ||
![]() |
4742530cf3 | ||
![]() |
a8d78ce185 | ||
![]() |
bba1eaccbe | ||
![]() |
cd6d05aa69 | ||
![]() |
412403c72a | ||
![]() |
93ae907dd1 | ||
![]() |
ce24b9cc52 | ||
![]() |
dc68372d76 | ||
![]() |
e0fe125cf2 | ||
![]() |
e594fcd0e7 | ||
![]() |
0219da4d85 | ||
![]() |
5e06b2248b | ||
![]() |
cdc3623986 | ||
![]() |
6d016002c0 | ||
![]() |
f3569f5d2d | ||
![]() |
4125582ef2 | ||
![]() |
c6331c9b1c | ||
![]() |
aaab475e5f | ||
![]() |
e6bf76c616 | ||
![]() |
e36bad2553 | ||
![]() |
154cc29333 | ||
![]() |
1b0402c2cf | ||
![]() |
15073cbc81 | ||
![]() |
3365b143d8 | ||
![]() |
4d9cc91e91 | ||
![]() |
946f4292ef | ||
![]() |
eb12b1ae60 | ||
![]() |
4765c97d31 | ||
![]() |
3fb32e1a97 | ||
![]() |
9ec1a0d253 | ||
![]() |
fef19615bb | ||
![]() |
4d237baf33 | ||
![]() |
03e654b5a0 | ||
![]() |
ef815eaa40 | ||
![]() |
4771a38747 | ||
![]() |
ce016793d4 | ||
![]() |
3a854f04e1 | ||
![]() |
b5658d61d9 | ||
![]() |
02750d8581 | ||
![]() |
077a3e6bba | ||
![]() |
5454be032a | ||
![]() |
8a0b4f82db | ||
![]() |
74fd1aeea5 | ||
![]() |
aac230e362 | ||
![]() |
ae82ed4a47 | ||
![]() |
9d1b0e9861 | ||
![]() |
8cb4e9f27d | ||
![]() |
c8c00a2c9b | ||
![]() |
bacb475896 | ||
![]() |
c8faa67083 | ||
![]() |
b6c0e3cdfb | ||
![]() |
323581d513 | ||
![]() |
bc7a537c4c | ||
![]() |
10ae6ffd99 | ||
![]() |
847628fbff | ||
![]() |
b502c3e84d | ||
![]() |
85e99ff0a8 | ||
![]() |
21b81f476c | ||
![]() |
02de15a6d2 | ||
![]() |
38a6e7fe67 | ||
![]() |
2283a5dad9 | ||
![]() |
e98c12d409 | ||
![]() |
aacc603309 | ||
![]() |
2ef3a81dd8 | ||
![]() |
22ef1bbb87 | ||
![]() |
7ff9f268c9 | ||
![]() |
7866bcd9a4 | ||
![]() |
5a20ac19d9 | ||
![]() |
915f6acf22 | ||
![]() |
59b73fcdc1 | ||
![]() |
8699634492 | ||
![]() |
d625e90464 | ||
![]() |
bc31c775e9 | ||
![]() |
49424e8da5 | ||
![]() |
2526c4e458 | ||
![]() |
24de3ba77c | ||
![]() |
157ed82000 | ||
![]() |
8275a9449a | ||
![]() |
6ed6b90840 | ||
![]() |
d7565e497d | ||
![]() |
de827ef61a | ||
![]() |
7b4e99fc5f | ||
![]() |
035a6f8da8 | ||
![]() |
bcdbab43de | ||
![]() |
a24f52c58a | ||
![]() |
0e745ea607 | ||
![]() |
8fe9232d9b | ||
![]() |
e6004fa980 | ||
![]() |
987b89b914 | ||
![]() |
9fddfa6fc2 | ||
![]() |
6d765bb1b8 | ||
![]() |
0ca971a289 | ||
![]() |
e87f6e7af0 | ||
![]() |
56be0a1085 | ||
![]() |
41f464d21d | ||
![]() |
c8dde73158 | ||
![]() |
0971a85db4 | ||
![]() |
51d54a8477 | ||
![]() |
b75775283f | ||
![]() |
66558290a0 | ||
![]() |
a1980afd9d | ||
![]() |
2b28802ce7 | ||
![]() |
0514a7c229 | ||
![]() |
326901b7e8 | ||
![]() |
bbe6b61d63 | ||
![]() |
204c1057db | ||
![]() |
dff6a2470c | ||
![]() |
cbebc09504 | ||
![]() |
f56dd71f43 | ||
![]() |
17f52a257e | ||
![]() |
8d09ddb686 | ||
![]() |
e6fd31e0b0 | ||
![]() |
c6188a49f5 | ||
![]() |
9a60b4d102 | ||
![]() |
7977c1d644 | ||
![]() |
ac85a1d7d3 | ||
![]() |
86b503093c | ||
![]() |
dd3e7a0f89 | ||
![]() |
8905106b48 | ||
![]() |
225760a9a5 | ||
![]() |
4aa79a76ea | ||
![]() |
1e2d6c7e75 | ||
![]() |
f1e79e9ada | ||
![]() |
37cc37650e | ||
![]() |
d607b7423a | ||
![]() |
a2e843ec84 | ||
![]() |
17cafbfa52 | ||
![]() |
91333abc4f | ||
![]() |
05b2b11af5 | ||
![]() |
3931e8088e | ||
![]() |
299ede2eb1 | ||
![]() |
4fed323a2a | ||
![]() |
b4bf8ec250 | ||
![]() |
780657ce1d | ||
![]() |
2d558563e4 | ||
![]() |
bc5e6e9535 | ||
![]() |
0c15fc2657 | ||
![]() |
5e115c63f1 | ||
![]() |
2bcf23cff1 | ||
![]() |
2c59022b78 | ||
![]() |
358d9f30d2 | ||
![]() |
afd6ce4346 | ||
![]() |
5c7256ffe5 | ||
![]() |
a15e79ad5a | ||
![]() |
f1ecbd1a93 | ||
![]() |
7da941d038 | ||
![]() |
3efc142630 | ||
![]() |
d592469237 | ||
![]() |
b3e63620b3 | ||
![]() |
22b79510ea | ||
![]() |
70cf63f8fa | ||
![]() |
c9067cf8b8 | ||
![]() |
4ccc406768 | ||
![]() |
1c25747de0 | ||
![]() |
8e4c36ec24 | ||
![]() |
444d92d393 | ||
![]() |
2597702676 | ||
![]() |
c9d75d81e4 | ||
![]() |
98eb68c845 | ||
![]() |
5185e1fe1d | ||
![]() |
5bde116a4e | ||
![]() |
179acc1382 | ||
![]() |
c6d918e401 | ||
![]() |
62b53575ac | ||
![]() |
32b29a91e9 | ||
![]() |
4346030459 | ||
![]() |
9e8c0ccb14 | ||
![]() |
6c8d00eb16 | ||
![]() |
b3fcfd0c8b | ||
![]() |
4eefab5655 | ||
![]() |
2745896ec3 | ||
![]() |
cdfaaabb70 | ||
![]() |
60ab6ece62 | ||
![]() |
436318b534 | ||
![]() |
248f431437 | ||
![]() |
7794280115 | ||
![]() |
c2cc4c977f | ||
![]() |
f9b7f97863 | ||
![]() |
59ce7eeee6 | ||
![]() |
0e012a90ea | ||
![]() |
6773d260cf | ||
![]() |
7379f6cd59 | ||
![]() |
3aee24bdbd | ||
![]() |
84dbfa5d6c | ||
![]() |
43958d88b8 | ||
![]() |
f4b0e4cb52 | ||
![]() |
d91c898f6d | ||
![]() |
f16989a45d | ||
![]() |
1ef524e832 | ||
![]() |
65fcdd2745 | ||
![]() |
7030f562e8 | ||
![]() |
047b31dd67 | ||
![]() |
ae0d33f026 | ||
![]() |
039a0b7eb5 | ||
![]() |
3d3fcc41b8 | ||
![]() |
3e3e8f3132 | ||
![]() |
da21895e40 | ||
![]() |
34752ed69e | ||
![]() |
008eb98f50 | ||
![]() |
e521cd4648 | ||
![]() |
cb97a784da | ||
![]() |
96d9d81be2 | ||
![]() |
71797eb93f | ||
![]() |
ae3870e297 | ||
![]() |
055de5013c | ||
![]() |
ad1ea01976 | ||
![]() |
064fbfac67 | ||
![]() |
a31c83476d | ||
![]() |
bc9f4c267e | ||
![]() |
3e92ae278e | ||
![]() |
6adc3543a8 | ||
![]() |
af5293948c | ||
![]() |
34620db925 | ||
![]() |
4a5a96ea16 | ||
![]() |
fcc9d7cf7d | ||
![]() |
9cae50bfc5 | ||
![]() |
3cff5909bd | ||
![]() |
0130cd9d54 | ||
![]() |
926d4f51b3 | ||
![]() |
efe390f68d | ||
![]() |
6d0b2608a2 | ||
![]() |
ddd306dbf6 | ||
![]() |
30c632a5cc | ||
![]() |
65b3254b77 | ||
![]() |
f776a30c9f | ||
![]() |
c02525440c | ||
![]() |
dbda8dad34 | ||
![]() |
bc44f55989 | ||
![]() |
a3c998adab | ||
![]() |
b62b59f9b8 | ||
![]() |
bb1557b0a4 | ||
![]() |
d0fe64355b | ||
![]() |
7b4e6e8f3a | ||
![]() |
bd11c90846 | ||
![]() |
21f33618d4 | ||
![]() |
11c8ca6582 | ||
![]() |
6e9ac1b59a | ||
![]() |
91591a81ff | ||
![]() |
1ce0ff2e00 | ||
![]() |
92cef766f6 | ||
![]() |
d1d55d39b1 | ||
![]() |
4ad55bff6e | ||
![]() |
f73c41a709 | ||
![]() |
3ca55d972a | ||
![]() |
2b25c25337 | ||
![]() |
3621877f32 | ||
![]() |
cf2a8ddc96 | ||
![]() |
d461515881 | ||
![]() |
5828571a95 | ||
![]() |
3aba7c9b93 | ||
![]() |
d371bf2f41 | ||
![]() |
51934dccbd | ||
![]() |
b6caf47ce6 | ||
![]() |
e8362268bb | ||
![]() |
88c57a6794 | ||
![]() |
69a0b46a20 | ||
![]() |
a5a662c05d | ||
![]() |
4ab0b51d87 | ||
![]() |
c3285b24d9 | ||
![]() |
313345da3d | ||
![]() |
7173be8c22 | ||
![]() |
b97ef8c643 | ||
![]() |
d221f8e561 | ||
![]() |
95ed0a58b9 | ||
![]() |
77d4176b55 | ||
![]() |
48013e2102 | ||
![]() |
31dcb2b514 | ||
![]() |
43a9a7cb19 | ||
![]() |
88cecba2b6 | ||
![]() |
91e1870f91 | ||
![]() |
705050a96a | ||
![]() |
8d2550fb99 | ||
![]() |
c4a89d4ee3 | ||
![]() |
6140cdfabc | ||
![]() |
5786d61620 | ||
![]() |
32f6e16275 | ||
![]() |
668986fc08 | ||
![]() |
9190893ccf | ||
![]() |
546837ab55 | ||
![]() |
3825feae08 | ||
![]() |
fdeabae061 | ||
![]() |
8b307be92d | ||
![]() |
45516c4013 | ||
![]() |
5d8f7a4e34 | ||
![]() |
792c9279e2 | ||
![]() |
8825a8163e | ||
![]() |
7e42328c6f | ||
![]() |
2dd99d43ed | ||
![]() |
991b4fc965 | ||
![]() |
e9d7af5320 | ||
![]() |
bff23fe825 | ||
![]() |
79bd94ee6f | ||
![]() |
fdd833ef7c | ||
![]() |
c386504296 | ||
![]() |
9cc8649422 | ||
![]() |
625a9179c5 | ||
![]() |
66ed73f7c9 | ||
![]() |
95bd48d6c6 | ||
![]() |
328490a85e | ||
![]() |
d08413aeab | ||
![]() |
922f1fbade | ||
![]() |
cb96c8d470 | ||
![]() |
f3ebc43667 | ||
![]() |
e7696dcdf3 | ||
![]() |
4abf7d7738 | ||
![]() |
be206161d6 | ||
![]() |
dcd17f886e | ||
![]() |
2c94dea941 | ||
![]() |
7a2291f7db | ||
![]() |
af0d9142ed | ||
![]() |
6ba7d5b78f | ||
![]() |
bbf035d5fd | ||
![]() |
84bc4369cb | ||
![]() |
e01f77998c | ||
![]() |
08acd4df46 | ||
![]() |
2c9d968aa8 | ||
![]() |
19a3996861 | ||
![]() |
6d187e8117 | ||
![]() |
a7687a6fc2 | ||
![]() |
7cbec63039 | ||
![]() |
91320f1cd7 | ||
![]() |
5518ce5e0c | ||
![]() |
d59c52d7a5 | ||
![]() |
dd3a4cb289 | ||
![]() |
fc6ded4b1a | ||
![]() |
d4f61b3846 | ||
![]() |
ffad7b6ba7 | ||
![]() |
499f541328 | ||
![]() |
7c893a3c4b | ||
![]() |
1f5c55826b | ||
![]() |
197824004e | ||
![]() |
ee1d465bf6 | ||
![]() |
12bb070def | ||
![]() |
13ab29bcab | ||
![]() |
8cf0445b6d | ||
![]() |
90cc06c3fd | ||
![]() |
7d7b2cbcfd | ||
![]() |
3a76e0bb2e | ||
![]() |
9e2d070ed4 | ||
![]() |
f796718cae | ||
![]() |
a4c2ccdb93 | ||
![]() |
ccbaf1c2c2 | ||
![]() |
7ccd97eb49 | ||
![]() |
6b320e9cf3 | ||
![]() |
a6a5f2b132 | ||
![]() |
6fd7e97ef2 | ||
![]() |
fc821b5abd | ||
![]() |
f69a9b38fe | ||
![]() |
710b9d79ab | ||
![]() |
fddae662c8 | ||
![]() |
c3b3a3cea6 | ||
![]() |
2201cfe142 | ||
![]() |
a9ae3b2475 | ||
![]() |
3238706b25 | ||
![]() |
a5aec13b7f | ||
![]() |
454887ad21 | ||
![]() |
0ad585d647 | ||
![]() |
5aa3b889f5 | ||
![]() |
d371857fa8 | ||
![]() |
e116a42f8b | ||
![]() |
76acbc6c9f | ||
![]() |
572a6e24c4 | ||
![]() |
b3731a21ba | ||
![]() |
f58ba65d97 | ||
![]() |
45a99bb0cb | ||
![]() |
ab70be983a | ||
![]() |
cad1f96df7 | ||
![]() |
71866521f4 | ||
![]() |
56206d4fb8 | ||
![]() |
347681d199 | ||
![]() |
e6abdcf3e9 | ||
![]() |
dbae3b66cd | ||
![]() |
40ec457d20 | ||
![]() |
063caf3bcd | ||
![]() |
9325fd0977 | ||
![]() |
6231583590 | ||
![]() |
fce3a2c822 | ||
![]() |
73f45c9a24 | ||
![]() |
ca65f23c70 | ||
![]() |
f525398827 | ||
![]() |
cf2baa74a8 | ||
![]() |
fbd896d593 | ||
![]() |
f747107042 | ||
![]() |
760ad140cd | ||
![]() |
a0df434ed2 | ||
![]() |
0bcd5cfd8f | ||
![]() |
e0b71783c0 | ||
![]() |
45b76b2d3e | ||
![]() |
8228c99350 | ||
![]() |
c4dbd8180d | ||
![]() |
d3b1545a1e | ||
![]() |
57d7936239 | ||
![]() |
9e5315043d | ||
![]() |
89ba81f2e1 | ||
![]() |
1ee734cd18 | ||
![]() |
0bcfb6babf | ||
![]() |
fddd9e9db2 | ||
![]() |
2433fd1442 | ||
![]() |
437d832ac1 | ||
![]() |
c90aef1dfa | ||
![]() |
2d25f15041 | ||
![]() |
993d5bfd25 | ||
![]() |
4d8681b5ee | ||
![]() |
1384e26dd8 | ||
![]() |
809bf3360d | ||
![]() |
444875b82a | ||
![]() |
c261b64c8e | ||
![]() |
ab1b8a4500 | ||
![]() |
e65d5ba93b | ||
![]() |
6f8ba6b44b | ||
![]() |
aede1c47a2 | ||
![]() |
7b9ff043ad | ||
![]() |
d759104c76 | ||
![]() |
676bbba7a4 | ||
![]() |
b8d9f6442a |
@@ -262,6 +262,87 @@
|
|||||||
"contributions": [
|
"contributions": [
|
||||||
"code"
|
"code"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Goobles",
|
||||||
|
"name": "Gobius Dolhain",
|
||||||
|
"avatar_url": "https://avatars3.githubusercontent.com/u/8776771?v=4",
|
||||||
|
"profile": "https://github.com/Goobles",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "3l0w",
|
||||||
|
"name": "Gwilherm Folliot",
|
||||||
|
"avatar_url": "https://avatars2.githubusercontent.com/u/37798980?v=4",
|
||||||
|
"profile": "https://github.com/3l0w",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "dimitory",
|
||||||
|
"name": "Dmitry Pronin",
|
||||||
|
"avatar_url": "https://avatars0.githubusercontent.com/u/475955?v=4",
|
||||||
|
"profile": "https://github.com/Dimitory",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "JonathanBeverley",
|
||||||
|
"name": "Jonathan Beverley",
|
||||||
|
"avatar_url": "https://avatars1.githubusercontent.com/u/20328966?v=4",
|
||||||
|
"profile": "https://github.com/JonathanBeverley",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "zend",
|
||||||
|
"name": "Zenghai Liang",
|
||||||
|
"avatar_url": "https://avatars1.githubusercontent.com/u/25160?v=4",
|
||||||
|
"profile": "https://github.com/zend",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "matishadow",
|
||||||
|
"name": "Mateusz Tracz",
|
||||||
|
"avatar_url": "https://avatars0.githubusercontent.com/u/9083085?v=4",
|
||||||
|
"profile": "https://about.me/matishadow",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "pinpins",
|
||||||
|
"name": "pinpin",
|
||||||
|
"avatar_url": "https://avatars3.githubusercontent.com/u/36234677?v=4",
|
||||||
|
"profile": "https://zergpool.com",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "TakuroOnoda",
|
||||||
|
"name": "Takuro Onoda",
|
||||||
|
"avatar_url": "https://avatars0.githubusercontent.com/u/1407926?v=4",
|
||||||
|
"profile": "https://github.com/TakuroOnoda",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "frauhottelmann",
|
||||||
|
"name": "frauhottelmann",
|
||||||
|
"avatar_url": "https://avatars2.githubusercontent.com/u/902705?v=4",
|
||||||
|
"profile": "https://github.com/frauhottelmann",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"contributorsPerLine": 7,
|
"contributorsPerLine": 7,
|
||||||
|
@@ -29,7 +29,6 @@ rules:
|
|||||||
'@typescript-eslint/no-magic-numbers': off
|
'@typescript-eslint/no-magic-numbers': off
|
||||||
'@typescript-eslint/member-delimiter-style': off
|
'@typescript-eslint/member-delimiter-style': off
|
||||||
'@typescript-eslint/promise-function-async': off
|
'@typescript-eslint/promise-function-async': off
|
||||||
'@typescript-eslint/no-unnecessary-type-assertion': off
|
|
||||||
'@typescript-eslint/require-array-sort-compare': off
|
'@typescript-eslint/require-array-sort-compare': off
|
||||||
'@typescript-eslint/no-floating-promises': off
|
'@typescript-eslint/no-floating-promises': off
|
||||||
'@typescript-eslint/prefer-readonly': off
|
'@typescript-eslint/prefer-readonly': off
|
||||||
@@ -37,6 +36,7 @@ rules:
|
|||||||
'@typescript-eslint/strict-boolean-expressions': off
|
'@typescript-eslint/strict-boolean-expressions': off
|
||||||
'@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/no-use-before-define':
|
'@typescript-eslint/no-use-before-define':
|
||||||
- error
|
- error
|
||||||
- classes: false
|
- classes: false
|
||||||
@@ -53,7 +53,8 @@ rules:
|
|||||||
computed-property-spacing:
|
computed-property-spacing:
|
||||||
- error
|
- error
|
||||||
- never
|
- never
|
||||||
comma-dangle:
|
comma-dangle: off
|
||||||
|
'@typescript-eslint/comma-dangle':
|
||||||
- error
|
- error
|
||||||
- always-multiline
|
- always-multiline
|
||||||
curly: error
|
curly: error
|
||||||
@@ -93,14 +94,22 @@ rules:
|
|||||||
- error
|
- error
|
||||||
- single
|
- single
|
||||||
- allowTemplateLiterals: true
|
- allowTemplateLiterals: true
|
||||||
|
'@typescript-eslint/no-confusing-void-expression': off
|
||||||
'@typescript-eslint/no-non-null-assertion': off
|
'@typescript-eslint/no-non-null-assertion': off
|
||||||
'@typescript-eslint/no-unnecessary-condition': off
|
'@typescript-eslint/no-unnecessary-condition':
|
||||||
'@typescript-eslint/no-untyped-public-signature': off # bugs out on constructors
|
- error
|
||||||
|
- allowConstantLoopConditions: true
|
||||||
'@typescript-eslint/restrict-template-expressions': off
|
'@typescript-eslint/restrict-template-expressions': off
|
||||||
'@typescript-eslint/no-dynamic-delete': off
|
|
||||||
'@typescript-eslint/prefer-nullish-coalescing': off
|
|
||||||
'@typescript-eslint/prefer-readonly-parameter-types': off
|
'@typescript-eslint/prefer-readonly-parameter-types': off
|
||||||
'@typescript-eslint/no-unsafe-member-access': off
|
'@typescript-eslint/no-unsafe-member-access': off
|
||||||
'@typescript-eslint/no-unsafe-call': off
|
'@typescript-eslint/no-unsafe-call': off
|
||||||
'@typescript-eslint/no-unsafe-return': off
|
'@typescript-eslint/no-unsafe-return': off
|
||||||
'@typescript-eslint/no-base-to-string': off # broken in typescript-eslint
|
'@typescript-eslint/no-unsafe-assignment': off
|
||||||
|
'@typescript-eslint/naming-convention': off
|
||||||
|
'@typescript-eslint/lines-between-class-members':
|
||||||
|
- error
|
||||||
|
- exceptAfterSingleLine: true
|
||||||
|
'@typescript-eslint/dot-notation': off
|
||||||
|
'@typescript-eslint/no-implicit-any-catch': off
|
||||||
|
'@typescript-eslint/member-ordering': off
|
||||||
|
'@typescript-eslint/no-var-requires': off
|
||||||
|
5
.github/workflows/lint.yml
vendored
5
.github/workflows/lint.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
|||||||
- name: Installing Node
|
- name: Installing Node
|
||||||
uses: actions/setup-node@v1
|
uses: actions/setup-node@v1
|
||||||
with:
|
with:
|
||||||
node-version: 10
|
node-version: 15
|
||||||
|
|
||||||
- name: Install deps
|
- name: Install deps
|
||||||
run: |
|
run: |
|
||||||
@@ -22,5 +22,8 @@ jobs:
|
|||||||
rm app/node_modules/.yarn-integrity
|
rm app/node_modules/.yarn-integrity
|
||||||
yarn
|
yarn
|
||||||
|
|
||||||
|
- name: Build typings
|
||||||
|
run: yarn run build:typings
|
||||||
|
|
||||||
- name: Lint
|
- name: Lint
|
||||||
run: yarn run lint
|
run: yarn run lint
|
||||||
|
12
.github/workflows/linux.yml
vendored
12
.github/workflows/linux.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
|||||||
- name: Install Node
|
- name: Install Node
|
||||||
uses: actions/setup-node@v1
|
uses: actions/setup-node@v1
|
||||||
with:
|
with:
|
||||||
node-version: 10
|
node-version: 15
|
||||||
|
|
||||||
- name: Install deps
|
- name: Install deps
|
||||||
run: |
|
run: |
|
||||||
@@ -36,6 +36,16 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
DEBUG: electron-builder,electron-builder:*
|
DEBUG: electron-builder,electron-builder:*
|
||||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||||
|
USE_HARD_LINKS: false
|
||||||
|
|
||||||
|
- name: Upload symbols
|
||||||
|
run: |
|
||||||
|
sudo npm install -g @sentry/cli --unsafe-perm
|
||||||
|
./scripts/sentry-upload.js
|
||||||
|
env:
|
||||||
|
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||||
|
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
|
||||||
|
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
|
||||||
|
|
||||||
- name: Package artifacts
|
- name: Package artifacts
|
||||||
run: |
|
run: |
|
||||||
|
43
.github/workflows/macos.yml
vendored
43
.github/workflows/macos.yml
vendored
@@ -2,7 +2,12 @@ name: macOS Build
|
|||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: macOS-latest
|
runs-on: macos-11.0
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- arch: x86_64
|
||||||
|
- arch: arm64
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@@ -11,40 +16,64 @@ jobs:
|
|||||||
- name: Installing Node
|
- name: Installing Node
|
||||||
uses: actions/setup-node@v1
|
uses: actions/setup-node@v1
|
||||||
with:
|
with:
|
||||||
node-version: 10
|
node-version: 15
|
||||||
|
|
||||||
- name: Install deps
|
- name: Install deps
|
||||||
run: |
|
run: |
|
||||||
sudo npm i -g yarn@1.19.1
|
sudo npm i -g yarn@1.22.1
|
||||||
cd app
|
cd app
|
||||||
yarn
|
yarn
|
||||||
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
|
||||||
|
env:
|
||||||
|
ARCH: ${{matrix.arch}}
|
||||||
|
|
||||||
- name: Webpack
|
- name: Webpack
|
||||||
run: yarn run build
|
run: yarn run build
|
||||||
|
|
||||||
- name: Prepackage plugins
|
- name: Prepackage plugins
|
||||||
run: scripts/prepackage-plugins.js
|
run: scripts/prepackage-plugins.js
|
||||||
|
env:
|
||||||
|
ARCH: ${{matrix.arch}}
|
||||||
|
|
||||||
|
- run: sed -i '' 's/updateInfo = await/\/\/updateInfo = await/g' node_modules/app-builder-lib/out/targets/ArchiveTarget.js
|
||||||
|
|
||||||
- name: Build and sign packages
|
- name: Build and sign packages
|
||||||
run: scripts/build-macos.js
|
run: scripts/build-macos.js
|
||||||
if: github.repository == 'Eugeny/terminus' && github.event_name == 'push'
|
if: github.repository == 'Eugeny/terminus' && github.event_name == 'push'
|
||||||
env:
|
env:
|
||||||
#DEBUG: electron-builder,electron-builder:*
|
ARCH: ${{matrix.arch}}
|
||||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||||
CSC_LINK: ${{ secrets.CSC_LINK }}
|
CSC_LINK: ${{ secrets.CSC_LINK }}
|
||||||
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
|
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
|
||||||
|
APPSTORE_USERNAME: ${{ secrets.APPSTORE_USERNAME }}
|
||||||
|
APPSTORE_PASSWORD: ${{ secrets.APPSTORE_PASSWORD }}
|
||||||
|
USE_HARD_LINKS: false
|
||||||
|
# DEBUG: electron-builder,electron-builder:*
|
||||||
|
|
||||||
- name: Build packages without signing
|
- name: Build packages without signing
|
||||||
run: scripts/build-macos.js
|
run: scripts/build-macos.js
|
||||||
if: github.repository != 'Eugeny/terminus' || github.event_name != 'push'
|
if: github.repository != 'Eugeny/terminus' || github.event_name != 'push'
|
||||||
env:
|
env:
|
||||||
DEBUG: electron-builder,electron-builder:*
|
ARCH: ${{matrix.arch}}
|
||||||
|
# DEBUG: electron-builder,electron-builder:*
|
||||||
|
|
||||||
|
- name: Upload symbols
|
||||||
|
run: |
|
||||||
|
sudo npm install -g @sentry/cli --unsafe-perm
|
||||||
|
./scripts/sentry-upload.js
|
||||||
|
env:
|
||||||
|
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||||
|
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
|
||||||
|
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
|
||||||
|
|
||||||
- name: Package artifacts
|
- name: Package artifacts
|
||||||
run: |
|
run: |
|
||||||
@@ -56,11 +85,11 @@ jobs:
|
|||||||
- uses: actions/upload-artifact@master
|
- uses: actions/upload-artifact@master
|
||||||
name: Upload PKG
|
name: Upload PKG
|
||||||
with:
|
with:
|
||||||
name: macOS .pkg
|
name: macOS .pkg (${{matrix.arch}})
|
||||||
path: artifact-pkg
|
path: artifact-pkg
|
||||||
|
|
||||||
- uses: actions/upload-artifact@master
|
- uses: actions/upload-artifact@master
|
||||||
name: Upload ZIP
|
name: Upload ZIP
|
||||||
with:
|
with:
|
||||||
name: macOS .zip
|
name: macOS .zip (${{matrix.arch}})
|
||||||
path: artifact-zip
|
path: artifact-zip
|
||||||
|
11
.github/workflows/windows.yml
vendored
11
.github/workflows/windows.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
|||||||
- name: Installing Node
|
- name: Installing Node
|
||||||
uses: actions/setup-node@v1
|
uses: actions/setup-node@v1
|
||||||
with:
|
with:
|
||||||
node-version: 10
|
node-version: 14
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
shell: powershell
|
shell: powershell
|
||||||
@@ -34,6 +34,15 @@ jobs:
|
|||||||
run: node scripts/build-windows.js
|
run: node scripts/build-windows.js
|
||||||
if: github.repository != 'Eugeny/terminus' || github.event_name != 'push'
|
if: github.repository != 'Eugeny/terminus' || github.event_name != 'push'
|
||||||
|
|
||||||
|
- name: Upload symbols
|
||||||
|
run: |
|
||||||
|
npm install @sentry/cli
|
||||||
|
node scripts/sentry-upload.js
|
||||||
|
env:
|
||||||
|
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||||
|
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
|
||||||
|
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
|
||||||
|
|
||||||
- name: Package artifacts
|
- name: Package artifacts
|
||||||
run: |
|
run: |
|
||||||
mkdir artifact-setup
|
mkdir artifact-setup
|
||||||
|
5
.gitignore
vendored
5
.gitignore
vendored
@@ -13,6 +13,9 @@ dist
|
|||||||
*.xcuserstate
|
*.xcuserstate
|
||||||
*.wixpdb
|
*.wixpdb
|
||||||
|
|
||||||
|
.DS_Store
|
||||||
|
.DS_Store?
|
||||||
|
|
||||||
coverage
|
coverage
|
||||||
.nyc_output
|
.nyc_output
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
@@ -28,3 +31,5 @@ docs/api
|
|||||||
.electron-symbols
|
.electron-symbols
|
||||||
sentry.properties
|
sentry.properties
|
||||||
sentry-symbols.js
|
sentry-symbols.js
|
||||||
|
|
||||||
|
terminus-ssh/util/pagent.exe
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
language: node_js
|
language: node_js
|
||||||
node_js: 11
|
node_js: 15
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- Build
|
- Build
|
||||||
|
76
README.md
76
README.md
@@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://raw.githubusercontent.com/Eugeny/terminus/master/LICENSE"><img alt="GitHub" src="https://img.shields.io/github/license/eugeny/terminus.svg?label=License&style=flat-square"></a> <a href="https://ci.appveyor.com/project/Eugeny/terminus"><img alt="AppVeyor" src="https://img.shields.io/appveyor/ci/eugeny/terminus.svg?label=CI&logo=appveyor&logoColor=white&style=flat-square"></a>
|
<a href="https://raw.githubusercontent.com/Eugeny/terminus/master/LICENSE"><img alt="GitHub" src="https://img.shields.io/github/license/eugeny/terminus.svg?label=License&style=flat-square"></a> <a href="https://ci.appveyor.com/project/Eugeny/terminus"><img alt="AppVeyor" src="https://img.shields.io/appveyor/ci/eugeny/****terminus****.svg?label=CI&logo=appveyor&logoColor=white&style=flat-square"></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://github.com/Eugeny/terminus/releases/latest"><img alt="GitHub All Releases" src="https://img.shields.io/github/downloads/eugeny/terminus/total.svg?label=DOWNLOAD&logo=github&style=for-the-badge"></a> <a href="https://ci.appveyor.com/project/Eugeny/terminus/build/artifacts"><img src="https://img.shields.io/badge/download-nightly%20build-magenta.svg?logo=appveyor&style=for-the-badge"/></a> <a href="https://gitter.im/terminus-terminal/community"><img alt="Gitter" src="https://img.shields.io/gitter/room/terminus/community.svg?color=blue&logo=gitter&style=for-the-badge"></a>
|
<a href="https://github.com/Eugeny/terminus/releases/latest"><img alt="GitHub All Releases" src="https://img.shields.io/github/downloads/eugeny/terminus/total.svg?label=RELEASE&logo=github&style=for-the-badge"></a> <a href="https://nightly.link/Eugeny/terminus/workflows/windows/master"><img src="https://shields.io/badge/-Nightly-blue?logo=windows&style=for-the-badge"/></a> <a href="https://nightly.link/Eugeny/terminus/workflows/macos/master"><img src="https://shields.io/badge/-Nightly-black?logo=apple&style=for-the-badge"/></a> <a href="https://nightly.link/Eugeny/terminus/workflows/linux/master"><img src="https://shields.io/badge/-Nightly-orange?logo=linux&style=for-the-badge"/></a> <a href="https://gitter.im/terminus-terminal/community"><img alt="Gitter" src="https://img.shields.io/gitter/room/terminus/community.svg?color=magenta&logo=gitter&style=for-the-badge"></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
----
|
----
|
||||||
@@ -74,45 +74,59 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|||||||
<!-- markdownlint-disable -->
|
<!-- markdownlint-disable -->
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td align="center"><a href="http://www.russellmyers.com"><img src="https://avatars2.githubusercontent.com/u/184085?v=4" width="100px;" alt=""/><br /><sub><b>Russell Myers</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=mezner" title="Code">💻</a></td>
|
<td align="center"><a href="http://www.russellmyers.com"><img src="https://avatars2.githubusercontent.com/u/184085?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Russell Myers</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=mezner" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="http://www.morwire.com"><img src="https://avatars1.githubusercontent.com/u/3991658?v=4" width="100px;" alt=""/><br /><sub><b>Austin Warren</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=ehwarren" title="Code">💻</a></td>
|
<td align="center"><a href="http://www.morwire.com"><img src="https://avatars1.githubusercontent.com/u/3991658?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Austin Warren</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=ehwarren" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="https://github.com/Drachenkaetzchen"><img src="https://avatars1.githubusercontent.com/u/162974?v=4" width="100px;" alt=""/><br /><sub><b>Felicia Hummel</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=Drachenkaetzchen" title="Code">💻</a></td>
|
<td align="center"><a href="https://github.com/Drachenkaetzchen"><img src="https://avatars1.githubusercontent.com/u/162974?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Felicia Hummel</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=Drachenkaetzchen" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="https://github.com/mikemaccana"><img src="https://avatars2.githubusercontent.com/u/172594?v=4" width="100px;" alt=""/><br /><sub><b>Mike MacCana</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=mikemaccana" title="Tests">⚠️</a> <a href="#design-mikemaccana" title="Design">🎨</a></td>
|
<td align="center"><a href="https://github.com/mikemaccana"><img src="https://avatars2.githubusercontent.com/u/172594?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mike MacCana</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=mikemaccana" title="Tests">⚠️</a> <a href="#design-mikemaccana" title="Design">🎨</a></td>
|
||||||
<td align="center"><a href="https://github.com/yxuko"><img src="https://avatars1.githubusercontent.com/u/1786317?v=4" width="100px;" alt=""/><br /><sub><b>Yacine Kanzari</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=yxuko" title="Code">💻</a></td>
|
<td align="center"><a href="https://github.com/yxuko"><img src="https://avatars1.githubusercontent.com/u/1786317?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Yacine Kanzari</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=yxuko" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="https://github.com/BBJip"><img src="https://avatars2.githubusercontent.com/u/32908927?v=4" width="100px;" alt=""/><br /><sub><b>BBJip</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=BBJip" title="Code">💻</a></td>
|
<td align="center"><a href="https://github.com/BBJip"><img src="https://avatars2.githubusercontent.com/u/32908927?v=4?s=100" width="100px;" alt=""/><br /><sub><b>BBJip</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=BBJip" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="https://github.com/Futagirl"><img src="https://avatars2.githubusercontent.com/u/33533958?v=4" width="100px;" alt=""/><br /><sub><b>Futagirl</b></sub></a><br /><a href="#design-Futagirl" title="Design">🎨</a></td>
|
<td align="center"><a href="https://github.com/Futagirl"><img src="https://avatars2.githubusercontent.com/u/33533958?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Futagirl</b></sub></a><br /><a href="#design-Futagirl" title="Design">🎨</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td align="center"><a href="https://www.levrik.io"><img src="https://avatars3.githubusercontent.com/u/9491603?v=4" width="100px;" alt=""/><br /><sub><b>Levin Rickert</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=levrik" title="Code">💻</a></td>
|
<td align="center"><a href="https://www.levrik.io"><img src="https://avatars3.githubusercontent.com/u/9491603?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Levin Rickert</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=levrik" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="https://kwonoj.github.io"><img src="https://avatars2.githubusercontent.com/u/1210596?v=4" width="100px;" alt=""/><br /><sub><b>OJ Kwon</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=kwonoj" title="Code">💻</a></td>
|
<td align="center"><a href="https://kwonoj.github.io"><img src="https://avatars2.githubusercontent.com/u/1210596?v=4?s=100" width="100px;" alt=""/><br /><sub><b>OJ Kwon</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=kwonoj" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="https://github.com/Domain"><img src="https://avatars2.githubusercontent.com/u/903197?v=4" width="100px;" alt=""/><br /><sub><b>domain</b></sub></a><br /><a href="#plugin-Domain" title="Plugin/utility libraries">🔌</a> <a href="https://github.com/Eugeny/terminus/commits?author=Domain" title="Code">💻</a></td>
|
<td align="center"><a href="https://github.com/Domain"><img src="https://avatars2.githubusercontent.com/u/903197?v=4?s=100" width="100px;" alt=""/><br /><sub><b>domain</b></sub></a><br /><a href="#plugin-Domain" title="Plugin/utility libraries">🔌</a> <a href="https://github.com/Eugeny/terminus/commits?author=Domain" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="http://www.jbrumond.me"><img src="https://avatars1.githubusercontent.com/u/195127?v=4" width="100px;" alt=""/><br /><sub><b>James Brumond</b></sub></a><br /><a href="#plugin-kbjr" title="Plugin/utility libraries">🔌</a></td>
|
<td align="center"><a href="http://www.jbrumond.me"><img src="https://avatars1.githubusercontent.com/u/195127?v=4?s=100" width="100px;" alt=""/><br /><sub><b>James Brumond</b></sub></a><br /><a href="#plugin-kbjr" title="Plugin/utility libraries">🔌</a></td>
|
||||||
<td align="center"><a href="http://www.growingwiththeweb.com"><img src="https://avatars0.githubusercontent.com/u/2193314?v=4" width="100px;" alt=""/><br /><sub><b>Daniel Imms</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=Tyriar" title="Code">💻</a> <a href="#plugin-Tyriar" title="Plugin/utility libraries">🔌</a> <a href="https://github.com/Eugeny/terminus/commits?author=Tyriar" title="Tests">⚠️</a></td>
|
<td align="center"><a href="http://www.growingwiththeweb.com"><img src="https://avatars0.githubusercontent.com/u/2193314?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Daniel Imms</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=Tyriar" title="Code">💻</a> <a href="#plugin-Tyriar" title="Plugin/utility libraries">🔌</a> <a href="https://github.com/Eugeny/terminus/commits?author=Tyriar" title="Tests">⚠️</a></td>
|
||||||
<td align="center"><a href="https://github.com/baflo"><img src="https://avatars2.githubusercontent.com/u/834350?v=4" width="100px;" alt=""/><br /><sub><b>Florian Bachmann</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=baflo" title="Code">💻</a></td>
|
<td align="center"><a href="https://github.com/baflo"><img src="https://avatars2.githubusercontent.com/u/834350?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Florian Bachmann</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=baflo" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="http://michael-kuehnel.de"><img src="https://avatars2.githubusercontent.com/u/441011?v=4" width="100px;" alt=""/><br /><sub><b>Michael Kühnel</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=mischah" title="Code">💻</a> <a href="#design-mischah" title="Design">🎨</a></td>
|
<td align="center"><a href="http://michael-kuehnel.de"><img src="https://avatars2.githubusercontent.com/u/441011?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Michael Kühnel</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=mischah" title="Code">💻</a> <a href="#design-mischah" title="Design">🎨</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td align="center"><a href="https://github.com/NieLeben"><img src="https://avatars3.githubusercontent.com/u/47182955?v=4" width="100px;" alt=""/><br /><sub><b>Tilmann Meyer</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=NieLeben" title="Code">💻</a></td>
|
<td align="center"><a href="https://github.com/NieLeben"><img src="https://avatars3.githubusercontent.com/u/47182955?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tilmann Meyer</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=NieLeben" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="http://www.jubeat.net"><img src="https://avatars3.githubusercontent.com/u/11289158?v=4" width="100px;" alt=""/><br /><sub><b>PM Extra</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/issues?q=author%3APMExtra" title="Bug reports">🐛</a></td>
|
<td align="center"><a href="http://www.jubeat.net"><img src="https://avatars3.githubusercontent.com/u/11289158?v=4?s=100" width="100px;" alt=""/><br /><sub><b>PM Extra</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/issues?q=author%3APMExtra" title="Bug reports">🐛</a></td>
|
||||||
<td align="center"><a href="https://jjuhas.keybase.pub//"><img src="https://avatars1.githubusercontent.com/u/6438760?v=4" width="100px;" alt=""/><br /><sub><b>Jonathan</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=IgnusG" title="Code">💻</a></td>
|
<td align="center"><a href="https://jjuhas.keybase.pub//"><img src="https://avatars1.githubusercontent.com/u/6438760?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jonathan</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=IgnusG" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="https://hans-koch.me"><img src="https://avatars0.githubusercontent.com/u/1093709?v=4" width="100px;" alt=""/><br /><sub><b>Hans Koch</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=hammster" title="Code">💻</a></td>
|
<td align="center"><a href="https://hans-koch.me"><img src="https://avatars0.githubusercontent.com/u/1093709?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Hans Koch</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=hammster" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="http://thepuzzlemaker.info"><img src="https://avatars3.githubusercontent.com/u/12666617?v=4" width="100px;" alt=""/><br /><sub><b>Dak Smyth</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=ThePuzzlemaker" title="Code">💻</a></td>
|
<td align="center"><a href="http://thepuzzlemaker.info"><img src="https://avatars3.githubusercontent.com/u/12666617?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dak Smyth</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=ThePuzzlemaker" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="http://yfwz100.github.io"><img src="https://avatars2.githubusercontent.com/u/983211?v=4" width="100px;" alt=""/><br /><sub><b>Wang Zhi</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=yfwz100" title="Code">💻</a></td>
|
<td align="center"><a href="http://yfwz100.github.io"><img src="https://avatars2.githubusercontent.com/u/983211?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Wang Zhi</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=yfwz100" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="https://github.com/jack1142"><img src="https://avatars0.githubusercontent.com/u/6032823?v=4" width="100px;" alt=""/><br /><sub><b>jack1142</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=jack1142" title="Code">💻</a></td>
|
<td align="center"><a href="https://github.com/jack1142"><img src="https://avatars0.githubusercontent.com/u/6032823?v=4?s=100" width="100px;" alt=""/><br /><sub><b>jack1142</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=jack1142" title="Code">💻</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td align="center"><a href="https://github.com/hdougie"><img src="https://avatars1.githubusercontent.com/u/450799?v=4" width="100px;" alt=""/><br /><sub><b>Howie Douglas</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=hdougie" title="Code">💻</a></td>
|
<td align="center"><a href="https://github.com/hdougie"><img src="https://avatars1.githubusercontent.com/u/450799?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Howie Douglas</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=hdougie" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="https://chriskaczor.com"><img src="https://avatars2.githubusercontent.com/u/180906?v=4" width="100px;" alt=""/><br /><sub><b>Chris Kaczor</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=ckaczor" title="Code">💻</a></td>
|
<td align="center"><a href="https://chriskaczor.com"><img src="https://avatars2.githubusercontent.com/u/180906?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Chris Kaczor</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=ckaczor" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="https://www.boxmein.net"><img src="https://avatars1.githubusercontent.com/u/358714?v=4" width="100px;" alt=""/><br /><sub><b>Johannes Kadak</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=boxmein" title="Code">💻</a></td>
|
<td align="center"><a href="https://www.boxmein.net"><img src="https://avatars1.githubusercontent.com/u/358714?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Johannes Kadak</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=boxmein" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="https://github.com/LeSeulArtichaut"><img src="https://avatars1.githubusercontent.com/u/38361244?v=4" width="100px;" alt=""/><br /><sub><b>LeSeulArtichaut</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=LeSeulArtichaut" title="Code">💻</a></td>
|
<td align="center"><a href="https://github.com/LeSeulArtichaut"><img src="https://avatars1.githubusercontent.com/u/38361244?v=4?s=100" width="100px;" alt=""/><br /><sub><b>LeSeulArtichaut</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=LeSeulArtichaut" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="https://github.com/CyrilTaylor"><img src="https://avatars0.githubusercontent.com/u/12631466?v=4" width="100px;" alt=""/><br /><sub><b>Cyril Taylor</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=CyrilTaylor" title="Code">💻</a></td>
|
<td align="center"><a href="https://github.com/CyrilTaylor"><img src="https://avatars0.githubusercontent.com/u/12631466?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Cyril Taylor</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=CyrilTaylor" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="https://github.com/nstefanou"><img src="https://avatars3.githubusercontent.com/u/51129173?v=4" width="100px;" alt=""/><br /><sub><b>nstefanou</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=nstefanou" title="Code">💻</a> <a href="#plugin-nstefanou" title="Plugin/utility libraries">🔌</a></td>
|
<td align="center"><a href="https://github.com/nstefanou"><img src="https://avatars3.githubusercontent.com/u/51129173?v=4?s=100" width="100px;" alt=""/><br /><sub><b>nstefanou</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=nstefanou" title="Code">💻</a> <a href="#plugin-nstefanou" title="Plugin/utility libraries">🔌</a></td>
|
||||||
<td align="center"><a href="https://github.com/orin220444"><img src="https://avatars3.githubusercontent.com/u/30747229?v=4" width="100px;" alt=""/><br /><sub><b>orin220444</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=orin220444" title="Code">💻</a></td>
|
<td align="center"><a href="https://github.com/orin220444"><img src="https://avatars3.githubusercontent.com/u/30747229?v=4?s=100" width="100px;" alt=""/><br /><sub><b>orin220444</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=orin220444" title="Code">💻</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://github.com/Goobles"><img src="https://avatars3.githubusercontent.com/u/8776771?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Gobius Dolhain</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=Goobles" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/3l0w"><img src="https://avatars2.githubusercontent.com/u/37798980?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Gwilherm Folliot</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=3l0w" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/Dimitory"><img src="https://avatars0.githubusercontent.com/u/475955?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dmitry Pronin</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=dimitory" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/JonathanBeverley"><img src="https://avatars1.githubusercontent.com/u/20328966?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jonathan Beverley</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=JonathanBeverley" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/zend"><img src="https://avatars1.githubusercontent.com/u/25160?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Zenghai Liang</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=zend" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://about.me/matishadow"><img src="https://avatars0.githubusercontent.com/u/9083085?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mateusz Tracz</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=matishadow" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://zergpool.com"><img src="https://avatars3.githubusercontent.com/u/36234677?v=4?s=100" width="100px;" alt=""/><br /><sub><b>pinpin</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=pinpins" title="Code">💻</a></td>
|
||||||
|
</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/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>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<!-- markdownlint-enable -->
|
<!-- markdownlint-restore -->
|
||||||
<!-- prettier-ignore-end -->
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||||
|
|
||||||
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
import { app, ipcMain, Menu, Tray, shell, globalShortcut } from 'electron'
|
import { app, ipcMain, Menu, Tray, shell, screen, globalShortcut, MenuItemConstructorOptions } from 'electron'
|
||||||
// eslint-disable-next-line no-duplicate-imports
|
import * as promiseIpc from 'electron-promise-ipc'
|
||||||
import * as electron from 'electron'
|
|
||||||
import { loadConfig } from './config'
|
import { loadConfig } from './config'
|
||||||
import { Window, WindowOptions } from './window'
|
import { Window, WindowOptions } from './window'
|
||||||
|
import { pluginManager } from './pluginManager'
|
||||||
|
|
||||||
export class Application {
|
export class Application {
|
||||||
private tray: Tray
|
private tray?: Tray
|
||||||
private windows: Window[] = []
|
private windows: Window[] = []
|
||||||
|
|
||||||
constructor () {
|
constructor () {
|
||||||
@@ -15,13 +15,21 @@ export class Application {
|
|||||||
|
|
||||||
ipcMain.on('app:register-global-hotkey', (_event, specs) => {
|
ipcMain.on('app:register-global-hotkey', (_event, specs) => {
|
||||||
globalShortcut.unregisterAll()
|
globalShortcut.unregisterAll()
|
||||||
for (let spec of specs) {
|
for (const spec of specs) {
|
||||||
globalShortcut.register(spec, () => {
|
globalShortcut.register(spec, () => {
|
||||||
this.onGlobalHotkey()
|
this.onGlobalHotkey()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
;(promiseIpc as any).on('plugin-manager:install', (path, name, version) => {
|
||||||
|
return pluginManager.install(path, name, version)
|
||||||
|
})
|
||||||
|
|
||||||
|
;(promiseIpc as any).on('plugin-manager:uninstall', (path, name) => {
|
||||||
|
return pluginManager.uninstall(path, name)
|
||||||
|
})
|
||||||
|
|
||||||
const configData = loadConfig()
|
const configData = loadConfig()
|
||||||
if (process.platform === 'linux') {
|
if (process.platform === 'linux') {
|
||||||
app.commandLine.appendSwitch('no-sandbox')
|
app.commandLine.appendSwitch('no-sandbox')
|
||||||
@@ -41,11 +49,13 @@ export class Application {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init (): void {
|
init (): void {
|
||||||
electron.screen.on('display-metrics-changed', () => this.broadcast('host:display-metrics-changed'))
|
screen.on('display-metrics-changed', () => this.broadcast('host:display-metrics-changed'))
|
||||||
|
screen.on('display-added', () => this.broadcast('host:displays-changed'))
|
||||||
|
screen.on('display-removed', () => this.broadcast('host:displays-changed'))
|
||||||
}
|
}
|
||||||
|
|
||||||
async newWindow (options?: WindowOptions): Promise<Window> {
|
async newWindow (options?: WindowOptions): Promise<Window> {
|
||||||
let window = new Window(options)
|
const window = new Window(options)
|
||||||
this.windows.push(window)
|
this.windows.push(window)
|
||||||
window.visible$.subscribe(visible => {
|
window.visible$.subscribe(visible => {
|
||||||
if (visible) {
|
if (visible) {
|
||||||
@@ -65,30 +75,30 @@ export class Application {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onGlobalHotkey (): void {
|
onGlobalHotkey (): void {
|
||||||
if (this.windows.some(x => x.isFocused())) {
|
if (this.windows.some(x => x.isFocused() && x.isVisible())) {
|
||||||
for (let window of this.windows) {
|
for (const window of this.windows) {
|
||||||
window.hide()
|
window.hide()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (let window of this.windows) {
|
for (const window of this.windows) {
|
||||||
window.present()
|
window.present()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
presentAllWindows (): void {
|
presentAllWindows (): void {
|
||||||
for (let window of this.windows) {
|
for (const window of this.windows) {
|
||||||
window.present()
|
window.present()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
broadcast (event: string, ...args): void {
|
broadcast (event: string, ...args: any[]): void {
|
||||||
for (const window of this.windows) {
|
for (const window of this.windows) {
|
||||||
window.send(event, ...args)
|
window.send(event, ...args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async send (event: string, ...args): Promise<void> {
|
async send (event: string, ...args: any[]): Promise<void> {
|
||||||
if (!this.hasWindows()) {
|
if (!this.hasWindows()) {
|
||||||
await this.newWindow()
|
await this.newWindow()
|
||||||
}
|
}
|
||||||
@@ -121,10 +131,8 @@ export class Application {
|
|||||||
}
|
}
|
||||||
|
|
||||||
disableTray (): void {
|
disableTray (): void {
|
||||||
if (this.tray) {
|
this.tray?.destroy()
|
||||||
this.tray.destroy()
|
this.tray = null
|
||||||
this.tray = null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hasWindows (): boolean {
|
hasWindows (): boolean {
|
||||||
@@ -132,13 +140,18 @@ export class Application {
|
|||||||
}
|
}
|
||||||
|
|
||||||
focus (): void {
|
focus (): void {
|
||||||
for (let window of this.windows) {
|
for (const window of this.windows) {
|
||||||
window.show()
|
window.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleSecondInstance (argv: string[], cwd: string): void {
|
||||||
|
this.presentAllWindows()
|
||||||
|
this.windows[this.windows.length - 1].passCliArguments(argv, cwd, true)
|
||||||
|
}
|
||||||
|
|
||||||
private setupMenu () {
|
private setupMenu () {
|
||||||
let template: Electron.MenuItemConstructorOptions[] = [
|
const template: MenuItemConstructorOptions[] = [
|
||||||
{
|
{
|
||||||
label: 'Application',
|
label: 'Application',
|
||||||
submenu: [
|
submenu: [
|
||||||
|
@@ -5,7 +5,7 @@ export function parseArgs (argv: string[], cwd: string): any {
|
|||||||
argv = argv.slice(1)
|
argv = argv.slice(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
return require('yargs')
|
return require('yargs/yargs')(argv.slice(1))
|
||||||
.usage('terminus [command] [arguments]')
|
.usage('terminus [command] [arguments]')
|
||||||
.command('open [directory]', 'open a shell in a directory', {
|
.command('open [directory]', 'open a shell in a directory', {
|
||||||
directory: { type: 'string', 'default': cwd },
|
directory: { type: 'string', 'default': cwd },
|
||||||
@@ -41,5 +41,5 @@ export function parseArgs (argv: string[], cwd: string): any {
|
|||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
})
|
})
|
||||||
.help('help')
|
.help('help')
|
||||||
.parse(argv.slice(1))
|
.parse()
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,7 @@ import * as yaml from 'js-yaml'
|
|||||||
import { app } from 'electron'
|
import { app } from 'electron'
|
||||||
|
|
||||||
export function loadConfig (): any {
|
export function loadConfig (): any {
|
||||||
let 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.safeLoad(fs.readFileSync(configPath, 'utf8'))
|
||||||
} else {
|
} else {
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import './portable'
|
import './portable'
|
||||||
|
import 'source-map-support/register'
|
||||||
import './sentry'
|
import './sentry'
|
||||||
import './lru'
|
import './lru'
|
||||||
import { app, ipcMain, Menu } from 'electron'
|
import { app, ipcMain, Menu } from 'electron'
|
||||||
@@ -34,8 +35,7 @@ process.on('uncaughtException' as any, err => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
app.on('second-instance', (_event, argv, cwd) => {
|
app.on('second-instance', (_event, argv, cwd) => {
|
||||||
application.presentAllWindows()
|
application.handleSecondInstance(argv, cwd)
|
||||||
application.send('host:second-instance', parseArgs(argv, cwd), cwd)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const argv = parseArgs(process.argv, process.cwd())
|
const argv = parseArgs(process.argv, process.cwd())
|
||||||
@@ -53,7 +53,7 @@ if (argv.d) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
app.on('ready', () => {
|
app.on('ready', async () => {
|
||||||
if (process.platform === 'darwin') {
|
if (process.platform === 'darwin') {
|
||||||
app.dock.setMenu(Menu.buildFromTemplate([
|
app.dock.setMenu(Menu.buildFromTemplate([
|
||||||
{
|
{
|
||||||
@@ -65,5 +65,8 @@ app.on('ready', () => {
|
|||||||
]))
|
]))
|
||||||
}
|
}
|
||||||
application.init()
|
application.init()
|
||||||
application.newWindow({ hidden: argv.hidden })
|
|
||||||
|
const window = await application.newWindow({ hidden: argv.hidden })
|
||||||
|
await window.ready
|
||||||
|
window.passCliArguments(process.argv, process.cwd(), false)
|
||||||
})
|
})
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import * as createLRU from 'lru-cache'
|
import * as LRU from 'lru-cache'
|
||||||
import * as fs from 'fs'
|
import * as fs from 'fs'
|
||||||
const lru = createLRU({ max: 256, maxAge: 250 })
|
const lru = new LRU({ max: 256, maxAge: 250 })
|
||||||
const origLstat = fs.realpathSync.bind(fs)
|
const origLstat = fs.realpathSync.bind(fs)
|
||||||
|
|
||||||
// NB: The biggest offender of thrashing realpathSync is the node module system
|
// NB: The biggest offender of thrashing realpathSync is the node module system
|
||||||
|
40
app/lib/pluginManager.ts
Normal file
40
app/lib/pluginManager.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { promisify } from 'util'
|
||||||
|
|
||||||
|
|
||||||
|
export class PluginManager {
|
||||||
|
npm: any
|
||||||
|
npmReady?: Promise<void>
|
||||||
|
|
||||||
|
async ensureLoaded (): Promise<void> {
|
||||||
|
if (!this.npmReady) {
|
||||||
|
this.npmReady = new Promise(resolve => {
|
||||||
|
const npm = require('npm')
|
||||||
|
npm.load(err => {
|
||||||
|
if (err) {
|
||||||
|
console.error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
npm.config.set('global', false)
|
||||||
|
this.npm = npm
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return this.npmReady
|
||||||
|
}
|
||||||
|
|
||||||
|
async install (path: string, name: string, version: string): Promise<void> {
|
||||||
|
await this.ensureLoaded()
|
||||||
|
this.npm.prefix = path
|
||||||
|
return promisify(this.npm.commands.install)([`${name}@${version}`])
|
||||||
|
}
|
||||||
|
|
||||||
|
async uninstall (path: string, name: string): Promise<void> {
|
||||||
|
await this.ensureLoaded()
|
||||||
|
this.npm.prefix = path
|
||||||
|
return promisify(this.npm.commands.remove)([name])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const pluginManager = new PluginManager()
|
@@ -8,17 +8,15 @@ try {
|
|||||||
appPath = path.dirname(require('electron').remote.app.getPath('exe'))
|
appPath = path.dirname(require('electron').remote.app.getPath('exe'))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null != appPath) {
|
if (fs.existsSync(path.join(appPath, 'terminus-data'))) {
|
||||||
if(fs.existsSync(path.join(appPath, 'terminus-data'))) {
|
fs.renameSync(path.join(appPath, 'terminus-data'), path.join(appPath, 'data'))
|
||||||
fs.renameSync(path.join(appPath, 'terminus-data'), path.join(appPath, 'data'))
|
}
|
||||||
}
|
const portableData = path.join(appPath, 'data')
|
||||||
const portableData = path.join(appPath, 'data')
|
if (fs.existsSync(portableData)) {
|
||||||
if (fs.existsSync(portableData)) {
|
console.log('reset user data to ' + portableData)
|
||||||
console.log('reset user data to ' + portableData)
|
try {
|
||||||
try {
|
require('electron').app.setPath('userData', portableData)
|
||||||
require('electron').app.setPath('userData', portableData)
|
} catch {
|
||||||
} catch {
|
require('electron').remote.app.setPath('userData', portableData)
|
||||||
require('electron').remote.app.setPath('userData', portableData)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
const { init } = process.type === 'main' ? require('@sentry/electron/dist/main') : require('@sentry/electron/dist/renderer')
|
const { init } = String(process.type) === 'main' ? require('@sentry/electron/dist/main') : require('@sentry/electron/dist/renderer')
|
||||||
import * as isDev from 'electron-is-dev'
|
import * as isDev from 'electron-is-dev'
|
||||||
|
|
||||||
|
|
||||||
const SENTRY_DSN = 'https://4717a0a7ee0b4429bd3a0f06c3d7eec3@sentry.io/181876'
|
const SENTRY_DSN = 'https://4717a0a7ee0b4429bd3a0f06c3d7eec3@sentry.io/181876'
|
||||||
let release
|
let release = null
|
||||||
try {
|
try {
|
||||||
release = require('electron').app.getVersion()
|
release = require('electron').app.getVersion()
|
||||||
} catch {
|
} catch {
|
||||||
|
@@ -1,18 +1,19 @@
|
|||||||
|
import * as glasstron from 'glasstron'
|
||||||
|
|
||||||
import { Subject, Observable } from 'rxjs'
|
import { Subject, Observable } from 'rxjs'
|
||||||
import { debounceTime } from 'rxjs/operators'
|
import { debounceTime } from 'rxjs/operators'
|
||||||
import { BrowserWindow, app, ipcMain, Rectangle, Menu, screen } from 'electron'
|
import { BrowserWindow, app, ipcMain, Rectangle, Menu, screen, BrowserWindowConstructorOptions } from 'electron'
|
||||||
import ElectronConfig = require('electron-config')
|
import ElectronConfig = require('electron-config')
|
||||||
import * as os from 'os'
|
import * as os from 'os'
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
|
import macOSRelease from 'macos-release'
|
||||||
|
import * as compareVersions from 'compare-versions'
|
||||||
|
|
||||||
|
import { parseArgs } from './cli'
|
||||||
import { loadConfig } from './config'
|
import { loadConfig } from './config'
|
||||||
|
|
||||||
let SetWindowCompositionAttribute: any
|
let DwmEnableBlurBehindWindow: any = null
|
||||||
let AccentState: any
|
|
||||||
let DwmEnableBlurBehindWindow: any
|
|
||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32') {
|
||||||
SetWindowCompositionAttribute = require('windows-swca').SetWindowCompositionAttribute
|
|
||||||
AccentState = require('windows-swca').ACCENT_STATE
|
|
||||||
DwmEnableBlurBehindWindow = require('windows-blurbehind').DwmEnableBlurBehindWindow
|
DwmEnableBlurBehindWindow = require('windows-blurbehind').DwmEnableBlurBehindWindow
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,13 +21,20 @@ export interface WindowOptions {
|
|||||||
hidden?: boolean
|
hidden?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class GlasstronWindow extends BrowserWindow {
|
||||||
|
blurType: string
|
||||||
|
abstract setBlur (_: boolean)
|
||||||
|
}
|
||||||
|
|
||||||
|
const macOSVibrancyType = process.platform === 'darwin' ? compareVersions.compare(macOSRelease().version, '10.14', '>=') ? 'fullscreen-ui' : 'dark' : null
|
||||||
|
|
||||||
export class Window {
|
export class Window {
|
||||||
ready: Promise<void>
|
ready: Promise<void>
|
||||||
private visible = new Subject<boolean>()
|
private visible = new Subject<boolean>()
|
||||||
private closed = new Subject<void>()
|
private closed = new Subject<void>()
|
||||||
private window: BrowserWindow
|
private window?: GlasstronWindow
|
||||||
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
|
||||||
@@ -38,13 +46,13 @@ export class Window {
|
|||||||
constructor (options?: WindowOptions) {
|
constructor (options?: WindowOptions) {
|
||||||
this.configStore = loadConfig()
|
this.configStore = loadConfig()
|
||||||
|
|
||||||
options = options || {}
|
options = options ?? {}
|
||||||
|
|
||||||
this.windowConfig = new ElectronConfig({ name: 'window' })
|
this.windowConfig = new ElectronConfig({ name: 'window' })
|
||||||
this.windowBounds = this.windowConfig.get('windowBoundaries')
|
this.windowBounds = this.windowConfig.get('windowBoundaries')
|
||||||
|
|
||||||
let maximized = this.windowConfig.get('maximized')
|
const maximized = this.windowConfig.get('maximized')
|
||||||
let bwOptions: Electron.BrowserWindowConstructorOptions = {
|
const bwOptions: BrowserWindowConstructorOptions = {
|
||||||
width: 800,
|
width: 800,
|
||||||
height: 600,
|
height: 600,
|
||||||
title: 'Terminus',
|
title: 'Terminus',
|
||||||
@@ -54,7 +62,10 @@ export class Window {
|
|||||||
nodeIntegration: true,
|
nodeIntegration: true,
|
||||||
preload: path.join(__dirname, 'sentry.js'),
|
preload: path.join(__dirname, 'sentry.js'),
|
||||||
backgroundThrottling: false,
|
backgroundThrottling: false,
|
||||||
|
enableRemoteModule: true,
|
||||||
|
contextIsolation: false,
|
||||||
},
|
},
|
||||||
|
maximizable: true,
|
||||||
frame: false,
|
frame: false,
|
||||||
show: false,
|
show: false,
|
||||||
backgroundColor: '#00000000',
|
backgroundColor: '#00000000',
|
||||||
@@ -81,14 +92,15 @@ export class Window {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process.platform === 'linux') {
|
if (process.platform === 'darwin') {
|
||||||
bwOptions.backgroundColor = '#131d27'
|
this.window = new BrowserWindow(bwOptions) as GlasstronWindow
|
||||||
|
} else {
|
||||||
|
this.window = new glasstron.BrowserWindow(bwOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.window = new BrowserWindow(bwOptions)
|
|
||||||
this.window.once('ready-to-show', () => {
|
this.window.once('ready-to-show', () => {
|
||||||
if (process.platform === 'darwin') {
|
if (process.platform === 'darwin') {
|
||||||
this.window.setVibrancy('window')
|
this.window.setVibrancy(macOSVibrancyType)
|
||||||
} else if (process.platform === 'win32' && (this.configStore.appearance || {}).vibrancy) {
|
} else if (process.platform === 'win32' && (this.configStore.appearance || {}).vibrancy) {
|
||||||
this.setVibrancy(true)
|
this.setVibrancy(true)
|
||||||
}
|
}
|
||||||
@@ -100,6 +112,13 @@ export class Window {
|
|||||||
this.window.show()
|
this.window.show()
|
||||||
}
|
}
|
||||||
this.window.focus()
|
this.window.focus()
|
||||||
|
this.window.moveTop()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.window.on('blur', () => {
|
||||||
|
if (this.configStore.appearance?.dockHideOnBlur) {
|
||||||
|
this.hide()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -122,36 +141,39 @@ export class Window {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
setVibrancy (enabled: boolean, type?: string): void {
|
setVibrancy (enabled: boolean, type?: string, userRequested?: boolean): void {
|
||||||
this.lastVibrancy = { enabled, type }
|
if (userRequested ?? true) {
|
||||||
|
this.lastVibrancy = { enabled, type }
|
||||||
|
}
|
||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32') {
|
||||||
if (parseFloat(os.release()) >= 10) {
|
if (parseFloat(os.release()) >= 10) {
|
||||||
let attribValue = AccentState.ACCENT_DISABLED
|
this.window.blurType = enabled ? type === 'fluent' ? 'acrylic' : 'blurbehind' : null
|
||||||
if (enabled) {
|
try {
|
||||||
if (type === 'fluent') {
|
this.window.setBlur(enabled)
|
||||||
attribValue = AccentState.ACCENT_ENABLE_ACRYLICBLURBEHIND
|
} catch (error) {
|
||||||
} else {
|
console.error('Failed to set window blur', error)
|
||||||
attribValue = AccentState.ACCENT_ENABLE_BLURBEHIND
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
SetWindowCompositionAttribute(this.window.getNativeWindowHandle(), attribValue, 0x00000000)
|
|
||||||
} else {
|
} else {
|
||||||
DwmEnableBlurBehindWindow(this.window, enabled)
|
DwmEnableBlurBehindWindow(this.window, enabled)
|
||||||
}
|
}
|
||||||
|
} else if (process.platform === 'linux') {
|
||||||
|
this.window.setBackgroundColor(enabled ? '#00000000' : '#131d27')
|
||||||
|
this.window.setBlur(enabled)
|
||||||
} else {
|
} else {
|
||||||
this.window.setVibrancy(enabled ? 'dark' : null as any) // electron issue 20269
|
this.window.setVibrancy(enabled ? macOSVibrancyType : null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
show (): void {
|
show (): void {
|
||||||
this.window.show()
|
this.window.show()
|
||||||
|
this.window.moveTop()
|
||||||
}
|
}
|
||||||
|
|
||||||
focus (): void {
|
focus (): void {
|
||||||
this.window.focus()
|
this.window.focus()
|
||||||
}
|
}
|
||||||
|
|
||||||
send (event: string, ...args): void {
|
send (event: string, ...args: any[]): void {
|
||||||
if (!this.window) {
|
if (!this.window) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -169,6 +191,10 @@ export class Window {
|
|||||||
return this.window.isFocused()
|
return this.window.isFocused()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isVisible (): boolean {
|
||||||
|
return this.window.isVisible()
|
||||||
|
}
|
||||||
|
|
||||||
hide (): void {
|
hide (): void {
|
||||||
if (process.platform === 'darwin') {
|
if (process.platform === 'darwin') {
|
||||||
// Lose focus
|
// Lose focus
|
||||||
@@ -193,12 +219,21 @@ export class Window {
|
|||||||
this.window.focus()
|
this.window.focus()
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// docked, visible
|
if (this.configStore.appearance?.dockAlwaysOnTop) {
|
||||||
this.window.hide()
|
// docked, visible, on top
|
||||||
|
this.window.hide()
|
||||||
|
} else {
|
||||||
|
// docked, visible, not on top
|
||||||
|
this.window.focus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
passCliArguments (argv: string[], cwd: string, secondInstance: boolean): void {
|
||||||
|
this.send('cli', parseArgs(argv, cwd), cwd, secondInstance)
|
||||||
|
}
|
||||||
|
|
||||||
private setupWindowManagement () {
|
private setupWindowManagement () {
|
||||||
this.window.on('show', () => {
|
this.window.on('show', () => {
|
||||||
this.visible.next(true)
|
this.visible.next(true)
|
||||||
@@ -209,7 +244,7 @@ export class Window {
|
|||||||
this.visible.next(false)
|
this.visible.next(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
let moveSubscription = new Observable<void>(observer => {
|
const moveSubscription = new Observable<void>(observer => {
|
||||||
this.window.on('move', () => observer.next())
|
this.window.on('move', () => observer.next())
|
||||||
}).pipe(debounceTime(250)).subscribe(() => {
|
}).pipe(debounceTime(250)).subscribe(() => {
|
||||||
this.send('host:window-moved')
|
this.send('host:window-moved')
|
||||||
@@ -344,24 +379,21 @@ export class Window {
|
|||||||
this.disableVibrancyWhileDragging = value
|
this.disableVibrancyWhileDragging = value
|
||||||
})
|
})
|
||||||
|
|
||||||
this.window.on('will-move', () => {
|
let moveEndedTimeout: number|null = null
|
||||||
|
const onBoundsChange = () => {
|
||||||
if (!this.lastVibrancy?.enabled || !this.disableVibrancyWhileDragging) {
|
if (!this.lastVibrancy?.enabled || !this.disableVibrancyWhileDragging) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let timeout: number|null = null
|
this.setVibrancy(false, undefined, false)
|
||||||
const oldVibrancy = this.lastVibrancy
|
if (moveEndedTimeout) {
|
||||||
this.setVibrancy(false)
|
clearTimeout(moveEndedTimeout)
|
||||||
const onMove = () => {
|
|
||||||
if (timeout) {
|
|
||||||
clearTimeout(timeout)
|
|
||||||
}
|
|
||||||
timeout = setTimeout(() => {
|
|
||||||
this.window.off('move', onMove)
|
|
||||||
this.setVibrancy(oldVibrancy.enabled, oldVibrancy.type)
|
|
||||||
}, 500)
|
|
||||||
}
|
}
|
||||||
this.window.on('move', onMove)
|
moveEndedTimeout = setTimeout(() => {
|
||||||
})
|
this.setVibrancy(this.lastVibrancy.enabled, this.lastVibrancy.type)
|
||||||
|
}, 50)
|
||||||
|
}
|
||||||
|
this.window.on('move', onBoundsChange)
|
||||||
|
this.window.on('resize', onBoundsChange)
|
||||||
}
|
}
|
||||||
|
|
||||||
private destroy () {
|
private destroy () {
|
||||||
|
@@ -13,43 +13,51 @@
|
|||||||
"watch": "webpack --progress --color --watch"
|
"watch": "webpack --progress --color --watch"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "9.1.0",
|
"@angular/animations": "^9.1.9",
|
||||||
"@angular/common": "9.1.2",
|
"@angular/common": "^9.1.11",
|
||||||
"@angular/compiler": "9.1.2",
|
"@angular/compiler": "^9.1.9",
|
||||||
"@angular/core": "9.1.2",
|
"@angular/core": "^9.1.9",
|
||||||
"@angular/forms": "9.1.1",
|
"@angular/forms": "^9.1.11",
|
||||||
"@angular/platform-browser": "9.1.1",
|
"@angular/platform-browser": "^9.1.9",
|
||||||
"@angular/platform-browser-dynamic": "9.1.2",
|
"@angular/platform-browser-dynamic": "^9.1.9",
|
||||||
"@ng-bootstrap/ng-bootstrap": "^6.0.2",
|
"@ng-bootstrap/ng-bootstrap": "^6.1.0",
|
||||||
"devtron": "1.4.0",
|
"@terminus-term/node-pty": "0.10.0-beta10",
|
||||||
"electron-config": "2.0.0",
|
"electron-config": "2.0.0",
|
||||||
"electron-debug": "^3.0.1",
|
"electron-debug": "^3.0.1",
|
||||||
"electron-is-dev": "1.1.0",
|
"electron-is-dev": "1.1.0",
|
||||||
"electron-updater": "^4.3.0",
|
"electron-promise-ipc": "^2.2.4",
|
||||||
"fontmanager-redux": "0.4.0",
|
"fontmanager-redux": "1.0.0",
|
||||||
"js-yaml": "3.13.1",
|
"glasstron": "0.0.6",
|
||||||
"keytar": "^5.5.0",
|
"js-yaml": "3.14.0",
|
||||||
|
"keytar": "^7.2.0",
|
||||||
"mz": "^2.7.0",
|
"mz": "^2.7.0",
|
||||||
"ngx-toastr": "^12.0.1",
|
"ngx-toastr": "^12.0.1",
|
||||||
"node-pty": "^0.10.0-beta8",
|
"npm": "6",
|
||||||
"npm": "6.9.0",
|
|
||||||
"path": "0.12.7",
|
"path": "0.12.7",
|
||||||
"rxjs": "^6.5.5",
|
"rxjs": "^6.5.5",
|
||||||
"rxjs-compat": "^6.5.5",
|
"yargs": "^15.4.1",
|
||||||
"yargs": "^15.3.1",
|
"zone.js": "^0.11.3"
|
||||||
"zone.js": "^0.10.3"
|
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"macos-native-processlist": "^1.0.2",
|
"macos-native-processlist": "^2.0.0",
|
||||||
"serialport": "^8.0.7",
|
"serialport": "^9.0.4",
|
||||||
"windows-blurbehind": "^1.0.1",
|
"windows-blurbehind": "^1.0.1",
|
||||||
"windows-native-registry": "^1.0.17",
|
"windows-native-registry": "^3.0.0",
|
||||||
"windows-process-tree": "^0.2.4",
|
"windows-process-tree": "^0.2.4"
|
||||||
"windows-swca": "^2.0.2"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/mz": "0.0.32",
|
"@types/mz": "0.0.32",
|
||||||
"@types/node": "12.7.12",
|
"@types/node": "14.14.14",
|
||||||
"node-abi": "^2.15.0"
|
"node-abi": "2.19.3",
|
||||||
|
"source-map-support": "^0.5.19"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"terminus-community-color-schemes": "*",
|
||||||
|
"terminus-core": "*",
|
||||||
|
"terminus-plugin-manager": "*",
|
||||||
|
"terminus-serial": "*",
|
||||||
|
"terminus-settings": "*",
|
||||||
|
"terminus-ssh": "*",
|
||||||
|
"terminus-terminal": "*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
12
app/patches/node-abi+2.19.3.patch
Normal file
12
app/patches/node-abi+2.19.3.patch
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
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"
|
||||||
|
}
|
||||||
|
]
|
@@ -3,6 +3,7 @@ import 'source-sans-pro/source-sans-pro.css'
|
|||||||
import 'source-code-pro/source-code-pro.css'
|
import 'source-code-pro/source-code-pro.css'
|
||||||
import '@fortawesome/fontawesome-free/css/solid.css'
|
import '@fortawesome/fontawesome-free/css/solid.css'
|
||||||
import '@fortawesome/fontawesome-free/css/brands.css'
|
import '@fortawesome/fontawesome-free/css/brands.css'
|
||||||
|
import '@fortawesome/fontawesome-free/css/regular.css'
|
||||||
import '@fortawesome/fontawesome-free/css/fontawesome.css'
|
import '@fortawesome/fontawesome-free/css/fontawesome.css'
|
||||||
import 'ngx-toastr/toastr.css'
|
import 'ngx-toastr/toastr.css'
|
||||||
import './preload.scss'
|
import './preload.scss'
|
||||||
|
@@ -58,8 +58,8 @@ findPlugins().then(async plugins => {
|
|||||||
window['safeModeReason'] = error
|
window['safeModeReason'] = error
|
||||||
try {
|
try {
|
||||||
await bootstrap(plugins, true)
|
await bootstrap(plugins, true)
|
||||||
} catch (error) {
|
} catch (error2) {
|
||||||
console.error('Bootstrap failed:', error)
|
console.error('Bootstrap failed:', error2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@@ -3,13 +3,13 @@ import * as path from 'path'
|
|||||||
const nodeModule = require('module') // eslint-disable-line @typescript-eslint/no-var-requires
|
const nodeModule = require('module') // eslint-disable-line @typescript-eslint/no-var-requires
|
||||||
const nodeRequire = (global as any).require
|
const nodeRequire = (global as any).require
|
||||||
|
|
||||||
function normalizePath (path: string): string {
|
function normalizePath (p: string): string {
|
||||||
const cygwinPrefix = '/cygdrive/'
|
const cygwinPrefix = '/cygdrive/'
|
||||||
if (path.startsWith(cygwinPrefix)) {
|
if (p.startsWith(cygwinPrefix)) {
|
||||||
path = path.substring(cygwinPrefix.length).replace('/', '\\')
|
p = p.substring(cygwinPrefix.length).replace('/', '\\')
|
||||||
path = path[0] + ':' + path.substring(1)
|
p = p[0] + ':' + p.substring(1)
|
||||||
}
|
}
|
||||||
return path
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
global['module'].paths.map((x: string) => nodeModule.globalPaths.push(normalizePath(x)))
|
global['module'].paths.map((x: string) => nodeModule.globalPaths.push(normalizePath(x)))
|
||||||
@@ -63,7 +63,6 @@ const builtinModules = [
|
|||||||
'ngx-toastr',
|
'ngx-toastr',
|
||||||
'rxjs',
|
'rxjs',
|
||||||
'rxjs/operators',
|
'rxjs/operators',
|
||||||
'rxjs-compat/Subject',
|
|
||||||
'terminus-core',
|
'terminus-core',
|
||||||
'terminus-settings',
|
'terminus-settings',
|
||||||
'terminus-terminal',
|
'terminus-terminal',
|
||||||
@@ -83,7 +82,7 @@ const originalRequire = (global as any).require
|
|||||||
if (cachedBuiltinModules[query]) {
|
if (cachedBuiltinModules[query]) {
|
||||||
return cachedBuiltinModules[query]
|
return cachedBuiltinModules[query]
|
||||||
}
|
}
|
||||||
return originalRequire.apply(this, arguments)
|
return originalRequire.apply(this, [query])
|
||||||
}
|
}
|
||||||
|
|
||||||
const originalModuleRequire = nodeModule.prototype.require
|
const originalModuleRequire = nodeModule.prototype.require
|
||||||
@@ -173,8 +172,8 @@ export async function loadPlugins (foundPlugins: PluginInfo[], progress: Progres
|
|||||||
console.time(label)
|
console.time(label)
|
||||||
const packageModule = nodeRequire(foundPlugin.path)
|
const packageModule = nodeRequire(foundPlugin.path)
|
||||||
const pluginModule = packageModule.default.forRoot ? packageModule.default.forRoot() : packageModule.default
|
const pluginModule = packageModule.default.forRoot ? packageModule.default.forRoot() : packageModule.default
|
||||||
pluginModule['pluginName'] = foundPlugin.name
|
pluginModule.pluginName = foundPlugin.name
|
||||||
pluginModule['bootstrap'] = packageModule.bootstrap
|
pluginModule.bootstrap = packageModule.bootstrap
|
||||||
plugins.push(pluginModule)
|
plugins.push(pluginModule)
|
||||||
console.timeEnd(label)
|
console.timeEnd(label)
|
||||||
await new Promise(x => setTimeout(x, 50))
|
await new Promise(x => setTimeout(x, 50))
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
padding: 10px;
|
padding: 10px;
|
||||||
background-image: none;
|
background-image: none;
|
||||||
width: auto;
|
width: auto;
|
||||||
|
flex-basis: auto;
|
||||||
|
|
||||||
&.toast-error {
|
&.toast-error {
|
||||||
background-color: #BD362F;
|
background-color: #BD362F;
|
||||||
|
@@ -12,7 +12,6 @@
|
|||||||
"noUnusedParameters": true,
|
"noUnusedParameters": true,
|
||||||
"noImplicitReturns": true,
|
"noImplicitReturns": true,
|
||||||
"noFallthroughCasesInSwitch": true,
|
"noFallthroughCasesInSwitch": true,
|
||||||
"noUnusedParameters": true,
|
|
||||||
"noUnusedLocals": true,
|
"noUnusedLocals": true,
|
||||||
"lib": [
|
"lib": [
|
||||||
"dom",
|
"dom",
|
||||||
|
@@ -35,11 +35,15 @@ module.exports = {
|
|||||||
externals: {
|
externals: {
|
||||||
electron: 'commonjs electron',
|
electron: 'commonjs electron',
|
||||||
'electron-config': 'commonjs electron-config',
|
'electron-config': 'commonjs electron-config',
|
||||||
|
'electron-promise-ipc': 'commonjs electron-promise-ipc',
|
||||||
'electron-vibrancy': 'commonjs electron-vibrancy',
|
'electron-vibrancy': 'commonjs electron-vibrancy',
|
||||||
fs: 'commonjs fs',
|
fs: 'commonjs fs',
|
||||||
|
glasstron: 'commonjs glasstron',
|
||||||
mz: 'commonjs mz',
|
mz: 'commonjs mz',
|
||||||
|
npm: 'commonjs npm',
|
||||||
path: 'commonjs path',
|
path: 'commonjs path',
|
||||||
yargs: 'commonjs yargs',
|
util: 'commonjs util',
|
||||||
|
'source-map-support': 'commonjs source-map-support',
|
||||||
'windows-swca': 'commonjs windows-swca',
|
'windows-swca': 'commonjs windows-swca',
|
||||||
'windows-blurbehind': 'commonjs windows-blurbehind',
|
'windows-blurbehind': 'commonjs windows-blurbehind',
|
||||||
},
|
},
|
||||||
@@ -49,4 +53,6 @@ module.exports = {
|
|||||||
'process.type': '"main"',
|
'process.type': '"main"',
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
// Ignore warnings due to yarg's dynamic module loading
|
||||||
|
ignoreWarnings: [/node_modules\/yargs/],
|
||||||
}
|
}
|
||||||
|
2492
app/yarn.lock
2492
app/yarn.lock
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@ platform:
|
|||||||
- x64
|
- x64
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
nodejs_version: "10"
|
nodejs_version: "15"
|
||||||
|
|
||||||
version: "{build}"
|
version: "{build}"
|
||||||
|
|
||||||
|
16
build/mac/afterBuildHook.js
Normal file
16
build/mac/afterBuildHook.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
const fs = require('fs')
|
||||||
|
const signHook = require('./afterSignHook')
|
||||||
|
|
||||||
|
module.exports = async function (params) {
|
||||||
|
// notarize the app on Mac OS only.
|
||||||
|
if (process.platform !== 'darwin' || !process.env.GITHUB_REF || !process.env.GITHUB_REF.startsWith('refs/tags/')) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.log('afterBuild hook triggered')
|
||||||
|
|
||||||
|
let pkgName = fs.readdirSync('dist').find(x => x.endsWith('.pkg'))
|
||||||
|
signHook({
|
||||||
|
appOutDir: 'dist',
|
||||||
|
_pathOverride: pkgName,
|
||||||
|
})
|
||||||
|
}
|
@@ -6,14 +6,14 @@ const notarizer = require('electron-notarize')
|
|||||||
|
|
||||||
module.exports = async function (params) {
|
module.exports = async function (params) {
|
||||||
// notarize the app on Mac OS only.
|
// notarize the app on Mac OS only.
|
||||||
if (process.platform !== 'darwin' || process.env.GITHUB_REF !== 'refs/heads/master' || process.env.GITHUB_REF && !process.env.GITHUB_REF.startsWith('refs/tags/')) {
|
if (process.platform !== 'darwin' || !process.env.GITHUB_REF || !process.env.GITHUB_REF.startsWith('refs/tags/')) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
console.log('afterSign hook triggered', params)
|
console.log('afterSign hook triggered', params)
|
||||||
|
|
||||||
let appId = 'org.terminus'
|
let appId = 'org.terminus'
|
||||||
|
|
||||||
let appPath = path.join(params.appOutDir, `${params.packager.appInfo.productFilename}.app`)
|
let appPath = path.join(params.appOutDir, params._pathOverride || `${params.packager.appInfo.productFilename}.app`)
|
||||||
if (!fs.existsSync(appPath)) {
|
if (!fs.existsSync(appPath)) {
|
||||||
throw new Error(`Cannot find application at: ${appPath}`)
|
throw new Error(`Cannot find application at: ${appPath}`)
|
||||||
}
|
}
|
||||||
|
@@ -10,5 +10,9 @@
|
|||||||
<true/>
|
<true/>
|
||||||
<key>com.apple.security.cs.disable-library-validation</key>
|
<key>com.apple.security.cs.disable-library-validation</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>com.apple.security.device.microphone</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.device.camera</key>
|
||||||
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
@@ -2,10 +2,33 @@
|
|||||||
appId: org.terminus
|
appId: org.terminus
|
||||||
productName: Terminus
|
productName: Terminus
|
||||||
compression: normal
|
compression: normal
|
||||||
|
npmRebuild: false
|
||||||
afterSign: "./build/mac/afterSignHook.js"
|
afterSign: "./build/mac/afterSignHook.js"
|
||||||
|
afterAllArtifactBuild: "./build/mac/afterBuildHook.js"
|
||||||
files:
|
files:
|
||||||
- "**/*"
|
- '**/*'
|
||||||
- dist
|
- dist
|
||||||
|
- '!src'
|
||||||
|
- '!**/node_modules/*/{CHANGELOG.md,README.md,README,readme.md,readme}'
|
||||||
|
- '!**/node_modules/*/{test,__tests__,tests,powered-test,example,examples,docs}'
|
||||||
|
- '!**/node_modules/@angular/common/locales'
|
||||||
|
- '!**/node_modules/@angular/compiler/src'
|
||||||
|
- '!**/node_modules/node-gyp'
|
||||||
|
- '!**/node_modules/**/*.d.ts'
|
||||||
|
- '!**/node_modules/**/*.map'
|
||||||
|
- '!**/node_modules/**/include/node'
|
||||||
|
- '!**/node_modules/.bin'
|
||||||
|
- '!**/node_modules/*/*/{esm5,fesm5,esm2015,fesm2015,_esm2015,_fesm2015}'
|
||||||
|
- '!**/*.{woff,ttf,otf,eot}'
|
||||||
|
- '!**/*.{iml,o,hprof,orig,pyc,pyo,rbc,swp,csproj,sln,xproj}'
|
||||||
|
- '!.editorconfig'
|
||||||
|
- '!**/._*'
|
||||||
|
- '!**/{.DS_Store,.git,.hg,.svn,CVS,RCS,SCCS,.gitignore,.gitattributes}'
|
||||||
|
- '!**/{__pycache__,thumbs.db,.flowconfig,.idea,.vs,.nyc_output}'
|
||||||
|
- '!**/{appveyor.yml,.travis.yml,circle.yml}'
|
||||||
|
- '!**/{npm-debug.log,yarn.lock,.yarn-integrity,.yarn-metadata.json'
|
||||||
|
asarUnpack:
|
||||||
|
- 'node_modules/**/Release/*.node'
|
||||||
extraResources:
|
extraResources:
|
||||||
- builtin-plugins
|
- builtin-plugins
|
||||||
- extras
|
- extras
|
||||||
@@ -20,18 +43,25 @@ nsis:
|
|||||||
oneClick: false
|
oneClick: false
|
||||||
artifactName: terminus-${version}-setup.${ext}
|
artifactName: terminus-${version}-setup.${ext}
|
||||||
installerIcon: "./build/windows/icon.ico"
|
installerIcon: "./build/windows/icon.ico"
|
||||||
|
allowToChangeInstallationDirectory: true
|
||||||
|
|
||||||
mac:
|
mac:
|
||||||
category: public.app-category.video
|
category: public.app-category.video
|
||||||
icon: "./build/mac/icon.icns"
|
icon: "./build/mac/icon.icns"
|
||||||
artifactName: terminus-${version}-macos.${ext}
|
artifactName: terminus-${version}-macos-${env.ARCH}.${ext}
|
||||||
hardenedRuntime: true
|
hardenedRuntime: true
|
||||||
entitlements: "./build/mac/entitlements.plist"
|
entitlements: "./build/mac/entitlements.plist"
|
||||||
entitlementsInherit: "./build/mac/entitlements.plist"
|
entitlementsInherit: "./build/mac/entitlements.plist"
|
||||||
extendInfo:
|
extendInfo:
|
||||||
NSRequiresAquaSystemAppearance: false
|
NSRequiresAquaSystemAppearance: false
|
||||||
pkg:
|
NSCameraUsageDescription: "A subprocess requests access to the device's camera."
|
||||||
artifactName: terminus-${version}-macos.pkg
|
NSMicrophoneUsageDescription: "A subprocess requests access to the device's microphone."
|
||||||
|
NSLocationUsageDescription: "A subprocess requests access to the user's location information."
|
||||||
|
NSDesktopFolderUsageDescription: "A subprocess requests access to the user's Desktop folder."
|
||||||
|
NSDocumentsFolderUsageDescription: "A subprocess requests access to the user's Documents folder."
|
||||||
|
NSDownloadsFolderUsageDescription: "A subprocess requests access to the user's Downloads folder."
|
||||||
|
NSNetworkVolumesUsageDescription: 'A subprocess requests access to files on a network volume.'
|
||||||
|
NSRemovableVolumesUsageDescription: 'A subprocess requests access to files on a removable volume.'
|
||||||
|
|
||||||
linux:
|
linux:
|
||||||
category: Utilities
|
category: Utilities
|
||||||
@@ -48,6 +78,7 @@ deb:
|
|||||||
depends:
|
depends:
|
||||||
- gconf2
|
- gconf2
|
||||||
- gconf-service
|
- gconf-service
|
||||||
|
- gnome-keyring
|
||||||
- libnotify4
|
- libnotify4
|
||||||
- libsecret-1-0
|
- libsecret-1-0
|
||||||
- libappindicator1
|
- libappindicator1
|
||||||
@@ -57,4 +88,4 @@ deb:
|
|||||||
rpm:
|
rpm:
|
||||||
depends:
|
depends:
|
||||||
- screen
|
- screen
|
||||||
- gnome-python2-gnomekeyring
|
- gnome-keyring
|
||||||
|
BIN
extras/UAC.exe
BIN
extras/UAC.exe
Binary file not shown.
72
package.json
72
package.json
@@ -1,67 +1,75 @@
|
|||||||
{
|
{
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@fortawesome/fontawesome-free": "^5.13.0",
|
"@fortawesome/fontawesome-free": "^5.13.0",
|
||||||
"@sentry/cli": "^1.52.1",
|
"@sentry/cli": "^1.61.0",
|
||||||
"@sentry/electron": "^1.2.1",
|
"@sentry/electron": "^2.0.4",
|
||||||
"@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/js-yaml": "^3.12.3",
|
"@types/fs-extra": "^8.1.1",
|
||||||
"@types/node": "12.7.12",
|
"@types/js-yaml": "^3.12.5",
|
||||||
"@types/webpack-env": "1.15.0",
|
"@types/node": "14.14.14",
|
||||||
"@typescript-eslint/eslint-plugin": "^2.26.0",
|
"@types/webpack-env": "^1.16.0",
|
||||||
"@typescript-eslint/parser": "^2.27.0",
|
"@typescript-eslint/eslint-plugin": "^4.11.0",
|
||||||
|
"@typescript-eslint/parser": "^4.11.0",
|
||||||
"apply-loader": "2.0.0",
|
"apply-loader": "2.0.0",
|
||||||
"awesome-typescript-loader": "^5.0.0",
|
"awesome-typescript-loader": "^5.2.1",
|
||||||
"core-js": "^3.6.5",
|
"compare-versions": "^3.6.0",
|
||||||
|
"core-js": "^3.8.1",
|
||||||
"cross-env": "7.0.2",
|
"cross-env": "7.0.2",
|
||||||
"css-loader": "3.4.2",
|
"css-loader": "3.4.2",
|
||||||
"electron": "^8.2.3",
|
"electron": "12.0.0-beta.16",
|
||||||
"electron-builder": "22.5.1",
|
"electron-builder": "22.10.4",
|
||||||
"electron-download": "^4.1.1",
|
"electron-download": "^4.1.1",
|
||||||
"electron-installer-snap": "^5.0.0",
|
"electron-installer-snap": "^5.1.0",
|
||||||
"electron-notarize": "^0.1.1",
|
"electron-notarize": "^1.0.0",
|
||||||
"electron-rebuild": "^1.10.1",
|
"electron-rebuild": "^2.3.4",
|
||||||
"eslint": "^6.8.0",
|
"eslint": "^7.6.0",
|
||||||
"eslint-plugin-import": "^2.20.2",
|
"eslint-plugin-import": "^2.21.1",
|
||||||
"file-loader": "^5.0.2",
|
"file-loader": "^5.1.0",
|
||||||
"graceful-fs": "^4.2.2",
|
"graceful-fs": "^4.2.4",
|
||||||
"html-loader": "0.5.5",
|
"html-loader": "0.5.5",
|
||||||
"json-loader": "0.5.7",
|
"json-loader": "0.5.7",
|
||||||
"node-abi": "^2.15.0",
|
"lru-cache": "^6.0.0",
|
||||||
"node-gyp": "^6.1.0",
|
"macos-release": "^2.4.1",
|
||||||
"node-sass": "^4.13.0",
|
"node-abi": "^2.19.3",
|
||||||
|
"node-gyp": "^7.1.2",
|
||||||
|
"node-sass": "^5.0.0",
|
||||||
"npmlog": "4.1.2",
|
"npmlog": "4.1.2",
|
||||||
"npx": "^10.2.0",
|
"npx": "^10.2.2",
|
||||||
|
"patch-package": "^6.2.2",
|
||||||
"pug": "^2.0.4",
|
"pug": "^2.0.4",
|
||||||
"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.1",
|
||||||
"sass-loader": "^8.0.0",
|
"sass-loader": "^10.1.0",
|
||||||
"shelljs": "0.8.3",
|
"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",
|
||||||
"style-loader": "^1.1.4",
|
"ssh2-streams": "^0.4.10",
|
||||||
"svg-inline-loader": "^0.8.0",
|
"style-loader": "^2.0.0",
|
||||||
|
"svg-inline-loader": "^0.8.2",
|
||||||
"to-string-loader": "1.1.6",
|
"to-string-loader": "1.1.6",
|
||||||
"tslib": "^1.11.1",
|
"tslib": "^2.0.3",
|
||||||
"typedoc": "^0.17.4",
|
"typedoc": "^0.18.0",
|
||||||
"typescript": "^3.8.3",
|
"typescript": "^3.9.7",
|
||||||
"url-loader": "^3.0.0",
|
"url-loader": "^3.0.0",
|
||||||
"val-loader": "2.1.1",
|
"val-loader": "2.1.1",
|
||||||
"webpack": "^5.0.0-beta.14",
|
"webpack": "^5.11.0",
|
||||||
"webpack-cli": "^3.3.10",
|
"webpack-cli": "^4.2.0",
|
||||||
"yaml-loader": "0.6.0"
|
"yaml-loader": "0.6.0"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"*/node-abi": "^2.14.0"
|
"*/node-abi": "^2.19.3",
|
||||||
|
"**/graceful-fs": "^4.2.4"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "npm run build:typings && webpack --color --config app/webpack.main.config.js && webpack --color --config app/webpack.config.js && webpack --color --config terminus-core/webpack.config.js && webpack --color --config terminus-settings/webpack.config.js && webpack --color --config terminus-terminal/webpack.config.js && webpack --color --config terminus-plugin-manager/webpack.config.js && webpack --color --config terminus-community-color-schemes/webpack.config.js && webpack --color --config terminus-ssh/webpack.config.js && webpack --color --config terminus-serial/webpack.config.js",
|
"build": "npm run build:typings && webpack --color --config app/webpack.main.config.js && webpack --color --config app/webpack.config.js && webpack --color --config terminus-core/webpack.config.js && webpack --color --config terminus-settings/webpack.config.js && webpack --color --config terminus-terminal/webpack.config.js && webpack --color --config terminus-plugin-manager/webpack.config.js && webpack --color --config terminus-community-color-schemes/webpack.config.js && webpack --color --config terminus-ssh/webpack.config.js && webpack --color --config terminus-serial/webpack.config.js",
|
||||||
"build:typings": "node scripts/build-typings.js",
|
"build:typings": "node scripts/build-typings.js",
|
||||||
"watch": "cross-env TERMINUS_DEV=1 webpack --progress --color --watch",
|
"watch": "cross-env TERMINUS_DEV=1 webpack --progress --color --watch",
|
||||||
"start": "cross-env TERMINUS_DEV=1 electron app --debug",
|
"start": "cross-env TERMINUS_DEV=1 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 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",
|
||||||
"lint": "eslint --ext ts */src */lib",
|
"lint": "eslint --ext ts */src */lib",
|
||||||
|
12
patches/node-abi+2.19.3.patch
Normal file
12
patches/node-abi+2.19.3.patch
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
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"
|
||||||
|
}
|
||||||
|
]
|
@@ -3,15 +3,21 @@ const builder = require('electron-builder').build
|
|||||||
const vars = require('./vars')
|
const vars = require('./vars')
|
||||||
|
|
||||||
const isTag = (process.env.GITHUB_REF || '').startsWith('refs/tags/')
|
const isTag = (process.env.GITHUB_REF || '').startsWith('refs/tags/')
|
||||||
const isCI = !!process.env.GITHUB_REF
|
|
||||||
|
process.env.ARCH = process.env.ARCH || process.arch
|
||||||
|
|
||||||
builder({
|
builder({
|
||||||
dir: true,
|
dir: true,
|
||||||
mac: ['pkg', 'zip'],
|
mac: ['pkg', 'zip'],
|
||||||
|
arm64: process.env.ARCH === 'arm64',
|
||||||
config: {
|
config: {
|
||||||
extraMetadata: {
|
extraMetadata: {
|
||||||
version: vars.version,
|
version: vars.version,
|
||||||
},
|
},
|
||||||
|
npmRebuild: process.env.ARCH !== 'arm64',
|
||||||
},
|
},
|
||||||
publish: isTag ? 'always' : 'onTag',
|
publish: isTag ? 'always' : 'onTag',
|
||||||
}).catch(() => process.exit(1))
|
}).catch(e => {
|
||||||
|
console.error(e)
|
||||||
|
process.exit(1)
|
||||||
|
})
|
||||||
|
@@ -8,6 +8,7 @@ for (let dir of ['app', 'terminus-core', 'terminus-ssh', 'terminus-terminal']) {
|
|||||||
const build = rebuild({
|
const build = rebuild({
|
||||||
buildPath: path.resolve(__dirname, '../' + dir),
|
buildPath: path.resolve(__dirname, '../' + dir),
|
||||||
electronVersion: vars.electronVersion,
|
electronVersion: vars.electronVersion,
|
||||||
|
arch: process.env.ARCH ?? process.arch,
|
||||||
force: true,
|
force: true,
|
||||||
})
|
})
|
||||||
build.catch(e => {
|
build.catch(e => {
|
||||||
|
@@ -10,13 +10,13 @@ const npx = `${localBinPath}/npx`;
|
|||||||
log.info('deps', 'app')
|
log.info('deps', 'app')
|
||||||
|
|
||||||
sh.cd('app')
|
sh.cd('app')
|
||||||
sh.exec(`${npx} yarn install`)
|
sh.exec(`${npx} yarn install --force`)
|
||||||
sh.cd('..')
|
sh.cd('..')
|
||||||
|
|
||||||
vars.builtinPlugins.forEach(plugin => {
|
vars.builtinPlugins.forEach(plugin => {
|
||||||
log.info('deps', plugin)
|
log.info('deps', plugin)
|
||||||
sh.cd(plugin)
|
sh.cd(plugin)
|
||||||
sh.exec(`${npx} yarn install`)
|
sh.exec(`${npx} yarn install --force`)
|
||||||
sh.cd('..')
|
sh.cd('..')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@@ -15,10 +15,17 @@ vars.builtinPlugins.forEach(plugin => {
|
|||||||
sh.cp('-r', path.join('..', plugin), '.')
|
sh.cp('-r', path.join('..', plugin), '.')
|
||||||
sh.rm('-rf', path.join(plugin, 'node_modules'))
|
sh.rm('-rf', path.join(plugin, 'node_modules'))
|
||||||
sh.cd(plugin)
|
sh.cd(plugin)
|
||||||
sh.exec(`npm install --only=prod`)
|
sh.exec(`yarn install --force --production`)
|
||||||
|
|
||||||
|
|
||||||
log.info('rebuild', 'native')
|
log.info('rebuild', 'native')
|
||||||
if (fs.existsSync('node_modules')) {
|
if (fs.existsSync('node_modules')) {
|
||||||
rebuild(path.resolve('.'), vars.electronVersion, process.arch, [], true)
|
rebuild({
|
||||||
|
buildPath: path.resolve('.'),
|
||||||
|
electronVersion: vars.electronVersion,
|
||||||
|
arch: process.env.ARCH ?? process.arch,
|
||||||
|
force: true,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
sh.cd('..')
|
sh.cd('..')
|
||||||
})
|
})
|
||||||
|
24
scripts/sentry-upload.js
Executable file
24
scripts/sentry-upload.js
Executable file
@@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
const sh = require('shelljs')
|
||||||
|
const vars = require('./vars')
|
||||||
|
|
||||||
|
const sentryCli = process.platform === 'win32' ? 'node_modules\\.bin\\sentry-cli.cmd' : 'sentry-cli'
|
||||||
|
|
||||||
|
sh.exec(`${sentryCli} releases new ${vars.version}`)
|
||||||
|
|
||||||
|
if (process.platform === 'darwin') {
|
||||||
|
for (const path of [
|
||||||
|
'app/node_modules/@serialport/bindings/build/Release/bindings.node',
|
||||||
|
'app/node_modules/@terminus-term/node-pty/build/Release/pty.node',
|
||||||
|
'app/node_modules/fontmanager-redux/build/Release/fontmanager.node',
|
||||||
|
'app/node_modules/macos-native-processlist/build/Release/native.node',
|
||||||
|
]) {
|
||||||
|
sh.exec('dsymutil ' + path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sh.exec(`${sentryCli} upload-dif app/node_modules`)
|
||||||
|
sh.exec(`${sentryCli} releases set-commits --auto ${vars.version}`)
|
||||||
|
for (const p of vars.builtinPlugins) {
|
||||||
|
sh.exec(`${sentryCli} releases files ${vars.version} upload-sourcemaps ${p}/dist -u ${p}/dist/ -d ${process.platform}-${p}`)
|
||||||
|
}
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "terminus-community-color-schemes",
|
"name": "terminus-community-color-schemes",
|
||||||
"version": "1.0.104-nightly.0",
|
"version": "1.0.123-nightly.0",
|
||||||
"description": "Community color schemes for Terminus",
|
"description": "Community color schemes for Terminus",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"terminus-builtin-plugin"
|
"terminus-builtin-plugin"
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
"author": "Eugene Pankov",
|
"author": "Eugene Pankov",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@angular/core": "^7",
|
"@angular/core": "^9.1.9",
|
||||||
"terminus-core": "*",
|
"terminus-core": "*",
|
||||||
"terminus-terminal": "*"
|
"terminus-terminal": "*"
|
||||||
}
|
}
|
||||||
|
@@ -1,14 +1,14 @@
|
|||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { TerminalColorSchemeProvider, TerminalColorScheme } from 'terminus-terminal'
|
import { TerminalColorSchemeProvider, TerminalColorScheme } from 'terminus-terminal'
|
||||||
|
|
||||||
const schemeContents = require.context('../schemes/', true, /.*/)
|
const schemeContents = require.context('../schemes/', false, /.*/)
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ColorSchemes extends TerminalColorSchemeProvider {
|
export class ColorSchemes extends TerminalColorSchemeProvider {
|
||||||
async getSchemes (): Promise<TerminalColorScheme[]> {
|
async getSchemes (): Promise<TerminalColorScheme[]> {
|
||||||
const schemes: TerminalColorScheme[] = []
|
const schemes: TerminalColorScheme[] = []
|
||||||
|
|
||||||
schemeContents.keys().forEach(schemeFile => {
|
schemeContents.keys().filter(x => !x.startsWith('./')).forEach(schemeFile => {
|
||||||
const lines = (schemeContents(schemeFile).default as string).split('\n')
|
const lines = (schemeContents(schemeFile).default as string).split('\n')
|
||||||
|
|
||||||
// process #define variables
|
// process #define variables
|
||||||
|
@@ -4,7 +4,7 @@ module.exports = {
|
|||||||
target: 'node',
|
target: 'node',
|
||||||
entry: 'src/index.ts',
|
entry: 'src/index.ts',
|
||||||
context: __dirname,
|
context: __dirname,
|
||||||
devtool: 'eval-cheap-module-source-map',
|
devtool: 'cheap-module-source-map',
|
||||||
output: {
|
output: {
|
||||||
path: path.resolve(__dirname, 'dist'),
|
path: path.resolve(__dirname, 'dist'),
|
||||||
filename: 'index.js',
|
filename: 'index.js',
|
||||||
|
1
terminus-core/.gitignore
vendored
1
terminus-core/.gitignore
vendored
@@ -1,2 +1 @@
|
|||||||
dist
|
dist
|
||||||
node_modules
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "terminus-core",
|
"name": "terminus-core",
|
||||||
"version": "1.0.104-nightly.0",
|
"version": "1.0.123-nightly.0",
|
||||||
"description": "Terminus core",
|
"description": "Terminus core",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"terminus-builtin-plugin"
|
"terminus-builtin-plugin"
|
||||||
@@ -29,17 +29,18 @@
|
|||||||
"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": "^8.0.0",
|
||||||
|
"readable-stream": "2.3.7",
|
||||||
"shell-escape": "^0.2.0",
|
"shell-escape": "^0.2.0",
|
||||||
"uuid": "^7.0.1",
|
"uuid": "^8.0.0",
|
||||||
"winston": "^3.2.1"
|
"winston": "^3.3.3"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@angular/animations": "^7",
|
"@angular/animations": "^9.1.9",
|
||||||
"@angular/common": "^7",
|
"@angular/common": "^9.1.11",
|
||||||
"@angular/core": "^7",
|
"@angular/core": "^9.1.9",
|
||||||
"@angular/forms": "^7",
|
"@angular/forms": "^9.1.11",
|
||||||
"@angular/platform-browser": "^7",
|
"@angular/platform-browser": "^9.1.11",
|
||||||
"@angular/platform-browser-dynamic": "^7",
|
"@angular/platform-browser-dynamic": "^9.1.11",
|
||||||
"rxjs": "^5"
|
"rxjs": "^6.6.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -33,5 +33,5 @@ export abstract class ConfigProvider {
|
|||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
platformDefaults: {[platform: string]: any} = {}
|
platformDefaults: Record<string, any> = {}
|
||||||
}
|
}
|
||||||
|
@@ -8,7 +8,5 @@ export interface HotkeyDescription {
|
|||||||
* must also provide the `hotkeys.foo` config options with the default values
|
* must also provide the `hotkeys.foo` config options with the default values
|
||||||
*/
|
*/
|
||||||
export abstract class HotkeyProvider {
|
export abstract class HotkeyProvider {
|
||||||
hotkeys: HotkeyDescription[] = []
|
|
||||||
|
|
||||||
abstract provide (): Promise<HotkeyDescription[]>
|
abstract provide (): Promise<HotkeyDescription[]>
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
import type { MenuItemConstructorOptions } from 'electron'
|
||||||
import { BaseTabComponent } from '../components/baseTab.component'
|
import { BaseTabComponent } from '../components/baseTab.component'
|
||||||
import { TabHeaderComponent } from '../components/tabHeader.component'
|
import { TabHeaderComponent } from '../components/tabHeader.component'
|
||||||
|
|
||||||
@@ -7,5 +8,5 @@ import { TabHeaderComponent } from '../components/tabHeader.component'
|
|||||||
export abstract class TabContextMenuItemProvider {
|
export abstract class TabContextMenuItemProvider {
|
||||||
weight = 0
|
weight = 0
|
||||||
|
|
||||||
abstract async getItems (tab: BaseTabComponent, tabHeader?: TabHeaderComponent): Promise<Electron.MenuItemConstructorOptions[]>
|
abstract async getItems (tab: BaseTabComponent, tabHeader?: TabHeaderComponent): Promise<MenuItemConstructorOptions[]>
|
||||||
}
|
}
|
||||||
|
@@ -4,10 +4,13 @@ title-bar(
|
|||||||
)
|
)
|
||||||
|
|
||||||
.content(
|
.content(
|
||||||
[class.tabs-on-top]='config.store.appearance.tabsLocation == "top"'
|
[class.tabs-on-top]='config.store.appearance.tabsLocation == "top" || config.store.appearance.tabsLocation == "left"',
|
||||||
|
[class.tabs-on-side]='hasVerticalTabs()',
|
||||||
)
|
)
|
||||||
.tab-bar
|
.tab-bar
|
||||||
.inset.background(*ngIf='hostApp.platform == Platform.macOS && config.store.appearance.frame == "thin" && config.store.appearance.tabsLocation == "top"')
|
.inset.background(*ngIf='hostApp.platform == Platform.macOS \
|
||||||
|
&& config.store.appearance.frame == "thin" \
|
||||||
|
&& (config.store.appearance.tabsLocation == "top" || config.store.appearance.tabsLocation == "left")')
|
||||||
.tabs(
|
.tabs(
|
||||||
dnd-sortable-container,
|
dnd-sortable-container,
|
||||||
[sortableData]='app.tabs',
|
[sortableData]='app.tabs',
|
||||||
@@ -18,12 +21,12 @@ title-bar(
|
|||||||
[sortableIndex]='idx',
|
[sortableIndex]='idx',
|
||||||
(onDragStart)='onTabDragStart()',
|
(onDragStart)='onTabDragStart()',
|
||||||
(onDragEnd)='onTabDragEnd()',
|
(onDragEnd)='onTabDragEnd()',
|
||||||
|
|
||||||
[index]='idx',
|
[index]='idx',
|
||||||
[tab]='tab',
|
[tab]='tab',
|
||||||
[active]='tab == app.activeTab',
|
[active]='tab == app.activeTab',
|
||||||
[hasActivity]='tab.activity$|async',
|
[hasActivity]='tab.activity$|async',
|
||||||
@animateTab,
|
@animateTab,
|
||||||
|
[@.disabled]='hasVerticalTabs()',
|
||||||
(click)='app.selectTab(tab)',
|
(click)='app.selectTab(tab)',
|
||||||
[class.fully-draggable]='hostApp.platform != Platform.macOS',
|
[class.fully-draggable]='hostApp.platform != Platform.macOS',
|
||||||
[class.drag-region]='hostApp.platform == Platform.macOS && !tabsDragging',
|
[class.drag-region]='hostApp.platform == Platform.macOS && !tabsDragging',
|
||||||
@@ -87,7 +90,8 @@ title-bar(
|
|||||||
)
|
)
|
||||||
|
|
||||||
window-controls.background(
|
window-controls.background(
|
||||||
*ngIf='config.store.appearance.frame == "thin" && (hostApp.platform == Platform.Windows || hostApp.platform == Platform.Linux)',
|
*ngIf='config.store.appearance.frame == "thin" \
|
||||||
|
&& (hostApp.platform == Platform.Windows || hostApp.platform == Platform.Linux)',
|
||||||
)
|
)
|
||||||
|
|
||||||
start-page(*ngIf='ready && app.tabs.length == 0')
|
start-page(*ngIf='ready && app.tabs.length == 0')
|
||||||
|
@@ -15,26 +15,73 @@
|
|||||||
|
|
||||||
$tabs-height: 38px;
|
$tabs-height: 38px;
|
||||||
$tab-border-radius: 4px;
|
$tab-border-radius: 4px;
|
||||||
|
$side-tab-width: 200px;
|
||||||
|
|
||||||
|
.wrap {
|
||||||
|
display: flex;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
height: 100%;
|
width: 100vw;
|
||||||
flex: auto;
|
flex: 1 1 0;
|
||||||
|
min-height: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column-reverse;
|
flex-direction: column-reverse;
|
||||||
|
|
||||||
&.tabs-on-top {
|
&.tabs-on-top {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.tabs-on-side {
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
|
||||||
|
&.tabs-on-top {
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.content.tabs-on-side > .tab-bar {
|
||||||
|
height: 100%;
|
||||||
|
width: $side-tab-width;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
flex-direction: column;
|
||||||
|
background: rgba(0, 0, 0, 0.25);
|
||||||
|
|
||||||
|
.tabs {
|
||||||
|
width: $side-tab-width;
|
||||||
|
flex: none;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
tab-header {
|
||||||
|
flex: 0 0 $tabs-height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.drag-space {
|
||||||
|
flex: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&>.inset {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.tab-bar {
|
.tab-bar {
|
||||||
flex: none;
|
flex: none;
|
||||||
height: $tabs-height;
|
height: $tabs-height;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
.btn-tab-bar {
|
.btn-tab-bar {
|
||||||
line-height: $tabs-height + 2px;
|
line-height: $tabs-height + 2px;
|
||||||
|
height: $tabs-height;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -50,6 +97,8 @@ $tab-border-radius: 4px;
|
|||||||
border: none;
|
border: none;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
&.dropdown-toggle::after {
|
&.dropdown-toggle::after {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@@ -74,7 +123,9 @@ $tab-border-radius: 4px;
|
|||||||
|
|
||||||
& > .inset {
|
& > .inset {
|
||||||
width: 85px;
|
width: 85px;
|
||||||
|
height: $tabs-height;
|
||||||
flex: none;
|
flex: none;
|
||||||
|
-webkit-app-region: drag;
|
||||||
}
|
}
|
||||||
|
|
||||||
window-controls {
|
window-controls {
|
||||||
|
@@ -184,6 +184,10 @@ export class AppRootComponent {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasVerticalTabs () {
|
||||||
|
return this.config.store.appearance.tabsLocation === 'left' || this.config.store.appearance.tabsLocation === 'right'
|
||||||
|
}
|
||||||
|
|
||||||
async updateApp () {
|
async updateApp () {
|
||||||
if ((await this.electron.showMessageBox(
|
if ((await this.electron.showMessageBox(
|
||||||
this.hostApp.getWindow(),
|
this.hostApp.getWindow(),
|
||||||
@@ -225,8 +229,8 @@ export class AppRootComponent {
|
|||||||
buttons = buttons.concat(provider.provide())
|
buttons = buttons.concat(provider.provide())
|
||||||
})
|
})
|
||||||
return buttons
|
return buttons
|
||||||
.filter(button => (button.weight || 0) > 0 === aboveZero)
|
.filter(button => (button.weight ?? 0) > 0 === aboveZero)
|
||||||
.sort((a: ToolbarButton, b: ToolbarButton) => (a.weight || 0) - (b.weight || 0))
|
.sort((a: ToolbarButton, b: ToolbarButton) => (a.weight ?? 0) - (b.weight ?? 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateVibrancy () {
|
private updateVibrancy () {
|
||||||
|
@@ -14,6 +14,11 @@ export interface BaseTabProcess {
|
|||||||
* Abstract base class for custom tab components
|
* Abstract base class for custom tab components
|
||||||
*/
|
*/
|
||||||
export abstract class BaseTabComponent {
|
export abstract class BaseTabComponent {
|
||||||
|
/**
|
||||||
|
* Parent tab (usually a SplitTabComponent)
|
||||||
|
*/
|
||||||
|
parent: BaseTabComponent|null = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current tab title
|
* Current tab title
|
||||||
*/
|
*/
|
||||||
|
@@ -50,7 +50,7 @@ export class SelectorModalComponent<T> {
|
|||||||
this.filteredOptions = this.options.filter(x => !x.freeInputPattern)
|
this.filteredOptions = this.options.filter(x => !x.freeInputPattern)
|
||||||
} else {
|
} else {
|
||||||
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
|
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
|
||||||
this.filteredOptions = this.options.filter(x => x.freeInputPattern || (x.name + (x.description || '')).toLowerCase().includes(f))
|
this.filteredOptions = this.options.filter(x => x.freeInputPattern ?? (x.name + (x.description ?? '')).toLowerCase().includes(f))
|
||||||
}
|
}
|
||||||
this.selectedIndex = Math.max(0, this.selectedIndex)
|
this.selectedIndex = Math.max(0, this.selectedIndex)
|
||||||
this.selectedIndex = Math.min(this.filteredOptions.length - 1, this.selectedIndex)
|
this.selectedIndex = Math.min(this.filteredOptions.length - 1, this.selectedIndex)
|
||||||
@@ -72,7 +72,7 @@ export class SelectorModalComponent<T> {
|
|||||||
this.modalInstance.dismiss()
|
this.modalInstance.dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
iconIsSVG (icon: string): boolean {
|
iconIsSVG (icon?: string): boolean {
|
||||||
return icon?.startsWith('<')
|
return icon?.startsWith('<') ?? false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -157,7 +157,11 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
/** @hidden */
|
/** @hidden */
|
||||||
_spanners: SplitSpannerInfo[] = []
|
_spanners: SplitSpannerInfo[] = []
|
||||||
|
|
||||||
private focusedTab: BaseTabComponent
|
/** @hidden */
|
||||||
|
_allFocusMode = false
|
||||||
|
|
||||||
|
/** @hidden */
|
||||||
|
private focusedTab: BaseTabComponent|null = null
|
||||||
private maximizedTab: BaseTabComponent|null = null
|
private maximizedTab: BaseTabComponent|null = null
|
||||||
private hotkeysSubscription: Subscription
|
private hotkeysSubscription: Subscription
|
||||||
private viewRefs: Map<BaseTabComponent, EmbeddedViewRef<any>> = new Map()
|
private viewRefs: Map<BaseTabComponent, EmbeddedViewRef<any>> = new Map()
|
||||||
@@ -207,7 +211,7 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
this.blurred$.subscribe(() => this.getAllTabs().forEach(x => x.emitBlurred()))
|
this.blurred$.subscribe(() => this.getAllTabs().forEach(x => x.emitBlurred()))
|
||||||
|
|
||||||
this.hotkeysSubscription = this.hotkeys.matchedHotkey.subscribe(hotkey => {
|
this.hotkeysSubscription = this.hotkeys.matchedHotkey.subscribe(hotkey => {
|
||||||
if (!this.hasFocus) {
|
if (!this.hasFocus || !this.focusedTab) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch (hotkey) {
|
switch (hotkey) {
|
||||||
@@ -254,12 +258,13 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
if (this._recoveredState) {
|
if (this._recoveredState) {
|
||||||
await this.recoverContainer(this.root, this._recoveredState)
|
await this.recoverContainer(this.root, this._recoveredState)
|
||||||
this.layout()
|
this.layout()
|
||||||
setImmediate(() => {
|
setTimeout(() => {
|
||||||
if (this.hasFocus) {
|
if (this.hasFocus) {
|
||||||
this.getAllTabs().forEach(x => x.emitFocused())
|
for (const tab of this.getAllTabs()) {
|
||||||
this.focusAnyIn(this.root)
|
this.focus(tab)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
}, 100)
|
||||||
}
|
}
|
||||||
this.initialized.next()
|
this.initialized.next()
|
||||||
this.initialized.complete()
|
this.initialized.complete()
|
||||||
@@ -275,7 +280,7 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
return this.root.getAllTabs()
|
return this.root.getAllTabs()
|
||||||
}
|
}
|
||||||
|
|
||||||
getFocusedTab (): BaseTabComponent {
|
getFocusedTab (): BaseTabComponent|null {
|
||||||
return this.focusedTab
|
return this.focusedTab
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,10 +295,8 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
x.emitBlurred()
|
x.emitBlurred()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tab) {
|
tab.emitFocused()
|
||||||
tab.emitFocused()
|
this.focusChanged.next(tab)
|
||||||
this.focusChanged.next(tab)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.maximizedTab !== tab) {
|
if (this.maximizedTab !== tab) {
|
||||||
this.maximizedTab = null
|
this.maximizedTab = null
|
||||||
@@ -309,7 +312,7 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
/**
|
/**
|
||||||
* Focuses the first available tab inside the given [[SplitContainer]]
|
* Focuses the first available tab inside the given [[SplitContainer]]
|
||||||
*/
|
*/
|
||||||
focusAnyIn (parent: BaseTabComponent | SplitContainer): void {
|
focusAnyIn (parent?: BaseTabComponent | SplitContainer): void {
|
||||||
if (!parent) {
|
if (!parent) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -324,9 +327,9 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
* Inserts a new `tab` to the `side` of the `relative` tab
|
* Inserts a new `tab` to the `side` of the `relative` tab
|
||||||
*/
|
*/
|
||||||
async addTab (tab: BaseTabComponent, relative: BaseTabComponent|null, side: SplitDirection): Promise<void> {
|
async addTab (tab: BaseTabComponent, relative: BaseTabComponent|null, side: SplitDirection): Promise<void> {
|
||||||
await this.initialized$.toPromise()
|
tab.parent = this
|
||||||
|
|
||||||
let target = (relative ? this.getParentOf(relative) : null) || this.root
|
let target = (relative ? this.getParentOf(relative) : null) ?? this.root
|
||||||
let insertIndex = relative ? target.children.indexOf(relative) : -1
|
let insertIndex = relative ? target.children.indexOf(relative) : -1
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@@ -355,6 +358,9 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
target.children.splice(insertIndex, 0, tab)
|
target.children.splice(insertIndex, 0, tab)
|
||||||
|
|
||||||
this.recoveryStateChangedHint.next()
|
this.recoveryStateChangedHint.next()
|
||||||
|
|
||||||
|
await this.initialized$.toPromise()
|
||||||
|
|
||||||
this.attachTabView(tab)
|
this.attachTabView(tab)
|
||||||
|
|
||||||
setImmediate(() => {
|
setImmediate(() => {
|
||||||
@@ -374,11 +380,11 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
parent.children.splice(index, 1)
|
parent.children.splice(index, 1)
|
||||||
|
|
||||||
this.detachTabView(tab)
|
this.detachTabView(tab)
|
||||||
|
tab.parent = null
|
||||||
|
|
||||||
this.layout()
|
this.layout()
|
||||||
|
|
||||||
this.tabRemoved.next(tab)
|
this.tabRemoved.next(tab)
|
||||||
|
|
||||||
if (this.root.children.length === 0) {
|
if (this.root.children.length === 0) {
|
||||||
this.destroy()
|
this.destroy()
|
||||||
} else {
|
} else {
|
||||||
@@ -390,6 +396,10 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
* Moves focus in the given direction
|
* Moves focus in the given direction
|
||||||
*/
|
*/
|
||||||
navigate (dir: SplitDirection): void {
|
navigate (dir: SplitDirection): void {
|
||||||
|
if (!this.focusedTab) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
let rel: BaseTabComponent | SplitContainer = this.focusedTab
|
let rel: BaseTabComponent | SplitContainer = this.focusedTab
|
||||||
let parent = this.getParentOf(rel)
|
let parent = this.getParentOf(rel)
|
||||||
if (!parent) {
|
if (!parent) {
|
||||||
@@ -434,7 +444,7 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
* @returns the immediate parent of `tab`
|
* @returns the immediate parent of `tab`
|
||||||
*/
|
*/
|
||||||
getParentOf (tab: BaseTabComponent | SplitContainer, root?: SplitContainer): SplitContainer|null {
|
getParentOf (tab: BaseTabComponent | SplitContainer, root?: SplitContainer): SplitContainer|null {
|
||||||
root = root || this.root
|
root = root ?? this.root
|
||||||
for (const child of root.children) {
|
for (const child of root.children) {
|
||||||
if (child instanceof SplitContainer) {
|
if (child instanceof SplitContainer) {
|
||||||
const r = this.getParentOf(tab, child)
|
const r = this.getParentOf(tab, child)
|
||||||
@@ -461,7 +471,7 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
async getCurrentProcess (): Promise<BaseTabProcess|null> {
|
async getCurrentProcess (): Promise<BaseTabProcess|null> {
|
||||||
return (await Promise.all(this.getAllTabs().map(x => x.getCurrentProcess()))).find(x => !!x) || null
|
return (await Promise.all(this.getAllTabs().map(x => x.getCurrentProcess()))).find(x => !!x) ?? null
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@@ -477,6 +487,12 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
layout (): void {
|
||||||
|
this.root.normalize()
|
||||||
|
this._spanners = []
|
||||||
|
this.layoutInternal(this.root, 0, 0, 100, 100)
|
||||||
|
}
|
||||||
|
|
||||||
private attachTabView (tab: BaseTabComponent) {
|
private attachTabView (tab: BaseTabComponent) {
|
||||||
const ref = this.viewContainer.insert(tab.hostView) as EmbeddedViewRef<any> // eslint-disable-line @typescript-eslint/no-unnecessary-type-assertion
|
const ref = this.viewContainer.insert(tab.hostView) as EmbeddedViewRef<any> // eslint-disable-line @typescript-eslint/no-unnecessary-type-assertion
|
||||||
this.viewRefs.set(tab, ref)
|
this.viewRefs.set(tab, ref)
|
||||||
@@ -502,15 +518,9 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private layout () {
|
|
||||||
this.root.normalize()
|
|
||||||
this._spanners = []
|
|
||||||
this.layoutInternal(this.root, 0, 0, 100, 100)
|
|
||||||
}
|
|
||||||
|
|
||||||
private layoutInternal (root: SplitContainer, x: number, y: number, w: number, h: number) {
|
private layoutInternal (root: SplitContainer, x: number, y: number, w: number, h: number) {
|
||||||
const size = root.orientation === 'v' ? h : w
|
const size = root.orientation === 'v' ? h : w
|
||||||
const sizes = root.ratios.map(x => x * size)
|
const sizes = root.ratios.map(ratio => ratio * size)
|
||||||
|
|
||||||
root.x = x
|
root.x = x
|
||||||
root.y = y
|
root.y = y
|
||||||
@@ -526,21 +536,24 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
if (child instanceof SplitContainer) {
|
if (child instanceof SplitContainer) {
|
||||||
this.layoutInternal(child, childX, childY, childW, childH)
|
this.layoutInternal(child, childX, childY, childW, childH)
|
||||||
} else {
|
} else {
|
||||||
const element = this.viewRefs.get(child)!.rootNodes[0]
|
const viewRef = this.viewRefs.get(child)
|
||||||
element.classList.toggle('child', true)
|
if (viewRef) {
|
||||||
element.classList.toggle('maximized', child === this.maximizedTab)
|
const element = viewRef.rootNodes[0]
|
||||||
element.classList.toggle('minimized', this.maximizedTab && child !== this.maximizedTab)
|
element.classList.toggle('child', true)
|
||||||
element.classList.toggle('focused', child === this.focusedTab)
|
element.classList.toggle('maximized', child === this.maximizedTab)
|
||||||
element.style.left = `${childX}%`
|
element.classList.toggle('minimized', this.maximizedTab && child !== this.maximizedTab)
|
||||||
element.style.top = `${childY}%`
|
element.classList.toggle('focused', this._allFocusMode || child === this.focusedTab)
|
||||||
element.style.width = `${childW}%`
|
element.style.left = `${childX}%`
|
||||||
element.style.height = `${childH}%`
|
element.style.top = `${childY}%`
|
||||||
|
element.style.width = `${childW}%`
|
||||||
|
element.style.height = `${childH}%`
|
||||||
|
|
||||||
if (child === this.maximizedTab) {
|
if (child === this.maximizedTab) {
|
||||||
element.style.left = '5%'
|
element.style.left = '5%'
|
||||||
element.style.top = '5%'
|
element.style.top = '5%'
|
||||||
element.style.width = '90%'
|
element.style.width = '90%'
|
||||||
element.style.height = '90%'
|
element.style.height = '90%'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
offset += sizes[i]
|
offset += sizes[i]
|
||||||
@@ -569,6 +582,7 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
if (recovered) {
|
if (recovered) {
|
||||||
const tab = this.tabsService.create(recovered.type, recovered.options)
|
const tab = this.tabsService.create(recovered.type, recovered.options)
|
||||||
children.push(tab)
|
children.push(tab)
|
||||||
|
tab.parent = this
|
||||||
this.attachTabView(tab)
|
this.attachTabView(tab)
|
||||||
} else {
|
} else {
|
||||||
state.ratios.splice(state.children.indexOf(childState), 0)
|
state.ratios.splice(state.children.indexOf(childState), 0)
|
||||||
@@ -586,7 +600,7 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class SplitTabRecoveryProvider extends TabRecoveryProvider {
|
export class SplitTabRecoveryProvider extends TabRecoveryProvider {
|
||||||
async recover (recoveryToken: RecoveryToken): Promise<RecoveredTab|null> {
|
async recover (recoveryToken: RecoveryToken): Promise<RecoveredTab|null> {
|
||||||
if (recoveryToken && recoveryToken.type === 'app:split-tab') {
|
if (recoveryToken.type === 'app:split-tab') {
|
||||||
return {
|
return {
|
||||||
type: SplitTabComponent,
|
type: SplitTabComponent,
|
||||||
options: { _recoveredState: recoveryToken },
|
options: { _recoveredState: recoveryToken },
|
||||||
|
@@ -34,8 +34,8 @@ export class SplitTabSpannerComponent {
|
|||||||
let current = start
|
let current = start
|
||||||
const oldPosition: number = this.isVertical ? this.element.nativeElement.offsetTop : this.element.nativeElement.offsetLeft
|
const oldPosition: number = this.isVertical ? this.element.nativeElement.offsetTop : this.element.nativeElement.offsetLeft
|
||||||
|
|
||||||
const dragHandler = (e: MouseEvent) => {
|
const dragHandler = (dragEvent: MouseEvent) => {
|
||||||
current = this.isVertical ? e.pageY : e.pageX
|
current = this.isVertical ? dragEvent.pageY : dragEvent.pageX
|
||||||
const newPosition = oldPosition + (current - start)
|
const newPosition = oldPosition + (current - start)
|
||||||
if (this.isVertical) {
|
if (this.isVertical) {
|
||||||
this.element.nativeElement.style.top = `${newPosition - this.marginOffset}px`
|
this.element.nativeElement.style.top = `${newPosition - this.marginOffset}px`
|
||||||
|
@@ -26,10 +26,10 @@ export class StartPageComponent {
|
|||||||
.map(provider => provider.provide())
|
.map(provider => provider.provide())
|
||||||
.reduce((a, b) => a.concat(b))
|
.reduce((a, b) => a.concat(b))
|
||||||
.filter(x => !!x.click)
|
.filter(x => !!x.click)
|
||||||
.sort((a: ToolbarButton, b: ToolbarButton) => (a.weight || 0) - (b.weight || 0))
|
.sort((a: ToolbarButton, b: ToolbarButton) => (a.weight ?? 0) - (b.weight ?? 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
sanitizeIcon (icon: string): any {
|
sanitizeIcon (icon?: string): any {
|
||||||
return this.domSanitizer.bypassSecurityTrustHtml(icon || '')
|
return this.domSanitizer.bypassSecurityTrustHtml(icon ?? '')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
.progressbar([style.width]='progress + "%"', *ngIf='progress != null')
|
.progressbar([style.width]='progress + "%"', *ngIf='progress != null')
|
||||||
.index(
|
.index(*ngIf='!config.store.terminal.hideTabIndex',
|
||||||
#handle,
|
#handle,
|
||||||
[style.background-color]='tab.color',
|
[style.background-color]='tab.color',
|
||||||
) {{index + 1}}
|
) {{index + 1}}
|
||||||
.name([title]='tab.customTitle || tab.title') {{tab.customTitle || tab.title}}
|
.name([title]='tab.customTitle || tab.title') {{tab.customTitle || tab.title}}
|
||||||
button((click)='app.closeTab(tab, true)') ×
|
button(*ngIf='!config.store.terminal.hideCloseButton',(click)='app.closeTab(tab, true)') ×
|
||||||
|
@@ -13,6 +13,11 @@ $tabs-height: 38px;
|
|||||||
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
|
&.vertical {
|
||||||
|
flex: none;
|
||||||
|
height: $tabs-height;
|
||||||
|
}
|
||||||
|
|
||||||
.index {
|
.index {
|
||||||
flex: none;
|
flex: none;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||||
|
import type { MenuItemConstructorOptions } from 'electron'
|
||||||
import { Component, Input, Optional, Inject, HostBinding, HostListener, ViewChild, ElementRef } from '@angular/core'
|
import { Component, Input, Optional, Inject, HostBinding, HostListener, ViewChild, ElementRef } from '@angular/core'
|
||||||
import { SortableComponent } from 'ng2-dnd'
|
import { SortableComponent } from 'ng2-dnd'
|
||||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
@@ -9,10 +10,11 @@ import { HotkeysService } from '../services/hotkeys.service'
|
|||||||
import { ElectronService } from '../services/electron.service'
|
import { ElectronService } from '../services/electron.service'
|
||||||
import { AppService } from '../services/app.service'
|
import { AppService } from '../services/app.service'
|
||||||
import { HostAppService, Platform } from '../services/hostApp.service'
|
import { HostAppService, Platform } from '../services/hostApp.service'
|
||||||
|
import { ConfigService } from '../services/config.service'
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
export interface SortableComponentProxy {
|
export interface SortableComponentProxy {
|
||||||
setDragHandle (_: HTMLElement)
|
setDragHandle: (_: HTMLElement) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@@ -31,6 +33,7 @@ export class TabHeaderComponent {
|
|||||||
|
|
||||||
private constructor (
|
private constructor (
|
||||||
public app: AppService,
|
public app: AppService,
|
||||||
|
public config: ConfigService,
|
||||||
private electron: ElectronService,
|
private electron: ElectronService,
|
||||||
private hostApp: HostAppService,
|
private hostApp: HostAppService,
|
||||||
private ngbModal: NgbModal,
|
private ngbModal: NgbModal,
|
||||||
@@ -69,8 +72,8 @@ export class TabHeaderComponent {
|
|||||||
}).catch(() => null)
|
}).catch(() => null)
|
||||||
}
|
}
|
||||||
|
|
||||||
async buildContextMenu (): Promise<Electron.MenuItemConstructorOptions[]> {
|
async buildContextMenu (): Promise<MenuItemConstructorOptions[]> {
|
||||||
let items: Electron.MenuItemConstructorOptions[] = []
|
let items: MenuItemConstructorOptions[] = []
|
||||||
for (const section of await Promise.all(this.contextMenuProviders.map(x => x.getItems(this.tab, this)))) {
|
for (const section of await Promise.all(this.contextMenuProviders.map(x => x.getItems(this.tab, this)))) {
|
||||||
items.push({ type: 'separator' })
|
items.push({ type: 'separator' })
|
||||||
items = items.concat(section)
|
items = items.concat(section)
|
||||||
|
@@ -9,18 +9,25 @@
|
|||||||
.form-line
|
.form-line
|
||||||
.header
|
.header
|
||||||
.title Enable analytics
|
.title Enable analytics
|
||||||
.description Help us track the number of Terminus installs across the world!
|
.description Help track the number of Terminus installs across the world!
|
||||||
toggle([(ngModel)]='config.store.enableAnalytics')
|
toggle([(ngModel)]='config.store.enableAnalytics')
|
||||||
|
|
||||||
|
|
||||||
.form-line
|
.form-line
|
||||||
.header
|
.header
|
||||||
.title Enable SSH plugin
|
.title Enable global hotkey (#[strong Ctrl-Space])
|
||||||
|
.description Toggles the Terminus window visibility
|
||||||
|
toggle([(ngModel)]='enableGlobalHotkey')
|
||||||
|
|
||||||
|
.form-line
|
||||||
|
.header
|
||||||
|
.title Enable #[strong SSH] plugin
|
||||||
.description Adds an SSH connection manager UI to Terminus
|
.description Adds an SSH connection manager UI to Terminus
|
||||||
toggle([(ngModel)]='enableSSH')
|
toggle([(ngModel)]='enableSSH')
|
||||||
|
|
||||||
.form-line
|
.form-line
|
||||||
.header
|
.header
|
||||||
.title Enable Serial plugin
|
.title Enable #[strong Serial] plugin
|
||||||
.description Allows attaching Terminus to serial ports
|
.description Allows attaching Terminus to serial ports
|
||||||
toggle([(ngModel)]='enableSerial')
|
toggle([(ngModel)]='enableSerial')
|
||||||
|
|
||||||
|
@@ -13,6 +13,7 @@ import { HostAppService } from '../services/hostApp.service'
|
|||||||
export class WelcomeTabComponent extends BaseTabComponent {
|
export class WelcomeTabComponent extends BaseTabComponent {
|
||||||
enableSSH = false
|
enableSSH = false
|
||||||
enableSerial = false
|
enableSerial = false
|
||||||
|
enableGlobalHotkey = true
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
private hostApp: HostAppService,
|
private hostApp: HostAppService,
|
||||||
@@ -33,6 +34,9 @@ export class WelcomeTabComponent extends BaseTabComponent {
|
|||||||
if (!this.enableSerial) {
|
if (!this.enableSerial) {
|
||||||
this.config.store.pluginBlacklist.push('serial')
|
this.config.store.pluginBlacklist.push('serial')
|
||||||
}
|
}
|
||||||
|
if (!this.enableGlobalHotkey) {
|
||||||
|
this.config.store.hotkeys['toggle-window'] = []
|
||||||
|
}
|
||||||
this.config.save()
|
this.config.save()
|
||||||
this.hostApp.getWindow().reload()
|
this.hostApp.getWindow().reload()
|
||||||
}
|
}
|
||||||
|
@@ -12,7 +12,8 @@ button {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
line-height: 0;
|
line-height: 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
&:not(:hover):not(:active) {
|
&:not(:hover):not(:active) {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,8 @@ appearance:
|
|||||||
dock: off
|
dock: off
|
||||||
dockScreen: current
|
dockScreen: current
|
||||||
dockFill: 0.5
|
dockFill: 0.5
|
||||||
|
dockHideOnBlur: false
|
||||||
|
dockAlwaysOnTop: true
|
||||||
tabsLocation: top
|
tabsLocation: top
|
||||||
cycleTabs: true
|
cycleTabs: true
|
||||||
theme: Standard
|
theme: Standard
|
||||||
|
@@ -36,7 +36,7 @@ import { ConfigService } from './services/config.service'
|
|||||||
import { StandardTheme, StandardCompactTheme, PaperTheme } from './theme'
|
import { StandardTheme, StandardCompactTheme, PaperTheme } from './theme'
|
||||||
import { CoreConfigProvider } from './config'
|
import { CoreConfigProvider } from './config'
|
||||||
import { AppHotkeyProvider } from './hotkeys'
|
import { AppHotkeyProvider } from './hotkeys'
|
||||||
import { TaskCompletionContextMenu, CommonOptionsContextMenu, CloseContextMenu } from './tabContextMenu'
|
import { TaskCompletionContextMenu, CommonOptionsContextMenu, TabManagementContextMenu } from './tabContextMenu'
|
||||||
|
|
||||||
import 'perfect-scrollbar/css/perfect-scrollbar.css'
|
import 'perfect-scrollbar/css/perfect-scrollbar.css'
|
||||||
import 'ng2-dnd/bundles/style.css'
|
import 'ng2-dnd/bundles/style.css'
|
||||||
@@ -54,7 +54,7 @@ const PROVIDERS = [
|
|||||||
{ provide: Theme, useClass: PaperTheme, multi: true },
|
{ provide: Theme, useClass: PaperTheme, multi: true },
|
||||||
{ provide: ConfigProvider, useClass: CoreConfigProvider, multi: true },
|
{ provide: ConfigProvider, useClass: CoreConfigProvider, multi: true },
|
||||||
{ provide: TabContextMenuItemProvider, useClass: CommonOptionsContextMenu, multi: true },
|
{ provide: TabContextMenuItemProvider, useClass: CommonOptionsContextMenu, multi: true },
|
||||||
{ provide: TabContextMenuItemProvider, useClass: CloseContextMenu, multi: true },
|
{ provide: TabContextMenuItemProvider, useClass: TabManagementContextMenu, multi: true },
|
||||||
{ provide: TabContextMenuItemProvider, useClass: TaskCompletionContextMenu, multi: true },
|
{ provide: TabContextMenuItemProvider, useClass: TaskCompletionContextMenu, multi: true },
|
||||||
{ provide: TabRecoveryProvider, useClass: SplitTabRecoveryProvider, multi: true },
|
{ provide: TabRecoveryProvider, useClass: SplitTabRecoveryProvider, multi: true },
|
||||||
{ provide: PERFECT_SCROLLBAR_CONFIG, useValue: { suppressScrollX: true } },
|
{ provide: PERFECT_SCROLLBAR_CONFIG, useValue: { suppressScrollX: true } },
|
||||||
|
@@ -46,13 +46,13 @@ class CompletionObserver {
|
|||||||
export class AppService {
|
export class AppService {
|
||||||
tabs: BaseTabComponent[] = []
|
tabs: BaseTabComponent[] = []
|
||||||
|
|
||||||
get activeTab (): BaseTabComponent { return this._activeTab }
|
get activeTab (): BaseTabComponent|null { return this._activeTab ?? null }
|
||||||
|
|
||||||
private lastTabIndex = 0
|
private lastTabIndex = 0
|
||||||
private _activeTab: BaseTabComponent
|
private _activeTab: BaseTabComponent | null = null
|
||||||
private closedTabsStack: RecoveryToken[] = []
|
private closedTabsStack: RecoveryToken[] = []
|
||||||
|
|
||||||
private activeTabChange = new Subject<BaseTabComponent>()
|
private activeTabChange = new Subject<BaseTabComponent|null>()
|
||||||
private tabsChanged = new Subject<void>()
|
private tabsChanged = new Subject<void>()
|
||||||
private tabOpened = new Subject<BaseTabComponent>()
|
private tabOpened = new Subject<BaseTabComponent>()
|
||||||
private tabClosed = new Subject<BaseTabComponent>()
|
private tabClosed = new Subject<BaseTabComponent>()
|
||||||
@@ -60,7 +60,7 @@ export class AppService {
|
|||||||
|
|
||||||
private completionObservers = new Map<BaseTabComponent, CompletionObserver>()
|
private completionObservers = new Map<BaseTabComponent, CompletionObserver>()
|
||||||
|
|
||||||
get activeTabChange$ (): Observable<BaseTabComponent> { return this.activeTabChange }
|
get activeTabChange$ (): Observable<BaseTabComponent|null> { return this.activeTabChange }
|
||||||
get tabOpened$ (): Observable<BaseTabComponent> { return this.tabOpened }
|
get tabOpened$ (): Observable<BaseTabComponent> { return this.tabOpened }
|
||||||
get tabsChanged$ (): Observable<void> { return this.tabsChanged }
|
get tabsChanged$ (): Observable<void> { return this.tabsChanged }
|
||||||
get tabClosed$ (): Observable<BaseTabComponent> { return this.tabClosed }
|
get tabClosed$ (): Observable<BaseTabComponent> { return this.tabClosed }
|
||||||
@@ -97,9 +97,7 @@ export class AppService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hostApp.windowFocused$.subscribe(() => {
|
hostApp.windowFocused$.subscribe(() => this._activeTab?.emitFocused())
|
||||||
this._activeTab?.emitFocused()
|
|
||||||
})
|
|
||||||
|
|
||||||
this.tabClosed$.subscribe(async tab => {
|
this.tabClosed$.subscribe(async tab => {
|
||||||
const token = await tab.getRecoveryToken()
|
const token = await tab.getRecoveryToken()
|
||||||
@@ -187,12 +185,12 @@ export class AppService {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
selectTab (tab: BaseTabComponent): void {
|
selectTab (tab: BaseTabComponent|null): void {
|
||||||
if (this._activeTab === tab) {
|
if (tab && this._activeTab === tab) {
|
||||||
this._activeTab.emitFocused()
|
this._activeTab.emitFocused()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (this.tabs.includes(this._activeTab)) {
|
if (this._activeTab && this.tabs.includes(this._activeTab)) {
|
||||||
this.lastTabIndex = this.tabs.indexOf(this._activeTab)
|
this.lastTabIndex = this.tabs.indexOf(this._activeTab)
|
||||||
} else {
|
} else {
|
||||||
this.lastTabIndex = 0
|
this.lastTabIndex = 0
|
||||||
@@ -203,12 +201,10 @@ export class AppService {
|
|||||||
}
|
}
|
||||||
this._activeTab = tab
|
this._activeTab = tab
|
||||||
this.activeTabChange.next(tab)
|
this.activeTabChange.next(tab)
|
||||||
if (this._activeTab) {
|
setImmediate(() => {
|
||||||
setImmediate(() => {
|
this._activeTab?.emitFocused()
|
||||||
this._activeTab.emitFocused()
|
})
|
||||||
})
|
this.hostApp.setTitle(this._activeTab?.title)
|
||||||
this.hostApp.setTitle(this._activeTab.title)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getParentTab (tab: BaseTabComponent): SplitTabComponent|null {
|
getParentTab (tab: BaseTabComponent): SplitTabComponent|null {
|
||||||
@@ -231,6 +227,9 @@ export class AppService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
nextTab (): void {
|
nextTab (): void {
|
||||||
|
if (!this._activeTab) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if (this.tabs.length > 1) {
|
if (this.tabs.length > 1) {
|
||||||
const tabIndex = this.tabs.indexOf(this._activeTab)
|
const tabIndex = this.tabs.indexOf(this._activeTab)
|
||||||
if (tabIndex < this.tabs.length - 1) {
|
if (tabIndex < this.tabs.length - 1) {
|
||||||
@@ -242,6 +241,9 @@ export class AppService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
previousTab (): void {
|
previousTab (): void {
|
||||||
|
if (!this._activeTab) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if (this.tabs.length > 1) {
|
if (this.tabs.length > 1) {
|
||||||
const tabIndex = this.tabs.indexOf(this._activeTab)
|
const tabIndex = this.tabs.indexOf(this._activeTab)
|
||||||
if (tabIndex > 0) {
|
if (tabIndex > 0) {
|
||||||
@@ -253,6 +255,9 @@ export class AppService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
moveSelectedTabLeft (): void {
|
moveSelectedTabLeft (): void {
|
||||||
|
if (!this._activeTab) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if (this.tabs.length > 1) {
|
if (this.tabs.length > 1) {
|
||||||
const tabIndex = this.tabs.indexOf(this._activeTab)
|
const tabIndex = this.tabs.indexOf(this._activeTab)
|
||||||
if (tabIndex > 0) {
|
if (tabIndex > 0) {
|
||||||
@@ -264,6 +269,9 @@ export class AppService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
moveSelectedTabRight (): void {
|
moveSelectedTabRight (): void {
|
||||||
|
if (!this._activeTab) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if (this.tabs.length > 1) {
|
if (this.tabs.length > 1) {
|
||||||
const tabIndex = this.tabs.indexOf(this._activeTab)
|
const tabIndex = this.tabs.indexOf(this._activeTab)
|
||||||
if (tabIndex < this.tabs.length - 1) {
|
if (tabIndex < this.tabs.length - 1) {
|
||||||
|
@@ -97,7 +97,7 @@ export class ConfigService {
|
|||||||
private changed = new Subject<void>()
|
private changed = new Subject<void>()
|
||||||
private _store: any
|
private _store: any
|
||||||
private defaults: any
|
private defaults: any
|
||||||
private servicesCache: { [id: string]: Function[] }|null = null
|
private servicesCache: Record<string, Function[]>|null = null // eslint-disable-line @typescript-eslint/ban-types
|
||||||
|
|
||||||
get changed$ (): Observable<void> { return this.changed }
|
get changed$ (): Observable<void> { return this.changed }
|
||||||
|
|
||||||
@@ -109,10 +109,7 @@ export class ConfigService {
|
|||||||
) {
|
) {
|
||||||
this.path = path.join(electron.app.getPath('userData'), 'config.yaml')
|
this.path = path.join(electron.app.getPath('userData'), 'config.yaml')
|
||||||
this.defaults = configProviders.map(provider => {
|
this.defaults = configProviders.map(provider => {
|
||||||
let defaults = {}
|
let defaults = provider.platformDefaults[hostApp.platform] || {}
|
||||||
if (provider.platformDefaults) {
|
|
||||||
defaults = configMerge(defaults, provider.platformDefaults[hostApp.platform] || {})
|
|
||||||
}
|
|
||||||
if (provider.defaults) {
|
if (provider.defaults) {
|
||||||
defaults = configMerge(defaults, provider.defaults)
|
defaults = configMerge(defaults, provider.defaults)
|
||||||
}
|
}
|
||||||
@@ -159,7 +156,7 @@ export class ConfigService {
|
|||||||
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.safeDump(this._store), 'utf8')
|
||||||
this.emitChange()
|
this.emitChange()
|
||||||
this.hostApp.broadcastConfigChange(this.store)
|
this.hostApp.broadcastConfigChange(JSON.parse(JSON.stringify(this.store)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -189,15 +186,15 @@ export class ConfigService {
|
|||||||
*
|
*
|
||||||
* @typeparam T Base provider type
|
* @typeparam T Base provider type
|
||||||
*/
|
*/
|
||||||
enabledServices<T extends object> (services: T[]): T[] {
|
enabledServices<T extends object> (services: T[]): T[] { // eslint-disable-line @typescript-eslint/ban-types
|
||||||
if (!this.servicesCache) {
|
if (!this.servicesCache) {
|
||||||
this.servicesCache = {}
|
this.servicesCache = {}
|
||||||
const ngModule = window['rootModule'].ɵinj
|
const ngModule = window['rootModule'].ɵinj
|
||||||
for (const imp of ngModule.imports) {
|
for (const imp of ngModule.imports) {
|
||||||
const module = imp['ngModule'] || imp
|
const module = imp.ngModule || imp
|
||||||
if (module.ɵinj?.providers) {
|
if (module.ɵinj?.providers) {
|
||||||
this.servicesCache[module['pluginName']] = module.ɵinj.providers.map(provider => {
|
this.servicesCache[module.pluginName] = module.ɵinj.providers.map(provider => {
|
||||||
return provider['useClass'] || provider
|
return provider.useClass || provider
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
import type { Display } from 'electron'
|
||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { ConfigService } from '../services/config.service'
|
import { ConfigService } from '../services/config.service'
|
||||||
import { ElectronService } from '../services/electron.service'
|
import { ElectronService } from '../services/electron.service'
|
||||||
@@ -11,8 +12,8 @@ export class DockingService {
|
|||||||
private config: ConfigService,
|
private config: ConfigService,
|
||||||
private hostApp: HostAppService,
|
private hostApp: HostAppService,
|
||||||
) {
|
) {
|
||||||
electron.screen.on('display-removed', () => this.repositionWindow())
|
hostApp.displaysChanged$.subscribe(() => this.repositionWindow())
|
||||||
electron.screen.on('display-metrics-changed', () => this.repositionWindow())
|
hostApp.displayMetricsChanged$.subscribe(() => this.repositionWindow())
|
||||||
}
|
}
|
||||||
|
|
||||||
dock (): void {
|
dock (): void {
|
||||||
@@ -25,6 +26,7 @@ export class DockingService {
|
|||||||
|
|
||||||
let display = this.electron.screen.getAllDisplays()
|
let display = this.electron.screen.getAllDisplays()
|
||||||
.filter(x => x.id === this.config.store.appearance.dockScreen)[0]
|
.filter(x => x.id === this.config.store.appearance.dockScreen)[0]
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
if (!display) {
|
if (!display) {
|
||||||
display = this.getCurrentScreen()
|
display = this.getCurrentScreen()
|
||||||
}
|
}
|
||||||
@@ -53,17 +55,19 @@ export class DockingService {
|
|||||||
newBounds.y = display.bounds.y
|
newBounds.y = display.bounds.y
|
||||||
}
|
}
|
||||||
|
|
||||||
this.hostApp.setAlwaysOnTop(true)
|
const alwaysOnTop = this.config.store.appearance.dockAlwaysOnTop
|
||||||
|
|
||||||
|
this.hostApp.setAlwaysOnTop(alwaysOnTop)
|
||||||
setImmediate(() => {
|
setImmediate(() => {
|
||||||
this.hostApp.setBounds(newBounds)
|
this.hostApp.setBounds(newBounds)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
getCurrentScreen (): Electron.Display {
|
getCurrentScreen (): Display {
|
||||||
return this.electron.screen.getDisplayNearestPoint(this.electron.screen.getCursorScreenPoint())
|
return this.electron.screen.getDisplayNearestPoint(this.electron.screen.getCursorScreenPoint())
|
||||||
}
|
}
|
||||||
|
|
||||||
getScreens (): Electron.Display[] {
|
getScreens (): Display[] {
|
||||||
const primaryDisplayID = this.electron.screen.getPrimaryDisplay().id
|
const primaryDisplayID = this.electron.screen.getPrimaryDisplay().id
|
||||||
return this.electron.screen.getAllDisplays().sort((a, b) =>
|
return this.electron.screen.getAllDisplays().sort((a, b) =>
|
||||||
a.bounds.x === b.bounds.x ? a.bounds.y - b.bounds.y : a.bounds.x - b.bounds.x
|
a.bounds.x === b.bounds.x ? a.bounds.y - b.bounds.y : a.bounds.x - b.bounds.x
|
||||||
@@ -71,7 +75,7 @@ export class DockingService {
|
|||||||
return {
|
return {
|
||||||
...display,
|
...display,
|
||||||
id: display.id,
|
id: display.id,
|
||||||
name: display.id === primaryDisplayID ? 'Primary Display' : `Display ${index +1}`,
|
name: display.id === primaryDisplayID ? 'Primary Display' : `Display ${index + 1}`,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { TouchBar, BrowserWindow, Menu, MenuItem, NativeImage } from 'electron'
|
import { App, IpcRenderer, Shell, Dialog, Clipboard, GlobalShortcut, Screen, Remote, AutoUpdater, TouchBar, BrowserWindow, Menu, MenuItem, NativeImage, MessageBoxOptions } from 'electron'
|
||||||
|
|
||||||
export interface MessageBoxResponse {
|
export interface MessageBoxResponse {
|
||||||
response: number
|
response: number
|
||||||
@@ -8,16 +8,16 @@ export interface MessageBoxResponse {
|
|||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class ElectronService {
|
export class ElectronService {
|
||||||
app: Electron.App
|
app: App
|
||||||
ipcRenderer: Electron.IpcRenderer
|
ipcRenderer: IpcRenderer
|
||||||
shell: Electron.Shell
|
shell: Shell
|
||||||
dialog: Electron.Dialog
|
dialog: Dialog
|
||||||
clipboard: Electron.Clipboard
|
clipboard: Clipboard
|
||||||
globalShortcut: Electron.GlobalShortcut
|
globalShortcut: GlobalShortcut
|
||||||
nativeImage: typeof NativeImage
|
nativeImage: typeof NativeImage
|
||||||
screen: Electron.Screen
|
screen: Screen
|
||||||
remote: Electron.Remote
|
remote: Remote
|
||||||
autoUpdater: Electron.AutoUpdater
|
autoUpdater: AutoUpdater
|
||||||
TouchBar: typeof TouchBar
|
TouchBar: typeof TouchBar
|
||||||
BrowserWindow: typeof BrowserWindow
|
BrowserWindow: typeof BrowserWindow
|
||||||
Menu: typeof Menu
|
Menu: typeof Menu
|
||||||
@@ -44,8 +44,8 @@ export class ElectronService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async showMessageBox (
|
async showMessageBox (
|
||||||
browserWindow: Electron.BrowserWindow,
|
browserWindow: BrowserWindow,
|
||||||
options: Electron.MessageBoxOptions
|
options: MessageBoxOptions
|
||||||
): Promise<MessageBoxResponse> {
|
): Promise<MessageBoxResponse> {
|
||||||
return this.dialog.showMessageBox(browserWindow, options)
|
return this.dialog.showMessageBox(browserWindow, options)
|
||||||
}
|
}
|
||||||
|
@@ -3,7 +3,7 @@ import { Injectable } from '@angular/core'
|
|||||||
import { ElectronService } from './electron.service'
|
import { ElectronService } from './electron.service'
|
||||||
import { ConfigService } from './config.service'
|
import { ConfigService } from './config.service'
|
||||||
import * as mixpanel from 'mixpanel'
|
import * as mixpanel from 'mixpanel'
|
||||||
import * as uuidv4 from 'uuid/v4'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class HomeBaseService {
|
export class HomeBaseService {
|
||||||
@@ -58,7 +58,7 @@ export class HomeBaseService {
|
|||||||
|
|
||||||
getAnalyticsProperties (): Record<string, string> {
|
getAnalyticsProperties (): Record<string, string> {
|
||||||
return {
|
return {
|
||||||
distinct_id: window.localStorage.analyticsUserID, // eslint-disable-line @typescript-eslint/camelcase
|
distinct_id: window.localStorage.analyticsUserID,
|
||||||
platform: process.platform,
|
platform: process.platform,
|
||||||
os: os.release(),
|
os: os.release(),
|
||||||
version: this.appVersion,
|
version: this.appVersion,
|
||||||
|
@@ -1,13 +1,17 @@
|
|||||||
|
import type { BrowserWindow, TouchBar, MenuItemConstructorOptions } from 'electron'
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
|
import * as fs from 'mz/fs'
|
||||||
import shellEscape from 'shell-escape'
|
import shellEscape from 'shell-escape'
|
||||||
import { Observable, Subject } from 'rxjs'
|
import { Observable, Subject } from 'rxjs'
|
||||||
import { Injectable, NgZone, EventEmitter } from '@angular/core'
|
import { Injectable, NgZone, EventEmitter } from '@angular/core'
|
||||||
import { ElectronService } from './electron.service'
|
import { ElectronService } from './electron.service'
|
||||||
import { Logger, LogService } from './log.service'
|
import { Logger, LogService } from './log.service'
|
||||||
import { isWindowsBuild, WIN_BUILD_FLUENT_BG_MOVE_BUG_FIXED, WIN_BUILD_FLUENT_BG_SUPPORTED } from '../utils'
|
import { isWindowsBuild, WIN_BUILD_FLUENT_BG_SUPPORTED } from '../utils'
|
||||||
|
|
||||||
export enum Platform {
|
export enum Platform {
|
||||||
Linux, macOS, Windows,
|
Linux = 'Linux',
|
||||||
|
macOS = 'macOS',
|
||||||
|
Windows = 'Windows',
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Bounds {
|
export interface Bounds {
|
||||||
@@ -42,6 +46,7 @@ export class HostAppService {
|
|||||||
private windowMoved = new Subject<void>()
|
private windowMoved = new Subject<void>()
|
||||||
private windowFocused = new Subject<void>()
|
private windowFocused = new Subject<void>()
|
||||||
private displayMetricsChanged = new Subject<void>()
|
private displayMetricsChanged = new Subject<void>()
|
||||||
|
private displaysChanged = new Subject<void>()
|
||||||
private logger: Logger
|
private logger: Logger
|
||||||
private windowId: number
|
private windowId: number
|
||||||
|
|
||||||
@@ -91,6 +96,8 @@ export class HostAppService {
|
|||||||
|
|
||||||
get displayMetricsChanged$ (): Observable<void> { return this.displayMetricsChanged }
|
get displayMetricsChanged$ (): Observable<void> { return this.displayMetricsChanged }
|
||||||
|
|
||||||
|
get displaysChanged$ (): Observable<void> { return this.displaysChanged }
|
||||||
|
|
||||||
private constructor (
|
private constructor (
|
||||||
private zone: NgZone,
|
private zone: NgZone,
|
||||||
private electron: ElectronService,
|
private electron: ElectronService,
|
||||||
@@ -140,9 +147,14 @@ export class HostAppService {
|
|||||||
this.zone.run(() => this.displayMetricsChanged.next())
|
this.zone.run(() => this.displayMetricsChanged.next())
|
||||||
})
|
})
|
||||||
|
|
||||||
electron.ipcRenderer.on('host:second-instance', (_$event, argv: any, cwd: string) => this.zone.run(() => {
|
electron.ipcRenderer.on('host:displays-changed', () => {
|
||||||
|
this.zone.run(() => this.displaysChanged.next())
|
||||||
|
})
|
||||||
|
|
||||||
|
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)
|
||||||
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') {
|
||||||
@@ -157,7 +169,11 @@ export class HostAppService {
|
|||||||
this.cliOpenProfile.next(argv.profileName)
|
this.cliOpenProfile.next(argv.profileName)
|
||||||
} else if (op === undefined) {
|
} else if (op === undefined) {
|
||||||
this.newWindow()
|
this.newWindow()
|
||||||
} else {
|
} else if ((await fs.lstat(opAsPath)).isDirectory()) {
|
||||||
|
this.cliOpenDirectory.next(opAsPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (secondInstance) {
|
||||||
this.secondInstance.next()
|
this.secondInstance.next()
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
@@ -166,10 +182,7 @@ export class HostAppService {
|
|||||||
this.configChangeBroadcast.next()
|
this.configChangeBroadcast.next()
|
||||||
}))
|
}))
|
||||||
|
|
||||||
if (
|
if (isWindowsBuild(WIN_BUILD_FLUENT_BG_SUPPORTED)) {
|
||||||
isWindowsBuild(WIN_BUILD_FLUENT_BG_SUPPORTED) &&
|
|
||||||
!isWindowsBuild(WIN_BUILD_FLUENT_BG_MOVE_BUG_FIXED)
|
|
||||||
) {
|
|
||||||
electron.ipcRenderer.send('window-set-disable-vibrancy-while-dragging', true)
|
electron.ipcRenderer.send('window-set-disable-vibrancy-while-dragging', true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -177,8 +190,8 @@ export class HostAppService {
|
|||||||
/**
|
/**
|
||||||
* Returns the current remote [[BrowserWindow]]
|
* Returns the current remote [[BrowserWindow]]
|
||||||
*/
|
*/
|
||||||
getWindow (): Electron.BrowserWindow {
|
getWindow (): BrowserWindow {
|
||||||
return this.electron.BrowserWindow.fromId(this.windowId)
|
return this.electron.BrowserWindow.fromId(this.windowId)!
|
||||||
}
|
}
|
||||||
|
|
||||||
newWindow (): void {
|
newWindow (): void {
|
||||||
@@ -228,29 +241,29 @@ export class HostAppService {
|
|||||||
* @param type `null`, or `fluent` when supported (Windowd only)
|
* @param type `null`, or `fluent` when supported (Windowd only)
|
||||||
*/
|
*/
|
||||||
setVibrancy (enable: boolean, type: string|null): void {
|
setVibrancy (enable: boolean, type: string|null): void {
|
||||||
if (!isWindowsBuild(WIN_BUILD_FLUENT_BG_SUPPORTED)) {
|
if (this.platform === Platform.Windows && !isWindowsBuild(WIN_BUILD_FLUENT_BG_SUPPORTED)) {
|
||||||
type = null
|
type = null
|
||||||
}
|
}
|
||||||
document.body.classList.toggle('vibrant', enable)
|
document.body.classList.toggle('vibrant', enable)
|
||||||
this.electron.ipcRenderer.send('window-set-vibrancy', enable, type)
|
this.electron.ipcRenderer.send('window-set-vibrancy', enable, type)
|
||||||
}
|
}
|
||||||
|
|
||||||
setTitle (title: string): void {
|
setTitle (title?: string): void {
|
||||||
this.electron.ipcRenderer.send('window-set-title', title)
|
this.electron.ipcRenderer.send('window-set-title', title ?? 'Terminus')
|
||||||
}
|
}
|
||||||
|
|
||||||
setTouchBar (touchBar: Electron.TouchBar): void {
|
setTouchBar (touchBar: TouchBar): void {
|
||||||
this.getWindow().setTouchBar(touchBar)
|
this.getWindow().setTouchBar(touchBar)
|
||||||
}
|
}
|
||||||
|
|
||||||
popupContextMenu (menuDefinition: Electron.MenuItemConstructorOptions[]): void {
|
popupContextMenu (menuDefinition: MenuItemConstructorOptions[]): void {
|
||||||
this.electron.Menu.buildFromTemplate(menuDefinition).popup({})
|
this.electron.Menu.buildFromTemplate(menuDefinition).popup({})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notifies other windows of config file changes
|
* Notifies other windows of config file changes
|
||||||
*/
|
*/
|
||||||
broadcastConfigChange (configStore: {[k: string]: any}): void {
|
broadcastConfigChange (configStore: Record<string, any>): void {
|
||||||
this.electron.ipcRenderer.send('app:config-change', configStore)
|
this.electron.ipcRenderer.send('app:config-change', configStore)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -172,7 +172,7 @@ export class HotkeysService {
|
|||||||
return (
|
return (
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
this.config.enabledServices(this.hotkeyProviders)
|
this.config.enabledServices(this.hotkeyProviders)
|
||||||
.map(async x => x.provide ? x.provide() : x.hotkeys)
|
.map(async x => x.provide())
|
||||||
)
|
)
|
||||||
).reduce((a, b) => a.concat(b))
|
).reduce((a, b) => a.concat(b))
|
||||||
}
|
}
|
||||||
@@ -189,6 +189,7 @@ export class HotkeysService {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
let electronKeySpec = item[0]
|
let electronKeySpec = item[0]
|
||||||
|
electronKeySpec = electronKeySpec.replace('Meta', 'Super')
|
||||||
electronKeySpec = electronKeySpec.replace('⌘', 'Command')
|
electronKeySpec = electronKeySpec.replace('⌘', 'Command')
|
||||||
electronKeySpec = electronKeySpec.replace('⌥', 'Alt')
|
electronKeySpec = electronKeySpec.replace('⌥', 'Alt')
|
||||||
electronKeySpec = electronKeySpec.replace(/-/g, '+')
|
electronKeySpec = electronKeySpec.replace(/-/g, '+')
|
||||||
@@ -221,7 +222,7 @@ export class HotkeysService {
|
|||||||
if (!(value instanceof Array)) {
|
if (!(value instanceof Array)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (value) {
|
if (value.length > 0) {
|
||||||
value = value.map((item: string | string[]) => typeof item === 'string' ? [item] : item)
|
value = value.map((item: string | string[]) => typeof item === 'string' ? [item] : item)
|
||||||
keys[key] = value
|
keys[key] = value
|
||||||
}
|
}
|
||||||
|
@@ -28,7 +28,7 @@ const initializeWinston = (electron: ElectronService) => {
|
|||||||
|
|
||||||
export class Logger {
|
export class Logger {
|
||||||
constructor (
|
constructor (
|
||||||
private winstonLogger: any,
|
private winstonLogger: winston.Logger,
|
||||||
private name: string,
|
private name: string,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@@ -54,15 +54,13 @@ export class Logger {
|
|||||||
|
|
||||||
private doLog (level: string, ...args: any[]): void {
|
private doLog (level: string, ...args: any[]): void {
|
||||||
console[level](`%c[${this.name}]`, 'color: #aaa', ...args)
|
console[level](`%c[${this.name}]`, 'color: #aaa', ...args)
|
||||||
if (this.winstonLogger) {
|
this.winstonLogger[level](...args)
|
||||||
this.winstonLogger[level](...args)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class LogService {
|
export class LogService {
|
||||||
private log: any
|
private log: winston.Logger
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
private constructor (electron: ElectronService) {
|
private constructor (electron: ElectronService) {
|
||||||
|
@@ -44,7 +44,7 @@ export class ShellIntegrationService {
|
|||||||
'extras',
|
'extras',
|
||||||
'automator-workflows',
|
'automator-workflows',
|
||||||
)
|
)
|
||||||
this.automatorWorkflowsDestination = path.join(process.env.HOME as string, 'Library', 'Services')
|
this.automatorWorkflowsDestination = path.join(process.env.HOME!, 'Library', 'Services')
|
||||||
}
|
}
|
||||||
this.updatePaths()
|
this.updatePaths()
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ export class ShellIntegrationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async install (): Promise<void> {
|
async install (): Promise<void> {
|
||||||
const exe: string = process.env.PORTABLE_EXECUTABLE_FILE || this.electron.app.getPath('exe')
|
const exe: string = process.env.PORTABLE_EXECUTABLE_FILE ?? this.electron.app.getPath('exe')
|
||||||
if (this.hostApp.platform === Platform.macOS) {
|
if (this.hostApp.platform === Platform.macOS) {
|
||||||
for (const wf of this.automatorWorkflows) {
|
for (const wf of this.automatorWorkflows) {
|
||||||
await exec(`cp -r "${this.automatorWorkflowsLocation}/${wf}" "${this.automatorWorkflowsDestination}"`)
|
await exec(`cp -r "${this.automatorWorkflowsLocation}/${wf}" "${this.automatorWorkflowsDestination}"`)
|
||||||
@@ -73,10 +73,10 @@ export class ShellIntegrationService {
|
|||||||
wnr.setRegistryValue(wnr.HK.CU, registryKey.path + '\\command', '', wnr.REG.SZ, exe + ' ' + registryKey.command)
|
wnr.setRegistryValue(wnr.HK.CU, registryKey.path + '\\command', '', wnr.REG.SZ, exe + ' ' + registryKey.command)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(wnr.getRegistryKey(wnr.HK.CU, 'Software\\Classes\\Directory\\Background\\shell\\Open Terminus here')) {
|
if (wnr.getRegistryKey(wnr.HK.CU, 'Software\\Classes\\Directory\\Background\\shell\\Open Terminus here')) {
|
||||||
wnr.deleteRegistryKey(wnr.HK.CU, 'Software\\Classes\\Directory\\Background\\shell\\Open Terminus here')
|
wnr.deleteRegistryKey(wnr.HK.CU, 'Software\\Classes\\Directory\\Background\\shell\\Open Terminus here')
|
||||||
}
|
}
|
||||||
if(wnr.getRegistryKey(wnr.HK.CU, 'Software\\Classes\\*\\shell\\Paste path into Terminus')) {
|
if (wnr.getRegistryKey(wnr.HK.CU, 'Software\\Classes\\*\\shell\\Paste path into Terminus')) {
|
||||||
wnr.deleteRegistryKey(wnr.HK.CU, 'Software\\Classes\\*\\shell\\Paste path into Terminus')
|
wnr.deleteRegistryKey(wnr.HK.CU, 'Software\\Classes\\*\\shell\\Paste path into Terminus')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -11,7 +11,7 @@ export class TabRecoveryService {
|
|||||||
enabled = false
|
enabled = false
|
||||||
|
|
||||||
private constructor (
|
private constructor (
|
||||||
@Inject(TabRecoveryProvider) private tabRecoveryProviders: TabRecoveryProvider[],
|
@Inject(TabRecoveryProvider) private tabRecoveryProviders: TabRecoveryProvider[]|null,
|
||||||
private config: ConfigService,
|
private config: ConfigService,
|
||||||
log: LogService
|
log: LogService
|
||||||
) {
|
) {
|
||||||
@@ -23,35 +23,28 @@ export class TabRecoveryService {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
window.localStorage.tabsRecovery = JSON.stringify(
|
window.localStorage.tabsRecovery = JSON.stringify(
|
||||||
await Promise.all(
|
(await Promise.all(
|
||||||
tabs
|
tabs
|
||||||
.map(tab => {
|
.map(async tab => tab.getRecoveryToken().then(r => {
|
||||||
let token = tab.getRecoveryToken()
|
if (r) {
|
||||||
if (token) {
|
r.tabTitle = tab.title
|
||||||
token = token.then(r => {
|
if (tab.color) {
|
||||||
if (r) {
|
r.tabColor = tab.color
|
||||||
r.tabTitle = tab.title
|
}
|
||||||
if (tab.color) {
|
|
||||||
r.tabColor = tab.color
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return r
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
return token
|
return r
|
||||||
})
|
}))
|
||||||
.filter(token => !!token)
|
)).filter(token => !!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 {
|
||||||
const tab = await provider.recover(token)
|
const tab = await provider.recover(token)
|
||||||
if (tab !== null) {
|
if (tab !== null) {
|
||||||
tab.options = tab.options || {}
|
tab.options = tab.options || {}
|
||||||
tab.options.color = token.tabColor || null
|
tab.options.color = token.tabColor ?? null
|
||||||
tab.options.title = token.tabTitle || ''
|
tab.options.title = token.tabTitle || ''
|
||||||
return tab
|
return tab
|
||||||
}
|
}
|
||||||
|
@@ -22,7 +22,7 @@ export class TabsService {
|
|||||||
const componentRef = componentFactory.create(this.injector)
|
const componentRef = componentFactory.create(this.injector)
|
||||||
const tab = componentRef.instance
|
const tab = componentRef.instance
|
||||||
tab.hostView = componentRef.hostView
|
tab.hostView = componentRef.hostView
|
||||||
Object.assign(tab, inputs || {})
|
Object.assign(tab, inputs ?? {})
|
||||||
return tab
|
return tab
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -18,11 +18,11 @@ export class ThemesService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
findTheme (name: string): Theme|null {
|
findTheme (name: string): Theme|null {
|
||||||
return this.config.enabledServices(this.themes).find(x => x.name === name) || null
|
return this.config.enabledServices(this.themes).find(x => x.name === name) ?? null
|
||||||
}
|
}
|
||||||
|
|
||||||
findCurrentTheme (): Theme {
|
findCurrentTheme (): Theme {
|
||||||
return this.findTheme(this.config.store.appearance.theme) || this.findTheme('Standard')!
|
return this.findTheme(this.config.store.appearance.theme) ?? this.findTheme('Standard')!
|
||||||
}
|
}
|
||||||
|
|
||||||
applyTheme (theme: Theme): void {
|
applyTheme (theme: Theme): void {
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
|
import { NativeImage, SegmentedControlSegment, TouchBarSegmentedControl } from 'electron'
|
||||||
import { Injectable, Inject, NgZone } from '@angular/core'
|
import { Injectable, Inject, NgZone } from '@angular/core'
|
||||||
import { TouchBarSegmentedControl, SegmentedControlSegment } from 'electron'
|
|
||||||
import { AppService } from './app.service'
|
import { AppService } from './app.service'
|
||||||
import { ConfigService } from './config.service'
|
import { ConfigService } from './config.service'
|
||||||
import { ElectronService } from './electron.service'
|
import { ElectronService } from './electron.service'
|
||||||
@@ -12,7 +12,7 @@ export class TouchbarService {
|
|||||||
private tabsSegmentedControl: TouchBarSegmentedControl
|
private tabsSegmentedControl: TouchBarSegmentedControl
|
||||||
private buttonsSegmentedControl: TouchBarSegmentedControl
|
private buttonsSegmentedControl: TouchBarSegmentedControl
|
||||||
private tabSegments: SegmentedControlSegment[] = []
|
private tabSegments: SegmentedControlSegment[] = []
|
||||||
private nsImageCache: {[id: string]: Electron.NativeImage} = {}
|
private nsImageCache: Record<string, NativeImage> = {}
|
||||||
|
|
||||||
private constructor (
|
private constructor (
|
||||||
private app: AppService,
|
private app: AppService,
|
||||||
@@ -33,6 +33,7 @@ export class TouchbarService {
|
|||||||
app.tabOpened$.subscribe(tab => {
|
app.tabOpened$.subscribe(tab => {
|
||||||
tab.titleChange$.subscribe(title => {
|
tab.titleChange$.subscribe(title => {
|
||||||
const segment = this.tabSegments[app.tabs.indexOf(tab)]
|
const segment = this.tabSegments[app.tabs.indexOf(tab)]
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
if (segment) {
|
if (segment) {
|
||||||
segment.label = this.shortenTitle(title)
|
segment.label = this.shortenTitle(title)
|
||||||
this.tabsSegmentedControl.segments = this.tabSegments
|
this.tabsSegmentedControl.segments = this.tabSegments
|
||||||
@@ -41,6 +42,7 @@ export class TouchbarService {
|
|||||||
tab.activity$.subscribe(hasActivity => {
|
tab.activity$.subscribe(hasActivity => {
|
||||||
const showIcon = this.app.activeTab !== tab && hasActivity
|
const showIcon = this.app.activeTab !== tab && hasActivity
|
||||||
const segment = this.tabSegments[app.tabs.indexOf(tab)]
|
const segment = this.tabSegments[app.tabs.indexOf(tab)]
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
if (segment) {
|
if (segment) {
|
||||||
segment.icon = showIcon ? activityIcon : undefined
|
segment.icon = showIcon ? activityIcon : undefined
|
||||||
}
|
}
|
||||||
@@ -53,7 +55,7 @@ export class TouchbarService {
|
|||||||
label: this.shortenTitle(tab.title),
|
label: this.shortenTitle(tab.title),
|
||||||
}))
|
}))
|
||||||
this.tabsSegmentedControl.segments = this.tabSegments
|
this.tabsSegmentedControl.segments = this.tabSegments
|
||||||
this.tabsSegmentedControl.selectedIndex = this.app.tabs.indexOf(this.app.activeTab)
|
this.tabsSegmentedControl.selectedIndex = this.app.activeTab ? this.app.tabs.indexOf(this.app.activeTab) : 0
|
||||||
}
|
}
|
||||||
|
|
||||||
update (): void {
|
update (): void {
|
||||||
@@ -66,14 +68,14 @@ export class TouchbarService {
|
|||||||
buttons = buttons.concat(provider.provide())
|
buttons = buttons.concat(provider.provide())
|
||||||
})
|
})
|
||||||
buttons = buttons.filter(x => !!x.touchBarNSImage)
|
buttons = buttons.filter(x => !!x.touchBarNSImage)
|
||||||
buttons.sort((a, b) => (a.weight || 0) - (b.weight || 0))
|
buttons.sort((a, b) => (a.weight ?? 0) - (b.weight ?? 0))
|
||||||
this.tabSegments = this.app.tabs.map(tab => ({
|
this.tabSegments = this.app.tabs.map(tab => ({
|
||||||
label: this.shortenTitle(tab.title),
|
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.tabs.indexOf(this.app.activeTab),
|
selectedIndex: this.app.activeTab ? this.app.tabs.indexOf(this.app.activeTab) : undefined,
|
||||||
change: (selectedIndex) => this.zone.run(() => {
|
change: (selectedIndex) => this.zone.run(() => {
|
||||||
this.app.selectTab(this.app.tabs[selectedIndex])
|
this.app.selectTab(this.app.tabs[selectedIndex])
|
||||||
}),
|
}),
|
||||||
@@ -100,15 +102,16 @@ export class TouchbarService {
|
|||||||
this.hostApp.setTouchBar(touchBar)
|
this.hostApp.setTouchBar(touchBar)
|
||||||
}
|
}
|
||||||
|
|
||||||
private getButton (button: ToolbarButton): Electron.SegmentedControlSegment {
|
private getButton (button: ToolbarButton): SegmentedControlSegment {
|
||||||
return {
|
return {
|
||||||
label: button.touchBarNSImage ? undefined : this.shortenTitle(button.touchBarTitle || button.title),
|
label: button.touchBarNSImage ? undefined : this.shortenTitle(button.touchBarTitle ?? button.title),
|
||||||
icon: button.touchBarNSImage ? this.getCachedNSImage(button.touchBarNSImage) : undefined,
|
icon: button.touchBarNSImage ? this.getCachedNSImage(button.touchBarNSImage) : undefined,
|
||||||
// click: () => this.zone.run(() => button.click()),
|
// click: () => this.zone.run(() => button.click()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private getCachedNSImage (name: string) {
|
private getCachedNSImage (name: string) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||||
if (!this.nsImageCache[name]) {
|
if (!this.nsImageCache[name]) {
|
||||||
this.nsImageCache[name] = this.electron.nativeImage.createFromNamedImage(name, [0, 0, 1])
|
this.nsImageCache[name] = this.electron.nativeImage.createFromNamedImage(name, [0, 0, 1])
|
||||||
}
|
}
|
||||||
|
@@ -1,14 +1,9 @@
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import * as fs from 'fs'
|
|
||||||
import os from 'os'
|
|
||||||
|
|
||||||
import { spawn } from 'mz/child_process'
|
|
||||||
|
|
||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { Logger, LogService } from './log.service'
|
import { Logger, LogService } from './log.service'
|
||||||
import { ElectronService } from './electron.service'
|
import { ElectronService } from './electron.service'
|
||||||
import { ConfigService } from './config.service'
|
import { ConfigService } from './config.service'
|
||||||
import { AppUpdater } from 'electron-updater'
|
|
||||||
|
|
||||||
const UPDATES_URL = 'https://api.github.com/repos/eugeny/terminus/releases/latest'
|
const UPDATES_URL = 'https://api.github.com/repos/eugeny/terminus/releases/latest'
|
||||||
|
|
||||||
@@ -19,7 +14,6 @@ export class UpdaterService {
|
|||||||
private downloaded: Promise<boolean>
|
private downloaded: Promise<boolean>
|
||||||
private electronUpdaterAvailable = true
|
private electronUpdaterAvailable = true
|
||||||
private updateURL: string
|
private updateURL: string
|
||||||
private autoUpdater: AppUpdater
|
|
||||||
|
|
||||||
private constructor (
|
private constructor (
|
||||||
log: LogService,
|
log: LogService,
|
||||||
@@ -33,26 +27,29 @@ export class UpdaterService {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
this.autoUpdater = electron.remote.require('electron-updater').autoUpdater
|
electron.autoUpdater.on('update-available', () => {
|
||||||
|
|
||||||
this.autoUpdater.autoInstallOnAppQuit = !!config.store.enableAutomaticUpdates
|
|
||||||
|
|
||||||
this.autoUpdater.on('update-available', () => {
|
|
||||||
this.logger.info('Update available')
|
this.logger.info('Update available')
|
||||||
this.autoUpdater.downloadUpdate()
|
|
||||||
})
|
})
|
||||||
this.autoUpdater.once('update-not-available', () => {
|
|
||||||
|
electron.autoUpdater.once('update-not-available', () => {
|
||||||
this.logger.info('No updates')
|
this.logger.info('No updates')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
electron.autoUpdater.once('error', err => {
|
||||||
|
this.logger.error(err)
|
||||||
|
})
|
||||||
|
|
||||||
this.downloaded = new Promise<boolean>(resolve => {
|
this.downloaded = new Promise<boolean>(resolve => {
|
||||||
this.autoUpdater.once('update-downloaded', () => resolve(true))
|
electron.autoUpdater.once('update-downloaded', () => resolve(true))
|
||||||
})
|
})
|
||||||
|
|
||||||
if (config.store.enableAutomaticUpdates && this.electronUpdaterAvailable && !process.env.TERMINUS_DEV) {
|
if (config.store.enableAutomaticUpdates && this.electronUpdaterAvailable && !process.env.TERMINUS_DEV) {
|
||||||
this.logger.debug('Checking for updates')
|
this.logger.debug('Checking for updates')
|
||||||
try {
|
try {
|
||||||
this.autoUpdater.checkForUpdates()
|
electron.autoUpdater.setFeedURL({
|
||||||
|
url: `https://update.electronjs.org/eugeny/terminus/${process.platform}-${process.arch}/${electron.app.getVersion()}`,
|
||||||
|
})
|
||||||
|
electron.autoUpdater.checkForUpdates()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.electronUpdaterAvailable = false
|
this.electronUpdaterAvailable = false
|
||||||
this.logger.info('Electron updater unavailable, falling back', e)
|
this.logger.info('Electron updater unavailable, falling back', e)
|
||||||
@@ -84,21 +81,8 @@ export class UpdaterService {
|
|||||||
if (!this.electronUpdaterAvailable) {
|
if (!this.electronUpdaterAvailable) {
|
||||||
this.electron.shell.openExternal(this.updateURL)
|
this.electron.shell.openExternal(this.updateURL)
|
||||||
} else {
|
} else {
|
||||||
if (process.platform === 'win32') {
|
await this.downloaded
|
||||||
let downloadpath = await this.autoUpdater.downloadUpdate()
|
this.electron.autoUpdater.quitAndInstall()
|
||||||
fs.exists(downloadpath[0], (exists) => {
|
|
||||||
if (exists) {
|
|
||||||
fs.copyFile(downloadpath[0], os.tmpdir() + 'terminus-installer-temp.exe', (err) => {
|
|
||||||
if (!err) {
|
|
||||||
spawn(os.tmpdir() + 'terminus-installer-temp.exe', ['--force-run'], { detached: true, stdio: 'ignore' })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
await this.downloaded
|
|
||||||
this.autoUpdater.quitAndInstall(false, true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,15 +1,17 @@
|
|||||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||||
|
import type { MenuItemConstructorOptions } from 'electron'
|
||||||
import { Injectable, NgZone } from '@angular/core'
|
import { Injectable, NgZone } from '@angular/core'
|
||||||
import { Subscription } from 'rxjs'
|
import { Subscription } from 'rxjs'
|
||||||
import { AppService } from './services/app.service'
|
import { AppService } from './services/app.service'
|
||||||
import { BaseTabComponent } from './components/baseTab.component'
|
import { BaseTabComponent } from './components/baseTab.component'
|
||||||
import { TabHeaderComponent } from './components/tabHeader.component'
|
import { TabHeaderComponent } from './components/tabHeader.component'
|
||||||
|
import { SplitTabComponent, SplitDirection } from './components/splitTab.component'
|
||||||
import { TabContextMenuItemProvider } from './api/tabContextMenuProvider'
|
import { TabContextMenuItemProvider } from './api/tabContextMenuProvider'
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CloseContextMenu extends TabContextMenuItemProvider {
|
export class TabManagementContextMenu extends TabContextMenuItemProvider {
|
||||||
weight = -5
|
weight = 99
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
private app: AppService,
|
private app: AppService,
|
||||||
@@ -18,8 +20,8 @@ export class CloseContextMenu extends TabContextMenuItemProvider {
|
|||||||
super()
|
super()
|
||||||
}
|
}
|
||||||
|
|
||||||
async getItems (tab: BaseTabComponent, tabHeader?: TabHeaderComponent): Promise<Electron.MenuItemConstructorOptions[]> {
|
async getItems (tab: BaseTabComponent, tabHeader?: TabHeaderComponent): Promise<MenuItemConstructorOptions[]> {
|
||||||
let items = [
|
let items: MenuItemConstructorOptions[] = [
|
||||||
{
|
{
|
||||||
label: 'Close',
|
label: 'Close',
|
||||||
click: () => this.zone.run(() => {
|
click: () => this.zone.run(() => {
|
||||||
@@ -59,6 +61,24 @@ export class CloseContextMenu extends TabContextMenuItemProvider {
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
} else {
|
||||||
|
if (tab.parent instanceof SplitTabComponent) {
|
||||||
|
const directions: SplitDirection[] = ['r', 'b', 'l', 't']
|
||||||
|
items.push({
|
||||||
|
label: 'Split',
|
||||||
|
submenu: directions.map(dir => ({
|
||||||
|
label: {
|
||||||
|
r: 'Right',
|
||||||
|
b: 'Down',
|
||||||
|
l: 'Left',
|
||||||
|
t: 'Up',
|
||||||
|
}[dir],
|
||||||
|
click: () => this.zone.run(() => {
|
||||||
|
(tab.parent as SplitTabComponent).splitTab(tab, dir)
|
||||||
|
}),
|
||||||
|
})) as MenuItemConstructorOptions[],
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return items
|
return items
|
||||||
}
|
}
|
||||||
@@ -86,12 +106,14 @@ export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
|
|||||||
super()
|
super()
|
||||||
}
|
}
|
||||||
|
|
||||||
async getItems (tab: BaseTabComponent, tabHeader?: TabHeaderComponent): Promise<Electron.MenuItemConstructorOptions[]> {
|
async getItems (tab: BaseTabComponent, tabHeader?: TabHeaderComponent): Promise<MenuItemConstructorOptions[]> {
|
||||||
|
let items: MenuItemConstructorOptions[] = []
|
||||||
if (tabHeader) {
|
if (tabHeader) {
|
||||||
return [
|
items = [
|
||||||
|
...items,
|
||||||
{
|
{
|
||||||
label: 'Rename',
|
label: 'Rename',
|
||||||
click: () => this.zone.run(() => tabHeader?.showRenameTabModal()),
|
click: () => this.zone.run(() => tabHeader.showRenameTabModal()),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Duplicate',
|
label: 'Duplicate',
|
||||||
@@ -99,7 +121,7 @@ export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Color',
|
label: 'Color',
|
||||||
sublabel: COLORS.find(x => x.value === tab.color)!.name,
|
sublabel: COLORS.find(x => x.value === tab.color)?.name,
|
||||||
submenu: COLORS.map(color => ({
|
submenu: COLORS.map(color => ({
|
||||||
label: color.name,
|
label: color.name,
|
||||||
type: 'radio',
|
type: 'radio',
|
||||||
@@ -107,11 +129,11 @@ export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
|
|||||||
click: () => this.zone.run(() => {
|
click: () => this.zone.run(() => {
|
||||||
tab.color = color.value
|
tab.color = color.value
|
||||||
}),
|
}),
|
||||||
})) as Electron.MenuItemConstructorOptions[],
|
})) as MenuItemConstructorOptions[],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
return []
|
return items
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,9 +147,9 @@ export class TaskCompletionContextMenu extends TabContextMenuItemProvider {
|
|||||||
super()
|
super()
|
||||||
}
|
}
|
||||||
|
|
||||||
async getItems (tab: BaseTabComponent): Promise<Electron.MenuItemConstructorOptions[]> {
|
async getItems (tab: BaseTabComponent): Promise<MenuItemConstructorOptions[]> {
|
||||||
const process = await tab.getCurrentProcess()
|
const process = await tab.getCurrentProcess()
|
||||||
let items: Electron.MenuItemConstructorOptions[] = []
|
const items: MenuItemConstructorOptions[] = []
|
||||||
|
|
||||||
const extTab: (BaseTabComponent & { __completionNotificationEnabled?: boolean, __outputNotificationSubscription?: Subscription|null }) = tab
|
const extTab: (BaseTabComponent & { __completionNotificationEnabled?: boolean, __outputNotificationSubscription?: Subscription|null }) = tab
|
||||||
|
|
||||||
|
@@ -6,7 +6,8 @@ app-root {
|
|||||||
|
|
||||||
.btn-tab-bar {
|
.btn-tab-bar {
|
||||||
line-height: 29px !important;
|
line-height: 29px !important;
|
||||||
|
height: 27px !important;
|
||||||
|
align-items: center;
|
||||||
svg {
|
svg {
|
||||||
height: 14px;
|
height: 14px;
|
||||||
}
|
}
|
||||||
|
@@ -137,7 +137,7 @@ app-root {
|
|||||||
.btn-tab-bar {
|
.btn-tab-bar {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
line-height: 42px;
|
line-height: 42px;
|
||||||
|
align-items: center;
|
||||||
svg, path {
|
svg, path {
|
||||||
fill: $black;
|
fill: $black;
|
||||||
fill-opacity: 0.75;
|
fill-opacity: 0.75;
|
||||||
|
@@ -29,7 +29,7 @@ body {
|
|||||||
background: $body-bg;
|
background: $body-bg;
|
||||||
|
|
||||||
&.vibrant {
|
&.vibrant {
|
||||||
background: rgba(0,0,0,.4);
|
background: rgba(0,0,0,.65);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -358,6 +358,7 @@ search-panel {
|
|||||||
.btn-secondary:not(:disabled):not(.disabled) {
|
.btn-secondary:not(:disabled):not(.disabled) {
|
||||||
&.active, &:active {
|
&.active, &:active {
|
||||||
background: #191e23;
|
background: #191e23;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -4,7 +4,6 @@ export const WIN_BUILD_CONPTY_SUPPORTED = 17692
|
|||||||
export const WIN_BUILD_CONPTY_STABLE = 18309
|
export const WIN_BUILD_CONPTY_STABLE = 18309
|
||||||
export const WIN_BUILD_WSL_EXE_DISTRO_FLAG = 17763
|
export const WIN_BUILD_WSL_EXE_DISTRO_FLAG = 17763
|
||||||
export const WIN_BUILD_FLUENT_BG_SUPPORTED = 17063
|
export const WIN_BUILD_FLUENT_BG_SUPPORTED = 17063
|
||||||
export const WIN_BUILD_FLUENT_BG_MOVE_BUG_FIXED = 18917
|
|
||||||
|
|
||||||
export function isWindowsBuild (build: number): boolean {
|
export function isWindowsBuild (build: number): boolean {
|
||||||
return process.platform === 'win32' && parseFloat(os.release()) >= 10 && parseInt(os.release().split('.')[2]) >= build
|
return process.platform === 'win32' && parseFloat(os.release()) >= 10 && parseInt(os.release().split('.')[2]) >= build
|
||||||
|
@@ -4,7 +4,7 @@ module.exports = {
|
|||||||
target: 'node',
|
target: 'node',
|
||||||
entry: 'src/index.ts',
|
entry: 'src/index.ts',
|
||||||
context: __dirname,
|
context: __dirname,
|
||||||
devtool: 'eval-cheap-module-source-map',
|
devtool: 'cheap-module-source-map',
|
||||||
output: {
|
output: {
|
||||||
path: path.resolve(__dirname, 'dist'),
|
path: path.resolve(__dirname, 'dist'),
|
||||||
filename: 'index.js',
|
filename: 'index.js',
|
||||||
|
@@ -2,22 +2,24 @@
|
|||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
"@types/js-yaml@^3.9.0":
|
"@dabh/diagnostics@^2.0.2":
|
||||||
version "3.12.3"
|
version "2.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-3.12.3.tgz#abf383c5b639d0aa8b8c4a420d6a85f703357d6c"
|
resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.2.tgz#290d08f7b381b8f94607dc8f471a12c675f9db31"
|
||||||
integrity sha512-otRe77JNNWzoVGLKw8TCspKswRoQToys4tuL6XYVBFxjgeM0RUrx7m3jkaTdxILxeGry3zM8mGYkGXMeQ02guA==
|
integrity sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q==
|
||||||
|
|
||||||
"@types/node@*":
|
|
||||||
version "13.7.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.7.1.tgz#238eb34a66431b71d2aaddeaa7db166f25971a0d"
|
|
||||||
integrity sha512-Zq8gcQGmn4txQEJeiXo/KiLpon8TzAl0kmKH4zdWctPj05nWwp1ClMdAVEloqrQKfaC48PNLdgN/aVaLqUrluA==
|
|
||||||
|
|
||||||
"@types/semver@^7.1.0":
|
|
||||||
version "7.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.1.0.tgz#c8c630d4c18cd326beff77404887596f96408408"
|
|
||||||
integrity sha512-pOKLaubrAEMUItGNpgwl0HMFPrSAFic8oSVIvfu1UwcgGNmNyK9gyhBHKmBnUTwwVvpZfkzUC0GaMgnL6P86uA==
|
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/node" "*"
|
colorspace "1.1.x"
|
||||||
|
enabled "2.0.x"
|
||||||
|
kuler "^2.0.0"
|
||||||
|
|
||||||
|
"@types/js-yaml@^3.9.0":
|
||||||
|
version "3.12.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-3.12.5.tgz#136d5e6a57a931e1cce6f9d8126aa98a9c92a6bb"
|
||||||
|
integrity sha512-JCcp6J0GV66Y4ZMDAQCXot4xprYB+Zfd3meK9+INSJeVZwJmHAW30BBEEkPzXswMXuiyReUGOP3GxrADc9wPww==
|
||||||
|
|
||||||
|
"@types/semver@^7.3.1":
|
||||||
|
version "7.3.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.4.tgz#43d7168fec6fa0988bb1a513a697b29296721afb"
|
||||||
|
integrity sha512-+nVsLKlcUCeMzD2ufHEYuJ9a2ovstb6Dp52A5VsoKxDXgvE051XgHI/33I1EymwkRGQkwnA0LkhnUzituGs4EQ==
|
||||||
|
|
||||||
"@types/shell-escape@^0.2.0":
|
"@types/shell-escape@^0.2.0":
|
||||||
version "0.2.0"
|
version "0.2.0"
|
||||||
@@ -45,12 +47,10 @@ argparse@^1.0.7:
|
|||||||
dependencies:
|
dependencies:
|
||||||
sprintf-js "~1.0.2"
|
sprintf-js "~1.0.2"
|
||||||
|
|
||||||
async@^2.6.1:
|
async@^3.1.0:
|
||||||
version "2.6.2"
|
version "3.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/async/-/async-2.6.2.tgz#18330ea7e6e313887f5d2f2a904bac6fe4dd5381"
|
resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720"
|
||||||
integrity sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==
|
integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==
|
||||||
dependencies:
|
|
||||||
lodash "^4.17.11"
|
|
||||||
|
|
||||||
at-least-node@^1.0.0:
|
at-least-node@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
@@ -65,14 +65,14 @@ axios@^0.19.0:
|
|||||||
follow-redirects "1.5.10"
|
follow-redirects "1.5.10"
|
||||||
|
|
||||||
bootstrap@^4.1.3:
|
bootstrap@^4.1.3:
|
||||||
version "4.4.1"
|
version "4.5.3"
|
||||||
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.4.1.tgz#8582960eea0c5cd2bede84d8b0baf3789c3e8b01"
|
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.5.3.tgz#c6a72b355aaf323920be800246a6e4ef30997fe6"
|
||||||
integrity sha512-tbx5cHubwE6e2ZG7nqM3g/FZ5PQEDMWmMGNrCUBVRPHXTJaH7CBDdsLeu3eCh3B1tzAxTnAbtmrzvWEvT2NNEA==
|
integrity sha512-o9ppKQioXGqhw8Z7mah6KdTYpNQY//tipnkxppWhPbiSWdD+1raYsnhwEZjkTHYbGee4cVQ0Rx65EhOY/HNLcQ==
|
||||||
|
|
||||||
builder-util-runtime@8.6.1:
|
builder-util-runtime@8.7.2:
|
||||||
version "8.6.1"
|
version "8.7.2"
|
||||||
resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-8.6.1.tgz#cf9a268fa51704de24f3c085aa8d1d1b3767d9ea"
|
resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-8.7.2.tgz#d93afc71428a12789b437e13850e1fa7da956d72"
|
||||||
integrity sha512-gwIUtMaICmc+e2EC3u3byXcwCyfhtG40LJRNnGfs8AYqacKl4ZLP50ab+uDttn7QAXe0LfMAuKz9v8bCODV0yg==
|
integrity sha512-xBqv+8bg6cfnzAQK1k3OGpfaHg+QkPgIgpEkXNhouZ0WiUkyZCftuRc2LYzQrLucFywpa14Xbc6+hTbpq83yRA==
|
||||||
dependencies:
|
dependencies:
|
||||||
debug "^4.1.1"
|
debug "^4.1.1"
|
||||||
sax "^1.2.4"
|
sax "^1.2.4"
|
||||||
@@ -95,9 +95,9 @@ color-name@^1.0.0:
|
|||||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||||
|
|
||||||
color-string@^1.5.2:
|
color-string@^1.5.2:
|
||||||
version "1.5.3"
|
version "1.5.4"
|
||||||
resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc"
|
resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.4.tgz#dd51cd25cfee953d138fe4002372cc3d0e504cb6"
|
||||||
integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==
|
integrity sha512-57yF5yt8Xa3czSEW1jfQDE79Idk0+AkN/4KWad6tbdxUmAs3MvjxlWSWD4deYytcRfoZ9nhKyFl1kj5tBvidbw==
|
||||||
dependencies:
|
dependencies:
|
||||||
color-name "^1.0.0"
|
color-name "^1.0.0"
|
||||||
simple-swizzle "^0.2.2"
|
simple-swizzle "^0.2.2"
|
||||||
@@ -110,15 +110,10 @@ color@3.0.x:
|
|||||||
color-convert "^1.9.1"
|
color-convert "^1.9.1"
|
||||||
color-string "^1.5.2"
|
color-string "^1.5.2"
|
||||||
|
|
||||||
colornames@^1.1.1:
|
|
||||||
version "1.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/colornames/-/colornames-1.1.1.tgz#f8889030685c7c4ff9e2a559f5077eb76a816f96"
|
|
||||||
integrity sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y=
|
|
||||||
|
|
||||||
colors@^1.2.1:
|
colors@^1.2.1:
|
||||||
version "1.3.3"
|
version "1.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d"
|
resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
|
||||||
integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==
|
integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==
|
||||||
|
|
||||||
colorspace@1.1.x:
|
colorspace@1.1.x:
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
@@ -129,9 +124,9 @@ 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.6.5"
|
version "3.8.2"
|
||||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a"
|
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.8.2.tgz#0a1fd6709246da9ca8eff5bb0cbd15fba9ac7044"
|
||||||
integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==
|
integrity sha512-FfApuSRgrR6G5s58casCBd9M2k+4ikuu4wbW6pJyYU7bd9zvFc9qf7vr5xmrZOhT9nn+8uwlH1oRR9jTnFoA3A==
|
||||||
|
|
||||||
core-util-is@~1.0.0:
|
core-util-is@~1.0.0:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
@@ -153,55 +148,39 @@ debug@^3.1.0:
|
|||||||
ms "^2.1.1"
|
ms "^2.1.1"
|
||||||
|
|
||||||
debug@^4.1.1:
|
debug@^4.1.1:
|
||||||
version "4.1.1"
|
version "4.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
|
resolved "https://registry.yarnpkg.com/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1"
|
||||||
integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
|
integrity sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==
|
||||||
dependencies:
|
dependencies:
|
||||||
ms "^2.1.1"
|
ms "2.1.2"
|
||||||
|
|
||||||
deepmerge@^4.1.1:
|
deepmerge@^4.1.1:
|
||||||
version "4.2.2"
|
version "4.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
|
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
|
||||||
integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==
|
integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==
|
||||||
|
|
||||||
diagnostics@^1.1.1:
|
|
||||||
version "1.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/diagnostics/-/diagnostics-1.1.1.tgz#cab6ac33df70c9d9a727490ae43ac995a769b22a"
|
|
||||||
integrity sha512-8wn1PmdunLJ9Tqbx+Fx/ZEuHfJf4NKSN2ZBj7SJC/OWRWha843+WsTjqMe1B5E3p28jqBlp+mJ2fPVxPyNgYKQ==
|
|
||||||
dependencies:
|
|
||||||
colorspace "1.1.x"
|
|
||||||
enabled "1.0.x"
|
|
||||||
kuler "1.0.x"
|
|
||||||
|
|
||||||
electron-updater@^4.0.6:
|
electron-updater@^4.0.6:
|
||||||
version "4.3.0"
|
version "4.3.5"
|
||||||
resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-4.3.0.tgz#f66c253b25431d9aeb04fbd33c79062f33943d44"
|
resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-4.3.5.tgz#4fb36f593a031c87ea07ee141c9f064d5deffb15"
|
||||||
integrity sha512-5K3vPgeiBGQaaCcZzQP00QYhGsh0l/q0mwzGWVZq1BHJ5akA+BpsY+EPiI9JzBhNVIdNlUvSKr5azUdbMwZeig==
|
integrity sha512-5jjN7ebvfj1cLI0VZMdCnJk6aC4bP+dy7ryBf21vArR0JzpRVk0OZHA2QBD+H5rm6ZSeDYHOY6+8PrMEqJ4wlQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/semver" "^7.1.0"
|
"@types/semver" "^7.3.1"
|
||||||
builder-util-runtime "8.6.1"
|
builder-util-runtime "8.7.2"
|
||||||
fs-extra "^9.0.0"
|
fs-extra "^9.0.1"
|
||||||
js-yaml "^3.13.1"
|
js-yaml "^3.14.0"
|
||||||
lazy-val "^1.0.4"
|
lazy-val "^1.0.4"
|
||||||
lodash.isequal "^4.5.0"
|
lodash.isequal "^4.5.0"
|
||||||
semver "^7.1.3"
|
semver "^7.3.2"
|
||||||
|
|
||||||
enabled@1.0.x:
|
enabled@2.0.x:
|
||||||
version "1.0.2"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/enabled/-/enabled-1.0.2.tgz#965f6513d2c2d1c5f4652b64a2e3396467fc2f93"
|
resolved "https://registry.yarnpkg.com/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2"
|
||||||
integrity sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M=
|
integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==
|
||||||
dependencies:
|
|
||||||
env-variable "0.0.x"
|
|
||||||
|
|
||||||
env-variable@0.0.x:
|
|
||||||
version "0.0.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/env-variable/-/env-variable-0.0.5.tgz#913dd830bef11e96a039c038d4130604eba37f88"
|
|
||||||
integrity sha512-zoB603vQReOFvTg5xMl9I1P2PnHsHQQKTEowsKKD7nseUfJq6UWzK+4YtlWUO1nhiQUxe6XMkk+JleSZD1NZFA==
|
|
||||||
|
|
||||||
es6-promise@^4.0.3:
|
es6-promise@^4.0.3:
|
||||||
version "4.2.6"
|
version "4.2.8"
|
||||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.6.tgz#b685edd8258886365ea62b57d30de28fadcd974f"
|
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
|
||||||
integrity sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==
|
integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==
|
||||||
|
|
||||||
es6-promisify@^5.0.0:
|
es6-promisify@^5.0.0:
|
||||||
version "5.0.0"
|
version "5.0.0"
|
||||||
@@ -216,14 +195,19 @@ esprima@^4.0.0:
|
|||||||
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
|
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
|
||||||
|
|
||||||
fast-safe-stringify@^2.0.4:
|
fast-safe-stringify@^2.0.4:
|
||||||
version "2.0.6"
|
version "2.0.7"
|
||||||
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz#04b26106cc56681f51a044cfc0d76cf0008ac2c2"
|
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743"
|
||||||
integrity sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg==
|
integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==
|
||||||
|
|
||||||
fecha@^2.3.3:
|
fecha@^4.2.0:
|
||||||
version "2.3.3"
|
version "4.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/fecha/-/fecha-2.3.3.tgz#948e74157df1a32fd1b12c3a3c3cdcb6ec9d96cd"
|
resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.0.tgz#3ffb6395453e3f3efff850404f0a59b6747f5f41"
|
||||||
integrity sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg==
|
integrity sha512-aN3pcx/DSmtyoovUudctc8+6Hl4T+hI9GBBHLjA76jdZl7+b1sgh5g4k+u/GL3dTy1/pnYzKp69FpJ0OicE3Wg==
|
||||||
|
|
||||||
|
fn.name@1.x.x:
|
||||||
|
version "1.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc"
|
||||||
|
integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==
|
||||||
|
|
||||||
follow-redirects@1.5.10:
|
follow-redirects@1.5.10:
|
||||||
version "1.5.10"
|
version "1.5.10"
|
||||||
@@ -232,10 +216,10 @@ follow-redirects@1.5.10:
|
|||||||
dependencies:
|
dependencies:
|
||||||
debug "=3.1.0"
|
debug "=3.1.0"
|
||||||
|
|
||||||
fs-extra@^9.0.0:
|
fs-extra@^9.0.1:
|
||||||
version "9.0.0"
|
version "9.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.0.0.tgz#b6afc31036e247b2466dc99c29ae797d5d4580a3"
|
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.0.1.tgz#910da0062437ba4c39fedd863f1675ccfefcb9fc"
|
||||||
integrity sha512-pmEYSk3vYsG/bF651KPUXZ+hvjpgWYw/Gc7W9NFUe3ZVLczKKWIij3IKpOrQcdw4TILtibFslZ0UmR8Vvzig4g==
|
integrity sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
at-least-node "^1.0.0"
|
at-least-node "^1.0.0"
|
||||||
graceful-fs "^4.2.0"
|
graceful-fs "^4.2.0"
|
||||||
@@ -243,9 +227,9 @@ fs-extra@^9.0.0:
|
|||||||
universalify "^1.0.0"
|
universalify "^1.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.2"
|
version "4.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02"
|
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
|
||||||
integrity sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==
|
integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==
|
||||||
|
|
||||||
https-proxy-agent@3.0.0:
|
https-proxy-agent@3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
@@ -256,48 +240,46 @@ https-proxy-agent@3.0.0:
|
|||||||
debug "^3.1.0"
|
debug "^3.1.0"
|
||||||
|
|
||||||
inherits@^2.0.3, inherits@~2.0.3:
|
inherits@^2.0.3, inherits@~2.0.3:
|
||||||
version "2.0.3"
|
version "2.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||||
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||||
|
|
||||||
is-arrayish@^0.3.1:
|
is-arrayish@^0.3.1:
|
||||||
version "0.3.2"
|
version "0.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03"
|
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03"
|
||||||
integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==
|
integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==
|
||||||
|
|
||||||
is-stream@^1.1.0:
|
is-stream@^2.0.0:
|
||||||
version "1.1.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3"
|
||||||
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
|
integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==
|
||||||
|
|
||||||
isarray@~1.0.0:
|
isarray@~1.0.0:
|
||||||
version "1.0.0"
|
version "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.13.1, js-yaml@^3.9.0:
|
js-yaml@^3.14.0, js-yaml@^3.9.0:
|
||||||
version "3.13.1"
|
version "3.14.0"
|
||||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
|
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482"
|
||||||
integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
|
integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==
|
||||||
dependencies:
|
dependencies:
|
||||||
argparse "^1.0.7"
|
argparse "^1.0.7"
|
||||||
esprima "^4.0.0"
|
esprima "^4.0.0"
|
||||||
|
|
||||||
jsonfile@^6.0.1:
|
jsonfile@^6.0.1:
|
||||||
version "6.0.1"
|
version "6.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.0.1.tgz#98966cba214378c8c84b82e085907b40bf614179"
|
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
|
||||||
integrity sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==
|
integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
universalify "^1.0.0"
|
universalify "^2.0.0"
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
graceful-fs "^4.1.6"
|
graceful-fs "^4.1.6"
|
||||||
|
|
||||||
kuler@1.0.x:
|
kuler@^2.0.0:
|
||||||
version "1.0.1"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/kuler/-/kuler-1.0.1.tgz#ef7c784f36c9fb6e16dd3150d152677b2b0228a6"
|
resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3"
|
||||||
integrity sha512-J9nVUucG1p/skKul6DU3PUZrhs0LPulNaeUOox0IyXDi8S4CztTHs1gQphhuZmzXG7VOQSf6NJfKuzteQLv9gQ==
|
integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==
|
||||||
dependencies:
|
|
||||||
colornames "^1.1.1"
|
|
||||||
|
|
||||||
lazy-val@^1.0.4:
|
lazy-val@^1.0.4:
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
@@ -309,19 +291,14 @@ lodash.isequal@^4.5.0:
|
|||||||
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
|
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
|
||||||
integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
|
integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
|
||||||
|
|
||||||
lodash@^4.17.11:
|
logform@^2.2.0:
|
||||||
version "4.17.14"
|
version "2.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba"
|
resolved "https://registry.yarnpkg.com/logform/-/logform-2.2.0.tgz#40f036d19161fc76b68ab50fdc7fe495544492f2"
|
||||||
integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw==
|
integrity sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg==
|
||||||
|
|
||||||
logform@^2.1.1:
|
|
||||||
version "2.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/logform/-/logform-2.1.2.tgz#957155ebeb67a13164069825ce67ddb5bb2dd360"
|
|
||||||
integrity sha512-+lZh4OpERDBLqjiwDLpAWNQu6KMjnlXH2ByZwCuSqVPJletw0kTWJf5CgSNAUKn1KUkv3m2cUz/LK8zyEy7wzQ==
|
|
||||||
dependencies:
|
dependencies:
|
||||||
colors "^1.2.1"
|
colors "^1.2.1"
|
||||||
fast-safe-stringify "^2.0.4"
|
fast-safe-stringify "^2.0.4"
|
||||||
fecha "^2.3.3"
|
fecha "^4.2.0"
|
||||||
ms "^2.1.1"
|
ms "^2.1.1"
|
||||||
triple-beam "^1.3.0"
|
triple-beam "^1.3.0"
|
||||||
|
|
||||||
@@ -337,7 +314,7 @@ ms@2.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||||
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
|
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
|
||||||
|
|
||||||
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"
|
||||||
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||||
@@ -355,25 +332,27 @@ ngx-perfect-scrollbar@^8.0.0:
|
|||||||
perfect-scrollbar "^1.4.0"
|
perfect-scrollbar "^1.4.0"
|
||||||
resize-observer-polyfill "^1.5.0"
|
resize-observer-polyfill "^1.5.0"
|
||||||
|
|
||||||
one-time@0.0.4:
|
one-time@^1.0.0:
|
||||||
version "0.0.4"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/one-time/-/one-time-0.0.4.tgz#f8cdf77884826fe4dff93e3a9cc37b1e4480742e"
|
resolved "https://registry.yarnpkg.com/one-time/-/one-time-1.0.0.tgz#e06bc174aed214ed58edede573b433bbf827cb45"
|
||||||
integrity sha1-+M33eISCb+Tf+T46nMN7HkSAdC4=
|
integrity sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==
|
||||||
|
dependencies:
|
||||||
|
fn.name "1.x.x"
|
||||||
|
|
||||||
perfect-scrollbar@^1.4.0:
|
perfect-scrollbar@^1.4.0:
|
||||||
version "1.4.0"
|
version "1.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/perfect-scrollbar/-/perfect-scrollbar-1.4.0.tgz#5d014ef9775e1f43058a1dbae9ed1daf0e7091f1"
|
resolved "https://registry.yarnpkg.com/perfect-scrollbar/-/perfect-scrollbar-1.5.0.tgz#821d224ed8ff61990c23f26db63048cdc75b6b83"
|
||||||
integrity sha512-/2Sk/khljhdrsamjJYS5NjrH+GKEHEwh7zFSiYyxROyYKagkE4kSn2zDQDRTOMo8mpT2jikxx6yI1dG7lNP/hw==
|
integrity sha512-NrNHJn5mUGupSiheBTy6x+6SXCFbLlm8fVZh9moIzw/LgqElN5q4ncR4pbCBCYuCJ8Kcl9mYM0NgDxvW+b4LxA==
|
||||||
|
|
||||||
process-nextick-args@~2.0.0:
|
process-nextick-args@~2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"
|
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
|
||||||
integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==
|
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
|
||||||
|
|
||||||
readable-stream@^2.3.6:
|
readable-stream@2.3.7, readable-stream@^2.3.7:
|
||||||
version "2.3.6"
|
version "2.3.7"
|
||||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
|
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
|
||||||
integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==
|
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
|
||||||
dependencies:
|
dependencies:
|
||||||
core-util-is "~1.0.0"
|
core-util-is "~1.0.0"
|
||||||
inherits "~2.0.3"
|
inherits "~2.0.3"
|
||||||
@@ -383,10 +362,10 @@ readable-stream@^2.3.6:
|
|||||||
string_decoder "~1.1.1"
|
string_decoder "~1.1.1"
|
||||||
util-deprecate "~1.0.1"
|
util-deprecate "~1.0.1"
|
||||||
|
|
||||||
readable-stream@^3.1.1:
|
readable-stream@^3.4.0:
|
||||||
version "3.3.0"
|
version "3.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.3.0.tgz#cb8011aad002eb717bf040291feba8569c986fb9"
|
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
|
||||||
integrity sha512-EsI+s3k3XsW+fU8fQACLN59ky34AZ14LoeVZpYwmZvldCFo0r0gnelwF2TcMjLor/BTL5aDJVBMkss0dthToPw==
|
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
|
||||||
dependencies:
|
dependencies:
|
||||||
inherits "^2.0.3"
|
inherits "^2.0.3"
|
||||||
string_decoder "^1.1.1"
|
string_decoder "^1.1.1"
|
||||||
@@ -402,15 +381,20 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1:
|
|||||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
|
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
|
||||||
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
|
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
|
||||||
|
|
||||||
|
safe-buffer@~5.2.0:
|
||||||
|
version "5.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||||
|
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||||
|
|
||||||
sax@^1.2.4:
|
sax@^1.2.4:
|
||||||
version "1.2.4"
|
version "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.1.3:
|
semver@^7.3.2:
|
||||||
version "7.1.3"
|
version "7.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.1.3.tgz#e4345ce73071c53f336445cfc19efb1c311df2a6"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938"
|
||||||
integrity sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA==
|
integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==
|
||||||
|
|
||||||
shell-escape@^0.2.0:
|
shell-escape@^0.2.0:
|
||||||
version "0.2.0"
|
version "0.2.0"
|
||||||
@@ -435,11 +419,11 @@ stack-trace@0.0.x:
|
|||||||
integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=
|
integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=
|
||||||
|
|
||||||
string_decoder@^1.1.1:
|
string_decoder@^1.1.1:
|
||||||
version "1.2.0"
|
version "1.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d"
|
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
|
||||||
integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==
|
integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
|
||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer "~5.1.0"
|
safe-buffer "~5.2.0"
|
||||||
|
|
||||||
string_decoder@~1.1.1:
|
string_decoder@~1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
@@ -463,35 +447,40 @@ universalify@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d"
|
resolved "https://registry.yarnpkg.com/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d"
|
||||||
integrity sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==
|
integrity sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==
|
||||||
|
|
||||||
|
universalify@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717"
|
||||||
|
integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==
|
||||||
|
|
||||||
util-deprecate@^1.0.1, util-deprecate@~1.0.1:
|
util-deprecate@^1.0.1, util-deprecate@~1.0.1:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||||
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
|
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
|
||||||
|
|
||||||
uuid@^7.0.1:
|
uuid@^8.0.0:
|
||||||
version "7.0.1"
|
version "8.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.1.tgz#95ed6ff3d8c881cbf85f0f05cc3915ef994818ef"
|
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.1.tgz#2ba2e6ca000da60fce5a196954ab241131e05a31"
|
||||||
integrity sha512-yqjRXZzSJm9Dbl84H2VDHpM3zMjzSJQ+hn6C4zqd5ilW+7P4ZmLEEqwho9LjP+tGuZlF4xrHQXT0h9QZUS/pWA==
|
integrity sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==
|
||||||
|
|
||||||
winston-transport@^4.3.0:
|
winston-transport@^4.4.0:
|
||||||
version "4.3.0"
|
version "4.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.3.0.tgz#df68c0c202482c448d9b47313c07304c2d7c2c66"
|
resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.4.0.tgz#17af518daa690d5b2ecccaa7acf7b20ca7925e59"
|
||||||
integrity sha512-B2wPuwUi3vhzn/51Uukcao4dIduEiPOcOt9HJ3QeaXgkJ5Z7UwpBzxS4ZGNHtrxrUvTwemsQiSys0ihOf8Mp1A==
|
integrity sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw==
|
||||||
dependencies:
|
dependencies:
|
||||||
readable-stream "^2.3.6"
|
readable-stream "^2.3.7"
|
||||||
triple-beam "^1.2.0"
|
triple-beam "^1.2.0"
|
||||||
|
|
||||||
winston@*, winston@^3.2.1:
|
winston@*, winston@^3.3.3:
|
||||||
version "3.2.1"
|
version "3.3.3"
|
||||||
resolved "https://registry.yarnpkg.com/winston/-/winston-3.2.1.tgz#63061377976c73584028be2490a1846055f77f07"
|
resolved "https://registry.yarnpkg.com/winston/-/winston-3.3.3.tgz#ae6172042cafb29786afa3d09c8ff833ab7c9170"
|
||||||
integrity sha512-zU6vgnS9dAWCEKg/QYigd6cgMVVNwyTzKs81XZtTFuRwJOcDdBg7AU0mXVyNbs7O5RH2zdv+BdNZUlx7mXPuOw==
|
integrity sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==
|
||||||
dependencies:
|
dependencies:
|
||||||
async "^2.6.1"
|
"@dabh/diagnostics" "^2.0.2"
|
||||||
diagnostics "^1.1.1"
|
async "^3.1.0"
|
||||||
is-stream "^1.1.0"
|
is-stream "^2.0.0"
|
||||||
logform "^2.1.1"
|
logform "^2.2.0"
|
||||||
one-time "0.0.4"
|
one-time "^1.0.0"
|
||||||
readable-stream "^3.1.1"
|
readable-stream "^3.4.0"
|
||||||
stack-trace "0.0.x"
|
stack-trace "0.0.x"
|
||||||
triple-beam "^1.3.0"
|
triple-beam "^1.3.0"
|
||||||
winston-transport "^4.3.0"
|
winston-transport "^4.4.0"
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "terminus-plugin-manager",
|
"name": "terminus-plugin-manager",
|
||||||
"version": "1.0.104-nightly.0",
|
"version": "1.0.123-nightly.0",
|
||||||
"description": "Terminus' plugin manager",
|
"description": "Terminus' plugin manager",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"terminus-builtin-plugin"
|
"terminus-builtin-plugin"
|
||||||
@@ -19,16 +19,17 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/semver": "^7.1.0",
|
"@types/semver": "^7.1.0",
|
||||||
"axios": "^0.19.0",
|
"axios": "^0.19.0",
|
||||||
|
"electron-promise-ipc": "^2.2.4",
|
||||||
"mz": "^2.6.0",
|
"mz": "^2.6.0",
|
||||||
"semver": "^7.1.1"
|
"semver": "^7.1.1"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@angular/common": "^7",
|
"@angular/common": "^9.1.11",
|
||||||
"@angular/core": "^7",
|
"@angular/core": "^9.1.9",
|
||||||
"@angular/forms": "^7",
|
"@angular/forms": "^9.1.11",
|
||||||
"@angular/platform-browser": "^7",
|
"@angular/platform-browser": "^9.1.11",
|
||||||
"@ng-bootstrap/ng-bootstrap": "^1",
|
"@ng-bootstrap/ng-bootstrap": "^6.1.0",
|
||||||
"rxjs": "^5",
|
"rxjs": "^6.5.5",
|
||||||
"terminus-core": "*",
|
"terminus-core": "*",
|
||||||
"terminus-settings": "*"
|
"terminus-settings": "*"
|
||||||
}
|
}
|
||||||
|
@@ -22,10 +22,10 @@
|
|||||||
button.btn.btn-primary.ml-2(
|
button.btn.btn-primary.ml-2(
|
||||||
*ngIf='knownUpgrades[plugin.name]',
|
*ngIf='knownUpgrades[plugin.name]',
|
||||||
(click)='upgradePlugin(plugin)',
|
(click)='upgradePlugin(plugin)',
|
||||||
[disabled]='busy[plugin.name] != undefined'
|
[disabled]='busy.has(plugin.name)'
|
||||||
)
|
)
|
||||||
i.fas.fa-fw.fa-arrow-up(*ngIf='busy[plugin.name] != BusyState.Installing')
|
i.fas.fa-fw.fa-arrow-up(*ngIf='busy.get(plugin.name) != BusyState.Installing')
|
||||||
i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='busy[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(
|
button.btn.btn-link.text-primary.ml-2(
|
||||||
@@ -43,10 +43,10 @@
|
|||||||
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',
|
||||||
[disabled]='busy[plugin.name] != undefined'
|
[disabled]='busy.has(plugin.name)'
|
||||||
)
|
)
|
||||||
i.fas.fa-fw.fa-trash(*ngIf='busy[plugin.name] != BusyState.Uninstalling')
|
i.fas.fa-fw.fa-trash(*ngIf='busy.get(plugin.name) != BusyState.Uninstalling')
|
||||||
i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='busy[plugin.name] == BusyState.Uninstalling')
|
i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='busy.get(plugin.name) == BusyState.Uninstalling')
|
||||||
|
|
||||||
div
|
div
|
||||||
h3.mt-4 Available
|
h3.mt-4 Available
|
||||||
@@ -69,10 +69,10 @@ div
|
|||||||
.list-group-item.d-flex.align-items-center(*ngIf='!isAlreadyInstalled(plugin)')
|
.list-group-item.d-flex.align-items-center(*ngIf='!isAlreadyInstalled(plugin)')
|
||||||
button.btn.btn-primary.mr-3(
|
button.btn.btn-primary.mr-3(
|
||||||
(click)='installPlugin(plugin)',
|
(click)='installPlugin(plugin)',
|
||||||
[disabled]='busy[plugin.name] != undefined'
|
[disabled]='busy.has(plugin.name)'
|
||||||
)
|
)
|
||||||
i.fas.fa-fw.fa-download(*ngIf='busy[plugin.name] != BusyState.Installing')
|
i.fas.fa-fw.fa-download(*ngIf='busy.get(plugin.name) != BusyState.Installing')
|
||||||
i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='busy[plugin.name] == BusyState.Installing')
|
i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='busy.get(plugin.name) == BusyState.Installing')
|
||||||
|
|
||||||
div((click)='showPluginInfo(plugin)')
|
div((click)='showPluginInfo(plugin)')
|
||||||
div
|
div
|
||||||
|
@@ -7,7 +7,7 @@ import { Component, Input } from '@angular/core'
|
|||||||
import { ConfigService, ElectronService } from 'terminus-core'
|
import { ConfigService, ElectronService } from 'terminus-core'
|
||||||
import { PluginInfo, PluginManagerService } from '../services/pluginManager.service'
|
import { PluginInfo, PluginManagerService } from '../services/pluginManager.service'
|
||||||
|
|
||||||
enum BusyState { Installing, Uninstalling }
|
enum BusyState { Installing = 'Installing', Uninstalling = 'Uninstalling' }
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@Component({
|
@Component({
|
||||||
@@ -19,8 +19,8 @@ export class PluginsSettingsTabComponent {
|
|||||||
@Input() availablePlugins$: Observable<PluginInfo[]>
|
@Input() availablePlugins$: Observable<PluginInfo[]>
|
||||||
@Input() availablePluginsQuery$ = new BehaviorSubject<string>('')
|
@Input() availablePluginsQuery$ = new BehaviorSubject<string>('')
|
||||||
@Input() availablePluginsReady = false
|
@Input() availablePluginsReady = false
|
||||||
@Input() knownUpgrades: {[id: string]: PluginInfo|null} = {}
|
@Input() knownUpgrades: Record<string, PluginInfo|null> = {}
|
||||||
@Input() busy: {[id: string]: BusyState} = {}
|
@Input() busy = new Map<string, BusyState>()
|
||||||
@Input() erroredPlugin: string
|
@Input() erroredPlugin: string
|
||||||
@Input() errorMessage: string
|
@Input() errorMessage: string
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ export class PluginsSettingsTabComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
openPluginsFolder (): void {
|
openPluginsFolder (): void {
|
||||||
this.electron.shell.openItem(this.pluginManager.userPluginsPath)
|
this.electron.shell.openPath(this.pluginManager.userPluginsPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
searchAvailable (query: string) {
|
searchAvailable (query: string) {
|
||||||
@@ -67,29 +67,29 @@ export class PluginsSettingsTabComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async installPlugin (plugin: PluginInfo): Promise<void> {
|
async installPlugin (plugin: PluginInfo): Promise<void> {
|
||||||
this.busy[plugin.name] = BusyState.Installing
|
this.busy.set(plugin.name, BusyState.Installing)
|
||||||
try {
|
try {
|
||||||
await this.pluginManager.installPlugin(plugin)
|
await this.pluginManager.installPlugin(plugin)
|
||||||
delete this.busy[plugin.name]
|
this.busy.delete(plugin.name)
|
||||||
this.config.requestRestart()
|
this.config.requestRestart()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.erroredPlugin = plugin.name
|
this.erroredPlugin = plugin.name
|
||||||
this.errorMessage = err
|
this.errorMessage = err
|
||||||
delete this.busy[plugin.name]
|
this.busy.delete(plugin.name)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async uninstallPlugin (plugin: PluginInfo): Promise<void> {
|
async uninstallPlugin (plugin: PluginInfo): Promise<void> {
|
||||||
this.busy[plugin.name] = BusyState.Uninstalling
|
this.busy.set(plugin.name, BusyState.Uninstalling)
|
||||||
try {
|
try {
|
||||||
await this.pluginManager.uninstallPlugin(plugin)
|
await this.pluginManager.uninstallPlugin(plugin)
|
||||||
delete this.busy[plugin.name]
|
this.busy.delete(plugin.name)
|
||||||
this.config.requestRestart()
|
this.config.requestRestart()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.erroredPlugin = plugin.name
|
this.erroredPlugin = plugin.name
|
||||||
this.errorMessage = err
|
this.errorMessage = err
|
||||||
delete this.busy[plugin.name]
|
this.busy.delete(plugin.name)
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
import promiseIpc from 'electron-promise-ipc'
|
||||||
import { Observable, from } from 'rxjs'
|
import { Observable, from } from 'rxjs'
|
||||||
import { map } from 'rxjs/operators'
|
import { map } from 'rxjs/operators'
|
||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
@@ -31,39 +32,15 @@ export class PluginManagerService {
|
|||||||
userPluginsPath: string = (window as any).userPluginsPath
|
userPluginsPath: string = (window as any).userPluginsPath
|
||||||
installedPlugins: PluginInfo[] = (window as any).installedPlugins
|
installedPlugins: PluginInfo[] = (window as any).installedPlugins
|
||||||
|
|
||||||
private npmReady: Promise<void>
|
|
||||||
private npm: any
|
|
||||||
|
|
||||||
private constructor (
|
private constructor (
|
||||||
log: LogService,
|
log: LogService,
|
||||||
) {
|
) {
|
||||||
this.logger = log.create('pluginManager')
|
this.logger = log.create('pluginManager')
|
||||||
}
|
}
|
||||||
|
|
||||||
async getNPM (): Promise<any> {
|
|
||||||
if (!this.npm) {
|
|
||||||
if (!this.npmReady) {
|
|
||||||
this.npmReady = new Promise(resolve => {
|
|
||||||
const npm = (global as any).require('npm')
|
|
||||||
npm.load({
|
|
||||||
prefix: this.userPluginsPath,
|
|
||||||
}, err => {
|
|
||||||
if (err) {
|
|
||||||
this.logger.error(err)
|
|
||||||
}
|
|
||||||
this.npm = npm
|
|
||||||
resolve()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
await this.npmReady
|
|
||||||
}
|
|
||||||
return this.npm
|
|
||||||
}
|
|
||||||
|
|
||||||
listAvailable (query?: string): Observable<PluginInfo[]> {
|
listAvailable (query?: string): Observable<PluginInfo[]> {
|
||||||
return from(
|
return from(
|
||||||
axios.get(`https://www.npmjs.com/search?q=keywords%3A${KEYWORD}+${encodeURIComponent(query || '')}&from=0&size=1000`, {
|
axios.get(`https://www.npmjs.com/search?q=keywords%3A${KEYWORD}+${encodeURIComponent(query ?? '')}&from=0&size=1000`, {
|
||||||
headers: {
|
headers: {
|
||||||
'x-spiferack': '1',
|
'x-spiferack': '1',
|
||||||
},
|
},
|
||||||
@@ -84,21 +61,23 @@ export class PluginManagerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async installPlugin (plugin: PluginInfo): Promise<void> {
|
async installPlugin (plugin: PluginInfo): Promise<void> {
|
||||||
(await this.getNPM()).commands.install([`${plugin.packageName}@${plugin.version}`], err => {
|
try {
|
||||||
if (err) {
|
await (promiseIpc as any).send('plugin-manager:install', this.userPluginsPath, plugin.packageName, plugin.version)
|
||||||
this.logger.error(err)
|
|
||||||
}
|
|
||||||
this.installedPlugins = this.installedPlugins.filter(x => x.packageName !== plugin.packageName)
|
this.installedPlugins = this.installedPlugins.filter(x => x.packageName !== plugin.packageName)
|
||||||
this.installedPlugins.push(plugin)
|
this.installedPlugins.push(plugin)
|
||||||
})
|
} catch (err) {
|
||||||
|
this.logger.error(err)
|
||||||
|
throw err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async uninstallPlugin (plugin: PluginInfo): Promise<void> {
|
async uninstallPlugin (plugin: PluginInfo): Promise<void> {
|
||||||
(await this.getNPM()).commands.remove([plugin.packageName], err => {
|
try {
|
||||||
if (err) {
|
await (promiseIpc as any).send('plugin-manager:uninstall', this.userPluginsPath, plugin.packageName)
|
||||||
this.logger.error(err)
|
|
||||||
}
|
|
||||||
this.installedPlugins = this.installedPlugins.filter(x => x.packageName !== plugin.packageName)
|
this.installedPlugins = this.installedPlugins.filter(x => x.packageName !== plugin.packageName)
|
||||||
})
|
} catch (err) {
|
||||||
|
this.logger.error(err)
|
||||||
|
throw err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,7 @@ module.exports = {
|
|||||||
target: 'node',
|
target: 'node',
|
||||||
entry: 'src/index.ts',
|
entry: 'src/index.ts',
|
||||||
context: __dirname,
|
context: __dirname,
|
||||||
devtool: 'eval-cheap-module-source-map',
|
devtool: 'cheap-module-source-map',
|
||||||
output: {
|
output: {
|
||||||
path: path.resolve(__dirname, 'dist'),
|
path: path.resolve(__dirname, 'dist'),
|
||||||
filename: 'index.js',
|
filename: 'index.js',
|
||||||
@@ -46,8 +46,8 @@ module.exports = {
|
|||||||
externals: [
|
externals: [
|
||||||
'fs',
|
'fs',
|
||||||
'net',
|
'net',
|
||||||
'npm',
|
|
||||||
'path',
|
'path',
|
||||||
|
'electron-promise-ipc',
|
||||||
/^rxjs/,
|
/^rxjs/,
|
||||||
/^@angular/,
|
/^@angular/,
|
||||||
/^@ng-bootstrap/,
|
/^@ng-bootstrap/,
|
||||||
|
@@ -2,17 +2,10 @@
|
|||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
"@types/node@*":
|
|
||||||
version "13.7.6"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.7.6.tgz#cb734a7c191472ae6a2b3a502b4dfffcea974113"
|
|
||||||
integrity sha512-eyK7MWD0R1HqVTp+PtwRgFeIsemzuj4gBFSQxfPHY5iMjS7474e5wq+VFgTcdpyHeNxyKSaetYAjdMLJlKoWqA==
|
|
||||||
|
|
||||||
"@types/semver@^7.1.0":
|
"@types/semver@^7.1.0":
|
||||||
version "7.1.0"
|
version "7.3.4"
|
||||||
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.1.0.tgz#c8c630d4c18cd326beff77404887596f96408408"
|
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.4.tgz#43d7168fec6fa0988bb1a513a697b29296721afb"
|
||||||
integrity sha512-pOKLaubrAEMUItGNpgwl0HMFPrSAFic8oSVIvfu1UwcgGNmNyK9gyhBHKmBnUTwwVvpZfkzUC0GaMgnL6P86uA==
|
integrity sha512-+nVsLKlcUCeMzD2ufHEYuJ9a2ovstb6Dp52A5VsoKxDXgvE051XgHI/33I1EymwkRGQkwnA0LkhnUzituGs4EQ==
|
||||||
dependencies:
|
|
||||||
"@types/node" "*"
|
|
||||||
|
|
||||||
any-promise@^1.0.0:
|
any-promise@^1.0.0:
|
||||||
version "1.3.0"
|
version "1.3.0"
|
||||||
@@ -26,6 +19,14 @@ axios@^0.19.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
follow-redirects "1.5.10"
|
follow-redirects "1.5.10"
|
||||||
|
|
||||||
|
call-bind@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.0.tgz#24127054bb3f9bdcb4b1fb82418186072f77b8ce"
|
||||||
|
integrity sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==
|
||||||
|
dependencies:
|
||||||
|
function-bind "^1.1.1"
|
||||||
|
get-intrinsic "^1.0.0"
|
||||||
|
|
||||||
debug@=3.1.0:
|
debug@=3.1.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
|
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
|
||||||
@@ -33,6 +34,50 @@ debug@=3.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ms "2.0.0"
|
ms "2.0.0"
|
||||||
|
|
||||||
|
define-properties@^1.1.3:
|
||||||
|
version "1.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
|
||||||
|
integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
|
||||||
|
dependencies:
|
||||||
|
object-keys "^1.0.12"
|
||||||
|
|
||||||
|
electron-promise-ipc@^2.2.4:
|
||||||
|
version "2.2.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/electron-promise-ipc/-/electron-promise-ipc-2.2.4.tgz#b82daf86ca6d0f0b8655937fdbe9a554590deeea"
|
||||||
|
integrity sha512-xCkFEeuru9l7H/+m1gpK4F1utexvTT7+n1PTquP2MVTpmBmpgFBlLqSXC7TqwpROkHRm9wGpaCJEx0djonnSEg==
|
||||||
|
dependencies:
|
||||||
|
is-electron-renderer "^2.0.1"
|
||||||
|
object.entries "^1.1.3"
|
||||||
|
serialize-error "^5.0.0"
|
||||||
|
uuid "^3.0.1"
|
||||||
|
|
||||||
|
es-abstract@^1.18.0-next.1:
|
||||||
|
version "1.18.0-next.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0-next.1.tgz#6e3a0a4bda717e5023ab3b8e90bec36108d22c68"
|
||||||
|
integrity sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==
|
||||||
|
dependencies:
|
||||||
|
es-to-primitive "^1.2.1"
|
||||||
|
function-bind "^1.1.1"
|
||||||
|
has "^1.0.3"
|
||||||
|
has-symbols "^1.0.1"
|
||||||
|
is-callable "^1.2.2"
|
||||||
|
is-negative-zero "^2.0.0"
|
||||||
|
is-regex "^1.1.1"
|
||||||
|
object-inspect "^1.8.0"
|
||||||
|
object-keys "^1.1.1"
|
||||||
|
object.assign "^4.1.1"
|
||||||
|
string.prototype.trimend "^1.0.1"
|
||||||
|
string.prototype.trimstart "^1.0.1"
|
||||||
|
|
||||||
|
es-to-primitive@^1.2.1:
|
||||||
|
version "1.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"
|
||||||
|
integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==
|
||||||
|
dependencies:
|
||||||
|
is-callable "^1.1.4"
|
||||||
|
is-date-object "^1.0.1"
|
||||||
|
is-symbol "^1.0.2"
|
||||||
|
|
||||||
follow-redirects@1.5.10:
|
follow-redirects@1.5.10:
|
||||||
version "1.5.10"
|
version "1.5.10"
|
||||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
|
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
|
||||||
@@ -40,6 +85,66 @@ follow-redirects@1.5.10:
|
|||||||
dependencies:
|
dependencies:
|
||||||
debug "=3.1.0"
|
debug "=3.1.0"
|
||||||
|
|
||||||
|
function-bind@^1.1.1:
|
||||||
|
version "1.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
||||||
|
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
|
||||||
|
|
||||||
|
get-intrinsic@^1.0.0:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.2.tgz#6820da226e50b24894e08859469dc68361545d49"
|
||||||
|
integrity sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==
|
||||||
|
dependencies:
|
||||||
|
function-bind "^1.1.1"
|
||||||
|
has "^1.0.3"
|
||||||
|
has-symbols "^1.0.1"
|
||||||
|
|
||||||
|
has-symbols@^1.0.1:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
|
||||||
|
integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==
|
||||||
|
|
||||||
|
has@^1.0.3:
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
|
||||||
|
integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
|
||||||
|
dependencies:
|
||||||
|
function-bind "^1.1.1"
|
||||||
|
|
||||||
|
is-callable@^1.1.4, is-callable@^1.2.2:
|
||||||
|
version "1.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.2.tgz#c7c6715cd22d4ddb48d3e19970223aceabb080d9"
|
||||||
|
integrity sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==
|
||||||
|
|
||||||
|
is-date-object@^1.0.1:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e"
|
||||||
|
integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==
|
||||||
|
|
||||||
|
is-electron-renderer@^2.0.1:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-electron-renderer/-/is-electron-renderer-2.0.1.tgz#a469d056f975697c58c98c6023eb0aa79af895a2"
|
||||||
|
integrity sha1-pGnQVvl1aXxYyYxgI+sKp5r4laI=
|
||||||
|
|
||||||
|
is-negative-zero@^2.0.0:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24"
|
||||||
|
integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==
|
||||||
|
|
||||||
|
is-regex@^1.1.1:
|
||||||
|
version "1.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.1.tgz#c6f98aacc546f6cec5468a07b7b153ab564a57b9"
|
||||||
|
integrity sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==
|
||||||
|
dependencies:
|
||||||
|
has-symbols "^1.0.1"
|
||||||
|
|
||||||
|
is-symbol@^1.0.2:
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937"
|
||||||
|
integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==
|
||||||
|
dependencies:
|
||||||
|
has-symbols "^1.0.1"
|
||||||
|
|
||||||
ms@2.0.0:
|
ms@2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||||
@@ -59,10 +164,63 @@ object-assign@^4.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||||
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
|
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
|
||||||
|
|
||||||
|
object-inspect@^1.8.0:
|
||||||
|
version "1.9.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a"
|
||||||
|
integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==
|
||||||
|
|
||||||
|
object-keys@^1.0.12, object-keys@^1.1.1:
|
||||||
|
version "1.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
|
||||||
|
integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
|
||||||
|
|
||||||
|
object.assign@^4.1.1:
|
||||||
|
version "4.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940"
|
||||||
|
integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==
|
||||||
|
dependencies:
|
||||||
|
call-bind "^1.0.0"
|
||||||
|
define-properties "^1.1.3"
|
||||||
|
has-symbols "^1.0.1"
|
||||||
|
object-keys "^1.1.1"
|
||||||
|
|
||||||
|
object.entries@^1.1.3:
|
||||||
|
version "1.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.3.tgz#c601c7f168b62374541a07ddbd3e2d5e4f7711a6"
|
||||||
|
integrity sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg==
|
||||||
|
dependencies:
|
||||||
|
call-bind "^1.0.0"
|
||||||
|
define-properties "^1.1.3"
|
||||||
|
es-abstract "^1.18.0-next.1"
|
||||||
|
has "^1.0.3"
|
||||||
|
|
||||||
semver@^7.1.1:
|
semver@^7.1.1:
|
||||||
version "7.2.2"
|
version "7.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.2.2.tgz#d01432d74ed3010a20ffaf909d63a691520521cd"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938"
|
||||||
integrity sha512-Zo84u6o2PebMSK3zjJ6Zp5wi8VnQZnEaCP13Ul/lt1ANsLACxnJxq4EEm1PY94/por1Hm9+7xpIswdS5AkieMA==
|
integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==
|
||||||
|
|
||||||
|
serialize-error@^5.0.0:
|
||||||
|
version "5.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-5.0.0.tgz#a7ebbcdb03a5d71a6ed8461ffe0fc1a1afed62ac"
|
||||||
|
integrity sha512-/VtpuyzYf82mHYTtI4QKtwHa79vAdU5OQpNPAmE/0UDdlGT0ZxHwC+J6gXkw29wwoVI8fMPsfcVHOwXtUQYYQA==
|
||||||
|
dependencies:
|
||||||
|
type-fest "^0.8.0"
|
||||||
|
|
||||||
|
string.prototype.trimend@^1.0.1:
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz#a22bd53cca5c7cf44d7c9d5c732118873d6cd18b"
|
||||||
|
integrity sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==
|
||||||
|
dependencies:
|
||||||
|
call-bind "^1.0.0"
|
||||||
|
define-properties "^1.1.3"
|
||||||
|
|
||||||
|
string.prototype.trimstart@^1.0.1:
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz#9b4cb590e123bb36564401d59824298de50fd5aa"
|
||||||
|
integrity sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==
|
||||||
|
dependencies:
|
||||||
|
call-bind "^1.0.0"
|
||||||
|
define-properties "^1.1.3"
|
||||||
|
|
||||||
thenify-all@^1.0.0:
|
thenify-all@^1.0.0:
|
||||||
version "1.6.0"
|
version "1.6.0"
|
||||||
@@ -72,8 +230,18 @@ thenify-all@^1.0.0:
|
|||||||
thenify ">= 3.1.0 < 4"
|
thenify ">= 3.1.0 < 4"
|
||||||
|
|
||||||
"thenify@>= 3.1.0 < 4":
|
"thenify@>= 3.1.0 < 4":
|
||||||
version "3.3.0"
|
version "3.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839"
|
resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f"
|
||||||
integrity sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=
|
integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==
|
||||||
dependencies:
|
dependencies:
|
||||||
any-promise "^1.0.0"
|
any-promise "^1.0.0"
|
||||||
|
|
||||||
|
type-fest@^0.8.0:
|
||||||
|
version "0.8.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
|
||||||
|
integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
|
||||||
|
|
||||||
|
uuid@^3.0.1:
|
||||||
|
version "3.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
|
||||||
|
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
|
||||||
|
0
terminus-serial/.gitignore
vendored
Normal file
0
terminus-serial/.gitignore
vendored
Normal file
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "terminus-serial",
|
"name": "terminus-serial",
|
||||||
"version": "1.0.104-nightly.0",
|
"version": "1.0.123-nightly.0",
|
||||||
"description": "Serial connection manager for Terminus",
|
"description": "Serial connection manager for Terminus",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"terminus-builtin-plugin"
|
"terminus-builtin-plugin"
|
||||||
@@ -17,19 +17,20 @@
|
|||||||
"author": "Eugene Pankov",
|
"author": "Eugene Pankov",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "12.7.3",
|
"@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",
|
"cli-spinner": "^0.2.10"
|
||||||
"electron-rebuild": "^1.10.0",
|
|
||||||
"terminus-terminal": "^1.0.98-nightly.0"
|
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@angular/common": "^7",
|
"@angular/animations": "^9.1.9",
|
||||||
"@angular/core": "^7",
|
"@angular/common": "^9.1.11",
|
||||||
"@angular/forms": "^7",
|
"@angular/core": "^9.1.9",
|
||||||
"@ng-bootstrap/ng-bootstrap": "^1",
|
"@angular/forms": "^9.1.11",
|
||||||
"rxjs": "^5",
|
"@angular/platform-browser": "^9.1.11",
|
||||||
|
"@angular/platform-browser-dynamic": "^9.1.11",
|
||||||
|
"@ng-bootstrap/ng-bootstrap": "^6.2.0",
|
||||||
|
"rxjs": "^6.6.3",
|
||||||
"terminus-core": "*",
|
"terminus-core": "*",
|
||||||
"terminus-settings": "*",
|
"terminus-settings": "*",
|
||||||
"terminus-terminal": "*"
|
"terminus-terminal": "*"
|
||||||
|
@@ -26,7 +26,7 @@ export interface SerialConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const BAUD_RATES = [
|
export const BAUD_RATES = [
|
||||||
110, 150, 300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600,
|
110, 150, 300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600, 1500000,
|
||||||
]
|
]
|
||||||
|
|
||||||
export interface SerialPortInfo {
|
export interface SerialPortInfo {
|
||||||
@@ -44,7 +44,7 @@ export class SerialSession extends BaseSession {
|
|||||||
|
|
||||||
constructor (public connection: SerialConnection) {
|
constructor (public connection: SerialConnection) {
|
||||||
super()
|
super()
|
||||||
this.scripts = connection.scripts || []
|
this.scripts = connection.scripts ?? []
|
||||||
}
|
}
|
||||||
|
|
||||||
async start (): Promise<void> {
|
async start (): Promise<void> {
|
||||||
@@ -131,6 +131,10 @@ export class SerialSession extends BaseSession {
|
|||||||
this.kill('TERM')
|
this.kill('TERM')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
supportsWorkingDirectory (): boolean {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
async getWorkingDirectory (): Promise<string|null> {
|
async getWorkingDirectory (): Promise<string|null> {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@@ -28,7 +28,7 @@ export class ButtonProvider extends ToolbarButtonProvider {
|
|||||||
weight: 5,
|
weight: 5,
|
||||||
title: 'Serial connections',
|
title: 'Serial connections',
|
||||||
touchBarNSImage: 'NSTouchBarOpenInBrowserTemplate',
|
touchBarNSImage: 'NSTouchBarOpenInBrowserTemplate',
|
||||||
click: async () => {
|
click: () => {
|
||||||
this.activate()
|
this.activate()
|
||||||
},
|
},
|
||||||
}]
|
}]
|
||||||
|
@@ -37,7 +37,7 @@ export class EditConnectionModalComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async ngOnInit () {
|
async ngOnInit () {
|
||||||
this.connection.scripts = this.connection.scripts || []
|
this.connection.scripts = this.connection.scripts ?? []
|
||||||
this.foundPorts = await this.serial.listPorts()
|
this.foundPorts = await this.serial.listPorts()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -11,13 +11,13 @@ import { Subscription } from 'rxjs'
|
|||||||
/** @hidden */
|
/** @hidden */
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'serial-tab',
|
selector: 'serial-tab',
|
||||||
template: BaseTerminalTabComponent.template + require<string>('./serialTab.component.pug'),
|
template: BaseTerminalTabComponent.template + (require('./serialTab.component.pug') as string),
|
||||||
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
|
||||||
serialPort: any
|
serialPort: any
|
||||||
private homeEndSubscription: Subscription
|
private homeEndSubscription: Subscription
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
|
|||||||
super.ngOnInit()
|
super.ngOnInit()
|
||||||
|
|
||||||
setImmediate(() => {
|
setImmediate(() => {
|
||||||
this.setTitle(this.connection.name)
|
this.setTitle(this.connection!.name)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,8 +64,8 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
|
|||||||
|
|
||||||
this.session = this.injector.get(SerialService).createSession(this.connection)
|
this.session = this.injector.get(SerialService).createSession(this.connection)
|
||||||
this.session.serviceMessage$.subscribe(msg => {
|
this.session.serviceMessage$.subscribe(msg => {
|
||||||
this.write('\r\n' + colors.black.bgWhite(' serial ') + ' ' + msg + '\r\n')
|
this.write(`\r\n${colors.black.bgWhite(' serial ')} ${msg}\r\n`)
|
||||||
this.session.resize(this.size.columns, this.size.rows)
|
this.session?.resize(this.size.columns, this.size.rows)
|
||||||
})
|
})
|
||||||
this.attachSessionHandlers()
|
this.attachSessionHandlers()
|
||||||
this.write(`Connecting to `)
|
this.write(`Connecting to `)
|
||||||
@@ -108,7 +108,7 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
|
|||||||
name: x.toString(), result: x,
|
name: x.toString(), result: x,
|
||||||
})))
|
})))
|
||||||
this.serialPort.update({ baudRate: rate })
|
this.serialPort.update({ baudRate: rate })
|
||||||
this.connection.baudrate = rate
|
this.connection!.baudrate = rate
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy () {
|
ngOnDestroy () {
|
||||||
|
@@ -7,12 +7,12 @@ import { SerialTabComponent } from './components/serialTab.component'
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class RecoveryProvider extends TabRecoveryProvider {
|
export class RecoveryProvider extends TabRecoveryProvider {
|
||||||
async recover (recoveryToken: RecoveryToken): Promise<RecoveredTab|null> {
|
async recover (recoveryToken: RecoveryToken): Promise<RecoveredTab|null> {
|
||||||
if (recoveryToken?.type === 'app:serial-tab') {
|
if (recoveryToken.type === 'app:serial-tab') {
|
||||||
return {
|
return {
|
||||||
type: SerialTabComponent,
|
type: SerialTabComponent,
|
||||||
options: {
|
options: {
|
||||||
connection: recoveryToken['connection'],
|
connection: recoveryToken.connection,
|
||||||
savedState: recoveryToken['savedState'],
|
savedState: recoveryToken.savedState,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -57,7 +57,6 @@ export class SerialService {
|
|||||||
this.toastr.error(e.message)
|
this.toastr.error(e.message)
|
||||||
reject(e)
|
reject(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
return serial
|
return serial
|
||||||
}
|
}
|
||||||
@@ -125,10 +124,10 @@ export class SerialService {
|
|||||||
{ connection }
|
{ connection }
|
||||||
) as SerialTabComponent
|
) as SerialTabComponent
|
||||||
if (connection.color) {
|
if (connection.color) {
|
||||||
(this.app.getParentTab(tab) || tab).color = connection.color
|
(this.app.getParentTab(tab) ?? tab).color = connection.color
|
||||||
}
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.app.activeTab.emitFocused()
|
this.app.activeTab?.emitFocused()
|
||||||
})
|
})
|
||||||
return tab
|
return tab
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user