mirror of
https://github.com/Eugeny/tabby.git
synced 2025-08-02 15:37:01 +00:00
Compare commits
946 Commits
v1.0.78-rc
...
v1.0.94
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b010791767 | ||
![]() |
ef61a141a6 | ||
![]() |
85cad2c8e3 | ||
![]() |
ac990c2bbc | ||
![]() |
cf1f3825c6 | ||
![]() |
fa8c30b279 | ||
![]() |
99f5a9ebb2 | ||
![]() |
15ed6ac632 | ||
![]() |
18aa78fa2e | ||
![]() |
8dcb6060b8 | ||
![]() |
d14424a891 | ||
![]() |
e569fe60a7 | ||
![]() |
9a666f3467 | ||
![]() |
edb098bf6f | ||
![]() |
dec575d7a4 | ||
![]() |
dee608c1c8 | ||
![]() |
d90f68c439 | ||
![]() |
6a7ac612ee | ||
![]() |
8c8f972448 | ||
![]() |
3c97bb4cd2 | ||
![]() |
ffeed1611d | ||
![]() |
7f4a3f0529 | ||
![]() |
3801d490e5 | ||
![]() |
43899a6683 | ||
![]() |
2e717eaeb9 | ||
![]() |
09fa765a3c | ||
![]() |
e2c4a08754 | ||
![]() |
1c1514bb3a | ||
![]() |
e6711f760d | ||
![]() |
133c5067b6 | ||
![]() |
dd1e7706a4 | ||
![]() |
c154efeb14 | ||
![]() |
78274b8504 | ||
![]() |
1ebf756f59 | ||
![]() |
33666529e5 | ||
![]() |
56b2b2a717 | ||
![]() |
2ac26685b0 | ||
![]() |
606392d1a5 | ||
![]() |
881e7bf91c | ||
![]() |
ba57f7b0c4 | ||
![]() |
be2a100738 | ||
![]() |
6749ef3b15 | ||
![]() |
a241f2b36f | ||
![]() |
efe444567d | ||
![]() |
afb4343828 | ||
![]() |
3a67f1eb41 | ||
![]() |
d7c8bc9da0 | ||
![]() |
8ed6a78610 | ||
![]() |
7574a692f0 | ||
![]() |
f4ea106816 | ||
![]() |
84b8e8b0aa | ||
![]() |
8a0152278f | ||
![]() |
d2416580c0 | ||
![]() |
bfae131b8b | ||
![]() |
d93a549406 | ||
![]() |
c29a430b92 | ||
![]() |
a4f8bc9dc1 | ||
![]() |
a186ae70c7 | ||
![]() |
f68c28cf6e | ||
![]() |
8101014a29 | ||
![]() |
ab1f8dba16 | ||
![]() |
cb4c36bf66 | ||
![]() |
eac6f92bcc | ||
![]() |
f6e6259678 | ||
![]() |
9c8692f049 | ||
![]() |
8d479c7392 | ||
![]() |
d1f7131386 | ||
![]() |
1a0eb415b0 | ||
![]() |
58e5a56ac1 | ||
![]() |
8924b74fb4 | ||
![]() |
c4af0886b4 | ||
![]() |
cf53e7a0da | ||
![]() |
617557998d | ||
![]() |
682d665fb7 | ||
![]() |
a72ccf32d7 | ||
![]() |
5f384c8cf5 | ||
![]() |
64309b364f | ||
![]() |
b5707c6884 | ||
![]() |
d12dcc2e06 | ||
![]() |
ee5e58d312 | ||
![]() |
da469c9f46 | ||
![]() |
4633d6e45e | ||
![]() |
6d10bc6592 | ||
![]() |
67f5e79f03 | ||
![]() |
3d604102c9 | ||
![]() |
aef7ea8fbf | ||
![]() |
354be07caa | ||
![]() |
4470abbd11 | ||
![]() |
e815394750 | ||
![]() |
1a67ab5503 | ||
![]() |
20a1ea49a5 | ||
![]() |
ec956d463a | ||
![]() |
555d072ef9 | ||
![]() |
866a374863 | ||
![]() |
dc6cee9f21 | ||
![]() |
7276eb6bef | ||
![]() |
3254e8ac19 | ||
![]() |
4f678cc8ce | ||
![]() |
384ec443a1 | ||
![]() |
64030c758a | ||
![]() |
31ecf46f12 | ||
![]() |
ab55650be8 | ||
![]() |
dde89b58b2 | ||
![]() |
36434fb93c | ||
![]() |
5e848f14df | ||
![]() |
a8f4c43e4b | ||
![]() |
35c92db737 | ||
![]() |
42e7e03cbd | ||
![]() |
455ce5fc7c | ||
![]() |
8546898841 | ||
![]() |
9fa2b85aeb | ||
![]() |
e2a6db3fbd | ||
![]() |
9ee3e2ac84 | ||
![]() |
205da833eb | ||
![]() |
9e38ff658e | ||
![]() |
331e6c6bdd | ||
![]() |
52689a587a | ||
![]() |
911369d9dd | ||
![]() |
3d013195ce | ||
![]() |
406927be3c | ||
![]() |
c3a00eb31d | ||
![]() |
5ff3593024 | ||
![]() |
e452a825c6 | ||
![]() |
87ba3f72d1 | ||
![]() |
86dfc49861 | ||
![]() |
53c03b4349 | ||
![]() |
9c3e63fd74 | ||
![]() |
2f9e9cbbda | ||
![]() |
c5b4eb5905 | ||
![]() |
a47862e0a8 | ||
![]() |
83492b9f26 | ||
![]() |
cccdab5739 | ||
![]() |
85799f49f3 | ||
![]() |
63a0cde5ff | ||
![]() |
c7c1e6ebd6 | ||
![]() |
70d3f30034 | ||
![]() |
184960c3f5 | ||
![]() |
25405440c7 | ||
![]() |
2dd1733926 | ||
![]() |
d815fe0836 | ||
![]() |
6c5f5d5570 | ||
![]() |
aa83e235f2 | ||
![]() |
a2de93d14f | ||
![]() |
24f0f17063 | ||
![]() |
89990fd148 | ||
![]() |
de0db8b7a5 | ||
![]() |
62946d0d4e | ||
![]() |
97adb8e508 | ||
![]() |
9eaa084e84 | ||
![]() |
a9dc550b01 | ||
![]() |
e7911f8fbc | ||
![]() |
4568e37586 | ||
![]() |
1faf9681a2 | ||
![]() |
ac3713e4a0 | ||
![]() |
db86150832 | ||
![]() |
607ea4b549 | ||
![]() |
4ee8e90665 | ||
![]() |
ead8c9e867 | ||
![]() |
69c2331279 | ||
![]() |
ebc2052874 | ||
![]() |
1491e1dc59 | ||
![]() |
96f5296062 | ||
![]() |
baf368d430 | ||
![]() |
2aaeb86f27 | ||
![]() |
e7f4158ad7 | ||
![]() |
bac97a2340 | ||
![]() |
d34650ef5f | ||
![]() |
73de8d8a81 | ||
![]() |
9077e78a85 | ||
![]() |
6545484a87 | ||
![]() |
996a8e9801 | ||
![]() |
c8ec91c54b | ||
![]() |
d9227f70ce | ||
![]() |
8599837e08 | ||
![]() |
4a9f4bced5 | ||
![]() |
d0a93cf258 | ||
![]() |
5c2e8a1db1 | ||
![]() |
c4dfb44bc8 | ||
![]() |
35289a54b3 | ||
![]() |
cbc60c606c | ||
![]() |
8cb783ddf6 | ||
![]() |
3aa4c6105b | ||
![]() |
4bf67b0904 | ||
![]() |
c3b4b3deac | ||
![]() |
35722f6257 | ||
![]() |
0a07d0cd7f | ||
![]() |
504f0a5183 | ||
![]() |
dd5ee69b11 | ||
![]() |
545cd36309 | ||
![]() |
74f87b848b | ||
![]() |
14d734365a | ||
![]() |
85d1763533 | ||
![]() |
86e1abd44f | ||
![]() |
e49e066e7a | ||
![]() |
6406e63e29 | ||
![]() |
389b2f06d2 | ||
![]() |
ebf6f41e8a | ||
![]() |
6d5fa04492 | ||
![]() |
d9fbd7626a | ||
![]() |
1ce48c02b5 | ||
![]() |
097b671a84 | ||
![]() |
ea15efb407 | ||
![]() |
6a8b37cd2b | ||
![]() |
96571dd543 | ||
![]() |
caa2bb7284 | ||
![]() |
fc2a335956 | ||
![]() |
2bdf3ec704 | ||
![]() |
0b26df4cde | ||
![]() |
425f399276 | ||
![]() |
68441af22a | ||
![]() |
3cb3d7b086 | ||
![]() |
9f2f97e0bb | ||
![]() |
6887c1d57b | ||
![]() |
638dd79cf4 | ||
![]() |
22e9d43f5b | ||
![]() |
47345afd3c | ||
![]() |
f74edad743 | ||
![]() |
96da7d2c52 | ||
![]() |
90a16b59f8 | ||
![]() |
3687de884a | ||
![]() |
36e73e22f1 | ||
![]() |
82d38f9c11 | ||
![]() |
bc25b3d304 | ||
![]() |
904563aef2 | ||
![]() |
c7881a9716 | ||
![]() |
145c982341 | ||
![]() |
55fefa65ff | ||
![]() |
8375c2bb38 | ||
![]() |
8280b542f9 | ||
![]() |
6e36165bb1 | ||
![]() |
63a3abe8f9 | ||
![]() |
a23935d4cb | ||
![]() |
27907b6979 | ||
![]() |
7b0c41d2a9 | ||
![]() |
998614bf2e | ||
![]() |
d069f39bc7 | ||
![]() |
7e92d4c49f | ||
![]() |
6c9c2b46f0 | ||
![]() |
94caaabef8 | ||
![]() |
76d4457651 | ||
![]() |
89691bd1a3 | ||
![]() |
2ed6014e85 | ||
![]() |
181c523020 | ||
![]() |
76fbdf926f | ||
![]() |
44b1bb8917 | ||
![]() |
ef400ae901 | ||
![]() |
9b904856fa | ||
![]() |
b2b6582bdb | ||
![]() |
d3ac784e79 | ||
![]() |
b40ad69b89 | ||
![]() |
0237aad34f | ||
![]() |
b9b3db78a1 | ||
![]() |
d2d1bd391e | ||
![]() |
e8dfc41504 | ||
![]() |
c575fa5ece | ||
![]() |
c161023a90 | ||
![]() |
3b073d68b4 | ||
![]() |
c20e4e75a6 | ||
![]() |
0fd712fb2e | ||
![]() |
5c49029060 | ||
![]() |
621ba8c1f3 | ||
![]() |
61c0511abc | ||
![]() |
47ca84cc64 | ||
![]() |
64643a2922 | ||
![]() |
f3bb875116 | ||
![]() |
534fc7f270 | ||
![]() |
2ff608c6ff | ||
![]() |
a9300f89bc | ||
![]() |
f3e99de219 | ||
![]() |
2a990f25ad | ||
![]() |
acbb9d4ce4 | ||
![]() |
6eafd88ec2 | ||
![]() |
0cf169ac8d | ||
![]() |
028d0b839c | ||
![]() |
a53eb6c188 | ||
![]() |
f6ed710063 | ||
![]() |
693bff2fee | ||
![]() |
9800b8cd89 | ||
![]() |
44be7a2cfa | ||
![]() |
8f257f29d0 | ||
![]() |
7dd118ab2a | ||
![]() |
579f59c520 | ||
![]() |
ee78f43c4b | ||
![]() |
60af21c139 | ||
![]() |
f44b495b99 | ||
![]() |
ed6229ee7c | ||
![]() |
99ddf637df | ||
![]() |
fb56957752 | ||
![]() |
6ae9c27860 | ||
![]() |
e0f1a684f8 | ||
![]() |
5350468c14 | ||
![]() |
a636b310a2 | ||
![]() |
31e28ff8eb | ||
![]() |
870f67f8de | ||
![]() |
93f558b359 | ||
![]() |
d8f99c5fa3 | ||
![]() |
1cfa08197a | ||
![]() |
7a5db36656 | ||
![]() |
28fa198568 | ||
![]() |
e74a5d1658 | ||
![]() |
61187d3f3e | ||
![]() |
850168a41b | ||
![]() |
fbdc143c85 | ||
![]() |
e7e89d6c80 | ||
![]() |
5f89f2877c | ||
![]() |
17065f4cee | ||
![]() |
299414639c | ||
![]() |
163fa009fb | ||
![]() |
c7eabbd248 | ||
![]() |
99e105492a | ||
![]() |
af772c41d6 | ||
![]() |
5deb763cac | ||
![]() |
e0aa475450 | ||
![]() |
7f7c10b775 | ||
![]() |
70a1ec60b5 | ||
![]() |
3d48f36df7 | ||
![]() |
b76830958c | ||
![]() |
ff6221255b | ||
![]() |
252edad93f | ||
![]() |
9ee0f8a937 | ||
![]() |
c834d89466 | ||
![]() |
331291f34d | ||
![]() |
e6303980fa | ||
![]() |
1280e13c1f | ||
![]() |
1dec46908a | ||
![]() |
e18c6c2db9 | ||
![]() |
ee24eec39b | ||
![]() |
47865c5718 | ||
![]() |
8c055dddda | ||
![]() |
b45914ece5 | ||
![]() |
6d55058de6 | ||
![]() |
f512663499 | ||
![]() |
4bd036c78c | ||
![]() |
e5575f93fb | ||
![]() |
7bc353b0dd | ||
![]() |
dc6a81d17f | ||
![]() |
4da21a2537 | ||
![]() |
8ea270fb74 | ||
![]() |
bc0e1936c2 | ||
![]() |
587f295c30 | ||
![]() |
27ff57e47e | ||
![]() |
dfbbb68286 | ||
![]() |
7bc92b12e3 | ||
![]() |
540732d129 | ||
![]() |
7eb70e2925 | ||
![]() |
28a9c55006 | ||
![]() |
3e4427deaa | ||
![]() |
b56471aef6 | ||
![]() |
1c812faf3d | ||
![]() |
95967882e3 | ||
![]() |
d1ddbe213f | ||
![]() |
ba073d546a | ||
![]() |
981f673dbb | ||
![]() |
eece7b7b3e | ||
![]() |
27c9df9bc8 | ||
![]() |
6968dcdd13 | ||
![]() |
bcaa638ef0 | ||
![]() |
c243de3704 | ||
![]() |
4e35d2a367 | ||
![]() |
c2e42682d6 | ||
![]() |
5e566c2fd9 | ||
![]() |
effaa81582 | ||
![]() |
4cd9290972 | ||
![]() |
b9a570be9b | ||
![]() |
3ddbb62658 | ||
![]() |
2ee336bef8 | ||
![]() |
8d767ac497 | ||
![]() |
955ef9b361 | ||
![]() |
90cf46b826 | ||
![]() |
c08ba92f33 | ||
![]() |
4bf2963d1e | ||
![]() |
e81228782d | ||
![]() |
dd6dd01e16 | ||
![]() |
31ad686545 | ||
![]() |
b79b3302ab | ||
![]() |
68220d1afc | ||
![]() |
a8e1cee84a | ||
![]() |
bd713f8e07 | ||
![]() |
3bc387b1d9 | ||
![]() |
2844f699ff | ||
![]() |
1d3333e83b | ||
![]() |
4f0daf7a77 | ||
![]() |
3421a8e19f | ||
![]() |
927ca57e56 | ||
![]() |
c63c7dae3f | ||
![]() |
e0f05654f7 | ||
![]() |
2a1501c91e | ||
![]() |
f244f09362 | ||
![]() |
3c2af3045d | ||
![]() |
d82b0b4661 | ||
![]() |
5e2ec1a9bf | ||
![]() |
1d8a71fbc0 | ||
![]() |
7b9a6f1055 | ||
![]() |
8bd9a0d4bc | ||
![]() |
69c1c9f664 | ||
![]() |
d30836681d | ||
![]() |
0a597ffd5f | ||
![]() |
757c91815b | ||
![]() |
deb01266ea | ||
![]() |
d3cff11602 | ||
![]() |
f177a5c734 | ||
![]() |
bf4e0e4f3d | ||
![]() |
9d509dd3ce | ||
![]() |
02674d0f86 | ||
![]() |
ff6ec006e7 | ||
![]() |
a4ed9a5444 | ||
![]() |
d01e3a97d5 | ||
![]() |
3f84a9239a | ||
![]() |
84d4ca4053 | ||
![]() |
19c4a77d6f | ||
![]() |
c16c250847 | ||
![]() |
0905be77bc | ||
![]() |
3d11179a06 | ||
![]() |
516d7eae9a | ||
![]() |
2e486c5e53 | ||
![]() |
d87f329838 | ||
![]() |
e6de63c689 | ||
![]() |
bb845ee803 | ||
![]() |
9e67996e24 | ||
![]() |
b5523d9820 | ||
![]() |
ad26e4f6a3 | ||
![]() |
ae40f009a0 | ||
![]() |
7ee603df60 | ||
![]() |
a8eb0d8346 | ||
![]() |
924a8da2f5 | ||
![]() |
07ab28279c | ||
![]() |
dbb6c544de | ||
![]() |
8c3d2531dc | ||
![]() |
e8fc47665b | ||
![]() |
574d8d9c7a | ||
![]() |
16c9e20b2a | ||
![]() |
665e0ff692 | ||
![]() |
8c71b26109 | ||
![]() |
6aeb9a62e6 | ||
![]() |
337d1f4df5 | ||
![]() |
057bd3f6d1 | ||
![]() |
b01a2e42fb | ||
![]() |
62efe406f5 | ||
![]() |
43f6ad3530 | ||
![]() |
a060246269 | ||
![]() |
802752d76c | ||
![]() |
a7fc2f4ddc | ||
![]() |
6a2fcd9f16 | ||
![]() |
90f475e532 | ||
![]() |
af6294e404 | ||
![]() |
17f471ac24 | ||
![]() |
4274ed563b | ||
![]() |
2acda3be5f | ||
![]() |
2848f9f257 | ||
![]() |
6536e3d4b5 | ||
![]() |
cdaa4fe106 | ||
![]() |
a07e27ef4b | ||
![]() |
2d5e4477b8 | ||
![]() |
f1213fb83e | ||
![]() |
947c751bc7 | ||
![]() |
0ca00b81d5 | ||
![]() |
7c10b57fb9 | ||
![]() |
ffa6d41d8b | ||
![]() |
5ecab9f304 | ||
![]() |
dc9508f80d | ||
![]() |
b6aa1f764b | ||
![]() |
63f8ac2d92 | ||
![]() |
da4622a2ed | ||
![]() |
2896321076 | ||
![]() |
092e5fb8aa | ||
![]() |
43bb3f7f2d | ||
![]() |
b144724ed5 | ||
![]() |
04f233b4a5 | ||
![]() |
7645a1d2c7 | ||
![]() |
2953ea60e8 | ||
![]() |
8d5b2bc4c5 | ||
![]() |
1d1e620db6 | ||
![]() |
3532195760 | ||
![]() |
9d55c7c0ed | ||
![]() |
b9fcf6cac3 | ||
![]() |
e49deee303 | ||
![]() |
f4da5955de | ||
![]() |
5db0ccf96a | ||
![]() |
f8f9c81a66 | ||
![]() |
75b51983cc | ||
![]() |
7e66af2585 | ||
![]() |
ac8026b6d9 | ||
![]() |
119cfdc577 | ||
![]() |
09ce7e062f | ||
![]() |
9cd4fb5417 | ||
![]() |
7887cf58d2 | ||
![]() |
af9c9e580c | ||
![]() |
a4c98db69e | ||
![]() |
122e68de04 | ||
![]() |
d922b2de1f | ||
![]() |
84e2cdb191 | ||
![]() |
b424876cf8 | ||
![]() |
3e306c1479 | ||
![]() |
fb4258d0a2 | ||
![]() |
c9965d3d1a | ||
![]() |
5411ef4802 | ||
![]() |
fbc67970b4 | ||
![]() |
08910933e0 | ||
![]() |
ee23ca0770 | ||
![]() |
febdb96c2b | ||
![]() |
d771bd196c | ||
![]() |
4782a67fe0 | ||
![]() |
6cd5d819ea | ||
![]() |
f8cc637e19 | ||
![]() |
23907ffffe | ||
![]() |
9af1f40086 | ||
![]() |
2a1e1007b7 | ||
![]() |
4c2168b4b5 | ||
![]() |
8920cc7924 | ||
![]() |
8ee7022307 | ||
![]() |
380266a57c | ||
![]() |
5679d5edf1 | ||
![]() |
6a9d569345 | ||
![]() |
eccbd66c18 | ||
![]() |
041a2a92d5 | ||
![]() |
35984ab66e | ||
![]() |
a4ad435341 | ||
![]() |
1b3f28415e | ||
![]() |
b942a2eb1d | ||
![]() |
60e6e2d3ca | ||
![]() |
77d209e285 | ||
![]() |
a735c910d5 | ||
![]() |
876aee93df | ||
![]() |
b0f8dd4036 | ||
![]() |
9413c80376 | ||
![]() |
735fa76239 | ||
![]() |
5820b7ff9a | ||
![]() |
ce49dd9dae | ||
![]() |
0804b949fc | ||
![]() |
dc6871f4a3 | ||
![]() |
2197dceeb2 | ||
![]() |
e4f29b5862 | ||
![]() |
aba3e190ed | ||
![]() |
0ef8c7a570 | ||
![]() |
04b3ab45ea | ||
![]() |
8f2f66c269 | ||
![]() |
1ebbe07870 | ||
![]() |
dadc6c1665 | ||
![]() |
3f3bcfe805 | ||
![]() |
e9ac1f81f7 | ||
![]() |
cd3bab2f6d | ||
![]() |
dc190ad733 | ||
![]() |
1e81e65df7 | ||
![]() |
409c33782e | ||
![]() |
65f2b98f08 | ||
![]() |
891ef52a44 | ||
![]() |
4a18038f15 | ||
![]() |
3891818863 | ||
![]() |
b03e6d449e | ||
![]() |
a70c084a03 | ||
![]() |
fa752b5987 | ||
![]() |
05f8adc323 | ||
![]() |
90df7ac5b7 | ||
![]() |
ea7825e7a8 | ||
![]() |
93f262cb0f | ||
![]() |
f7d60efeb9 | ||
![]() |
be7e6b8d6e | ||
![]() |
4972d2ffea | ||
![]() |
08cebe202c | ||
![]() |
26ca65e10f | ||
![]() |
bb00b07ee8 | ||
![]() |
7bff0a1174 | ||
![]() |
4b67e02f6b | ||
![]() |
046f56215e | ||
![]() |
09b6428705 | ||
![]() |
6c5eb9c525 | ||
![]() |
4f5ee31a69 | ||
![]() |
8eeb8f3f10 | ||
![]() |
31b69f676c | ||
![]() |
9fc3b41247 | ||
![]() |
af946a4a51 | ||
![]() |
85a69ed922 | ||
![]() |
80a4b7bdfc | ||
![]() |
bcbc6e3b46 | ||
![]() |
4828156c7a | ||
![]() |
93119dbfca | ||
![]() |
393c113d77 | ||
![]() |
a6e5c317ae | ||
![]() |
5d22cab164 | ||
![]() |
745923d0b9 | ||
![]() |
e6e3c59e63 | ||
![]() |
55bc4f47bb | ||
![]() |
6484a1baff | ||
![]() |
493186ce53 | ||
![]() |
9a72184f94 | ||
![]() |
6e845eff7d | ||
![]() |
5596dce8ef | ||
![]() |
48b2547759 | ||
![]() |
f616cb9b8f | ||
![]() |
4441bc7e05 | ||
![]() |
7b249a82d7 | ||
![]() |
d8f4c29073 | ||
![]() |
f5485fae2f | ||
![]() |
0bd1700872 | ||
![]() |
e7ac91a322 | ||
![]() |
dc42a2a992 | ||
![]() |
846f1cca16 | ||
![]() |
c11f43b637 | ||
![]() |
6a02bb7f51 | ||
![]() |
2238a231f0 | ||
![]() |
c5c4168afe | ||
![]() |
f49f37992d | ||
![]() |
6fe08475ff | ||
![]() |
99618d75ec | ||
![]() |
f8f2d007a2 | ||
![]() |
4db27f4623 | ||
![]() |
5cd4209ec5 | ||
![]() |
1bd5204d24 | ||
![]() |
c6bd1358e3 | ||
![]() |
d6c9ce84ea | ||
![]() |
1fdf5367b6 | ||
![]() |
e5234b0945 | ||
![]() |
a146505c5a | ||
![]() |
20a1ae3374 | ||
![]() |
8a19a93b4d | ||
![]() |
f9c51e04e1 | ||
![]() |
1afc212e71 | ||
![]() |
d44224d23e | ||
![]() |
e1cca33379 | ||
![]() |
e48936484d | ||
![]() |
911b72508b | ||
![]() |
8575555204 | ||
![]() |
4775632c51 | ||
![]() |
b198864063 | ||
![]() |
0896844e96 | ||
![]() |
3c27e8105e | ||
![]() |
269971ab60 | ||
![]() |
b98bde71df | ||
![]() |
0238515b42 | ||
![]() |
be2f2f4575 | ||
![]() |
38494c9704 | ||
![]() |
fa6fa3f1ea | ||
![]() |
8632f1eedf | ||
![]() |
944c7b072b | ||
![]() |
a08df2fd12 | ||
![]() |
c0804b6940 | ||
![]() |
ebdc2e4105 | ||
![]() |
a0a4346cc4 | ||
![]() |
336cac78c7 | ||
![]() |
fc9389ab30 | ||
![]() |
eb52a37f77 | ||
![]() |
cc68ad492a | ||
![]() |
a1c3829572 | ||
![]() |
32890f17c0 | ||
![]() |
3f8ee9b4fc | ||
![]() |
3eb15a6e66 | ||
![]() |
b62f54ef05 | ||
![]() |
95abe8bb4d | ||
![]() |
8f3ab68705 | ||
![]() |
dce6df7783 | ||
![]() |
7b3426d2f9 | ||
![]() |
0cfbdf368f | ||
![]() |
e7bc93a5e2 | ||
![]() |
d9559f2a8f | ||
![]() |
6531c7eaa7 | ||
![]() |
986bdf8e24 | ||
![]() |
2188eef202 | ||
![]() |
87850edc0e | ||
![]() |
3a9c69d828 | ||
![]() |
ff64d949ec | ||
![]() |
596ef10ba4 | ||
![]() |
ba1008cc95 | ||
![]() |
89173d0f58 | ||
![]() |
736f3728f6 | ||
![]() |
d5d2341e69 | ||
![]() |
b9cdae6832 | ||
![]() |
c6565d0246 | ||
![]() |
84503a87c2 | ||
![]() |
d454a16ff6 | ||
![]() |
fb90ae7b93 | ||
![]() |
8241bb2679 | ||
![]() |
fac506e0b3 | ||
![]() |
34e9c47508 | ||
![]() |
b1512df789 | ||
![]() |
902d63d302 | ||
![]() |
0d83541ebb | ||
![]() |
69d51ec091 | ||
![]() |
5bf0ffeae9 | ||
![]() |
e1e21554e8 | ||
![]() |
6331cd1fab | ||
![]() |
44d335fb7f | ||
![]() |
7f729bb839 | ||
![]() |
515e46ea08 | ||
![]() |
b837a23fbe | ||
![]() |
8ace6dc92e | ||
![]() |
2cffcbefa4 | ||
![]() |
97d9173821 | ||
![]() |
8a2a0d8013 | ||
![]() |
f3096a0a08 | ||
![]() |
378f020f01 | ||
![]() |
0776ae0090 | ||
![]() |
12165e480b | ||
![]() |
9cb93d7971 | ||
![]() |
a20756aec4 | ||
![]() |
40df352872 | ||
![]() |
94c5353328 | ||
![]() |
c411394149 | ||
![]() |
8fce065c18 | ||
![]() |
a628df7591 | ||
![]() |
0c84032726 | ||
![]() |
4e0854d5ea | ||
![]() |
f210c82af3 | ||
![]() |
938d9bfcdc | ||
![]() |
bb97b55af2 | ||
![]() |
6e3aa05f4e | ||
![]() |
aae0f9a3cb | ||
![]() |
ef0d517982 | ||
![]() |
b8aeadf4d6 | ||
![]() |
27ebf58ff9 | ||
![]() |
cbbd9aa742 | ||
![]() |
20c397695f | ||
![]() |
87dd6d343d | ||
![]() |
9766184c59 | ||
![]() |
926fce143e | ||
![]() |
c466dcb594 | ||
![]() |
966941b646 | ||
![]() |
0468035b46 | ||
![]() |
686d444f0d | ||
![]() |
59f61f97b3 | ||
![]() |
a89849a129 | ||
![]() |
70622551ff | ||
![]() |
bca3f78c0b | ||
![]() |
e11c0548e0 | ||
![]() |
33ebe81793 | ||
![]() |
dcf071bdf2 | ||
![]() |
650d2ac24e | ||
![]() |
e18105632b | ||
![]() |
6d34826036 | ||
![]() |
36bd5f9ed7 | ||
![]() |
c180f3faff | ||
![]() |
76b81f8605 | ||
![]() |
e08227cf4c | ||
![]() |
7321fd3d4f | ||
![]() |
d680c345e1 | ||
![]() |
16fdacdafb | ||
![]() |
487400f00d | ||
![]() |
0df75cdd48 | ||
![]() |
8bcd849b83 | ||
![]() |
6610563241 | ||
![]() |
0e732a548b | ||
![]() |
dced067821 | ||
![]() |
f279f1a1e5 | ||
![]() |
db3b8cc718 | ||
![]() |
77058c0472 | ||
![]() |
c35c8791f9 | ||
![]() |
b94c97017c | ||
![]() |
37fc878f37 | ||
![]() |
fac5b7bb3f | ||
![]() |
ff860fbb0c | ||
![]() |
7624405bb4 | ||
![]() |
24bc15c4ea | ||
![]() |
3fd69a1c29 | ||
![]() |
6cdcd96902 | ||
![]() |
9257824f45 | ||
![]() |
fb474d96fd | ||
![]() |
ba67449f03 | ||
![]() |
2bdb85a420 | ||
![]() |
c008a3478e | ||
![]() |
a5ecdeb5ea | ||
![]() |
82e3348122 | ||
![]() |
4c659b80fd | ||
![]() |
ba10b89006 | ||
![]() |
496f0288dc | ||
![]() |
a90496dc1b | ||
![]() |
f7eeb8df14 | ||
![]() |
99c6c5220a | ||
![]() |
19f0ea4310 | ||
![]() |
e88fc8a2b4 | ||
![]() |
3ed5ccd2ee | ||
![]() |
f9a493a53e | ||
![]() |
75b7811541 | ||
![]() |
589b7ea46c | ||
![]() |
2505ee89d0 | ||
![]() |
ab9d436057 | ||
![]() |
7c75089b71 | ||
![]() |
548257ba8b | ||
![]() |
02ff97990c | ||
![]() |
dfbe19b4d0 | ||
![]() |
4ded6f6528 | ||
![]() |
f21e6efad3 | ||
![]() |
5089b444b1 | ||
![]() |
9ad5d10bda | ||
![]() |
9719017bf6 | ||
![]() |
08d476a9cf | ||
![]() |
a2b633d3a5 | ||
![]() |
f7f7bccbe3 | ||
![]() |
14723732f2 | ||
![]() |
19b23f61bb | ||
![]() |
45de0d3936 | ||
![]() |
b96e200d4a | ||
![]() |
bdea4109c8 | ||
![]() |
be7fabd4ce | ||
![]() |
68aab556d6 | ||
![]() |
2fad5b741e | ||
![]() |
1bf95721dd | ||
![]() |
0e4f141075 | ||
![]() |
7cd74373be | ||
![]() |
15d959e871 | ||
![]() |
aac6d024ae | ||
![]() |
80e67fed22 | ||
![]() |
05a19b188b | ||
![]() |
f706034efb | ||
![]() |
e8538a970b | ||
![]() |
f5013096d2 | ||
![]() |
639b8e561c | ||
![]() |
fe03ca12ed | ||
![]() |
375a98b013 | ||
![]() |
522ce2d8a6 | ||
![]() |
6a981ae30b | ||
![]() |
3851206185 | ||
![]() |
beed2d44ca | ||
![]() |
860f1e39fb | ||
![]() |
956d3dc6b1 | ||
![]() |
3582addb62 | ||
![]() |
e392ede4c1 | ||
![]() |
61ee0c4d02 | ||
![]() |
e451190e3c | ||
![]() |
cf83bd3798 | ||
![]() |
4165056c12 | ||
![]() |
596d75adc1 | ||
![]() |
45f6e59583 | ||
![]() |
ff3f606aea | ||
![]() |
e7311a21e9 | ||
![]() |
c4a4255a7a | ||
![]() |
247053665c | ||
![]() |
141c890b9c | ||
![]() |
ccb5d90634 | ||
![]() |
8c61b8a778 | ||
![]() |
093aa66797 | ||
![]() |
669c339f87 | ||
![]() |
e6ab403e3e | ||
![]() |
fcbcdfe660 | ||
![]() |
450073d418 | ||
![]() |
8b0ba30b9f | ||
![]() |
34abc9813b | ||
![]() |
3df0c71a5a | ||
![]() |
1d9206886a | ||
![]() |
4b346b5428 | ||
![]() |
5f51049c1a | ||
![]() |
5e1f652225 | ||
![]() |
1622977991 | ||
![]() |
9a5021110d | ||
![]() |
05d842b69b | ||
![]() |
4a24bd5d90 | ||
![]() |
0fdc780eca | ||
![]() |
6f8bf46c01 | ||
![]() |
7de78365b0 | ||
![]() |
5f87123fb2 | ||
![]() |
fa1cb5fb4b | ||
![]() |
d973d6c60f | ||
![]() |
b002c59578 | ||
![]() |
ec981dc24d | ||
![]() |
12d625f561 | ||
![]() |
37a7d32bc8 | ||
![]() |
044a39abc9 | ||
![]() |
7bedfc5122 | ||
![]() |
1031b2912c | ||
![]() |
732e494400 | ||
![]() |
0a700fc6c3 | ||
![]() |
af069f25e2 | ||
![]() |
c50257fec4 | ||
![]() |
025927577e | ||
![]() |
39bbe54992 | ||
![]() |
f94c7fd607 | ||
![]() |
e3a0a4bc5e | ||
![]() |
44ab6cf9b7 | ||
![]() |
1c23db3b55 | ||
![]() |
ac727885c4 | ||
![]() |
0e8482e28d | ||
![]() |
46720e3236 | ||
![]() |
c3693f5d44 | ||
![]() |
d4f3c6ebf4 | ||
![]() |
3cc4c5d1b4 | ||
![]() |
5cea920270 | ||
![]() |
0dcba9861a | ||
![]() |
03e299ecc6 | ||
![]() |
5e1e63c37b | ||
![]() |
59e73616cd | ||
![]() |
e03e96f61b | ||
![]() |
01cd2cc4b1 | ||
![]() |
f00a4cf38f | ||
![]() |
9d5860a452 | ||
![]() |
24bbbd3e96 | ||
![]() |
673cc2f9f9 | ||
![]() |
db12702baa | ||
![]() |
807cb0aac4 | ||
![]() |
4033885eb7 | ||
![]() |
4deee0d6c1 | ||
![]() |
58ef772764 | ||
![]() |
f9707f796e | ||
![]() |
37f4be68aa | ||
![]() |
84a4491104 | ||
![]() |
2b2453a397 | ||
![]() |
cc6443bb6c | ||
![]() |
58482ecc63 | ||
![]() |
00b9a3e773 | ||
![]() |
249d487813 | ||
![]() |
f6176eca6f | ||
![]() |
f4cf07b565 | ||
![]() |
581b31964e | ||
![]() |
01bc47a6b7 | ||
![]() |
7fc5228297 | ||
![]() |
6153a8ba9f | ||
![]() |
adf029cf72 | ||
![]() |
aa2989d485 | ||
![]() |
df9abb0241 | ||
![]() |
d54e6125f4 | ||
![]() |
fe6516ac44 | ||
![]() |
7a59edbe71 | ||
![]() |
f7f3ef181d | ||
![]() |
b303291ec4 | ||
![]() |
89b67e534e | ||
![]() |
928d60985b | ||
![]() |
403f988248 | ||
![]() |
2099b1b3c2 | ||
![]() |
8ab5e2f976 | ||
![]() |
92227484ac | ||
![]() |
2ede6f6a83 | ||
![]() |
dce39a6075 | ||
![]() |
15e6c42692 | ||
![]() |
f061ff53f2 | ||
![]() |
b8a0207078 | ||
![]() |
4ec09ad650 | ||
![]() |
59f1f5e986 | ||
![]() |
91bdefd9ba | ||
![]() |
382c47aae0 | ||
![]() |
b6bcb852e5 | ||
![]() |
a91a2604dc | ||
![]() |
43e9768819 | ||
![]() |
b45da4edc8 | ||
![]() |
f42abb3c52 | ||
![]() |
ac171b1d61 | ||
![]() |
62a1ce526a | ||
![]() |
ce4abc28a7 | ||
![]() |
c9bafa74d1 | ||
![]() |
37f324a458 | ||
![]() |
bb2a4c69ad | ||
![]() |
c1b70332fc | ||
![]() |
0270b56185 | ||
![]() |
e09351760d | ||
![]() |
bba98b46f5 | ||
![]() |
874cf0ed7d | ||
![]() |
9ba0cbb3c7 | ||
![]() |
3587f179a4 | ||
![]() |
5a9b4e56b7 | ||
![]() |
71780a707a |
236
.all-contributorsrc
Normal file
236
.all-contributorsrc
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
{
|
||||||
|
"files": [
|
||||||
|
"README.md"
|
||||||
|
],
|
||||||
|
"imageSize": 100,
|
||||||
|
"commit": false,
|
||||||
|
"contributors": [
|
||||||
|
{
|
||||||
|
"login": "mezner",
|
||||||
|
"name": "Russell Myers",
|
||||||
|
"avatar_url": "https://avatars2.githubusercontent.com/u/184085?v=4",
|
||||||
|
"profile": "http://www.russellmyers.com",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "ehwarren",
|
||||||
|
"name": "Austin Warren",
|
||||||
|
"avatar_url": "https://avatars1.githubusercontent.com/u/3991658?v=4",
|
||||||
|
"profile": "http://www.morwire.com",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Drachenkaetzchen",
|
||||||
|
"name": "Felicia Hummel",
|
||||||
|
"avatar_url": "https://avatars1.githubusercontent.com/u/162974?v=4",
|
||||||
|
"profile": "https://github.com/Drachenkaetzchen",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "mikemaccana",
|
||||||
|
"name": "Mike MacCana",
|
||||||
|
"avatar_url": "https://avatars2.githubusercontent.com/u/172594?v=4",
|
||||||
|
"profile": "https://github.com/mikemaccana",
|
||||||
|
"contributions": [
|
||||||
|
"test",
|
||||||
|
"design"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "yxuko",
|
||||||
|
"name": "Yacine Kanzari",
|
||||||
|
"avatar_url": "https://avatars1.githubusercontent.com/u/1786317?v=4",
|
||||||
|
"profile": "https://github.com/yxuko",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "BBJip",
|
||||||
|
"name": "BBJip",
|
||||||
|
"avatar_url": "https://avatars2.githubusercontent.com/u/32908927?v=4",
|
||||||
|
"profile": "https://github.com/BBJip",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Futagirl",
|
||||||
|
"name": "Futagirl",
|
||||||
|
"avatar_url": "https://avatars2.githubusercontent.com/u/33533958?v=4",
|
||||||
|
"profile": "https://github.com/Futagirl",
|
||||||
|
"contributions": [
|
||||||
|
"design"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "levrik",
|
||||||
|
"name": "Levin Rickert",
|
||||||
|
"avatar_url": "https://avatars3.githubusercontent.com/u/9491603?v=4",
|
||||||
|
"profile": "https://www.levrik.io",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "kwonoj",
|
||||||
|
"name": "OJ Kwon",
|
||||||
|
"avatar_url": "https://avatars2.githubusercontent.com/u/1210596?v=4",
|
||||||
|
"profile": "https://kwonoj.github.io",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Domain",
|
||||||
|
"name": "domain",
|
||||||
|
"avatar_url": "https://avatars2.githubusercontent.com/u/903197?v=4",
|
||||||
|
"profile": "https://github.com/Domain",
|
||||||
|
"contributions": [
|
||||||
|
"plugin",
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "kbjr",
|
||||||
|
"name": "James Brumond",
|
||||||
|
"avatar_url": "https://avatars1.githubusercontent.com/u/195127?v=4",
|
||||||
|
"profile": "http://www.jbrumond.me",
|
||||||
|
"contributions": [
|
||||||
|
"plugin"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Tyriar",
|
||||||
|
"name": "Daniel Imms",
|
||||||
|
"avatar_url": "https://avatars0.githubusercontent.com/u/2193314?v=4",
|
||||||
|
"profile": "http://www.growingwiththeweb.com",
|
||||||
|
"contributions": [
|
||||||
|
"code",
|
||||||
|
"plugin",
|
||||||
|
"test"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "baflo",
|
||||||
|
"name": "Florian Bachmann",
|
||||||
|
"avatar_url": "https://avatars2.githubusercontent.com/u/834350?v=4",
|
||||||
|
"profile": "https://github.com/baflo",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "mischah",
|
||||||
|
"name": "Michael Kühnel",
|
||||||
|
"avatar_url": "https://avatars2.githubusercontent.com/u/441011?v=4",
|
||||||
|
"profile": "http://michael-kuehnel.de",
|
||||||
|
"contributions": [
|
||||||
|
"code",
|
||||||
|
"design"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "NieLeben",
|
||||||
|
"name": "Tilmann Meyer",
|
||||||
|
"avatar_url": "https://avatars3.githubusercontent.com/u/47182955?v=4",
|
||||||
|
"profile": "https://github.com/NieLeben",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "PMExtra",
|
||||||
|
"name": "PM Extra",
|
||||||
|
"avatar_url": "https://avatars3.githubusercontent.com/u/11289158?v=4",
|
||||||
|
"profile": "http://www.jubeat.net",
|
||||||
|
"contributions": [
|
||||||
|
"bug"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "IgnusG",
|
||||||
|
"name": "Jonathan",
|
||||||
|
"avatar_url": "https://avatars1.githubusercontent.com/u/6438760?v=4",
|
||||||
|
"profile": "https://jjuhas.keybase.pub//",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "hammster",
|
||||||
|
"name": "Hans Koch",
|
||||||
|
"avatar_url": "https://avatars0.githubusercontent.com/u/1093709?v=4",
|
||||||
|
"profile": "https://hans-koch.me",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "ThePuzzlemaker",
|
||||||
|
"name": "Dak Smyth",
|
||||||
|
"avatar_url": "https://avatars3.githubusercontent.com/u/12666617?v=4",
|
||||||
|
"profile": "http://thepuzzlemaker.info",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "yfwz100",
|
||||||
|
"name": "Wang Zhi",
|
||||||
|
"avatar_url": "https://avatars2.githubusercontent.com/u/983211?v=4",
|
||||||
|
"profile": "http://yfwz100.github.io",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "jack1142",
|
||||||
|
"name": "jack1142",
|
||||||
|
"avatar_url": "https://avatars0.githubusercontent.com/u/6032823?v=4",
|
||||||
|
"profile": "https://github.com/jack1142",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "hdougie",
|
||||||
|
"name": "Howie Douglas",
|
||||||
|
"avatar_url": "https://avatars1.githubusercontent.com/u/450799?v=4",
|
||||||
|
"profile": "https://github.com/hdougie",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "ckaczor",
|
||||||
|
"name": "Chris Kaczor",
|
||||||
|
"avatar_url": "https://avatars2.githubusercontent.com/u/180906?v=4",
|
||||||
|
"profile": "https://chriskaczor.com",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "boxmein",
|
||||||
|
"name": "Johannes Kadak",
|
||||||
|
"avatar_url": "https://avatars1.githubusercontent.com/u/358714?v=4",
|
||||||
|
"profile": "https://www.boxmein.net",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"contributorsPerLine": 7,
|
||||||
|
"projectName": "terminus",
|
||||||
|
"projectOwner": "Eugeny",
|
||||||
|
"repoType": "github",
|
||||||
|
"repoHost": "https://github.com",
|
||||||
|
"commitConvention": "none"
|
||||||
|
}
|
99
.eslintrc.yml
Normal file
99
.eslintrc.yml
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
parser: '@typescript-eslint/parser'
|
||||||
|
parserOptions:
|
||||||
|
project: tsconfig.json
|
||||||
|
extends:
|
||||||
|
- 'plugin:@typescript-eslint/all'
|
||||||
|
plugins:
|
||||||
|
- '@typescript-eslint'
|
||||||
|
env:
|
||||||
|
browser: true
|
||||||
|
es6: true
|
||||||
|
node: true
|
||||||
|
commonjs: true
|
||||||
|
rules:
|
||||||
|
'@typescript-eslint/semi':
|
||||||
|
- error
|
||||||
|
- never
|
||||||
|
'@typescript-eslint/indent':
|
||||||
|
- error
|
||||||
|
- 4
|
||||||
|
'@typescript-eslint/explicit-member-accessibility':
|
||||||
|
- error
|
||||||
|
- accessibility: no-public
|
||||||
|
overrides:
|
||||||
|
parameterProperties: explicit
|
||||||
|
'@typescript-eslint/no-require-imports': off
|
||||||
|
'@typescript-eslint/no-parameter-properties': off
|
||||||
|
'@typescript-eslint/explicit-function-return-type': off
|
||||||
|
'@typescript-eslint/no-explicit-any': off
|
||||||
|
'@typescript-eslint/no-magic-numbers': off
|
||||||
|
'@typescript-eslint/member-delimiter-style': off
|
||||||
|
'@typescript-eslint/promise-function-async': off
|
||||||
|
'@typescript-eslint/no-unnecessary-type-assertion': off
|
||||||
|
'@typescript-eslint/require-array-sort-compare': off
|
||||||
|
'@typescript-eslint/no-floating-promises': off
|
||||||
|
'@typescript-eslint/prefer-readonly': off
|
||||||
|
'@typescript-eslint/require-await': off
|
||||||
|
'@typescript-eslint/strict-boolean-expressions': off
|
||||||
|
'@typescript-eslint/no-misused-promises': off
|
||||||
|
'@typescript-eslint/typedef': off
|
||||||
|
'@typescript-eslint/no-use-before-define':
|
||||||
|
- error
|
||||||
|
- classes: false
|
||||||
|
no-duplicate-imports: error
|
||||||
|
array-bracket-spacing:
|
||||||
|
- error
|
||||||
|
- never
|
||||||
|
block-scoped-var: error
|
||||||
|
brace-style: off
|
||||||
|
'@typescript-eslint/brace-style':
|
||||||
|
- error
|
||||||
|
- 1tbs
|
||||||
|
- allowSingleLine: true
|
||||||
|
computed-property-spacing:
|
||||||
|
- error
|
||||||
|
- never
|
||||||
|
comma-dangle:
|
||||||
|
- error
|
||||||
|
- always-multiline
|
||||||
|
curly: error
|
||||||
|
eol-last: error
|
||||||
|
eqeqeq:
|
||||||
|
- error
|
||||||
|
- smart
|
||||||
|
linebreak-style:
|
||||||
|
- error
|
||||||
|
- unix
|
||||||
|
max-depth:
|
||||||
|
- 1
|
||||||
|
- 5
|
||||||
|
max-statements:
|
||||||
|
- 1
|
||||||
|
- 80
|
||||||
|
no-multiple-empty-lines: error
|
||||||
|
no-mixed-spaces-and-tabs: error
|
||||||
|
no-trailing-spaces: error
|
||||||
|
'@typescript-eslint/no-unused-vars':
|
||||||
|
- error
|
||||||
|
- vars: all
|
||||||
|
args: after-used
|
||||||
|
argsIgnorePattern: ^_
|
||||||
|
no-undef: error
|
||||||
|
object-curly-spacing:
|
||||||
|
- error
|
||||||
|
- always
|
||||||
|
quote-props:
|
||||||
|
- warn
|
||||||
|
- as-needed
|
||||||
|
- keywords: true
|
||||||
|
numbers: true
|
||||||
|
quotes: off
|
||||||
|
'@typescript-eslint/quotes':
|
||||||
|
- error
|
||||||
|
- single
|
||||||
|
- allowTemplateLiterals: true
|
||||||
|
'@typescript-eslint/no-non-null-assertion': off
|
||||||
|
'@typescript-eslint/no-unnecessary-condition': off
|
||||||
|
'@typescript-eslint/no-untyped-public-signature': off # bugs out on constructors
|
||||||
|
'@typescript-eslint/restrict-template-expressions': off
|
||||||
|
'@typescript-eslint/no-dynamic-delete': off
|
4
.github/stale.yml
vendored
4
.github/stale.yml
vendored
@@ -1,7 +1,7 @@
|
|||||||
# Number of days of inactivity before an issue becomes stale
|
# Number of days of inactivity before an issue becomes stale
|
||||||
daysUntilStale: 60
|
daysUntilStale: 180
|
||||||
# Number of days of inactivity before a stale issue is closed
|
# Number of days of inactivity before a stale issue is closed
|
||||||
daysUntilClose: 14
|
daysUntilClose: 90
|
||||||
# Issues with these labels will never be considered stale
|
# Issues with these labels will never be considered stale
|
||||||
exemptLabels:
|
exemptLabels:
|
||||||
- "T: Enhancement"
|
- "T: Enhancement"
|
||||||
|
30
.github/workflows/docs.yml
vendored
Normal file
30
.github/workflows/docs.yml
vendored
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
name: Docs
|
||||||
|
on: push
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-18.04
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
|
||||||
|
- name: Installing Node
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
version: 10
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
eval $(ssh-agent -s)
|
||||||
|
ssh-add <(echo "$DOCS_PRIVATE_KEY")
|
||||||
|
yarn cache clean
|
||||||
|
cd app
|
||||||
|
yarn
|
||||||
|
cd ..
|
||||||
|
rm app/node_modules/.yarn-integrity
|
||||||
|
yarn
|
||||||
|
yarn run docs
|
||||||
|
rsync -e "ssh -o StrictHostKeyChecking=no" -arv docs/api/ root@ajenti.org:/srv/terminus-docs/
|
||||||
|
|
||||||
|
env:
|
||||||
|
DOCS_PRIVATE_KEY: ${{ secrets.DOCS_PRIVATE_KEY }}
|
26
.github/workflows/lint.yml
vendored
Normal file
26
.github/workflows/lint.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
name: Lint
|
||||||
|
on: [push, pull_request]
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: macOS-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
|
||||||
|
- name: Installing Node
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
version: 10
|
||||||
|
|
||||||
|
- name: Install deps
|
||||||
|
run: |
|
||||||
|
npm i -g yarn@1.19.1
|
||||||
|
cd app
|
||||||
|
yarn
|
||||||
|
cd ..
|
||||||
|
rm app/node_modules/.yarn-integrity
|
||||||
|
yarn
|
||||||
|
|
||||||
|
- name: Lint
|
||||||
|
run: yarn run lint
|
76
.github/workflows/linux.yml
vendored
Normal file
76
.github/workflows/linux.yml
vendored
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
name: Linux Build
|
||||||
|
on: [push, pull_request]
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
|
||||||
|
- name: Install Node
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
version: 10
|
||||||
|
|
||||||
|
- name: Install deps
|
||||||
|
run: |
|
||||||
|
npm i -g yarn@1.19.1
|
||||||
|
cd app
|
||||||
|
yarn
|
||||||
|
cd ..
|
||||||
|
rm app/node_modules/.yarn-integrity
|
||||||
|
yarn
|
||||||
|
|
||||||
|
- name: Build native deps
|
||||||
|
run: scripts/build-native.js
|
||||||
|
|
||||||
|
- name: Build typings
|
||||||
|
run: yarn run build:typings
|
||||||
|
|
||||||
|
- name: Webpack
|
||||||
|
run: yarn run build
|
||||||
|
|
||||||
|
- name: Prepackage plugins
|
||||||
|
run: scripts/prepackage-plugins.js
|
||||||
|
|
||||||
|
- name: Build packages
|
||||||
|
run: scripts/build-linux.js
|
||||||
|
env:
|
||||||
|
DEBUG: electron-builder,electron-builder:*
|
||||||
|
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||||
|
|
||||||
|
- name: Package artifacts
|
||||||
|
run: |
|
||||||
|
mkdir artifact-deb
|
||||||
|
mv dist/*.deb artifact-deb/ || true
|
||||||
|
mkdir artifact-rpm
|
||||||
|
mv dist/*.rpm artifact-rpm/ || true
|
||||||
|
mkdir artifact-snap
|
||||||
|
mv dist/*.snap artifact-snap/ || true
|
||||||
|
mkdir artifact-tar.gz
|
||||||
|
mv dist/*.tar.gz artifact-tar.gz/ || true
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@master
|
||||||
|
name: Upload DEB
|
||||||
|
with:
|
||||||
|
name: Linux .deb
|
||||||
|
path: artifact-deb
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@master
|
||||||
|
name: Upload RPM
|
||||||
|
with:
|
||||||
|
name: Linux .rpm
|
||||||
|
path: artifact-rpm
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@master
|
||||||
|
name: Upload Snap
|
||||||
|
with:
|
||||||
|
name: Linux .snap
|
||||||
|
path: artifact-snap
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@master
|
||||||
|
name: Upload tarball
|
||||||
|
with:
|
||||||
|
name: Linux tarball
|
||||||
|
path: artifact-tar.gz
|
69
.github/workflows/macos.yml
vendored
Normal file
69
.github/workflows/macos.yml
vendored
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
name: macOS Build
|
||||||
|
on: [push, pull_request]
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: macOS-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
|
||||||
|
- name: Installing Node
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
version: 10
|
||||||
|
|
||||||
|
- name: Install deps
|
||||||
|
run: |
|
||||||
|
sudo npm i -g yarn@1.19.1
|
||||||
|
cd app
|
||||||
|
yarn
|
||||||
|
cd ..
|
||||||
|
rm app/node_modules/.yarn-integrity
|
||||||
|
yarn
|
||||||
|
|
||||||
|
- name: Build native deps
|
||||||
|
run: scripts/build-native.js
|
||||||
|
|
||||||
|
- name: Build typings
|
||||||
|
run: yarn run build:typings
|
||||||
|
|
||||||
|
- name: Webpack
|
||||||
|
run: yarn run build
|
||||||
|
|
||||||
|
- name: Prepackage plugins
|
||||||
|
run: scripts/prepackage-plugins.js
|
||||||
|
|
||||||
|
- name: Build and sign packages
|
||||||
|
run: scripts/build-macos.js
|
||||||
|
if: github.repository == 'Eugeny/terminus' && github.event_name == 'push'
|
||||||
|
env:
|
||||||
|
DEBUG: electron-builder,electron-builder:*
|
||||||
|
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||||
|
CSC_LINK: ${{ secrets.CSC_LINK }}
|
||||||
|
CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
|
||||||
|
|
||||||
|
- name: Build packages without signing
|
||||||
|
run: scripts/build-macos.js
|
||||||
|
if: github.repository != 'Eugeny/terminus' || github.event_name != 'push'
|
||||||
|
env:
|
||||||
|
DEBUG: electron-builder,electron-builder:*
|
||||||
|
|
||||||
|
- name: Package artifacts
|
||||||
|
run: |
|
||||||
|
mkdir artifact-pkg
|
||||||
|
mv dist/*.pkg artifact-pkg/
|
||||||
|
mkdir artifact-zip
|
||||||
|
mv dist/*.zip artifact-zip/
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@master
|
||||||
|
name: Upload PKG
|
||||||
|
with:
|
||||||
|
name: macOS .pkg
|
||||||
|
path: artifact-pkg
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@master
|
||||||
|
name: Upload ZIP
|
||||||
|
with:
|
||||||
|
name: macOS .zip
|
||||||
|
path: artifact-zip
|
54
.github/workflows/windows.yml
vendored
Normal file
54
.github/workflows/windows.yml
vendored
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
name: Windows Build
|
||||||
|
on: [push, pull_request]
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: windows-2016
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
|
||||||
|
- name: Installing Node
|
||||||
|
uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
version: 10
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
shell: powershell
|
||||||
|
run: |
|
||||||
|
npm i -g yarn@1.19.1
|
||||||
|
yarn
|
||||||
|
node scripts/build-native.js
|
||||||
|
yarn run build
|
||||||
|
node scripts/prepackage-plugins.js
|
||||||
|
|
||||||
|
- name: Build and sign packages
|
||||||
|
run: node scripts/build-windows.js
|
||||||
|
if: github.repository == 'Eugeny/terminus' && github.event_name == 'push'
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||||
|
WIN_CSC_LINK: ${{ secrets.WIN_CSC_LINK }}
|
||||||
|
WIN_CSC_KEY_PASSWORD: ${{ secrets.WIN_CSC_KEY_PASSWORD }}
|
||||||
|
|
||||||
|
- name: Build packages without signing
|
||||||
|
run: node scripts/build-windows.js
|
||||||
|
if: github.repository != 'Eugeny/terminus' || github.event_name != 'push'
|
||||||
|
|
||||||
|
- name: Package artifacts
|
||||||
|
run: |
|
||||||
|
mkdir artifact-setup
|
||||||
|
mv dist/*-setup.exe artifact-setup/
|
||||||
|
mkdir artifact-portable
|
||||||
|
mv dist/*-portable.exe artifact-portable/
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@master
|
||||||
|
name: Upload installer
|
||||||
|
with:
|
||||||
|
name: Installer
|
||||||
|
path: artifact-setup
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@master
|
||||||
|
name: Upload portable build
|
||||||
|
with:
|
||||||
|
name: Portable build
|
||||||
|
path: artifact-portable
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -6,6 +6,8 @@ node_modules
|
|||||||
build/files.wxs
|
build/files.wxs
|
||||||
dist
|
dist
|
||||||
*/dist
|
*/dist
|
||||||
|
*/typings
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
*.xcworkspacedata
|
*.xcworkspacedata
|
||||||
*.xcuserstate
|
*.xcuserstate
|
||||||
@@ -21,3 +23,4 @@ yarn-error.log
|
|||||||
|
|
||||||
docs/api
|
docs/api
|
||||||
.travis.ssh.key
|
.travis.ssh.key
|
||||||
|
*.code-workspace
|
||||||
|
14
.mergify.yml
Normal file
14
.mergify.yml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
pull_request_rules:
|
||||||
|
- name: automatic merge on CI success and review
|
||||||
|
conditions:
|
||||||
|
- "status-success=Windows Build / Build"
|
||||||
|
- "status-success=macOS Build / Build"
|
||||||
|
- "status-success=Linux Build / Build"
|
||||||
|
- "status-success=continuous-integration/appveyor/pr"
|
||||||
|
- "#approved-reviews-by>=1"
|
||||||
|
- "#changes-requested-reviews-by=0"
|
||||||
|
- base=master
|
||||||
|
actions:
|
||||||
|
merge:
|
||||||
|
method: merge
|
||||||
|
strict: true
|
Binary file not shown.
@@ -1 +0,0 @@
|
|||||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDDFM4nHSbET5V7EYNgjA8NeVfOxV0wVMdZ2YvsDzD+qPJ4+MYbvsL7ZPaSxQSn7n6ATkLHjKje5RpF/Rl9K3kucGs0P6cqJVeE0qryEteQ3Q+fYAk+bD2J9ZQ/hv/0NtLl8T+7lJUZ3WUxFH73sgph77Sw0z+kMpPaK7U2vqMBQD/7+6iJgya31wP0qW0XKDz1BjKeXgwTg10Pm4vcGsR4c2q7YIzSzBHffcyo0vJyFvOX/ZKHlZRcq/wnQMeOl/hPgf1xCENjQZmFVReQlYSw5cNNDT9HZPKekOAZFFez7/AbPiTIo/bnBYIv0mdUjr3nw8nXF505q8LiD3z/ksaaWDqe9CCLM4W0Bh7/dhP7IGPdfX0fVHLhOnYIOsG21D8rWJjMPkVRSLyEvWNAnVuObJNHoQu8VATnOxfPNnMun72IHyyFWVoADk5JcsMbzcP7gZB+5oJO7U1qpcdndtBOA3ZlF0Uz2jVZnqavoEBWT39tl3vs69hAA3aTPGclg7HMuAJOl4HsKmaUgDxqV2wCX/S4pDqmKMbmumDLX+MM0xl0gXj/zpVJp9BzdnrArkC40ivmC6TSA4wrdN0tNBlqApkH5/jxGWrcu2AXVn9PGF3+QrjW0iu+QMZCaKWDhLIQC835uFwzhnNGlx41B7uxMLuNFxKXdQ3f/cC9QMG8ew== TravisCIDeployKey
|
|
27
.travis.yml
27
.travis.yml
@@ -8,32 +8,12 @@ stages:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
include:
|
include:
|
||||||
- stage: 'Build'
|
|
||||||
os: linux
|
|
||||||
before_install:
|
|
||||||
- yarn
|
|
||||||
- rm app/node_modules/.yarn-integrity || true
|
|
||||||
- scripts/install-deps.js
|
|
||||||
script:
|
|
||||||
- scripts/build-native.js
|
|
||||||
- yarn run build
|
|
||||||
- scripts/prepackage-plugins.js
|
|
||||||
- scripts/build-linux.js
|
|
||||||
|
|
||||||
- stage: 'Build'
|
|
||||||
os: osx
|
|
||||||
before_install:
|
|
||||||
- rm app/node_modules/.yarn-integrity || true
|
|
||||||
- yarn
|
|
||||||
script:
|
|
||||||
- scripts/build-native.js
|
|
||||||
- yarn run build
|
|
||||||
- scripts/prepackage-plugins.js
|
|
||||||
- scripts/build-macos.js
|
|
||||||
|
|
||||||
- stage: 'Docs'
|
- stage: 'Docs'
|
||||||
os: linux
|
os: linux
|
||||||
|
if: branch = master
|
||||||
script:
|
script:
|
||||||
|
- '[ -z "${encrypted_4e2fb4889ef8_iv}" ] && exit 0 || true'
|
||||||
|
- set -e
|
||||||
- openssl aes-256-cbc -K $encrypted_4e2fb4889ef8_key -iv $encrypted_4e2fb4889ef8_iv -in .travis.ssh.key.enc -out .travis.ssh.key -d
|
- openssl aes-256-cbc -K $encrypted_4e2fb4889ef8_key -iv $encrypted_4e2fb4889ef8_iv -in .travis.ssh.key.enc -out .travis.ssh.key -d
|
||||||
- eval "$(ssh-agent -s)"
|
- eval "$(ssh-agent -s)"
|
||||||
- chmod 600 .travis.ssh.key
|
- chmod 600 .travis.ssh.key
|
||||||
@@ -50,6 +30,7 @@ addons:
|
|||||||
packages:
|
packages:
|
||||||
- rpm
|
- rpm
|
||||||
- yarn
|
- yarn
|
||||||
|
- libsecret-1-dev
|
||||||
sources:
|
sources:
|
||||||
- sourceline: 'deb https://dl.yarnpkg.com/debian/ stable main'
|
- sourceline: 'deb https://dl.yarnpkg.com/debian/ stable main'
|
||||||
key_url: 'https://dl.yarnpkg.com/debian/pubkey.gpg'
|
key_url: 'https://dl.yarnpkg.com/debian/pubkey.gpg'
|
||||||
|
@@ -92,11 +92,11 @@ Plugins provide functionality by exporting singular or multi providers:
|
|||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
import { NgModule, Injectable } from '@angular/core'
|
import { NgModule, Injectable } from '@angular/core'
|
||||||
import { ToolbarButtonProvider, IToolbarButton } from 'terminus-core'
|
import { ToolbarButtonProvider, ToolbarButton } from 'terminus-core'
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class MyButtonProvider extends ToolbarButtonProvider {
|
export class MyButtonProvider extends ToolbarButtonProvider {
|
||||||
provide (): IToolbarButton[] {
|
provide (): ToolbarButton[] {
|
||||||
return [{
|
return [{
|
||||||
icon: 'star',
|
icon: 'star',
|
||||||
title: 'Foobar',
|
title: 'Foobar',
|
||||||
|
56
README.md
56
README.md
@@ -1,12 +1,12 @@
|
|||||||

|

|
||||||
|
|
||||||
|
|
||||||
<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://travis-ci.org/Eugeny/terminus"><img alt="Travis (.org)" src="https://img.shields.io/travis/Eugeny/terminus.svg?label=CI&logo=travis&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>
|
||||||
<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=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>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
----
|
----
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
* **Terminus is** an alternative to Windows' standard terminal (conhost), PowerShell ISE, PuTTY or iTerm
|
* **Terminus is** an alternative to Windows' standard terminal (conhost), PowerShell ISE, PuTTY or iTerm
|
||||||
|
|
||||||
* **Terminus is not** a new shell or a MinGW or Cygwin replacement. Neither is it lightweight - if RAM usage is of importance, consider [Conemu](https://conemu.github.io) or [Alacritty](https://github.com/jwilm/alacritty)
|
* **Terminus is not** a new shell or a MinGW or Cygwin replacement. Neither is it lightweight - if RAM usage is of importance, consider [Conemu](https://conemu.github.io) or [Alacritty](https://github.com/jwilm/alacritty)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ Plugins and themes can be installed directly from the Settings view inside Termi
|
|||||||
* [gruvbox](https://github.com/porkloin/terminus-theme-gruvbox)
|
* [gruvbox](https://github.com/porkloin/terminus-theme-gruvbox)
|
||||||
* [windows10](https://www.npmjs.com/package/terminus-theme-windows10)
|
* [windows10](https://www.npmjs.com/package/terminus-theme-windows10)
|
||||||
* [altair](https://github.com/yxuko/terminus-altair)
|
* [altair](https://github.com/yxuko/terminus-altair)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Contributing
|
# Contributing
|
||||||
@@ -61,5 +61,47 @@ Pull requests and plugins are welcome!
|
|||||||
|
|
||||||
See [HACKING.md](https://github.com/Eugeny/terminus/blob/master/HACKING.md) and [API docs](http://ajenti.org/terminus-docs/) for information of how the project is laid out, and a very brief plugin development tutorial.
|
See [HACKING.md](https://github.com/Eugeny/terminus/blob/master/HACKING.md) and [API docs](http://ajenti.org/terminus-docs/) for information of how the project is laid out, and a very brief plugin development tutorial.
|
||||||
|
|
||||||
## License
|
---
|
||||||
[](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2FEugeny%2Fterminus?ref=badge_large)
|
|
||||||
|
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
|
||||||
|
|
||||||
|
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
||||||
|
<!-- prettier-ignore -->
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="http://www.russellmyers.com"><img src="https://avatars2.githubusercontent.com/u/184085?v=4" width="100px;" alt="Russell Myers"/><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="Austin Warren"/><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="Felicia Hummel"/><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="Mike MacCana"/><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="Yacine Kanzari"/><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="BBJip"/><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="Futagirl"/><br /><sub><b>Futagirl</b></sub></a><br /><a href="#design-Futagirl" title="Design">🎨</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://www.levrik.io"><img src="https://avatars3.githubusercontent.com/u/9491603?v=4" width="100px;" alt="Levin Rickert"/><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="OJ Kwon"/><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="domain"/><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="James Brumond"/><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="Daniel Imms"/><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="Florian Bachmann"/><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="Michael Kühnel"/><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>
|
||||||
|
<td align="center"><a href="https://github.com/NieLeben"><img src="https://avatars3.githubusercontent.com/u/47182955?v=4" width="100px;" alt="Tilmann Meyer"/><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="PM Extra"/><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="Jonathan"/><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="Hans Koch"/><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="Dak Smyth"/><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="Wang Zhi"/><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="jack1142"/><br /><sub><b>jack1142</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=jack1142" title="Code">💻</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://github.com/hdougie"><img src="https://avatars1.githubusercontent.com/u/450799?v=4" width="100px;" alt="Howie Douglas"/><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="Chris Kaczor"/><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="Johannes Kadak"/><br /><sub><b>Johannes Kadak</b></sub></a><br /><a href="https://github.com/Eugeny/terminus/commits?author=boxmein" title="Code">💻</a></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||||
|
|
||||||
|
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
||||||
|
@@ -19,12 +19,16 @@ export class Application {
|
|||||||
}
|
}
|
||||||
|
|
||||||
app.commandLine.appendSwitch('disable-http-cache')
|
app.commandLine.appendSwitch('disable-http-cache')
|
||||||
app.commandLine.appendSwitch('force_discrete_gpu', '0')
|
|
||||||
app.commandLine.appendSwitch('lang', 'EN')
|
app.commandLine.appendSwitch('lang', 'EN')
|
||||||
|
|
||||||
|
for (const flag of configData.flags || [['force_discrete_gpu', '0']]) {
|
||||||
|
console.log('Setting Electron flag:', flag.join('='))
|
||||||
|
app.commandLine.appendSwitch(flag[0], flag[1])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init () {
|
init () {
|
||||||
electron.screen.on('display-metrics-changed', () => this.broadcast('host:display-metrics-changed'))
|
electron.screen.on('display-metrics-changed', () => this.broadcast('host:display-metrics-changed'))
|
||||||
}
|
}
|
||||||
|
|
||||||
async newWindow (options?: WindowOptions): Promise<Window> {
|
async newWindow (options?: WindowOptions): Promise<Window> {
|
||||||
@@ -54,7 +58,7 @@ export class Application {
|
|||||||
if (!this.hasWindows()) {
|
if (!this.hasWindows()) {
|
||||||
await this.newWindow()
|
await this.newWindow()
|
||||||
}
|
}
|
||||||
this.windows[0].send(event, ...args)
|
this.windows.filter(w => !w.isDestroyed())[0].send(event, ...args)
|
||||||
}
|
}
|
||||||
|
|
||||||
enableTray () {
|
enableTray () {
|
||||||
@@ -68,7 +72,7 @@ export class Application {
|
|||||||
this.tray = new Tray(`${app.getAppPath()}/assets/tray.png`)
|
this.tray = new Tray(`${app.getAppPath()}/assets/tray.png`)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.tray.on('click', () => this.focus())
|
this.tray.on('click', () => setTimeout(() => this.focus()));
|
||||||
|
|
||||||
const contextMenu = Menu.buildFromTemplate([{
|
const contextMenu = Menu.buildFromTemplate([{
|
||||||
label: 'Show',
|
label: 'Show',
|
||||||
@@ -96,7 +100,6 @@ export class Application {
|
|||||||
focus () {
|
focus () {
|
||||||
for (let window of this.windows) {
|
for (let window of this.windows) {
|
||||||
window.show()
|
window.show()
|
||||||
window.focus()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +124,7 @@ export class Application {
|
|||||||
{ role: 'services', submenu: [] },
|
{ role: 'services', submenu: [] },
|
||||||
{ type: 'separator' },
|
{ type: 'separator' },
|
||||||
{ role: 'hide' },
|
{ role: 'hide' },
|
||||||
{ role: 'hideothers' },
|
{ role: 'hideOthers' },
|
||||||
{ role: 'unhide' },
|
{ role: 'unhide' },
|
||||||
{ type: 'separator' },
|
{ type: 'separator' },
|
||||||
{
|
{
|
||||||
@@ -142,21 +145,21 @@ export class Application {
|
|||||||
{ role: 'cut' },
|
{ role: 'cut' },
|
||||||
{ role: 'copy' },
|
{ role: 'copy' },
|
||||||
{ role: 'paste' },
|
{ role: 'paste' },
|
||||||
{ role: 'pasteandmatchstyle' },
|
{ role: 'pasteAndMatchStyle' },
|
||||||
{ role: 'delete' },
|
{ role: 'delete' },
|
||||||
{ role: 'selectall' },
|
{ role: 'selectAll' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'View',
|
label: 'View',
|
||||||
submenu: [
|
submenu: [
|
||||||
{ role: 'reload' },
|
{ role: 'reload' },
|
||||||
{ role: 'forcereload' },
|
{ role: 'forceReload' },
|
||||||
{ role: 'toggledevtools' },
|
{ role: 'toggleDevTools' },
|
||||||
{ type: 'separator' },
|
{ type: 'separator' },
|
||||||
{ role: 'resetzoom' },
|
{ role: 'resetZoom' },
|
||||||
{ role: 'zoomin' },
|
{ role: 'zoomIn' },
|
||||||
{ role: 'zoomout' },
|
{ role: 'zoomOut' },
|
||||||
{ type: 'separator' },
|
{ type: 'separator' },
|
||||||
{ role: 'togglefullscreen' },
|
{ role: 'togglefullscreen' },
|
||||||
],
|
],
|
||||||
|
@@ -41,6 +41,5 @@ export function parseArgs (argv, cwd) {
|
|||||||
type: 'boolean'
|
type: 'boolean'
|
||||||
})
|
})
|
||||||
.help('help')
|
.help('help')
|
||||||
.strict()
|
|
||||||
.parse(argv.slice(1))
|
.parse(argv.slice(1))
|
||||||
}
|
}
|
||||||
|
@@ -39,7 +39,7 @@ const argv = parseArgs(process.argv, process.cwd())
|
|||||||
|
|
||||||
if (!app.requestSingleInstanceLock()) {
|
if (!app.requestSingleInstanceLock()) {
|
||||||
app.quit()
|
app.quit()
|
||||||
process.exit(0)
|
app.exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argv.d) {
|
if (argv.d) {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
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 } from 'electron'
|
import { BrowserWindow, app, ipcMain, Rectangle, screen } from 'electron'
|
||||||
import ElectronConfig = require('electron-config')
|
import ElectronConfig = require('electron-config')
|
||||||
import * as os from 'os'
|
import * as os from 'os'
|
||||||
|
|
||||||
@@ -49,9 +49,21 @@ export class Window {
|
|||||||
},
|
},
|
||||||
frame: false,
|
frame: false,
|
||||||
show: false,
|
show: false,
|
||||||
backgroundColor: '#00000000'
|
backgroundColor: '#00000000',
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.windowBounds) {
|
||||||
|
Object.assign(bwOptions, this.windowBounds)
|
||||||
|
const closestDisplay = screen.getDisplayNearestPoint( {x: this.windowBounds.x, y: this.windowBounds.y} )
|
||||||
|
|
||||||
|
const [left1, top1, right1, bottom1] = [this.windowBounds.x, this.windowBounds.y, this.windowBounds.x + this.windowBounds.width, this.windowBounds.y + this.windowBounds.height];
|
||||||
|
const [left2, top2, right2, bottom2] = [closestDisplay.bounds.x, closestDisplay.bounds.y, closestDisplay.bounds.x + closestDisplay.bounds.width, closestDisplay.bounds.y + closestDisplay.bounds.height];
|
||||||
|
|
||||||
|
if ((left2 > right1 || right2 < left1 || top2 > bottom1 || bottom2 < top1) && !maximized) {
|
||||||
|
bwOptions.x = closestDisplay.bounds.width / 2 - bwOptions.width / 2;
|
||||||
|
bwOptions.y = closestDisplay.bounds.height / 2 - bwOptions.height / 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Object.assign(bwOptions, this.windowBounds)
|
|
||||||
|
|
||||||
if ((configData.appearance || {}).frame === 'native') {
|
if ((configData.appearance || {}).frame === 'native') {
|
||||||
bwOptions.frame = true
|
bwOptions.frame = true
|
||||||
@@ -68,7 +80,7 @@ export class Window {
|
|||||||
this.window = new 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('dark')
|
this.window.setVibrancy('window')
|
||||||
} else if (process.platform === 'win32' && (configData.appearance || {}).vibrancy) {
|
} else if (process.platform === 'win32' && (configData.appearance || {}).vibrancy) {
|
||||||
this.setVibrancy(true)
|
this.setVibrancy(true)
|
||||||
}
|
}
|
||||||
@@ -82,6 +94,7 @@ export class Window {
|
|||||||
this.window.focus()
|
this.window.focus()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
this.window.loadURL(`file://${app.getAppPath()}/dist/index.html?${this.window.id}`, { extraHeaders: 'pragma: no-cache\n' })
|
this.window.loadURL(`file://${app.getAppPath()}/dist/index.html?${this.window.id}`, { extraHeaders: 'pragma: no-cache\n' })
|
||||||
|
|
||||||
if (process.platform !== 'darwin') {
|
if (process.platform !== 'darwin') {
|
||||||
@@ -93,7 +106,7 @@ export class Window {
|
|||||||
this.ready = new Promise(resolve => {
|
this.ready = new Promise(resolve => {
|
||||||
const listener = event => {
|
const listener = event => {
|
||||||
if (event.sender === this.window.webContents) {
|
if (event.sender === this.window.webContents) {
|
||||||
ipcMain.removeListener('app:ready', listener)
|
ipcMain.removeListener('app:ready', listener as any)
|
||||||
resolve()
|
resolve()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -134,6 +147,10 @@ export class Window {
|
|||||||
this.window.webContents.send(event, ...args)
|
this.window.webContents.send(event, ...args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isDestroyed() {
|
||||||
|
return !this.window || this.window.isDestroyed();
|
||||||
|
}
|
||||||
|
|
||||||
private setupWindowManagement () {
|
private setupWindowManagement () {
|
||||||
this.window.on('show', () => {
|
this.window.on('show', () => {
|
||||||
this.visible.next(true)
|
this.visible.next(true)
|
||||||
|
@@ -20,25 +20,35 @@
|
|||||||
"@angular/forms": "7.2.8",
|
"@angular/forms": "7.2.8",
|
||||||
"@angular/platform-browser": "7.2.8",
|
"@angular/platform-browser": "7.2.8",
|
||||||
"@angular/platform-browser-dynamic": "7.2.8",
|
"@angular/platform-browser-dynamic": "7.2.8",
|
||||||
"@ng-bootstrap/ng-bootstrap": "^4.1.3",
|
"@ng-bootstrap/ng-bootstrap": "^4.2.2",
|
||||||
"devtron": "1.4.0",
|
"devtron": "1.4.0",
|
||||||
"electron-config": "2.0.0",
|
"electron-config": "2.0.0",
|
||||||
"electron-debug": "^3.0.0",
|
"electron-debug": "^3.0.1",
|
||||||
"electron-is-dev": "1.1.0",
|
"electron-is-dev": "1.1.0",
|
||||||
"electron-updater": "^4.0.6",
|
"electron-updater": "^4.2.0",
|
||||||
|
"fontmanager-redux": "0.4.0",
|
||||||
"js-yaml": "3.13.1",
|
"js-yaml": "3.13.1",
|
||||||
|
"keytar": "^5.0.0",
|
||||||
"mz": "^2.7.0",
|
"mz": "^2.7.0",
|
||||||
"ngx-toastr": "^9.1.1",
|
"ngx-toastr": "^10.2.0",
|
||||||
|
"node-pty": "^0.10.0-beta2",
|
||||||
|
"npm": "6.9.0",
|
||||||
"path": "0.12.7",
|
"path": "0.12.7",
|
||||||
"rxjs": "^6.5.2",
|
"rxjs": "^6.5.3",
|
||||||
"yargs": "^13.2.4",
|
"rxjs-compat": "^6.5.3",
|
||||||
|
"yargs": "^15.0.2",
|
||||||
"zone.js": "^0.8.29"
|
"zone.js": "^0.8.29"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
|
"macos-native-processlist": "^1.0.2",
|
||||||
"windows-blurbehind": "^1.0.1",
|
"windows-blurbehind": "^1.0.1",
|
||||||
|
"windows-native-registry": "^1.0.15",
|
||||||
|
"windows-process-tree": "^0.2.4",
|
||||||
"windows-swca": "^2.0.2"
|
"windows-swca": "^2.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/mz": "0.0.32"
|
"@types/mz": "0.0.32",
|
||||||
|
"@types/node": "12.7.12",
|
||||||
|
"node-abi": "^2.12.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,18 +4,19 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
|
|||||||
import { ToastrModule } from 'ngx-toastr'
|
import { ToastrModule } from 'ngx-toastr'
|
||||||
|
|
||||||
export function getRootModule (plugins: any[]) {
|
export function getRootModule (plugins: any[]) {
|
||||||
let imports = [
|
const imports = [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
...plugins,
|
...plugins,
|
||||||
NgbModule.forRoot(),
|
NgbModule.forRoot(),
|
||||||
ToastrModule.forRoot({
|
ToastrModule.forRoot({
|
||||||
positionClass: 'toast-bottom-center',
|
positionClass: 'toast-bottom-center',
|
||||||
|
toastClass: 'toast',
|
||||||
preventDuplicates: true,
|
preventDuplicates: true,
|
||||||
extendedTimeOut: 5000,
|
extendedTimeOut: 5000,
|
||||||
}),
|
}),
|
||||||
]
|
]
|
||||||
let bootstrap = [
|
const bootstrap = [
|
||||||
...(plugins.filter(x => x.bootstrap).map(x => x.bootstrap)),
|
...plugins.filter(x => x.bootstrap).map(x => x.bootstrap),
|
||||||
]
|
]
|
||||||
|
|
||||||
if (bootstrap.length === 0) {
|
if (bootstrap.length === 0) {
|
||||||
@@ -25,7 +26,7 @@ export function getRootModule (plugins: any[]) {
|
|||||||
@NgModule({
|
@NgModule({
|
||||||
imports,
|
imports,
|
||||||
bootstrap,
|
bootstrap,
|
||||||
}) class RootModule { }
|
}) class RootModule { } // eslint-disable-line @typescript-eslint/no-extraneous-class
|
||||||
|
|
||||||
return RootModule
|
return RootModule
|
||||||
}
|
}
|
||||||
|
@@ -16,20 +16,20 @@ Raven.config(
|
|||||||
{
|
{
|
||||||
release: require('electron').remote.app.getVersion(),
|
release: require('electron').remote.app.getVersion(),
|
||||||
dataCallback: (data: any) => {
|
dataCallback: (data: any) => {
|
||||||
const normalize = (filename) => {
|
const normalize = (filename: string) => {
|
||||||
let splitArray = filename.split('/')
|
const splitArray = filename.split('/')
|
||||||
return splitArray[splitArray.length - 1]
|
return splitArray[splitArray.length - 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
data.exception.values[0].stacktrace.frames.forEach(frame => {
|
data.exception.values[0].stacktrace.frames.forEach((frame: any) => {
|
||||||
frame.filename = normalize(frame.filename)
|
frame.filename = normalize(frame.filename)
|
||||||
})
|
})
|
||||||
|
|
||||||
data.culprit = data.exception.values[0].stacktrace.frames[0].filename
|
data.culprit = data.exception.values[0].stacktrace.frames[0].filename
|
||||||
|
|
||||||
return data
|
return data
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
process.on('uncaughtException' as any, (err) => {
|
process.on('uncaughtException' as any, (err) => {
|
||||||
|
@@ -2,24 +2,24 @@ import 'zone.js'
|
|||||||
import 'core-js/proposals/reflect-metadata'
|
import 'core-js/proposals/reflect-metadata'
|
||||||
import 'rxjs'
|
import 'rxjs'
|
||||||
|
|
||||||
import isDev = require('electron-is-dev')
|
import * as isDev from 'electron-is-dev'
|
||||||
|
|
||||||
import './global.scss'
|
import './global.scss'
|
||||||
import './toastr.scss'
|
import './toastr.scss'
|
||||||
|
|
||||||
// Always land on the start view
|
|
||||||
location.hash = ''
|
|
||||||
|
|
||||||
import { enableProdMode, NgModuleRef } from '@angular/core'
|
import { enableProdMode, NgModuleRef } from '@angular/core'
|
||||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'
|
||||||
|
|
||||||
import { getRootModule } from './app.module'
|
import { getRootModule } from './app.module'
|
||||||
import { findPlugins, loadPlugins, IPluginInfo } from './plugins'
|
import { findPlugins, loadPlugins, PluginInfo } from './plugins'
|
||||||
|
|
||||||
|
// Always land on the start view
|
||||||
|
location.hash = ''
|
||||||
|
|
||||||
;(process as any).enablePromiseAPI = true
|
;(process as any).enablePromiseAPI = true
|
||||||
|
|
||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32' && !('HOME' in process.env)) {
|
||||||
process.env.HOME = process.env.HOMEDRIVE + process.env.HOMEPATH
|
process.env.HOME = `${process.env.HOMEDRIVE}${process.env.HOMEPATH}`
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isDev) {
|
if (isDev) {
|
||||||
@@ -28,14 +28,14 @@ if (isDev) {
|
|||||||
enableProdMode()
|
enableProdMode()
|
||||||
}
|
}
|
||||||
|
|
||||||
async function bootstrap (plugins: IPluginInfo[], safeMode = false): Promise<NgModuleRef<any>> {
|
async function bootstrap (plugins: PluginInfo[], safeMode = false): Promise<NgModuleRef<any>> {
|
||||||
if (safeMode) {
|
if (safeMode) {
|
||||||
plugins = plugins.filter(x => x.isBuiltin)
|
plugins = plugins.filter(x => x.isBuiltin)
|
||||||
}
|
}
|
||||||
let pluginsModules = await loadPlugins(plugins, (current, total) => {
|
const pluginsModules = await loadPlugins(plugins, (current, total) => {
|
||||||
(document.querySelector('.progress .bar') as HTMLElement).style.width = 100 * current / total + '%'
|
(document.querySelector('.progress .bar') as HTMLElement).style.width = `${100 * current / total}%` // eslint-disable-line
|
||||||
})
|
})
|
||||||
let module = getRootModule(pluginsModules)
|
const module = getRootModule(pluginsModules)
|
||||||
window['rootModule'] = module
|
window['rootModule'] = module
|
||||||
return platformBrowserDynamic().bootstrapModule(module)
|
return platformBrowserDynamic().bootstrapModule(module)
|
||||||
}
|
}
|
||||||
|
@@ -16,6 +16,12 @@ body {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
& > svg {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.form-line {
|
.form-line {
|
||||||
display: flex;
|
display: flex;
|
||||||
border-top: 1px solid rgba(0, 0, 0, 0.2);
|
border-top: 1px solid rgba(0, 0, 0, 0.2);
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import * as fs from 'mz/fs'
|
import * as fs from 'mz/fs'
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
const nodeModule = require('module')
|
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 (path: string): string {
|
||||||
@@ -12,7 +12,7 @@ function normalizePath (path: string): string {
|
|||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeRequire.main.paths.map(x => nodeModule.globalPaths.push(normalizePath(x)))
|
global['module'].paths.map((x: string) => nodeModule.globalPaths.push(normalizePath(x)))
|
||||||
|
|
||||||
if (process.env.TERMINUS_DEV) {
|
if (process.env.TERMINUS_DEV) {
|
||||||
nodeModule.globalPaths.unshift(path.dirname(require('electron').remote.app.getAppPath()))
|
nodeModule.globalPaths.unshift(path.dirname(require('electron').remote.app.getAppPath()))
|
||||||
@@ -38,9 +38,9 @@ if (process.env.TERMINUS_PLUGINS) {
|
|||||||
process.env.TERMINUS_PLUGINS.split(':').map(x => nodeModule.globalPaths.push(normalizePath(x)))
|
process.env.TERMINUS_PLUGINS.split(':').map(x => nodeModule.globalPaths.push(normalizePath(x)))
|
||||||
}
|
}
|
||||||
|
|
||||||
export declare type ProgressCallback = (current, total) => void
|
export type ProgressCallback = (current: number, total: number) => void // eslint-disable-line @typescript-eslint/no-type-alias
|
||||||
|
|
||||||
export interface IPluginInfo {
|
export interface PluginInfo {
|
||||||
name: string
|
name: string
|
||||||
description: string
|
description: string
|
||||||
packageName: string
|
packageName: string
|
||||||
@@ -64,6 +64,7 @@ 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',
|
||||||
@@ -72,47 +73,61 @@ const builtinModules = [
|
|||||||
|
|
||||||
const cachedBuiltinModules = {}
|
const cachedBuiltinModules = {}
|
||||||
builtinModules.forEach(m => {
|
builtinModules.forEach(m => {
|
||||||
|
const label = 'Caching ' + m
|
||||||
|
console.time(label)
|
||||||
cachedBuiltinModules[m] = nodeRequire(m)
|
cachedBuiltinModules[m] = nodeRequire(m)
|
||||||
|
console.timeEnd(label)
|
||||||
})
|
})
|
||||||
|
|
||||||
const originalRequire = nodeRequire('module').prototype.require
|
const originalRequire = (global as any).require
|
||||||
nodeRequire('module').prototype.require = function (query) {
|
;(global as any).require = function (query: string) {
|
||||||
if (cachedBuiltinModules[query]) {
|
if (cachedBuiltinModules[query]) {
|
||||||
return cachedBuiltinModules[query]
|
return cachedBuiltinModules[query]
|
||||||
}
|
}
|
||||||
return originalRequire.apply(this, arguments)
|
return originalRequire.apply(this, arguments)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function findPlugins (): Promise<IPluginInfo[]> {
|
const originalModuleRequire = nodeModule.prototype.require
|
||||||
let paths = nodeModule.globalPaths
|
nodeModule.prototype.require = function (query: string) {
|
||||||
let foundPlugins: IPluginInfo[] = []
|
if (cachedBuiltinModules[query]) {
|
||||||
let candidateLocations: { pluginDir: string, packageName: string }[] = []
|
return cachedBuiltinModules[query]
|
||||||
|
}
|
||||||
|
return originalModuleRequire.call(this, query)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function findPlugins (): Promise<PluginInfo[]> {
|
||||||
|
const paths = nodeModule.globalPaths
|
||||||
|
let foundPlugins: PluginInfo[] = []
|
||||||
|
const candidateLocations: { pluginDir: string, packageName: string }[] = []
|
||||||
|
const PREFIX = 'terminus-'
|
||||||
|
|
||||||
for (let pluginDir of paths) {
|
for (let pluginDir of paths) {
|
||||||
pluginDir = normalizePath(pluginDir)
|
pluginDir = normalizePath(pluginDir)
|
||||||
if (!await fs.exists(pluginDir)) {
|
if (!await fs.exists(pluginDir)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
let pluginNames = await fs.readdir(pluginDir)
|
const pluginNames = await fs.readdir(pluginDir)
|
||||||
if (await fs.exists(path.join(pluginDir, 'package.json'))) {
|
if (await fs.exists(path.join(pluginDir, 'package.json'))) {
|
||||||
candidateLocations.push({
|
candidateLocations.push({
|
||||||
pluginDir: path.dirname(pluginDir),
|
pluginDir: path.dirname(pluginDir),
|
||||||
packageName: path.basename(pluginDir)
|
packageName: path.basename(pluginDir),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
for (let packageName of pluginNames) {
|
for (const packageName of pluginNames) {
|
||||||
candidateLocations.push({ pluginDir, packageName })
|
if (packageName.startsWith(PREFIX)) {
|
||||||
|
candidateLocations.push({ pluginDir, packageName })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let { pluginDir, packageName } of candidateLocations) {
|
for (const { pluginDir, packageName } of candidateLocations) {
|
||||||
let pluginPath = path.join(pluginDir, packageName)
|
const pluginPath = path.join(pluginDir, packageName)
|
||||||
let infoPath = path.join(pluginPath, 'package.json')
|
const infoPath = path.join(pluginPath, 'package.json')
|
||||||
if (!await fs.exists(infoPath)) {
|
if (!await fs.exists(infoPath)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
let name = packageName.substring('terminus-'.length)
|
const name = packageName.substring(PREFIX.length)
|
||||||
|
|
||||||
if (foundPlugins.some(x => x.name === name)) {
|
if (foundPlugins.some(x => x.name === name)) {
|
||||||
console.info(`Plugin ${packageName} already exists, overriding`)
|
console.info(`Plugin ${packageName} already exists, overriding`)
|
||||||
@@ -120,7 +135,7 @@ export async function findPlugins (): Promise<IPluginInfo[]> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let info = JSON.parse(await fs.readFile(infoPath, { encoding: 'utf-8' }))
|
const info = JSON.parse(await fs.readFile(infoPath, { encoding: 'utf-8' }))
|
||||||
if (!info.keywords || !(info.keywords.includes('terminus-plugin') || info.keywords.includes('terminus-builtin-plugin'))) {
|
if (!info.keywords || !(info.keywords.includes('terminus-plugin') || info.keywords.includes('terminus-builtin-plugin'))) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -141,23 +156,29 @@ export async function findPlugins (): Promise<IPluginInfo[]> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(window as any).installedPlugins = foundPlugins
|
foundPlugins.sort((a, b) => a.name > b.name ? 1 : -1)
|
||||||
|
|
||||||
|
;(window as any).installedPlugins = foundPlugins
|
||||||
return foundPlugins
|
return foundPlugins
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadPlugins (foundPlugins: IPluginInfo[], progress: ProgressCallback): Promise<any[]> {
|
export async function loadPlugins (foundPlugins: PluginInfo[], progress: ProgressCallback): Promise<any[]> {
|
||||||
let plugins: any[] = []
|
const plugins: any[] = []
|
||||||
progress(0, 1)
|
progress(0, 1)
|
||||||
let index = 0
|
let index = 0
|
||||||
for (let foundPlugin of foundPlugins) {
|
for (const foundPlugin of foundPlugins) {
|
||||||
console.info(`Loading ${foundPlugin.name}: ${nodeRequire.resolve(foundPlugin.path)}`)
|
console.info(`Loading ${foundPlugin.name}: ${nodeRequire.resolve(foundPlugin.path)}`)
|
||||||
progress(index, foundPlugins.length)
|
progress(index, foundPlugins.length)
|
||||||
try {
|
try {
|
||||||
let packageModule = nodeRequire(foundPlugin.path)
|
const label = 'Loading ' + foundPlugin.name
|
||||||
let pluginModule = packageModule.default.forRoot ? packageModule.default.forRoot() : packageModule.default
|
console.time(label)
|
||||||
|
const packageModule = nodeRequire(foundPlugin.path)
|
||||||
|
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)
|
||||||
|
await new Promise(x => setTimeout(x, 50))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Could not load ${foundPlugin.name}:`, error)
|
console.error(`Could not load ${foundPlugin.name}:`, error)
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { Component } from '@angular/core'
|
import { Component } from '@angular/core'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
template: '<app-root></app-root>'
|
template: '<app-root></app-root>',
|
||||||
})
|
})
|
||||||
export class RootComponent { }
|
export class RootComponent { } // eslint-disable-line @typescript-eslint/no-extraneous-class
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
padding: 20px;
|
||||||
|
|
||||||
.toast {
|
.toast {
|
||||||
box-shadow: 0 1px 0 rgba(0,0,0,.25);
|
box-shadow: 0 1px 0 rgba(0,0,0,.25);
|
||||||
|
@@ -14,7 +14,7 @@ module.exports = {
|
|||||||
minimize: false,
|
minimize: false,
|
||||||
},
|
},
|
||||||
context: __dirname,
|
context: __dirname,
|
||||||
devtool: 'eval-source-map',
|
devtool: 'source-map',
|
||||||
output: {
|
output: {
|
||||||
path: path.join(__dirname, 'dist'),
|
path: path.join(__dirname, 'dist'),
|
||||||
pathinfo: true,
|
pathinfo: true,
|
||||||
|
@@ -9,7 +9,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
mode: process.env.TERMINUS_DEV ? 'development' : 'production',
|
mode: process.env.TERMINUS_DEV ? 'development' : 'production',
|
||||||
context: __dirname,
|
context: __dirname,
|
||||||
devtool: 'eval-source-map',
|
devtool: 'source-map',
|
||||||
output: {
|
output: {
|
||||||
path: path.join(__dirname, 'dist'),
|
path: path.join(__dirname, 'dist'),
|
||||||
pathinfo: true,
|
pathinfo: true,
|
||||||
|
3105
app/yarn.lock
3105
app/yarn.lock
File diff suppressed because it is too large
Load Diff
10
appveyor.yml
10
appveyor.yml
@@ -6,10 +6,6 @@ platform:
|
|||||||
environment:
|
environment:
|
||||||
nodejs_version: "10"
|
nodejs_version: "10"
|
||||||
|
|
||||||
cache:
|
|
||||||
- "%USERPROFILE%\\.electron"
|
|
||||||
- "%LOCALAPPDATA%\\Yarn"
|
|
||||||
|
|
||||||
version: "{build}"
|
version: "{build}"
|
||||||
|
|
||||||
install:
|
install:
|
||||||
@@ -24,3 +20,9 @@ build_script:
|
|||||||
|
|
||||||
artifacts:
|
artifacts:
|
||||||
- path: 'dist\*.exe'
|
- path: 'dist\*.exe'
|
||||||
|
|
||||||
|
cache:
|
||||||
|
- node_modules
|
||||||
|
- "*\\node_modules"
|
||||||
|
- "%USERPROFILE%\\.electron"
|
||||||
|
- "%LOCALAPPDATA%\\Yarn"
|
||||||
|
35
build/mac/afterSignHook.js
Normal file
35
build/mac/afterSignHook.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
// See: https://medium.com/@TwitterArchiveEraser/notarize-electron-apps-7a5f988406db
|
||||||
|
|
||||||
|
const fs = require('fs')
|
||||||
|
const path = require('path')
|
||||||
|
const notarizer = require('electron-notarize')
|
||||||
|
|
||||||
|
module.exports = async function (params) {
|
||||||
|
// 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/')) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.log('afterSign hook triggered', params)
|
||||||
|
|
||||||
|
let appId = 'org.terminus'
|
||||||
|
|
||||||
|
let appPath = path.join(params.appOutDir, `${params.packager.appInfo.productFilename}.app`)
|
||||||
|
if (!fs.existsSync(appPath)) {
|
||||||
|
throw new Error(`Cannot find application at: ${appPath}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Notarizing ${appId} found at ${appPath}`)
|
||||||
|
|
||||||
|
try {
|
||||||
|
await notarizer.notarize({
|
||||||
|
appBundleId: appId,
|
||||||
|
appPath: appPath,
|
||||||
|
appleId: process.env.APPSTORE_USERNAME,
|
||||||
|
appleIdPassword: process.env.APPSTORE_PASSWORD,
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Done notarizing ${appId}`)
|
||||||
|
}
|
14
build/mac/entitlements.plist
Normal file
14
build/mac/entitlements.plist
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>com.apple.security.cs.allow-jit</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.cs.disable-library-validation</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
101
package.json
101
package.json
@@ -1,55 +1,54 @@
|
|||||||
{
|
{
|
||||||
"name": "term",
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@fortawesome/fontawesome-free": "^5.8.2",
|
"@fortawesome/fontawesome-free": "^5.11.2",
|
||||||
"@types/electron-config": "^3.2.2",
|
"@types/electron-config": "^3.2.2",
|
||||||
"@types/electron-debug": "^2.1.0",
|
"@types/electron-debug": "^2.1.0",
|
||||||
"@types/fs-promise": "1.0.3",
|
|
||||||
"@types/js-yaml": "^3.12.1",
|
"@types/js-yaml": "^3.12.1",
|
||||||
"@types/node": "^12.0.2",
|
"@types/node": "12.7.12",
|
||||||
"@types/webpack-env": "1.13.9",
|
"@types/webpack-env": "1.14.1",
|
||||||
"app-builder-lib": "^20.42.0",
|
"@typescript-eslint/eslint-plugin": "^2.8.0",
|
||||||
|
"@typescript-eslint/parser": "^2.8.0",
|
||||||
"apply-loader": "2.0.0",
|
"apply-loader": "2.0.0",
|
||||||
"awesome-typescript-loader": "^5.0.0",
|
"awesome-typescript-loader": "^5.0.0",
|
||||||
"core-js": "^3.1.2",
|
"core-js": "^3.4.2",
|
||||||
"cross-env": "5.2.0",
|
"cross-env": "6.0.3",
|
||||||
"css-loader": "2.1.1",
|
"css-loader": "3.2.0",
|
||||||
"electron": "^5.0.2",
|
"electron": "^7.1.2",
|
||||||
"electron-builder": "^20.41.0",
|
"electron-builder": "22.1.0",
|
||||||
"electron-installer-snap": "^3.2.0",
|
"electron-installer-snap": "^4.1.0",
|
||||||
|
"electron-notarize": "^0.1.1",
|
||||||
"electron-rebuild": "^1.8.5",
|
"electron-rebuild": "^1.8.5",
|
||||||
"file-loader": "^3.0.1",
|
"eslint": "^6.7.1",
|
||||||
"graceful-fs": "^4.1.15",
|
"file-loader": "^4.3.0",
|
||||||
|
"graceful-fs": "^4.2.2",
|
||||||
"html-loader": "0.5.5",
|
"html-loader": "0.5.5",
|
||||||
"json-loader": "0.5.7",
|
"json-loader": "0.5.7",
|
||||||
"node-abi": "^2.8.0",
|
"node-abi": "^2.12.0",
|
||||||
"node-gyp": "^4.0.0",
|
"node-gyp": "^6.0.1",
|
||||||
"node-sass": "^4.12.0",
|
"node-sass": "^4.13.0",
|
||||||
"npmlog": "4.1.2",
|
"npmlog": "4.1.2",
|
||||||
"npx": "^10.2.0",
|
"npx": "^10.2.0",
|
||||||
"pug": "^2.0.3",
|
"pug": "^2.0.4",
|
||||||
"pug-html-loader": "1.1.5",
|
"pug-html-loader": "1.1.5",
|
||||||
"pug-lint": "^2.5.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",
|
||||||
"raven-js": "3.27.1",
|
"raven-js": "3.27.2",
|
||||||
"raw-loader": "2.0.0",
|
"raw-loader": "3.1.0",
|
||||||
"sass-loader": "^7.0.1",
|
"sass-loader": "^8.0.0",
|
||||||
"shelljs": "0.8.3",
|
"shelljs": "0.8.3",
|
||||||
"source-code-pro": "^2.30.1",
|
"source-code-pro": "^2.30.2",
|
||||||
"source-sans-pro": "2.45.0",
|
"source-sans-pro": "3.6.0",
|
||||||
"style-loader": "^0.23.1",
|
"style-loader": "^1.0.0",
|
||||||
"svg-inline-loader": "^0.8.0",
|
"svg-inline-loader": "^0.8.0",
|
||||||
"to-string-loader": "1.1.5",
|
"to-string-loader": "1.1.6",
|
||||||
"tslint": "^5.16.0",
|
"tslib": "^1.10.0",
|
||||||
"tslint-config-standard": "^8.0.1",
|
"typedoc": "^0.15.3",
|
||||||
"tslint-eslint-rules": "^5.4.0",
|
"typescript": "^3.6.4",
|
||||||
"typedoc": "^0.14.2",
|
"url-loader": "^2.3.0",
|
||||||
"typescript": "^3.4.5",
|
"val-loader": "2.0.1",
|
||||||
"url-loader": "^1.1.1",
|
"webpack": "^5.0.0-beta.7",
|
||||||
"val-loader": "1.1.1",
|
"webpack-cli": "^3.3.10",
|
||||||
"webpack": "^4.32.2",
|
|
||||||
"webpack-cli": "^3.3.2",
|
|
||||||
"yaml-loader": "0.5.0"
|
"yaml-loader": "0.5.0"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
@@ -59,6 +58,7 @@
|
|||||||
"appId": "org.terminus",
|
"appId": "org.terminus",
|
||||||
"productName": "Terminus",
|
"productName": "Terminus",
|
||||||
"compression": "normal",
|
"compression": "normal",
|
||||||
|
"afterSign": "./build/mac/afterSignHook.js",
|
||||||
"files": [
|
"files": [
|
||||||
"**/*",
|
"**/*",
|
||||||
"dist"
|
"dist"
|
||||||
@@ -69,7 +69,8 @@
|
|||||||
],
|
],
|
||||||
"win": {
|
"win": {
|
||||||
"icon": "./build/windows/icon.ico",
|
"icon": "./build/windows/icon.ico",
|
||||||
"artifactName": "terminus-${version}-setup.exe"
|
"artifactName": "terminus-${version}-setup.exe",
|
||||||
|
"rfc3161TimeStampServer": "http://sha256timestamp.ws.symantec.com/sha256/timestamp"
|
||||||
},
|
},
|
||||||
"nsis": {
|
"nsis": {
|
||||||
"oneClick": false,
|
"oneClick": false,
|
||||||
@@ -77,10 +78,6 @@
|
|||||||
"installerIcon": "./build/windows/icon.ico"
|
"installerIcon": "./build/windows/icon.ico"
|
||||||
},
|
},
|
||||||
"publish": [
|
"publish": [
|
||||||
{
|
|
||||||
"provider": "bintray",
|
|
||||||
"token": "d993c4faa708a4cba84fa3a8e822457e7298d75c"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"provider": "github"
|
"provider": "github"
|
||||||
}
|
}
|
||||||
@@ -92,12 +89,15 @@
|
|||||||
"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.${ext}",
|
||||||
|
"hardenedRuntime": true,
|
||||||
|
"entitlements": "./build/mac/entitlements.plist",
|
||||||
|
"entitlementsInherit": "./build/mac/entitlements.plist",
|
||||||
"extendInfo": {
|
"extendInfo": {
|
||||||
"NSRequiresAquaSystemAppearance": false
|
"NSRequiresAquaSystemAppearance": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dmg": {
|
"pkg": {
|
||||||
"artifactName": "terminus-${version}-macos.dmg"
|
"artifactName": "terminus-${version}-macos.pkg"
|
||||||
},
|
},
|
||||||
"linux": {
|
"linux": {
|
||||||
"category": "Utilities",
|
"category": "Utilities",
|
||||||
@@ -106,14 +106,13 @@
|
|||||||
},
|
},
|
||||||
"deb": {
|
"deb": {
|
||||||
"depends": [
|
"depends": [
|
||||||
"screen",
|
|
||||||
"gconf2",
|
"gconf2",
|
||||||
"gconf-service",
|
"gconf-service",
|
||||||
"libnotify4",
|
"libnotify4",
|
||||||
|
"libsecret-1-0",
|
||||||
"libappindicator1",
|
"libappindicator1",
|
||||||
"libxtst6",
|
"libxtst6",
|
||||||
"libnss3",
|
"libnss3"
|
||||||
"tmux"
|
|
||||||
],
|
],
|
||||||
"afterInstall": "build/linux/after-install.tpl"
|
"afterInstall": "build/linux/after-install.tpl"
|
||||||
},
|
},
|
||||||
@@ -125,13 +124,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "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-settings/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",
|
"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",
|
||||||
|
"build:typings": "tsc --project terminus-core/tsconfig.typings.json && tsc --project terminus-settings/tsconfig.typings.json && tsc --project terminus-terminal/tsconfig.typings.json && tsc --project terminus-plugin-manager/tsconfig.typings.json && tsc --project terminus-ssh/tsconfig.typings.json",
|
||||||
"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",
|
||||||
"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 terminus-terminal/src && typedoc --out docs/api/settings 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": "tslint -c tslint.json -t stylish terminus-*/src/**/*.ts terminus-*/src/*.ts app/src/*.ts",
|
"lint": "eslint --ext ts */src",
|
||||||
"postinstall": "node ./scripts/install-deps.js"
|
"postinstall": "node ./scripts/install-deps.js"
|
||||||
},
|
},
|
||||||
"repository": "eugeny/terminus"
|
"repository": "eugeny/terminus",
|
||||||
|
"dependencies": {
|
||||||
|
"eslint-plugin-import": "^2.18.2"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,13 +2,16 @@
|
|||||||
const builder = require('electron-builder').build
|
const builder = require('electron-builder').build
|
||||||
const vars = require('./vars')
|
const vars = require('./vars')
|
||||||
|
|
||||||
|
const isTag = (process.env.GITHUB_REF || '').startsWith('refs/tags/')
|
||||||
|
const isCI = !!process.env.GITHUB_REF
|
||||||
|
|
||||||
builder({
|
builder({
|
||||||
dir: true,
|
dir: true,
|
||||||
linux: ['snap', 'deb', 'rpm', 'tar.gz'],
|
linux: ['deb', 'tar.gz', 'rpm'],
|
||||||
config: {
|
config: {
|
||||||
extraMetadata: {
|
extraMetadata: {
|
||||||
version: vars.version,
|
version: vars.version,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
publish: isTag ? 'always' : 'onTag',
|
||||||
publish: 'onTag',
|
}).catch(() => process.exit(1))
|
||||||
})
|
|
||||||
|
@@ -2,13 +2,16 @@
|
|||||||
const builder = require('electron-builder').build
|
const builder = require('electron-builder').build
|
||||||
const vars = require('./vars')
|
const vars = require('./vars')
|
||||||
|
|
||||||
|
const isTag = (process.env.GITHUB_REF || '').startsWith('refs/tags/')
|
||||||
|
const isCI = !!process.env.GITHUB_REF
|
||||||
|
|
||||||
builder({
|
builder({
|
||||||
dir: true,
|
dir: true,
|
||||||
mac: ['dmg', 'zip'],
|
mac: ['pkg', 'zip'],
|
||||||
config: {
|
config: {
|
||||||
extraMetadata: {
|
extraMetadata: {
|
||||||
version: vars.version,
|
version: vars.version,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
publish: isTag ? 'always' : 'onTag',
|
||||||
publish: 'onTag',
|
}).catch(() => process.exit(1))
|
||||||
})
|
|
||||||
|
@@ -3,19 +3,24 @@ const rebuild = require('electron-rebuild').default
|
|||||||
const path = require('path')
|
const path = require('path')
|
||||||
const vars = require('./vars')
|
const vars = require('./vars')
|
||||||
|
|
||||||
lifecycles = []
|
let lifecycles = []
|
||||||
for (let dir of ['app', 'terminus-core', 'terminus-ssh', 'terminus-terminal']) {
|
for (let dir of ['app', 'terminus-core', 'terminus-ssh', 'terminus-terminal']) {
|
||||||
lifecycles.push([rebuild({
|
const build = rebuild({
|
||||||
buildPath: path.resolve(__dirname, '../' + dir),
|
buildPath: path.resolve(__dirname, '../' + dir),
|
||||||
electronVersion: vars.electronVersion,
|
electronVersion: vars.electronVersion,
|
||||||
force: true,
|
force: true,
|
||||||
}).lifecycle, dir])
|
})
|
||||||
|
build.catch(e => {
|
||||||
|
console.error(e)
|
||||||
|
process.exit(1)
|
||||||
|
})
|
||||||
|
lifecycles.push([build.lifecycle, dir])
|
||||||
}
|
}
|
||||||
|
|
||||||
console.info('Building against Electron', vars.electronVersion)
|
console.info('Building against Electron', vars.electronVersion)
|
||||||
|
|
||||||
for (let [lc, dir] of lifecycles) {
|
for (let [lc, dir] of lifecycles) {
|
||||||
lc.on('module-found', name => {
|
lc.on('module-found', name => {
|
||||||
console.info('Rebuilding', dir + '/' + name)
|
console.info('Rebuilding', dir + '/' + name)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@@ -2,13 +2,16 @@
|
|||||||
const builder = require('electron-builder').build
|
const builder = require('electron-builder').build
|
||||||
const vars = require('./vars')
|
const vars = require('./vars')
|
||||||
|
|
||||||
|
const isTag = (process.env.GITHUB_REF || process.env.BUILD_SOURCEBRANCH || '').startsWith('refs/tags/')
|
||||||
|
const isCI = !!process.env.GITHUB_REF
|
||||||
|
|
||||||
builder({
|
builder({
|
||||||
dir: true,
|
dir: true,
|
||||||
win: ['nsis', 'portable'],
|
win: ['nsis', 'portable'],
|
||||||
config: {
|
config: {
|
||||||
extraMetadata: {
|
extraMetadata: {
|
||||||
version: vars.version,
|
version: vars.version,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
publish: isTag ? 'always' : 'onTag',
|
||||||
publish: 'onTag',
|
}).catch(() => process.exit(1))
|
||||||
})
|
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
const path = require('path')
|
const path = require('path')
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
|
const semver = require('semver')
|
||||||
const childProcess = require('child_process')
|
const childProcess = require('child_process')
|
||||||
|
|
||||||
const appInfo = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../app/package.json')))
|
const appInfo = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../app/package.json')))
|
||||||
@@ -9,6 +10,10 @@ exports.version = childProcess.execSync('git describe --tags', {encoding:'utf-8'
|
|||||||
exports.version = exports.version.substring(1).trim()
|
exports.version = exports.version.substring(1).trim()
|
||||||
exports.version = exports.version.replace('-', '-c')
|
exports.version = exports.version.replace('-', '-c')
|
||||||
|
|
||||||
|
if (exports.version.includes('-c')) {
|
||||||
|
exports.version = semver.inc(exports.version, 'prepatch').replace('-0', '-nightly.0')
|
||||||
|
}
|
||||||
|
|
||||||
exports.builtinPlugins = [
|
exports.builtinPlugins = [
|
||||||
'terminus-core',
|
'terminus-core',
|
||||||
'terminus-settings',
|
'terminus-settings',
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "terminus-community-color-schemes",
|
"name": "terminus-community-color-schemes",
|
||||||
"version": "1.0.73-c4-ga7d62b0",
|
"version": "1.0.93-nightly.0",
|
||||||
"description": "Community color schemes for Terminus",
|
"description": "Community color schemes for Terminus",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"terminus-builtin-plugin"
|
"terminus-builtin-plugin"
|
||||||
],
|
],
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"typings": "dist/index.d.ts",
|
"typings": "typings/index.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "webpack --progress --color",
|
"build": "webpack --progress --color",
|
||||||
"watch": "webpack --progress --color --watch"
|
"watch": "webpack --progress --color --watch"
|
||||||
@@ -17,13 +17,8 @@
|
|||||||
"author": "Eugene Pankov",
|
"author": "Eugene Pankov",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@angular/core": "4.0.1",
|
"@angular/core": "^7",
|
||||||
"terminus-core": "*",
|
"terminus-core": "*",
|
||||||
"terminus-terminal": "*"
|
"terminus-terminal": "*"
|
||||||
},
|
}
|
||||||
"devDependencies": {
|
|
||||||
"@types/node": "12.0.2",
|
|
||||||
"@types/webpack-env": "^1.13.0"
|
|
||||||
},
|
|
||||||
"false": {}
|
|
||||||
}
|
}
|
||||||
|
@@ -1,26 +1,26 @@
|
|||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { TerminalColorSchemeProvider, ITerminalColorScheme } from 'terminus-terminal'
|
import { TerminalColorSchemeProvider, TerminalColorScheme } from 'terminus-terminal'
|
||||||
|
|
||||||
const schemeContents = require.context('../schemes/', true, /.*/)
|
const schemeContents = require.context('../schemes/', true, /.*/)
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ColorSchemes extends TerminalColorSchemeProvider {
|
export class ColorSchemes extends TerminalColorSchemeProvider {
|
||||||
async getSchemes (): Promise<ITerminalColorScheme[]> {
|
async getSchemes (): Promise<TerminalColorScheme[]> {
|
||||||
let schemes: ITerminalColorScheme[] = []
|
const schemes: TerminalColorScheme[] = []
|
||||||
|
|
||||||
schemeContents.keys().forEach(schemeFile => {
|
schemeContents.keys().forEach(schemeFile => {
|
||||||
let lines = (schemeContents(schemeFile) as string).split('\n')
|
const lines = (schemeContents(schemeFile).default as string).split('\n')
|
||||||
|
|
||||||
// process #define variables
|
// process #define variables
|
||||||
let variables: any = {}
|
const variables: any = {}
|
||||||
lines
|
lines
|
||||||
.filter(x => x.startsWith('#define'))
|
.filter(x => x.startsWith('#define'))
|
||||||
.map(x => x.split(' ').map(v => v.trim()))
|
.map(x => x.split(' ').map(v => v.trim()))
|
||||||
.forEach(([ignore, variableName, variableValue]) => {
|
.forEach(([_, variableName, variableValue]) => {
|
||||||
variables[variableName] = variableValue
|
variables[variableName] = variableValue
|
||||||
})
|
})
|
||||||
|
|
||||||
let values: any = {}
|
const values: any = {}
|
||||||
lines
|
lines
|
||||||
.filter(x => x.startsWith('*.'))
|
.filter(x => x.startsWith('*.'))
|
||||||
.map(x => x.substring(2))
|
.map(x => x.substring(2))
|
||||||
@@ -29,7 +29,7 @@ export class ColorSchemes extends TerminalColorSchemeProvider {
|
|||||||
values[key] = variables[value] ? variables[value] : value
|
values[key] = variables[value] ? variables[value] : value
|
||||||
})
|
})
|
||||||
|
|
||||||
let colors: string[] = []
|
const colors: string[] = []
|
||||||
let colorIndex = 0
|
let colorIndex = 0
|
||||||
while (values[`color${colorIndex}`]) {
|
while (values[`color${colorIndex}`]) {
|
||||||
colors.push(values[`color${colorIndex}`])
|
colors.push(values[`color${colorIndex}`])
|
||||||
|
@@ -8,4 +8,4 @@ import { ColorSchemes } from './colorSchemes'
|
|||||||
{ provide: TerminalColorSchemeProvider, useClass: ColorSchemes, multi: true },
|
{ provide: TerminalColorSchemeProvider, useClass: ColorSchemes, multi: true },
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export default class PopularThemesModule { }
|
export default class PopularThemesModule { } // eslint-disable-line @typescript-eslint/no-extraneous-class
|
||||||
|
@@ -2,7 +2,6 @@
|
|||||||
"extends": "../tsconfig.json",
|
"extends": "../tsconfig.json",
|
||||||
"exclude": ["node_modules", "dist"],
|
"exclude": ["node_modules", "dist"],
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"baseUrl": "src",
|
"baseUrl": "src"
|
||||||
"declarationDir": "dist"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,52 +1,51 @@
|
|||||||
const path = require('path')
|
const path = require('path')
|
||||||
const webpack = require('webpack')
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
target: 'node',
|
target: 'node',
|
||||||
entry: 'src/index.ts',
|
entry: 'src/index.ts',
|
||||||
devtool: 'eval-source-map',
|
context: __dirname,
|
||||||
context: __dirname,
|
devtool: 'eval-cheap-module-source-map',
|
||||||
output: {
|
output: {
|
||||||
path: path.resolve(__dirname, 'dist'),
|
path: path.resolve(__dirname, 'dist'),
|
||||||
filename: 'index.js',
|
filename: 'index.js',
|
||||||
pathinfo: true,
|
pathinfo: true,
|
||||||
libraryTarget: 'umd',
|
libraryTarget: 'umd',
|
||||||
devtoolModuleFilenameTemplate: 'webpack-terminus-community-color-schemes:///[resource-path]',
|
devtoolModuleFilenameTemplate: 'webpack-terminus-community-color-schemes:///[resource-path]',
|
||||||
},
|
},
|
||||||
mode: process.env.TERMINUS_DEV ? 'development' : 'production',
|
mode: process.env.TERMINUS_DEV ? 'development' : 'production',
|
||||||
optimization:{
|
optimization:{
|
||||||
minimize: false,
|
minimize: false,
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
modules: ['.', 'src', 'node_modules', '../app/node_modules'].map(x => path.join(__dirname, x)),
|
modules: ['.', 'src', 'node_modules', '../app/node_modules'].map(x => path.join(__dirname, x)),
|
||||||
extensions: ['.ts', '.js'],
|
extensions: ['.ts', '.js'],
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
test: /\.ts$/,
|
test: /\.ts$/,
|
||||||
use: {
|
use: {
|
||||||
loader: 'awesome-typescript-loader',
|
loader: 'awesome-typescript-loader',
|
||||||
options: {
|
options: {
|
||||||
configFileName: path.resolve(__dirname, 'tsconfig.json'),
|
configFileName: path.resolve(__dirname, 'tsconfig.json'),
|
||||||
typeRoots: [path.resolve(__dirname, 'node_modules/@types')],
|
typeRoots: [
|
||||||
paths: {
|
path.resolve(__dirname, 'node_modules/@types'),
|
||||||
"terminus-*": [path.resolve(__dirname, '../terminus-*')],
|
path.resolve(__dirname, '../node_modules/@types'),
|
||||||
"*": [path.resolve(__dirname, '../app/node_modules/*')],
|
],
|
||||||
}
|
paths: {
|
||||||
}
|
"terminus-*": [path.resolve(__dirname, '../terminus-*')],
|
||||||
}
|
"*": [path.resolve(__dirname, '../app/node_modules/*')],
|
||||||
},
|
},
|
||||||
{ test: /[\\\/]schemes[\\\/]/, use: "raw-loader" },
|
},
|
||||||
]
|
},
|
||||||
},
|
},
|
||||||
externals: [
|
{ test: /[\\\/]schemes[\\\/]/, use: "raw-loader" },
|
||||||
/^rxjs/,
|
],
|
||||||
/^@angular/,
|
},
|
||||||
/^@ng-bootstrap/,
|
externals: [
|
||||||
/^terminus-/,
|
/^rxjs/,
|
||||||
],
|
/^@angular/,
|
||||||
plugins: [
|
/^@ng-bootstrap/,
|
||||||
new webpack.optimize.ModuleConcatenationPlugin(),
|
/^terminus-/,
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
@@ -2,12 +2,3 @@
|
|||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
"@types/node@12.0.2":
|
|
||||||
version "12.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.0.2.tgz#3452a24edf9fea138b48fad4a0a028a683da1e40"
|
|
||||||
integrity sha512-5tabW/i+9mhrfEOUcLDu2xBPsHJ+X5Orqy9FKpale3SjDA17j5AEpYq5vfy3oAeAHGcvANRCO3NV3d2D6q3NiA==
|
|
||||||
|
|
||||||
"@types/webpack-env@^1.13.0":
|
|
||||||
version "1.13.9"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.13.9.tgz#a67287861c928ebf4159a908d1fb1a2a34d4097a"
|
|
||||||
integrity sha512-p8zp5xqkly3g4cCmo2mKOHI9+Z/kObmDj0BmjbDDJQlgDTiEGTbm17MEwTAusV6XceCy+bNw9q/ZHXHyKo3zkg==
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
Terminus Core Plugin
|
Terminus Core Plugin
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
See also: [Settings plugin API](./settings/), [Terminal plugin API](./settings/)
|
See also: [Settings plugin API](./settings/), [Terminal plugin API](./terminal/)
|
||||||
|
|
||||||
* tabbed interface services
|
* tabbed interface services
|
||||||
* toolbar UI
|
* toolbar UI
|
||||||
|
@@ -1,51 +1,45 @@
|
|||||||
{
|
{
|
||||||
"name": "terminus-core",
|
"name": "terminus-core",
|
||||||
"version": "1.0.73-c4-ga7d62b0",
|
"version": "1.0.93-nightly.0",
|
||||||
"description": "Terminus core",
|
"description": "Terminus core",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"terminus-builtin-plugin"
|
"terminus-builtin-plugin"
|
||||||
],
|
],
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"typings": "dist/index.d.ts",
|
"typings": "typings/index.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "webpack --progress --color --display-modules",
|
"build": "webpack --progress --color --display-modules",
|
||||||
"watch": "webpack --progress --color --watch"
|
"watch": "webpack --progress --color --watch"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist"
|
"typings"
|
||||||
],
|
],
|
||||||
"author": "Eugene Pankov",
|
"author": "Eugene Pankov",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/js-yaml": "^3.9.0",
|
"@types/js-yaml": "^3.9.0",
|
||||||
"@types/node": "^12.0.2",
|
"@types/shell-escape": "^0.2.0",
|
||||||
"@types/webpack-env": "^1.13.0",
|
|
||||||
"@types/winston": "^2.3.6",
|
"@types/winston": "^2.3.6",
|
||||||
"axios": "^0.18.0",
|
"axios": "^0.19.0",
|
||||||
"bootstrap": "^4.1.3",
|
"bootstrap": "^4.1.3",
|
||||||
"core-js": "^3.1.2",
|
"core-js": "^3.1.2",
|
||||||
|
"deepmerge": "^4.1.1",
|
||||||
"electron-updater": "^4.0.6",
|
"electron-updater": "^4.0.6",
|
||||||
|
"js-yaml": "^3.9.0",
|
||||||
|
"mixpanel": "^0.10.2",
|
||||||
"ng2-dnd": "^5.0.2",
|
"ng2-dnd": "^5.0.2",
|
||||||
"ngx-perfect-scrollbar": "^6.0.0",
|
"ngx-perfect-scrollbar": "^8.0.0",
|
||||||
"shell-escape": "^0.2.0",
|
"shell-escape": "^0.2.0",
|
||||||
"universal-analytics": "^0.4.17"
|
"uuid": "^3.3.2",
|
||||||
},
|
"winston": "^3.2.1"
|
||||||
"optionalDependencies": {
|
|
||||||
"windows-native-registry": "^1.0.14"
|
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@angular/animations": "4.0.1",
|
"@angular/animations": "^7",
|
||||||
"@angular/common": "4.0.1",
|
"@angular/common": "^7",
|
||||||
"@angular/core": "4.0.1",
|
"@angular/core": "^7",
|
||||||
"@angular/forms": "4.0.1",
|
"@angular/forms": "^7",
|
||||||
"@angular/platform-browser": "4.0.1",
|
"@angular/platform-browser": "^7",
|
||||||
"@angular/platform-browser-dynamic": "4.0.1",
|
"@angular/platform-browser-dynamic": "^7",
|
||||||
"rxjs": "5.3.0",
|
"rxjs": "^5"
|
||||||
"zone.js": "0.8.4"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"deepmerge": "^3.2.0",
|
|
||||||
"js-yaml": "^3.9.0",
|
|
||||||
"winston": "^3.2.1"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
export interface IHotkeyDescription {
|
export interface HotkeyDescription {
|
||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,7 @@ export interface IHotkeyDescription {
|
|||||||
* 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: IHotkeyDescription[] = []
|
hotkeys: HotkeyDescription[] = []
|
||||||
|
|
||||||
abstract provide (): Promise<IHotkeyDescription[]>
|
abstract provide (): Promise<HotkeyDescription[]>
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
export { BaseTabComponent, BaseTabProcess } from '../components/baseTab.component'
|
export { BaseTabComponent, BaseTabProcess } from '../components/baseTab.component'
|
||||||
export { SplitTabComponent, SplitContainer } from '../components/splitTab.component'
|
export { SplitTabComponent, SplitContainer } from '../components/splitTab.component'
|
||||||
export { TabRecoveryProvider, RecoveredTab } from './tabRecovery'
|
export { TabRecoveryProvider, RecoveredTab } from './tabRecovery'
|
||||||
export { ToolbarButtonProvider, IToolbarButton } from './toolbarButtonProvider'
|
export { ToolbarButtonProvider, ToolbarButton } from './toolbarButtonProvider'
|
||||||
export { ConfigProvider } from './configProvider'
|
export { ConfigProvider } from './configProvider'
|
||||||
export { HotkeyProvider, IHotkeyDescription } from './hotkeyProvider'
|
export { HotkeyProvider, HotkeyDescription } from './hotkeyProvider'
|
||||||
export { Theme } from './theme'
|
export { Theme } from './theme'
|
||||||
export { TabContextMenuItemProvider } from './tabContextMenuProvider'
|
export { TabContextMenuItemProvider } from './tabContextMenuProvider'
|
||||||
|
|
||||||
|
@@ -34,5 +34,5 @@ export abstract class TabRecoveryProvider {
|
|||||||
* @returns [[RecoveredTab]] descriptor containing tab type and component inputs
|
* @returns [[RecoveredTab]] descriptor containing tab type and component inputs
|
||||||
* or `null` if this token is from a different tab type or is not supported
|
* or `null` if this token is from a different tab type or is not supported
|
||||||
*/
|
*/
|
||||||
abstract async recover (recoveryToken: any): Promise<RecoveredTab | null>
|
abstract async recover (recoveryToken: any): Promise<RecoveredTab|null>
|
||||||
}
|
}
|
||||||
|
@@ -1,13 +1,11 @@
|
|||||||
import { SafeHtml } from '@angular/platform-browser'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See [[ToolbarButtonProvider]]
|
* See [[ToolbarButtonProvider]]
|
||||||
*/
|
*/
|
||||||
export interface IToolbarButton {
|
export interface ToolbarButton {
|
||||||
/**
|
/**
|
||||||
* Raw SVG icon code
|
* Raw SVG icon code
|
||||||
*/
|
*/
|
||||||
icon: SafeHtml
|
icon?: string
|
||||||
|
|
||||||
title: string
|
title: string
|
||||||
|
|
||||||
@@ -25,15 +23,15 @@ export interface IToolbarButton {
|
|||||||
|
|
||||||
click?: () => void
|
click?: () => void
|
||||||
|
|
||||||
submenu?: () => Promise<IToolbarButton[]>
|
submenu?: () => Promise<ToolbarButton[]>
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
submenuItems?: IToolbarButton[]
|
submenuItems?: ToolbarButton[]
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extend to add buttons to the toolbar
|
* Extend to add buttons to the toolbar
|
||||||
*/
|
*/
|
||||||
export abstract class ToolbarButtonProvider {
|
export abstract class ToolbarButtonProvider {
|
||||||
abstract provide (): IToolbarButton[]
|
abstract provide (): ToolbarButton[]
|
||||||
}
|
}
|
||||||
|
@@ -6,9 +6,7 @@ title-bar(
|
|||||||
.content(
|
.content(
|
||||||
[class.tabs-on-top]='config.store.appearance.tabsLocation == "top"'
|
[class.tabs-on-top]='config.store.appearance.tabsLocation == "top"'
|
||||||
)
|
)
|
||||||
.tab-bar(
|
.tab-bar
|
||||||
*ngIf='!hostApp.isFullScreen',
|
|
||||||
)
|
|
||||||
.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"')
|
||||||
.tabs(
|
.tabs(
|
||||||
dnd-sortable-container,
|
dnd-sortable-container,
|
||||||
@@ -33,53 +31,53 @@ title-bar(
|
|||||||
|
|
||||||
.btn-group.background
|
.btn-group.background
|
||||||
.d-flex(
|
.d-flex(
|
||||||
*ngFor='let button of leftToolbarButtons',
|
*ngFor='let button of leftToolbarButtons',
|
||||||
ngbDropdown,
|
ngbDropdown,
|
||||||
(openChange)='generateButtonSubmenu(button)',
|
(openChange)='generateButtonSubmenu(button)',
|
||||||
)
|
)
|
||||||
button.btn.btn-secondary.btn-tab-bar(
|
button.btn.btn-secondary.btn-tab-bar(
|
||||||
[title]='button.title',
|
[title]='button.title',
|
||||||
(click)='button.click && button.click()',
|
(click)='button.click && button.click()',
|
||||||
[innerHTML]='button.icon',
|
[innerHTML]='sanitizeIcon(button.icon)',
|
||||||
ngbDropdownToggle,
|
ngbDropdownToggle,
|
||||||
)
|
)
|
||||||
div(*ngIf='button.submenu', ngbDropdownMenu)
|
div(*ngIf='button.submenu', ngbDropdownMenu)
|
||||||
button.dropdown-item.d-flex.align-items-center(
|
button.dropdown-item.d-flex.align-items-center(
|
||||||
*ngFor='let item of button.submenuItems',
|
*ngFor='let item of button.submenuItems',
|
||||||
(click)='item.click()',
|
(click)='item.click()',
|
||||||
ngbDropdownItem,
|
ngbDropdownItem,
|
||||||
)
|
)
|
||||||
.icon-wrapper([innerHTML]='item.icon')
|
.icon-wrapper([innerHTML]='sanitizeIcon(item.icon)')
|
||||||
.ml-3 {{item.title}}
|
.ml-3 {{item.title}}
|
||||||
|
|
||||||
.drag-space.background([class.persistent]='config.store.appearance.frame == "thin" && hostApp.platform != Platform.macOS')
|
.drag-space.background([class.persistent]='config.store.appearance.frame == "thin" && hostApp.platform != Platform.macOS')
|
||||||
|
|
||||||
.btn-group.background
|
.btn-group.background
|
||||||
.d-flex(
|
.d-flex(
|
||||||
*ngFor='let button of rightToolbarButtons',
|
*ngFor='let button of rightToolbarButtons',
|
||||||
ngbDropdown,
|
ngbDropdown,
|
||||||
(openChange)='generateButtonSubmenu(button)',
|
(openChange)='generateButtonSubmenu(button)',
|
||||||
)
|
)
|
||||||
button.btn.btn-secondary.btn-tab-bar(
|
button.btn.btn-secondary.btn-tab-bar(
|
||||||
[title]='button.title',
|
[title]='button.title',
|
||||||
(click)='button.click && button.click()',
|
(click)='button.click && button.click()',
|
||||||
[innerHTML]='button.icon',
|
[innerHTML]='sanitizeIcon(button.icon)',
|
||||||
ngbDropdownToggle,
|
ngbDropdownToggle,
|
||||||
)
|
)
|
||||||
div(*ngIf='button.submenu', ngbDropdownMenu)
|
div(*ngIf='button.submenu', ngbDropdownMenu)
|
||||||
button.dropdown-item.d-flex.align-items-center(
|
button.dropdown-item.d-flex.align-items-center(
|
||||||
*ngFor='let item of button.submenuItems',
|
*ngFor='let item of button.submenuItems',
|
||||||
(click)='item.click()',
|
(click)='item.click()',
|
||||||
ngbDropdownItem,
|
ngbDropdownItem,
|
||||||
)
|
)
|
||||||
.icon-wrapper([innerHTML]='item.icon')
|
.icon-wrapper([innerHTML]='sanitizeIcon(item.icon)')
|
||||||
.ml-3 {{item.title}}
|
.ml-3 {{item.title}}
|
||||||
|
|
||||||
button.btn.btn-secondary.btn-tab-bar.btn-update(
|
button.btn.btn-secondary.btn-tab-bar.btn-update(
|
||||||
*ngIf='updatesAvailable',
|
*ngIf='updatesAvailable',
|
||||||
title='Update available',
|
title='Update available - Click to install',
|
||||||
(click)='updateApp()',
|
(click)='updateApp()',
|
||||||
[innerHTML]='updateIcon'
|
[innerHTML]='sanitizeIcon(updateIcon)'
|
||||||
)
|
)
|
||||||
|
|
||||||
window-controls.background(
|
window-controls.background(
|
||||||
|
@@ -18,6 +18,7 @@ $tab-border-radius: 4px;
|
|||||||
|
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
|
height: 100%;
|
||||||
flex: auto;
|
flex: auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column-reverse;
|
flex-direction: column-reverse;
|
||||||
@@ -48,6 +49,10 @@ $tab-border-radius: 4px;
|
|||||||
color: #aaa;
|
color: #aaa;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
|
|
||||||
|
&.dropdown-toggle::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&>.tabs {
|
&>.tabs {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { Component, Inject, Input, HostListener, HostBinding } from '@angular/core'
|
import { Component, Inject, Input, HostListener, HostBinding } from '@angular/core'
|
||||||
import { trigger, style, animate, transition, state } from '@angular/animations'
|
import { trigger, style, animate, transition, state } from '@angular/animations'
|
||||||
import { DomSanitizer, SafeHtml } from '@angular/platform-browser'
|
import { DomSanitizer } from '@angular/platform-browser'
|
||||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
|
|
||||||
import { ElectronService } from '../services/electron.service'
|
import { ElectronService } from '../services/electron.service'
|
||||||
@@ -15,7 +15,7 @@ import { TouchbarService } from '../services/touchbar.service'
|
|||||||
|
|
||||||
import { BaseTabComponent } from './baseTab.component'
|
import { BaseTabComponent } from './baseTab.component'
|
||||||
import { SafeModeModalComponent } from './safeModeModal.component'
|
import { SafeModeModalComponent } from './safeModeModal.component'
|
||||||
import { AppService, IToolbarButton, ToolbarButtonProvider } from '../api'
|
import { AppService, ToolbarButton, ToolbarButtonProvider } from '../api'
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@Component({
|
@Component({
|
||||||
@@ -26,47 +26,47 @@ import { AppService, IToolbarButton, ToolbarButtonProvider } from '../api'
|
|||||||
trigger('animateTab', [
|
trigger('animateTab', [
|
||||||
state('in', style({
|
state('in', style({
|
||||||
'flex-basis': '200px',
|
'flex-basis': '200px',
|
||||||
'width': '200px',
|
width: '200px',
|
||||||
})),
|
})),
|
||||||
transition(':enter', [
|
transition(':enter', [
|
||||||
style({
|
style({
|
||||||
'flex-basis': '1px',
|
'flex-basis': '1px',
|
||||||
'width': '1px',
|
width: '1px',
|
||||||
}),
|
}),
|
||||||
animate('250ms ease-in-out', style({
|
animate('250ms ease-in-out', style({
|
||||||
'flex-basis': '200px',
|
'flex-basis': '200px',
|
||||||
'width': '200px',
|
width: '200px',
|
||||||
}))
|
})),
|
||||||
]),
|
]),
|
||||||
transition(':leave', [
|
transition(':leave', [
|
||||||
style({
|
style({
|
||||||
'flex-basis': '200px',
|
'flex-basis': '200px',
|
||||||
'width': '200px',
|
width: '200px',
|
||||||
}),
|
}),
|
||||||
animate('250ms ease-in-out', style({
|
animate('250ms ease-in-out', style({
|
||||||
'flex-basis': '1px',
|
'flex-basis': '1px',
|
||||||
'width': '1px',
|
width: '1px',
|
||||||
}))
|
})),
|
||||||
])
|
]),
|
||||||
])
|
]),
|
||||||
]
|
],
|
||||||
})
|
})
|
||||||
export class AppRootComponent {
|
export class AppRootComponent {
|
||||||
Platform = Platform
|
Platform = Platform
|
||||||
@Input() ready = false
|
@Input() ready = false
|
||||||
@Input() leftToolbarButtons: IToolbarButton[]
|
@Input() leftToolbarButtons: ToolbarButton[]
|
||||||
@Input() rightToolbarButtons: IToolbarButton[]
|
@Input() rightToolbarButtons: ToolbarButton[]
|
||||||
@HostBinding('class.platform-win32') platformClassWindows = process.platform === 'win32'
|
@HostBinding('class.platform-win32') platformClassWindows = process.platform === 'win32'
|
||||||
@HostBinding('class.platform-darwin') platformClassMacOS = process.platform === 'darwin'
|
@HostBinding('class.platform-darwin') platformClassMacOS = process.platform === 'darwin'
|
||||||
@HostBinding('class.platform-linux') platformClassLinux = process.platform === 'linux'
|
@HostBinding('class.platform-linux') platformClassLinux = process.platform === 'linux'
|
||||||
@HostBinding('class.no-tabs') noTabs = true
|
@HostBinding('class.no-tabs') noTabs = true
|
||||||
tabsDragging = false
|
tabsDragging = false
|
||||||
unsortedTabs: BaseTabComponent[] = []
|
unsortedTabs: BaseTabComponent[] = []
|
||||||
updateIcon: SafeHtml
|
updateIcon: string
|
||||||
updatesAvailable = false
|
updatesAvailable = false
|
||||||
private logger: Logger
|
private logger: Logger
|
||||||
|
|
||||||
constructor (
|
private constructor (
|
||||||
private docking: DockingService,
|
private docking: DockingService,
|
||||||
private electron: ElectronService,
|
private electron: ElectronService,
|
||||||
private hotkeys: HotkeysService,
|
private hotkeys: HotkeysService,
|
||||||
@@ -75,10 +75,10 @@ export class AppRootComponent {
|
|||||||
public hostApp: HostAppService,
|
public hostApp: HostAppService,
|
||||||
public config: ConfigService,
|
public config: ConfigService,
|
||||||
public app: AppService,
|
public app: AppService,
|
||||||
|
private domSanitizer: DomSanitizer,
|
||||||
@Inject(ToolbarButtonProvider) private toolbarButtonProviders: ToolbarButtonProvider[],
|
@Inject(ToolbarButtonProvider) private toolbarButtonProviders: ToolbarButtonProvider[],
|
||||||
log: LogService,
|
log: LogService,
|
||||||
ngbModal: NgbModal,
|
ngbModal: NgbModal,
|
||||||
domSanitizer: DomSanitizer,
|
|
||||||
_themes: ThemesService,
|
_themes: ThemesService,
|
||||||
) {
|
) {
|
||||||
this.logger = log.create('main')
|
this.logger = log.create('main')
|
||||||
@@ -87,11 +87,11 @@ export class AppRootComponent {
|
|||||||
this.leftToolbarButtons = this.getToolbarButtons(false)
|
this.leftToolbarButtons = this.getToolbarButtons(false)
|
||||||
this.rightToolbarButtons = this.getToolbarButtons(true)
|
this.rightToolbarButtons = this.getToolbarButtons(true)
|
||||||
|
|
||||||
this.updateIcon = domSanitizer.bypassSecurityTrustHtml(require('../icons/gift.svg')),
|
this.updateIcon = require('../icons/gift.svg')
|
||||||
|
|
||||||
this.hotkeys.matchedHotkey.subscribe((hotkey) => {
|
this.hotkeys.matchedHotkey.subscribe((hotkey: string) => {
|
||||||
if (hotkey.startsWith('tab-')) {
|
if (hotkey.startsWith('tab-')) {
|
||||||
let index = parseInt(hotkey.split('-')[1])
|
const index = parseInt(hotkey.split('-')[1])
|
||||||
if (index <= this.app.tabs.length) {
|
if (index <= this.app.tabs.length) {
|
||||||
this.app.selectTab(this.app.tabs[index - 1])
|
this.app.selectTab(this.app.tabs[index - 1])
|
||||||
}
|
}
|
||||||
@@ -128,8 +128,9 @@ export class AppRootComponent {
|
|||||||
})
|
})
|
||||||
|
|
||||||
this.hostApp.windowCloseRequest$.subscribe(async () => {
|
this.hostApp.windowCloseRequest$.subscribe(async () => {
|
||||||
await this.app.closeAllTabs()
|
if (await this.app.closeAllTabs()) {
|
||||||
this.hostApp.closeWindow()
|
this.hostApp.closeWindow()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if (window['safeModeReason']) {
|
if (window['safeModeReason']) {
|
||||||
@@ -145,7 +146,7 @@ export class AppRootComponent {
|
|||||||
config.changed$.subscribe(() => this.updateVibrancy())
|
config.changed$.subscribe(() => this.updateVibrancy())
|
||||||
this.updateVibrancy()
|
this.updateVibrancy()
|
||||||
|
|
||||||
let lastProgress = null
|
let lastProgress: number|null = null
|
||||||
this.app.tabOpened$.subscribe(tab => {
|
this.app.tabOpened$.subscribe(tab => {
|
||||||
this.unsortedTabs.push(tab)
|
this.unsortedTabs.push(tab)
|
||||||
tab.progress$.subscribe(progress => {
|
tab.progress$.subscribe(progress => {
|
||||||
@@ -218,8 +219,18 @@ export class AppRootComponent {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
updateApp () {
|
async updateApp () {
|
||||||
this.updater.update()
|
if ((await this.electron.showMessageBox(
|
||||||
|
this.hostApp.getWindow(),
|
||||||
|
{
|
||||||
|
type: 'warning',
|
||||||
|
message: 'Installing the update will close all tabs and restart Terminus.',
|
||||||
|
buttons: ['Cancel', 'Update'],
|
||||||
|
defaultId: 1,
|
||||||
|
}
|
||||||
|
)).response === 1) {
|
||||||
|
this.updater.update()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onTabDragStart () {
|
onTabDragStart () {
|
||||||
@@ -233,20 +244,24 @@ export class AppRootComponent {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async generateButtonSubmenu (button: IToolbarButton) {
|
async generateButtonSubmenu (button: ToolbarButton) {
|
||||||
if (button.submenu) {
|
if (button.submenu) {
|
||||||
button.submenuItems = await button.submenu()
|
button.submenuItems = await button.submenu()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private getToolbarButtons (aboveZero: boolean): IToolbarButton[] {
|
sanitizeIcon (icon: string): any {
|
||||||
let buttons: IToolbarButton[] = []
|
return this.domSanitizer.bypassSecurityTrustHtml(icon || '')
|
||||||
|
}
|
||||||
|
|
||||||
|
private getToolbarButtons (aboveZero: boolean): ToolbarButton[] {
|
||||||
|
let buttons: ToolbarButton[] = []
|
||||||
this.config.enabledServices(this.toolbarButtonProviders).forEach(provider => {
|
this.config.enabledServices(this.toolbarButtonProviders).forEach(provider => {
|
||||||
buttons = buttons.concat(provider.provide())
|
buttons = buttons.concat(provider.provide())
|
||||||
})
|
})
|
||||||
return buttons
|
return buttons
|
||||||
.filter((button) => (button.weight > 0) === aboveZero)
|
.filter(button => (button.weight || 0) > 0 === aboveZero)
|
||||||
.sort((a: IToolbarButton, b: IToolbarButton) => (a.weight || 0) - (b.weight || 0))
|
.sort((a: ToolbarButton, b: ToolbarButton) => (a.weight || 0) - (b.weight || 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateVibrancy () {
|
private updateVibrancy () {
|
||||||
|
@@ -36,7 +36,7 @@ export abstract class BaseTabComponent {
|
|||||||
/**
|
/**
|
||||||
* CSS color override for the tab's header
|
* CSS color override for the tab's header
|
||||||
*/
|
*/
|
||||||
color: string = null
|
color: string|null = null
|
||||||
|
|
||||||
protected hasFocus = false
|
protected hasFocus = false
|
||||||
|
|
||||||
@@ -50,14 +50,14 @@ export abstract class BaseTabComponent {
|
|||||||
private titleChange = new Subject<string>()
|
private titleChange = new Subject<string>()
|
||||||
private focused = new Subject<void>()
|
private focused = new Subject<void>()
|
||||||
private blurred = new Subject<void>()
|
private blurred = new Subject<void>()
|
||||||
private progress = new Subject<number>()
|
private progress = new Subject<number|null>()
|
||||||
private activity = new Subject<boolean>()
|
private activity = new Subject<boolean>()
|
||||||
private destroyed = new Subject<void>()
|
private destroyed = new Subject<void>()
|
||||||
|
|
||||||
get focused$ (): Observable<void> { return this.focused }
|
get focused$ (): Observable<void> { return this.focused }
|
||||||
get blurred$ (): Observable<void> { return this.blurred }
|
get blurred$ (): Observable<void> { return this.blurred }
|
||||||
get titleChange$ (): Observable<string> { return this.titleChange }
|
get titleChange$ (): Observable<string> { return this.titleChange }
|
||||||
get progress$ (): Observable<number> { return this.progress }
|
get progress$ (): Observable<number|null> { return this.progress }
|
||||||
get activity$ (): Observable<boolean> { return this.activity }
|
get activity$ (): Observable<boolean> { return this.activity }
|
||||||
get destroyed$ (): Observable<void> { return this.destroyed }
|
get destroyed$ (): Observable<void> { return this.destroyed }
|
||||||
get recoveryStateChangedHint$ (): Observable<void> { return this.recoveryStateChangedHint }
|
get recoveryStateChangedHint$ (): Observable<void> { return this.recoveryStateChangedHint }
|
||||||
@@ -83,7 +83,7 @@ export abstract class BaseTabComponent {
|
|||||||
*
|
*
|
||||||
* @param {type} progress: value between 0 and 1, or `null` to remove
|
* @param {type} progress: value between 0 and 1, or `null` to remove
|
||||||
*/
|
*/
|
||||||
setProgress (progress: number) {
|
setProgress (progress: number|null) {
|
||||||
this.progress.next(progress)
|
this.progress.next(progress)
|
||||||
if (progress) {
|
if (progress) {
|
||||||
if (this.progressClearTimeout) {
|
if (this.progressClearTimeout) {
|
||||||
@@ -91,7 +91,7 @@ export abstract class BaseTabComponent {
|
|||||||
}
|
}
|
||||||
this.progressClearTimeout = setTimeout(() => {
|
this.progressClearTimeout = setTimeout(() => {
|
||||||
this.setProgress(null)
|
this.setProgress(null)
|
||||||
}, 5000)
|
}, 5000) as any
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +125,7 @@ export abstract class BaseTabComponent {
|
|||||||
/**
|
/**
|
||||||
* Override this to enable task completion notifications for the tab
|
* Override this to enable task completion notifications for the tab
|
||||||
*/
|
*/
|
||||||
async getCurrentProcess (): Promise<BaseTabProcess> {
|
async getCurrentProcess (): Promise<BaseTabProcess|null> {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,13 +147,15 @@ export abstract class BaseTabComponent {
|
|||||||
/**
|
/**
|
||||||
* Called before the tab is closed
|
* Called before the tab is closed
|
||||||
*/
|
*/
|
||||||
destroy (): void {
|
destroy (skipDestroyedEvent = false): void {
|
||||||
this.focused.complete()
|
this.focused.complete()
|
||||||
this.blurred.complete()
|
this.blurred.complete()
|
||||||
this.titleChange.complete()
|
this.titleChange.complete()
|
||||||
this.progress.complete()
|
this.progress.complete()
|
||||||
this.recoveryStateChangedHint.complete()
|
this.recoveryStateChangedHint.complete()
|
||||||
this.destroyed.next()
|
if (!skipDestroyedEvent) {
|
||||||
|
this.destroyed.next()
|
||||||
|
}
|
||||||
this.destroyed.complete()
|
this.destroyed.complete()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,7 +8,7 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'
|
|||||||
styles: [require('./checkbox.component.scss')],
|
styles: [require('./checkbox.component.scss')],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: NG_VALUE_ACCESSOR, useExisting: CheckboxComponent, multi: true },
|
{ provide: NG_VALUE_ACCESSOR, useExisting: CheckboxComponent, multi: true },
|
||||||
]
|
],
|
||||||
})
|
})
|
||||||
export class CheckboxComponent implements ControlValueAccessor {
|
export class CheckboxComponent implements ControlValueAccessor {
|
||||||
@HostBinding('class.active') @Input() model: boolean
|
@HostBinding('class.active') @Input() model: boolean
|
||||||
@@ -23,7 +23,7 @@ export class CheckboxComponent implements ControlValueAccessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.model = !this.model
|
this.model = !this.model
|
||||||
for (let fx of this.changed) {
|
for (const fx of this.changed) {
|
||||||
fx(this.model)
|
fx(this.model)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,8 +6,8 @@ import { TabsService } from '../services/tabs.service'
|
|||||||
import { HotkeysService } from '../services/hotkeys.service'
|
import { HotkeysService } from '../services/hotkeys.service'
|
||||||
import { TabRecoveryService } from '../services/tabRecovery.service'
|
import { TabRecoveryService } from '../services/tabRecovery.service'
|
||||||
|
|
||||||
export declare type SplitOrientation = 'v' | 'h'
|
export type SplitOrientation = 'v' | 'h' // eslint-disable-line @typescript-eslint/no-type-alias
|
||||||
export declare type SplitDirection = 'r' | 't' | 'b' | 'l'
|
export type SplitDirection = 'r' | 't' | 'b' | 'l' // eslint-disable-line @typescript-eslint/no-type-alias
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes a horizontal or vertical split row or column
|
* Describes a horizontal or vertical split row or column
|
||||||
@@ -33,9 +33,9 @@ export class SplitContainer {
|
|||||||
/**
|
/**
|
||||||
* @return Flat list of all tabs inside this container
|
* @return Flat list of all tabs inside this container
|
||||||
*/
|
*/
|
||||||
getAllTabs () {
|
getAllTabs (): BaseTabComponent[] {
|
||||||
let r = []
|
let r: BaseTabComponent[] = []
|
||||||
for (let child of this.children) {
|
for (const child of this.children) {
|
||||||
if (child instanceof SplitContainer) {
|
if (child instanceof SplitContainer) {
|
||||||
r = r.concat(child.getAllTabs())
|
r = r.concat(child.getAllTabs())
|
||||||
} else {
|
} else {
|
||||||
@@ -50,7 +50,7 @@ export class SplitContainer {
|
|||||||
*/
|
*/
|
||||||
normalize () {
|
normalize () {
|
||||||
for (let i = 0; i < this.children.length; i++) {
|
for (let i = 0; i < this.children.length; i++) {
|
||||||
let child = this.children[i]
|
const child = this.children[i]
|
||||||
|
|
||||||
if (child instanceof SplitContainer) {
|
if (child instanceof SplitContainer) {
|
||||||
child.normalize()
|
child.normalize()
|
||||||
@@ -63,7 +63,7 @@ export class SplitContainer {
|
|||||||
} else if (child.children.length === 1) {
|
} else if (child.children.length === 1) {
|
||||||
this.children[i] = child.children[0]
|
this.children[i] = child.children[0]
|
||||||
} else if (child.orientation === this.orientation) {
|
} else if (child.orientation === this.orientation) {
|
||||||
let ratio = this.ratios[i]
|
const ratio = this.ratios[i]
|
||||||
this.children.splice(i, 1)
|
this.children.splice(i, 1)
|
||||||
this.ratios.splice(i, 1)
|
this.ratios.splice(i, 1)
|
||||||
for (let j = 0; j < child.children.length; j++) {
|
for (let j = 0; j < child.children.length; j++) {
|
||||||
@@ -76,7 +76,7 @@ export class SplitContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let s = 0
|
let s = 0
|
||||||
for (let x of this.ratios) {
|
for (const x of this.ratios) {
|
||||||
s += x
|
s += x
|
||||||
}
|
}
|
||||||
this.ratios = this.ratios.map(x => x / s)
|
this.ratios = this.ratios.map(x => x / s)
|
||||||
@@ -94,8 +94,8 @@ export class SplitContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async serialize () {
|
async serialize () {
|
||||||
let children = []
|
const children: any[] = []
|
||||||
for (let child of this.children) {
|
for (const child of this.children) {
|
||||||
if (child instanceof SplitContainer) {
|
if (child instanceof SplitContainer) {
|
||||||
children.push(await child.serialize())
|
children.push(await child.serialize())
|
||||||
} else {
|
} else {
|
||||||
@@ -189,7 +189,11 @@ export class SplitTabComponent extends BaseTabComponent implements OnInit, OnDes
|
|||||||
|
|
||||||
this.focused$.subscribe(() => {
|
this.focused$.subscribe(() => {
|
||||||
this.getAllTabs().forEach(x => x.emitFocused())
|
this.getAllTabs().forEach(x => x.emitFocused())
|
||||||
this.focus(this.focusedTab)
|
if (this.focusedTab) {
|
||||||
|
this.focus(this.focusedTab)
|
||||||
|
} else {
|
||||||
|
this.focusAnyIn(this.root)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
this.blurred$.subscribe(() => this.getAllTabs().forEach(x => x.emitBlurred()))
|
this.blurred$.subscribe(() => this.getAllTabs().forEach(x => x.emitBlurred()))
|
||||||
|
|
||||||
@@ -198,33 +202,33 @@ export class SplitTabComponent extends BaseTabComponent implements OnInit, OnDes
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
switch (hotkey) {
|
switch (hotkey) {
|
||||||
case 'split-right':
|
case 'split-right':
|
||||||
this.splitTab(this.focusedTab, 'r')
|
this.splitTab(this.focusedTab, 'r')
|
||||||
break
|
break
|
||||||
case 'split-bottom':
|
case 'split-bottom':
|
||||||
this.splitTab(this.focusedTab, 'b')
|
this.splitTab(this.focusedTab, 'b')
|
||||||
break
|
break
|
||||||
case 'split-top':
|
case 'split-top':
|
||||||
this.splitTab(this.focusedTab, 't')
|
this.splitTab(this.focusedTab, 't')
|
||||||
break
|
break
|
||||||
case 'split-left':
|
case 'split-left':
|
||||||
this.splitTab(this.focusedTab, 'l')
|
this.splitTab(this.focusedTab, 'l')
|
||||||
break
|
break
|
||||||
case 'pane-nav-left':
|
case 'pane-nav-left':
|
||||||
this.navigate('l')
|
this.navigate('l')
|
||||||
break
|
break
|
||||||
case 'pane-nav-right':
|
case 'pane-nav-right':
|
||||||
this.navigate('r')
|
this.navigate('r')
|
||||||
break
|
break
|
||||||
case 'pane-nav-up':
|
case 'pane-nav-up':
|
||||||
this.navigate('t')
|
this.navigate('t')
|
||||||
break
|
break
|
||||||
case 'pane-nav-down':
|
case 'pane-nav-down':
|
||||||
this.navigate('b')
|
this.navigate('b')
|
||||||
break
|
break
|
||||||
case 'close-pane':
|
case 'close-pane':
|
||||||
this.removeTab(this.focusedTab)
|
this.removeTab(this.focusedTab)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -235,8 +239,10 @@ export class SplitTabComponent extends BaseTabComponent implements OnInit, OnDes
|
|||||||
await this.recoverContainer(this.root, this._recoveredState)
|
await this.recoverContainer(this.root, this._recoveredState)
|
||||||
this.layout()
|
this.layout()
|
||||||
setImmediate(() => {
|
setImmediate(() => {
|
||||||
this.getAllTabs().forEach(x => x.emitFocused())
|
if (this.hasFocus) {
|
||||||
this.focusAnyIn(this.root)
|
this.getAllTabs().forEach(x => x.emitFocused())
|
||||||
|
this.focusAnyIn(this.root)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -257,7 +263,7 @@ export class SplitTabComponent extends BaseTabComponent implements OnInit, OnDes
|
|||||||
|
|
||||||
focus (tab: BaseTabComponent) {
|
focus (tab: BaseTabComponent) {
|
||||||
this.focusedTab = tab
|
this.focusedTab = tab
|
||||||
for (let x of this.getAllTabs()) {
|
for (const x of this.getAllTabs()) {
|
||||||
if (x !== tab) {
|
if (x !== tab) {
|
||||||
x.emitBlurred()
|
x.emitBlurred()
|
||||||
}
|
}
|
||||||
@@ -286,17 +292,17 @@ export class SplitTabComponent extends BaseTabComponent implements OnInit, OnDes
|
|||||||
/**
|
/**
|
||||||
* Inserts a new `tab` to the `side` of the `relative` tab
|
* Inserts a new `tab` to the `side` of the `relative` tab
|
||||||
*/
|
*/
|
||||||
addTab (tab: BaseTabComponent, relative: BaseTabComponent, side: SplitDirection) {
|
addTab (tab: BaseTabComponent, relative: BaseTabComponent|null, side: SplitDirection) {
|
||||||
let target = this.getParentOf(relative) || this.root
|
let target = (relative ? this.getParentOf(relative) : null) || this.root
|
||||||
let insertIndex = target.children.indexOf(relative)
|
let insertIndex = relative ? target.children.indexOf(relative) : -1
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(target.orientation === 'v' && ['l', 'r'].includes(side)) ||
|
target.orientation === 'v' && ['l', 'r'].includes(side) ||
|
||||||
(target.orientation === 'h' && ['t', 'b'].includes(side))
|
target.orientation === 'h' && ['t', 'b'].includes(side)
|
||||||
) {
|
) {
|
||||||
let newContainer = new SplitContainer()
|
const newContainer = new SplitContainer()
|
||||||
newContainer.orientation = (target.orientation === 'v') ? 'h' : 'v'
|
newContainer.orientation = target.orientation === 'v' ? 'h' : 'v'
|
||||||
newContainer.children = [relative]
|
newContainer.children = relative ? [relative] : []
|
||||||
newContainer.ratios = [1]
|
newContainer.ratios = [1]
|
||||||
target.children[insertIndex] = newContainer
|
target.children[insertIndex] = newContainer
|
||||||
target = newContainer
|
target = newContainer
|
||||||
@@ -306,7 +312,7 @@ export class SplitTabComponent extends BaseTabComponent implements OnInit, OnDes
|
|||||||
if (insertIndex === -1) {
|
if (insertIndex === -1) {
|
||||||
insertIndex = 0
|
insertIndex = 0
|
||||||
} else {
|
} else {
|
||||||
insertIndex += (side === 'l' || side === 't') ? 0 : 1
|
insertIndex += side === 'l' || side === 't' ? 0 : 1
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < target.children.length; i++) {
|
for (let i = 0; i < target.children.length; i++) {
|
||||||
@@ -326,8 +332,11 @@ export class SplitTabComponent extends BaseTabComponent implements OnInit, OnDes
|
|||||||
}
|
}
|
||||||
|
|
||||||
removeTab (tab: BaseTabComponent) {
|
removeTab (tab: BaseTabComponent) {
|
||||||
let parent = this.getParentOf(tab)
|
const parent = this.getParentOf(tab)
|
||||||
let index = parent.children.indexOf(tab)
|
if (!parent) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const index = parent.children.indexOf(tab)
|
||||||
parent.ratios.splice(index, 1)
|
parent.ratios.splice(index, 1)
|
||||||
parent.children.splice(index, 1)
|
parent.children.splice(index, 1)
|
||||||
|
|
||||||
@@ -350,18 +359,25 @@ export class SplitTabComponent extends BaseTabComponent implements OnInit, OnDes
|
|||||||
navigate (dir: SplitDirection) {
|
navigate (dir: SplitDirection) {
|
||||||
let rel: BaseTabComponent | SplitContainer = this.focusedTab
|
let rel: BaseTabComponent | SplitContainer = this.focusedTab
|
||||||
let parent = this.getParentOf(rel)
|
let parent = this.getParentOf(rel)
|
||||||
let orientation = ['l', 'r'].includes(dir) ? 'h' : 'v'
|
if (!parent) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const orientation = ['l', 'r'].includes(dir) ? 'h' : 'v'
|
||||||
|
|
||||||
while (parent !== this.root && parent.orientation !== orientation) {
|
while (parent !== this.root && parent.orientation !== orientation) {
|
||||||
rel = parent
|
rel = parent
|
||||||
parent = this.getParentOf(rel)
|
parent = this.getParentOf(rel)
|
||||||
|
if (!parent) {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parent.orientation !== orientation) {
|
if (parent.orientation !== orientation) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let index = parent.children.indexOf(rel)
|
const index = parent.children.indexOf(rel)
|
||||||
if (['l', 't'].includes(dir)) {
|
if (['l', 't'].includes(dir)) {
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
this.focusAnyIn(parent.children[index - 1])
|
this.focusAnyIn(parent.children[index - 1])
|
||||||
@@ -374,18 +390,20 @@ export class SplitTabComponent extends BaseTabComponent implements OnInit, OnDes
|
|||||||
}
|
}
|
||||||
|
|
||||||
async splitTab (tab: BaseTabComponent, dir: SplitDirection) {
|
async splitTab (tab: BaseTabComponent, dir: SplitDirection) {
|
||||||
let newTab = await this.tabsService.duplicate(tab)
|
const newTab = await this.tabsService.duplicate(tab)
|
||||||
this.addTab(newTab, tab, dir)
|
if (newTab) {
|
||||||
|
this.addTab(newTab, tab, dir)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns the immediate parent of `tab`
|
* @returns the immediate parent of `tab`
|
||||||
*/
|
*/
|
||||||
getParentOf (tab: BaseTabComponent | SplitContainer, root?: SplitContainer): SplitContainer {
|
getParentOf (tab: BaseTabComponent | SplitContainer, root?: SplitContainer): SplitContainer|null {
|
||||||
root = root || this.root
|
root = root || this.root
|
||||||
for (let child of root.children) {
|
for (const child of root.children) {
|
||||||
if (child instanceof SplitContainer) {
|
if (child instanceof SplitContainer) {
|
||||||
let r = this.getParentOf(tab, child)
|
const r = this.getParentOf(tab, child)
|
||||||
if (r) {
|
if (r) {
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
@@ -408,8 +426,8 @@ export class SplitTabComponent extends BaseTabComponent implements OnInit, OnDes
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
async getCurrentProcess (): Promise<BaseTabProcess> {
|
async getCurrentProcess (): Promise<BaseTabProcess|null> {
|
||||||
return (await Promise.all(this.getAllTabs().map(x => x.getCurrentProcess()))).find(x => !!x)
|
return (await Promise.all(this.getAllTabs().map(x => x.getCurrentProcess()))).find(x => !!x) || null
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@@ -419,7 +437,7 @@ export class SplitTabComponent extends BaseTabComponent implements OnInit, OnDes
|
|||||||
}
|
}
|
||||||
|
|
||||||
private attachTabView (tab: BaseTabComponent) {
|
private attachTabView (tab: BaseTabComponent) {
|
||||||
let ref = this.viewContainer.insert(tab.hostView) as EmbeddedViewRef<any>
|
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)
|
||||||
|
|
||||||
ref.rootNodes[0].addEventListener('click', () => this.focus(tab))
|
ref.rootNodes[0].addEventListener('click', () => this.focus(tab))
|
||||||
@@ -436,9 +454,11 @@ export class SplitTabComponent extends BaseTabComponent implements OnInit, OnDes
|
|||||||
}
|
}
|
||||||
|
|
||||||
private detachTabView (tab: BaseTabComponent) {
|
private detachTabView (tab: BaseTabComponent) {
|
||||||
let ref = this.viewRefs.get(tab)
|
const ref = this.viewRefs.get(tab)
|
||||||
this.viewRefs.delete(tab)
|
if (ref) {
|
||||||
this.viewContainer.remove(this.viewContainer.indexOf(ref))
|
this.viewRefs.delete(tab)
|
||||||
|
this.viewContainer.remove(this.viewContainer.indexOf(ref))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private layout () {
|
private layout () {
|
||||||
@@ -448,8 +468,8 @@ export class SplitTabComponent extends BaseTabComponent implements OnInit, OnDes
|
|||||||
}
|
}
|
||||||
|
|
||||||
private layoutInternal (root: SplitContainer, x: number, y: number, w: number, h: number) {
|
private layoutInternal (root: SplitContainer, x: number, y: number, w: number, h: number) {
|
||||||
let size = (root.orientation === 'v') ? h : w
|
const size = root.orientation === 'v' ? h : w
|
||||||
let sizes = root.ratios.map(x => x * size)
|
const sizes = root.ratios.map(x => x * size)
|
||||||
|
|
||||||
root.x = x
|
root.x = x
|
||||||
root.y = y
|
root.y = y
|
||||||
@@ -458,21 +478,21 @@ export class SplitTabComponent extends BaseTabComponent implements OnInit, OnDes
|
|||||||
|
|
||||||
let offset = 0
|
let offset = 0
|
||||||
root.children.forEach((child, i) => {
|
root.children.forEach((child, i) => {
|
||||||
let childX = (root.orientation === 'v') ? x : (x + offset)
|
const childX = root.orientation === 'v' ? x : x + offset
|
||||||
let childY = (root.orientation === 'v') ? (y + offset) : y
|
const childY = root.orientation === 'v' ? y + offset : y
|
||||||
let childW = (root.orientation === 'v') ? w : sizes[i]
|
const childW = root.orientation === 'v' ? w : sizes[i]
|
||||||
let childH = (root.orientation === 'v') ? sizes[i] : h
|
const childH = root.orientation === 'v' ? sizes[i] : h
|
||||||
if (child instanceof SplitContainer) {
|
if (child instanceof SplitContainer) {
|
||||||
this.layoutInternal(child, childX, childY, childW, childH)
|
this.layoutInternal(child, childX, childY, childW, childH)
|
||||||
} else {
|
} else {
|
||||||
let element = this.viewRefs.get(child).rootNodes[0]
|
const element = this.viewRefs.get(child)!.rootNodes[0]
|
||||||
element.style.position = 'absolute'
|
element.style.position = 'absolute'
|
||||||
element.style.left = `${childX}%`
|
element.style.left = `${childX}%`
|
||||||
element.style.top = `${childY}%`
|
element.style.top = `${childY}%`
|
||||||
element.style.width = `${childW}%`
|
element.style.width = `${childW}%`
|
||||||
element.style.height = `${childH}%`
|
element.style.height = `${childH}%`
|
||||||
|
|
||||||
element.style.opacity = (child === this.focusedTab) ? 1 : 0.75
|
element.style.opacity = child === this.focusedTab ? 1 : 0.75
|
||||||
}
|
}
|
||||||
offset += sizes[i]
|
offset += sizes[i]
|
||||||
|
|
||||||
@@ -486,19 +506,19 @@ export class SplitTabComponent extends BaseTabComponent implements OnInit, OnDes
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async recoverContainer (root: SplitContainer, state: any) {
|
private async recoverContainer (root: SplitContainer, state: any) {
|
||||||
let children: (SplitContainer | BaseTabComponent)[] = []
|
const children: (SplitContainer | BaseTabComponent)[] = []
|
||||||
root.orientation = state.orientation
|
root.orientation = state.orientation
|
||||||
root.ratios = state.ratios
|
root.ratios = state.ratios
|
||||||
root.children = children
|
root.children = children
|
||||||
for (let childState of state.children) {
|
for (const childState of state.children) {
|
||||||
if (childState.type === 'app:split-tab') {
|
if (childState.type === 'app:split-tab') {
|
||||||
let child = new SplitContainer()
|
const child = new SplitContainer()
|
||||||
await this.recoverContainer(child, childState)
|
await this.recoverContainer(child, childState)
|
||||||
children.push(child)
|
children.push(child)
|
||||||
} else {
|
} else {
|
||||||
let recovered = await this.tabRecovery.recoverTab(childState)
|
const recovered = await this.tabRecovery.recoverTab(childState)
|
||||||
if (recovered) {
|
if (recovered) {
|
||||||
let tab = this.tabsService.create(recovered.type, recovered.options)
|
const tab = this.tabsService.create(recovered.type, recovered.options)
|
||||||
children.push(tab)
|
children.push(tab)
|
||||||
this.attachTabView(tab)
|
this.attachTabView(tab)
|
||||||
} else {
|
} else {
|
||||||
@@ -512,7 +532,7 @@ export class SplitTabComponent extends BaseTabComponent implements OnInit, OnDes
|
|||||||
/** @hidden */
|
/** @hidden */
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SplitTabRecoveryProvider extends TabRecoveryProvider {
|
export class SplitTabRecoveryProvider extends TabRecoveryProvider {
|
||||||
async recover (recoveryToken: any): Promise<RecoveredTab> {
|
async recover (recoveryToken: any): Promise<RecoveredTab|null> {
|
||||||
if (recoveryToken && recoveryToken.type === 'app:split-tab') {
|
if (recoveryToken && recoveryToken.type === 'app:split-tab') {
|
||||||
return {
|
return {
|
||||||
type: SplitTabComponent,
|
type: SplitTabComponent,
|
||||||
|
@@ -23,15 +23,15 @@ export class SplitTabSpannerComponent {
|
|||||||
constructor (private element: ElementRef) { }
|
constructor (private element: ElementRef) { }
|
||||||
|
|
||||||
ngAfterViewInit () {
|
ngAfterViewInit () {
|
||||||
this.element.nativeElement.addEventListener('mousedown', e => {
|
this.element.nativeElement.addEventListener('mousedown', (e: MouseEvent) => {
|
||||||
this.isActive = true
|
this.isActive = true
|
||||||
let start = this.isVertical ? e.pageY : e.pageX
|
const start = this.isVertical ? e.pageY : e.pageX
|
||||||
let current = start
|
let current = start
|
||||||
let oldPosition = 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 => {
|
const dragHandler = (e: MouseEvent) => {
|
||||||
current = this.isVertical ? e.pageY : e.pageX
|
current = this.isVertical ? e.pageY : e.pageX
|
||||||
let 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`
|
||||||
} else {
|
} else {
|
||||||
@@ -67,13 +67,13 @@ export class SplitTabSpannerComponent {
|
|||||||
this.container.x,
|
this.container.x,
|
||||||
this.container.y + this.container.h * this.container.getOffsetRatio(this.index),
|
this.container.y + this.container.h * this.container.getOffsetRatio(this.index),
|
||||||
this.container.w,
|
this.container.w,
|
||||||
null
|
0
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
this.setDimensions(
|
this.setDimensions(
|
||||||
this.container.x + this.container.w * this.container.getOffsetRatio(this.index),
|
this.container.x + this.container.w * this.container.getOffsetRatio(this.index),
|
||||||
this.container.y,
|
this.container.y,
|
||||||
null,
|
0,
|
||||||
this.container.h
|
this.container.h
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -82,7 +82,7 @@ export class SplitTabSpannerComponent {
|
|||||||
private setDimensions (x: number, y: number, w: number, h: number) {
|
private setDimensions (x: number, y: number, w: number, h: number) {
|
||||||
this.cssLeft = `${x}%`
|
this.cssLeft = `${x}%`
|
||||||
this.cssTop = `${y}%`
|
this.cssTop = `${y}%`
|
||||||
this.cssWidth = w ? `${w}%` : null
|
this.cssWidth = w ? `${w}%` : 'initial'
|
||||||
this.cssHeight = h ? `${h}%` : null
|
this.cssHeight = h ? `${h}%` : 'initial'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,14 +1,14 @@
|
|||||||
div
|
div
|
||||||
.terminus-logo
|
.terminus-logo
|
||||||
h1.terminus-title Terminus
|
h1.terminus-title Terminus
|
||||||
sup α
|
sup α
|
||||||
|
|
||||||
.list-group
|
.list-group
|
||||||
a.list-group-item.list-group-item-action.d-flex(
|
a.list-group-item.list-group-item-action.d-flex(
|
||||||
*ngFor='let button of getButtons()',
|
*ngFor='let button of getButtons()',
|
||||||
(click)='button.click()',
|
(click)='button.click()',
|
||||||
)
|
)
|
||||||
.d-flex.align-self-center([innerHTML]='button.icon')
|
.d-flex.align-self-center([innerHTML]='sanitizeIcon(button.icon)')
|
||||||
span {{button.title}}
|
span {{button.title}}
|
||||||
|
|
||||||
footer.d-flex.align-items-center
|
footer.d-flex.align-items-center
|
||||||
|
@@ -2,7 +2,6 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex: auto;
|
flex: auto;
|
||||||
-webkit-app-region: drag;
|
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,10 +24,6 @@ footer {
|
|||||||
background: rgba(0,0,0,.5);
|
background: rgba(0,0,0,.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
a, button {
|
|
||||||
-webkit-app-region: no-drag;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-group-item ::ng-deep svg {
|
.list-group-item ::ng-deep svg {
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
import { Component, Inject } from '@angular/core'
|
import { Component, Inject } from '@angular/core'
|
||||||
|
import { DomSanitizer } from '@angular/platform-browser'
|
||||||
import { ConfigService } from '../services/config.service'
|
import { ConfigService } from '../services/config.service'
|
||||||
import { HomeBaseService } from '../services/homeBase.service'
|
import { HomeBaseService } from '../services/homeBase.service'
|
||||||
import { IToolbarButton, ToolbarButtonProvider } from '../api'
|
import { ToolbarButton, ToolbarButtonProvider } from '../api'
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@Component({
|
@Component({
|
||||||
@@ -14,16 +15,21 @@ export class StartPageComponent {
|
|||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
private config: ConfigService,
|
private config: ConfigService,
|
||||||
|
private domSanitizer: DomSanitizer,
|
||||||
public homeBase: HomeBaseService,
|
public homeBase: HomeBaseService,
|
||||||
@Inject(ToolbarButtonProvider) private toolbarButtonProviders: ToolbarButtonProvider[],
|
@Inject(ToolbarButtonProvider) private toolbarButtonProviders: ToolbarButtonProvider[],
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
getButtons (): IToolbarButton[] {
|
getButtons (): ToolbarButton[] {
|
||||||
return this.config.enabledServices(this.toolbarButtonProviders)
|
return this.config.enabledServices(this.toolbarButtonProviders)
|
||||||
.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: IToolbarButton, b: IToolbarButton) => (a.weight || 0) - (b.weight || 0))
|
.sort((a: ToolbarButton, b: ToolbarButton) => (a.weight || 0) - (b.weight || 0))
|
||||||
|
}
|
||||||
|
|
||||||
|
sanitizeIcon (icon: string): any {
|
||||||
|
return this.domSanitizer.bypassSecurityTrustHtml(icon || '')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -9,6 +9,11 @@ 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'
|
||||||
|
|
||||||
|
/** @hidden */
|
||||||
|
export interface SortableComponentProxy {
|
||||||
|
setDragHandle (_: HTMLElement)
|
||||||
|
}
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'tab-header',
|
selector: 'tab-header',
|
||||||
@@ -20,16 +25,16 @@ export class TabHeaderComponent {
|
|||||||
@Input() @HostBinding('class.active') active: boolean
|
@Input() @HostBinding('class.active') active: boolean
|
||||||
@Input() @HostBinding('class.has-activity') hasActivity: boolean
|
@Input() @HostBinding('class.has-activity') hasActivity: boolean
|
||||||
@Input() tab: BaseTabComponent
|
@Input() tab: BaseTabComponent
|
||||||
@Input() progress: number
|
@Input() progress: number|null
|
||||||
@ViewChild('handle') handle: ElementRef
|
@ViewChild('handle') handle: ElementRef
|
||||||
|
|
||||||
constructor (
|
private constructor (
|
||||||
public app: AppService,
|
public app: AppService,
|
||||||
private electron: ElectronService,
|
private electron: ElectronService,
|
||||||
private hostApp: HostAppService,
|
private hostApp: HostAppService,
|
||||||
private ngbModal: NgbModal,
|
private ngbModal: NgbModal,
|
||||||
private hotkeys: HotkeysService,
|
private hotkeys: HotkeysService,
|
||||||
private parentDraggable: SortableComponent,
|
@Inject(SortableComponent) private parentDraggable: SortableComponentProxy,
|
||||||
@Optional() @Inject(TabContextMenuItemProvider) protected contextMenuProviders: TabContextMenuItemProvider[],
|
@Optional() @Inject(TabContextMenuItemProvider) protected contextMenuProviders: TabContextMenuItemProvider[],
|
||||||
) {
|
) {
|
||||||
this.hotkeys.matchedHotkey.subscribe((hotkey) => {
|
this.hotkeys.matchedHotkey.subscribe((hotkey) => {
|
||||||
@@ -52,7 +57,7 @@ export class TabHeaderComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
showRenameTabModal (): void {
|
showRenameTabModal (): void {
|
||||||
let modal = this.ngbModal.open(RenameTabModalComponent)
|
const modal = this.ngbModal.open(RenameTabModalComponent)
|
||||||
modal.componentInstance.value = this.tab.customTitle || this.tab.title
|
modal.componentInstance.value = this.tab.customTitle || this.tab.title
|
||||||
modal.result.then(result => {
|
modal.result.then(result => {
|
||||||
this.tab.setTitle(result)
|
this.tab.setTitle(result)
|
||||||
@@ -62,7 +67,7 @@ export class TabHeaderComponent {
|
|||||||
|
|
||||||
async buildContextMenu (): Promise<Electron.MenuItemConstructorOptions[]> {
|
async buildContextMenu (): Promise<Electron.MenuItemConstructorOptions[]> {
|
||||||
let items: Electron.MenuItemConstructorOptions[] = []
|
let items: Electron.MenuItemConstructorOptions[] = []
|
||||||
for (let 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)
|
||||||
}
|
}
|
||||||
@@ -73,19 +78,27 @@ export class TabHeaderComponent {
|
|||||||
this.showRenameTabModal()
|
this.showRenameTabModal()
|
||||||
}
|
}
|
||||||
|
|
||||||
@HostListener('auxclick', ['$event']) async onAuxClick ($event: MouseEvent) {
|
@HostListener('mousedown', ['$event']) async onMouseDown ($event: MouseEvent) {
|
||||||
|
if ($event.which === 2) {
|
||||||
|
$event.preventDefault()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@HostListener('mouseup', ['$event']) async onMouseUp ($event: MouseEvent) {
|
||||||
if ($event.which === 2) {
|
if ($event.which === 2) {
|
||||||
this.app.closeTab(this.tab, true)
|
this.app.closeTab(this.tab, true)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@HostListener('auxclick', ['$event']) async onAuxClick ($event: MouseEvent) {
|
||||||
if ($event.which === 3) {
|
if ($event.which === 3) {
|
||||||
event.preventDefault()
|
$event.preventDefault()
|
||||||
|
|
||||||
const contextMenu = this.electron.remote.Menu.buildFromTemplate(await this.buildContextMenu())
|
const contextMenu = this.electron.remote.Menu.buildFromTemplate(await this.buildContextMenu())
|
||||||
|
|
||||||
contextMenu.popup({
|
contextMenu.popup({
|
||||||
x: $event.pageX,
|
x: $event.pageX,
|
||||||
y: $event.pageY,
|
y: $event.pageY,
|
||||||
async: true,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,4 +6,4 @@ import { Component } from '@angular/core'
|
|||||||
template: require('./titleBar.component.pug'),
|
template: require('./titleBar.component.pug'),
|
||||||
styles: [require('./titleBar.component.scss')],
|
styles: [require('./titleBar.component.scss')],
|
||||||
})
|
})
|
||||||
export class TitleBarComponent { }
|
export class TitleBarComponent { } // eslint-disable-line @typescript-eslint/no-extraneous-class
|
||||||
|
@@ -17,7 +17,7 @@ import { CheckboxComponent } from './checkbox.component'
|
|||||||
styles: [require('./toggle.component.scss')],
|
styles: [require('./toggle.component.scss')],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: NG_VALUE_ACCESSOR, useExisting: ToggleComponent, multi: true },
|
{ provide: NG_VALUE_ACCESSOR, useExisting: ToggleComponent, multi: true },
|
||||||
]
|
],
|
||||||
})
|
})
|
||||||
export class ToggleComponent extends CheckboxComponent {
|
export class ToggleComponent extends CheckboxComponent {
|
||||||
}
|
}
|
||||||
|
@@ -12,7 +12,8 @@ export class WindowControlsComponent {
|
|||||||
constructor (public hostApp: HostAppService, public app: AppService) { }
|
constructor (public hostApp: HostAppService, public app: AppService) { }
|
||||||
|
|
||||||
async closeWindow () {
|
async closeWindow () {
|
||||||
await this.app.closeAllTabs()
|
if (await this.app.closeAllTabs()) {
|
||||||
this.hostApp.closeWindow()
|
this.hostApp.closeWindow()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -11,10 +11,10 @@ hotkeys:
|
|||||||
rename-tab:
|
rename-tab:
|
||||||
- 'Ctrl-Shift-R'
|
- 'Ctrl-Shift-R'
|
||||||
next-tab:
|
next-tab:
|
||||||
- 'Ctrl-Shift-ArrowRight'
|
- 'Ctrl-Shift-Right'
|
||||||
- 'Ctrl-Tab'
|
- 'Ctrl-Tab'
|
||||||
previous-tab:
|
previous-tab:
|
||||||
- 'Ctrl-Shift-ArrowLeft'
|
- 'Ctrl-Shift-Left'
|
||||||
- 'Ctrl-Shift-Tab'
|
- 'Ctrl-Shift-Tab'
|
||||||
tab-1:
|
tab-1:
|
||||||
- 'Alt-1'
|
- 'Alt-1'
|
||||||
@@ -43,12 +43,12 @@ hotkeys:
|
|||||||
split-left: []
|
split-left: []
|
||||||
split-top: []
|
split-top: []
|
||||||
pane-nav-right:
|
pane-nav-right:
|
||||||
- 'Ctrl-Alt-ArrowRight'
|
- 'Ctrl-Alt-Right'
|
||||||
pane-nav-down:
|
pane-nav-down:
|
||||||
- 'Ctrl-Alt-ArrowDown'
|
- 'Ctrl-Alt-Down'
|
||||||
pane-nav-up:
|
pane-nav-up:
|
||||||
- 'Ctrl-Alt-ArrowUp'
|
- 'Ctrl-Alt-Up'
|
||||||
pane-nav-left:
|
pane-nav-left:
|
||||||
- 'Ctrl-Alt-ArrowLeft'
|
- 'Ctrl-Alt-Left'
|
||||||
close-pane: []
|
close-pane: []
|
||||||
pluginBlacklist: ['ssh']
|
pluginBlacklist: ['ssh']
|
||||||
|
@@ -41,13 +41,13 @@ hotkeys:
|
|||||||
split-left: []
|
split-left: []
|
||||||
split-top: []
|
split-top: []
|
||||||
pane-nav-right:
|
pane-nav-right:
|
||||||
- '⌘-⌥-ArrowRight'
|
- '⌘-⌥-Right'
|
||||||
pane-nav-down:
|
pane-nav-down:
|
||||||
- '⌘-⌥-ArrowDown'
|
- '⌘-⌥-Down'
|
||||||
pane-nav-up:
|
pane-nav-up:
|
||||||
- '⌘-⌥-ArrowUp'
|
- '⌘-⌥-Up'
|
||||||
pane-nav-left:
|
pane-nav-left:
|
||||||
- '⌘-⌥-ArrowLeft'
|
- '⌘-⌥-Left'
|
||||||
close-pane:
|
close-pane:
|
||||||
- '⌘-Shift-W'
|
- '⌘-Shift-W'
|
||||||
pluginBlacklist: ['ssh']
|
pluginBlacklist: ['ssh']
|
||||||
|
@@ -11,10 +11,10 @@ hotkeys:
|
|||||||
rename-tab:
|
rename-tab:
|
||||||
- 'Ctrl-Shift-R'
|
- 'Ctrl-Shift-R'
|
||||||
next-tab:
|
next-tab:
|
||||||
- 'Ctrl-Shift-ArrowRight'
|
- 'Ctrl-Shift-Right'
|
||||||
- 'Ctrl-Tab'
|
- 'Ctrl-Tab'
|
||||||
previous-tab:
|
previous-tab:
|
||||||
- 'Ctrl-Shift-ArrowLeft'
|
- 'Ctrl-Shift-Left'
|
||||||
- 'Ctrl-Shift-Tab'
|
- 'Ctrl-Shift-Tab'
|
||||||
tab-1:
|
tab-1:
|
||||||
- 'Alt-1'
|
- 'Alt-1'
|
||||||
@@ -43,12 +43,12 @@ hotkeys:
|
|||||||
split-left: []
|
split-left: []
|
||||||
split-top: []
|
split-top: []
|
||||||
pane-nav-right:
|
pane-nav-right:
|
||||||
- 'Ctrl-Alt-ArrowRight'
|
- 'Ctrl-Alt-Right'
|
||||||
pane-nav-down:
|
pane-nav-down:
|
||||||
- 'Ctrl-Alt-ArrowDown'
|
- 'Ctrl-Alt-Down'
|
||||||
pane-nav-up:
|
pane-nav-up:
|
||||||
- 'Ctrl-Alt-ArrowUp'
|
- 'Ctrl-Alt-Up'
|
||||||
pane-nav-left:
|
pane-nav-left:
|
||||||
- 'Ctrl-Alt-ArrowLeft'
|
- 'Ctrl-Alt-Left'
|
||||||
close-pane: []
|
close-pane: []
|
||||||
pluginBlacklist: []
|
pluginBlacklist: []
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
appearance:
|
appearance:
|
||||||
dock: off
|
dock: off
|
||||||
dockScreen: current
|
dockScreen: current
|
||||||
dockFill: 50
|
dockFill: 0.5
|
||||||
tabsLocation: top
|
tabsLocation: top
|
||||||
cycleTabs: true
|
cycleTabs: true
|
||||||
theme: Standard
|
theme: Standard
|
||||||
@@ -12,3 +12,6 @@ appearance:
|
|||||||
vibrancyType: 'blur'
|
vibrancyType: 'blur'
|
||||||
enableAnalytics: true
|
enableAnalytics: true
|
||||||
enableWelcomeTab: true
|
enableWelcomeTab: true
|
||||||
|
electronFlags:
|
||||||
|
- ['force_discrete_gpu', '0']
|
||||||
|
enableAutomaticUpdates: true
|
||||||
|
@@ -2,7 +2,7 @@ import { Directive, AfterViewInit, ElementRef } from '@angular/core'
|
|||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@Directive({
|
@Directive({
|
||||||
selector: '[autofocus]'
|
selector: '[autofocus]',
|
||||||
})
|
})
|
||||||
export class AutofocusDirective implements AfterViewInit {
|
export class AutofocusDirective implements AfterViewInit {
|
||||||
constructor (private el: ElementRef) { }
|
constructor (private el: ElementRef) { }
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { IHotkeyDescription, HotkeyProvider } from './api/hotkeyProvider'
|
import { HotkeyDescription, HotkeyProvider } from './api/hotkeyProvider'
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AppHotkeyProvider extends HotkeyProvider {
|
export class AppHotkeyProvider extends HotkeyProvider {
|
||||||
hotkeys: IHotkeyDescription[] = [
|
hotkeys: HotkeyDescription[] = [
|
||||||
{
|
{
|
||||||
id: 'new-window',
|
id: 'new-window',
|
||||||
name: 'New window',
|
name: 'New window',
|
||||||
@@ -115,7 +115,7 @@ export class AppHotkeyProvider extends HotkeyProvider {
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
async provide (): Promise<IHotkeyDescription[]> {
|
async provide (): Promise<HotkeyDescription[]> {
|
||||||
return this.hotkeys
|
return this.hotkeys
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -39,6 +39,12 @@ import { TaskCompletionContextMenu, CommonOptionsContextMenu, CloseContextMenu }
|
|||||||
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'
|
||||||
|
|
||||||
|
// PerfectScrollbar fix
|
||||||
|
import { fromEvent } from 'rxjs/internal/observable/fromEvent'
|
||||||
|
import { merge } from 'rxjs/internal/observable/merge'
|
||||||
|
require('rxjs').fromEvent = fromEvent
|
||||||
|
require('rxjs').merge = merge
|
||||||
|
|
||||||
const PROVIDERS = [
|
const PROVIDERS = [
|
||||||
{ provide: HotkeyProvider, useClass: AppHotkeyProvider, multi: true },
|
{ provide: HotkeyProvider, useClass: AppHotkeyProvider, multi: true },
|
||||||
{ provide: Theme, useClass: StandardTheme, multi: true },
|
{ provide: Theme, useClass: StandardTheme, multi: true },
|
||||||
@@ -49,7 +55,7 @@ const PROVIDERS = [
|
|||||||
{ provide: TabContextMenuItemProvider, useClass: CloseContextMenu, multi: true },
|
{ provide: TabContextMenuItemProvider, useClass: CloseContextMenu, 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 } },
|
||||||
]
|
]
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@@ -63,7 +69,7 @@ const PROVIDERS = [
|
|||||||
DndModule.forRoot(),
|
DndModule.forRoot(),
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
AppRootComponent,
|
AppRootComponent as any,
|
||||||
CheckboxComponent,
|
CheckboxComponent,
|
||||||
StartPageComponent,
|
StartPageComponent,
|
||||||
TabBodyComponent,
|
TabBodyComponent,
|
||||||
@@ -88,9 +94,9 @@ const PROVIDERS = [
|
|||||||
CheckboxComponent,
|
CheckboxComponent,
|
||||||
ToggleComponent,
|
ToggleComponent,
|
||||||
AutofocusDirective,
|
AutofocusDirective,
|
||||||
]
|
],
|
||||||
})
|
})
|
||||||
export default class AppModule {
|
export default class AppModule { // eslint-disable-line @typescript-eslint/no-extraneous-class
|
||||||
constructor (app: AppService, config: ConfigService) {
|
constructor (app: AppService, config: ConfigService) {
|
||||||
app.ready$.subscribe(() => {
|
app.ready$.subscribe(() => {
|
||||||
if (config.store.enableWelcomeTab) {
|
if (config.store.enableWelcomeTab) {
|
||||||
@@ -107,11 +113,9 @@ export default class AppModule {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PerfectScrollbar fix
|
|
||||||
import { fromEvent } from 'rxjs/internal/observable/fromEvent'
|
|
||||||
import { merge } from 'rxjs/internal/observable/merge'
|
|
||||||
require('rxjs').fromEvent = fromEvent
|
|
||||||
require('rxjs').merge = merge
|
|
||||||
|
|
||||||
export { AppRootComponent as bootstrap }
|
export { AppRootComponent as bootstrap }
|
||||||
export * from './api'
|
export * from './api'
|
||||||
|
|
||||||
|
// Deprecations
|
||||||
|
export { ToolbarButton as IToolbarButton } from './api'
|
||||||
|
export { HotkeyDescription as IHotkeyDescription } from './api'
|
||||||
|
@@ -1,8 +1,11 @@
|
|||||||
|
|
||||||
import { Observable, Subject, AsyncSubject } from 'rxjs'
|
import { Observable, Subject, AsyncSubject } from 'rxjs'
|
||||||
import { takeUntil } from 'rxjs/operators'
|
import { takeUntil } from 'rxjs/operators'
|
||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
|
|
||||||
import { BaseTabComponent } from '../components/baseTab.component'
|
import { BaseTabComponent } from '../components/baseTab.component'
|
||||||
import { SplitTabComponent } from '../components/splitTab.component'
|
import { SplitTabComponent } from '../components/splitTab.component'
|
||||||
|
|
||||||
import { ConfigService } from './config.service'
|
import { ConfigService } from './config.service'
|
||||||
import { HostAppService } from './hostApp.service'
|
import { HostAppService } from './hostApp.service'
|
||||||
import { TabRecoveryService } from './tabRecovery.service'
|
import { TabRecoveryService } from './tabRecovery.service'
|
||||||
@@ -16,20 +19,20 @@ class CompletionObserver {
|
|||||||
private interval: number
|
private interval: number
|
||||||
|
|
||||||
constructor (private tab: BaseTabComponent) {
|
constructor (private tab: BaseTabComponent) {
|
||||||
this.interval = setInterval(() => this.tick(), 1000)
|
this.interval = setInterval(() => this.tick(), 1000) as any
|
||||||
this.tab.destroyed$.pipe(takeUntil(this.destroyed$)).subscribe(() => this.stop())
|
this.tab.destroyed$.pipe(takeUntil(this.destroyed$)).subscribe(() => this.stop())
|
||||||
}
|
}
|
||||||
|
|
||||||
async tick () {
|
async tick () {
|
||||||
if (!(await this.tab.getCurrentProcess())) {
|
if (!await this.tab.getCurrentProcess()) {
|
||||||
this.done.next(null)
|
this.done.next()
|
||||||
this.stop()
|
this.stop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stop () {
|
stop () {
|
||||||
clearInterval(this.interval)
|
clearInterval(this.interval)
|
||||||
this.destroyed.next(null)
|
this.destroyed.next()
|
||||||
this.destroyed.complete()
|
this.destroyed.complete()
|
||||||
this.done.complete()
|
this.done.complete()
|
||||||
}
|
}
|
||||||
@@ -67,29 +70,41 @@ export class AppService {
|
|||||||
private tabRecovery: TabRecoveryService,
|
private tabRecovery: TabRecoveryService,
|
||||||
private tabsService: TabsService,
|
private tabsService: TabsService,
|
||||||
) {
|
) {
|
||||||
this.tabRecovery.recoverTabs().then(tabs => {
|
if (hostApp.getWindow().id === 1) {
|
||||||
for (let tab of tabs) {
|
if (config.store.terminal.recoverTabs) {
|
||||||
this.openNewTabRaw(tab.type, tab.options)
|
this.tabRecovery.recoverTabs().then(tabs => {
|
||||||
|
for (const tab of tabs) {
|
||||||
|
this.openNewTabRaw(tab.type, tab.options)
|
||||||
|
}
|
||||||
|
this.startTabStorage()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
/** Continue to store the tabs even if the setting is currently off */
|
||||||
|
this.startTabStorage()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
this.tabsChanged$.subscribe(() => {
|
|
||||||
tabRecovery.saveTabs(this.tabs)
|
|
||||||
})
|
|
||||||
setInterval(() => {
|
|
||||||
tabRecovery.saveTabs(this.tabs)
|
|
||||||
}, 30000)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private addTabRaw (tab: BaseTabComponent) {
|
startTabStorage () {
|
||||||
|
this.tabsChanged$.subscribe(() => {
|
||||||
|
this.tabRecovery.saveTabs(this.tabs)
|
||||||
|
})
|
||||||
|
setInterval(() => {
|
||||||
|
this.tabRecovery.saveTabs(this.tabs)
|
||||||
|
}, 30000)
|
||||||
|
}
|
||||||
|
|
||||||
|
addTabRaw (tab: BaseTabComponent) {
|
||||||
this.tabs.push(tab)
|
this.tabs.push(tab)
|
||||||
this.selectTab(tab)
|
this.selectTab(tab)
|
||||||
this.tabsChanged.next()
|
this.tabsChanged.next()
|
||||||
this.tabOpened.next(tab)
|
this.tabOpened.next(tab)
|
||||||
|
|
||||||
tab.recoveryStateChangedHint$.subscribe(() => {
|
if (this.hostApp.getWindow().id === 1) {
|
||||||
this.tabRecovery.saveTabs(this.tabs)
|
tab.recoveryStateChangedHint$.subscribe(() => {
|
||||||
})
|
this.tabRecovery.saveTabs(this.tabs)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
tab.titleChange$.subscribe(title => {
|
tab.titleChange$.subscribe(title => {
|
||||||
if (tab === this._activeTab) {
|
if (tab === this._activeTab) {
|
||||||
@@ -98,7 +113,7 @@ export class AppService {
|
|||||||
})
|
})
|
||||||
|
|
||||||
tab.destroyed$.subscribe(() => {
|
tab.destroyed$.subscribe(() => {
|
||||||
let newIndex = Math.max(0, this.tabs.indexOf(tab) - 1)
|
const newIndex = Math.max(0, this.tabs.indexOf(tab) - 1)
|
||||||
this.tabs = this.tabs.filter((x) => x !== tab)
|
this.tabs = this.tabs.filter((x) => x !== tab)
|
||||||
if (tab === this._activeTab) {
|
if (tab === this._activeTab) {
|
||||||
this.selectTab(this.tabs[newIndex])
|
this.selectTab(this.tabs[newIndex])
|
||||||
@@ -113,7 +128,7 @@ export class AppService {
|
|||||||
* @param inputs Properties to be assigned on the new tab component instance
|
* @param inputs Properties to be assigned on the new tab component instance
|
||||||
*/
|
*/
|
||||||
openNewTabRaw (type: TabComponentType, inputs?: any): BaseTabComponent {
|
openNewTabRaw (type: TabComponentType, inputs?: any): BaseTabComponent {
|
||||||
let tab = this.tabsService.create(type, inputs)
|
const tab = this.tabsService.create(type, inputs)
|
||||||
this.addTabRaw(tab)
|
this.addTabRaw(tab)
|
||||||
return tab
|
return tab
|
||||||
}
|
}
|
||||||
@@ -123,8 +138,8 @@ export class AppService {
|
|||||||
* @param inputs Properties to be assigned on the new tab component instance
|
* @param inputs Properties to be assigned on the new tab component instance
|
||||||
*/
|
*/
|
||||||
openNewTab (type: TabComponentType, inputs?: any): BaseTabComponent {
|
openNewTab (type: TabComponentType, inputs?: any): BaseTabComponent {
|
||||||
let splitTab = this.tabsService.create(SplitTabComponent) as SplitTabComponent
|
const splitTab = this.tabsService.create(SplitTabComponent) as SplitTabComponent
|
||||||
let tab = this.tabsService.create(type, inputs)
|
const tab = this.tabsService.create(type, inputs)
|
||||||
splitTab.addTab(tab, null, 'r')
|
splitTab.addTab(tab, null, 'r')
|
||||||
this.addTabRaw(splitTab)
|
this.addTabRaw(splitTab)
|
||||||
return tab
|
return tab
|
||||||
@@ -138,7 +153,7 @@ export class AppService {
|
|||||||
if (this.tabs.includes(this._activeTab)) {
|
if (this.tabs.includes(this._activeTab)) {
|
||||||
this.lastTabIndex = this.tabs.indexOf(this._activeTab)
|
this.lastTabIndex = this.tabs.indexOf(this._activeTab)
|
||||||
} else {
|
} else {
|
||||||
this.lastTabIndex = null
|
this.lastTabIndex = 0
|
||||||
}
|
}
|
||||||
if (this._activeTab) {
|
if (this._activeTab) {
|
||||||
this._activeTab.clearActivity()
|
this._activeTab.clearActivity()
|
||||||
@@ -164,7 +179,7 @@ export class AppService {
|
|||||||
|
|
||||||
nextTab () {
|
nextTab () {
|
||||||
if (this.tabs.length > 1) {
|
if (this.tabs.length > 1) {
|
||||||
let 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) {
|
||||||
this.selectTab(this.tabs[tabIndex + 1])
|
this.selectTab(this.tabs[tabIndex + 1])
|
||||||
} else if (this.config.store.appearance.cycleTabs) {
|
} else if (this.config.store.appearance.cycleTabs) {
|
||||||
@@ -175,7 +190,7 @@ export class AppService {
|
|||||||
|
|
||||||
previousTab () {
|
previousTab () {
|
||||||
if (this.tabs.length > 1) {
|
if (this.tabs.length > 1) {
|
||||||
let tabIndex = this.tabs.indexOf(this._activeTab)
|
const tabIndex = this.tabs.indexOf(this._activeTab)
|
||||||
if (tabIndex > 0) {
|
if (tabIndex > 0) {
|
||||||
this.selectTab(this.tabs[tabIndex - 1])
|
this.selectTab(this.tabs[tabIndex - 1])
|
||||||
} else if (this.config.store.appearance.cycleTabs) {
|
} else if (this.config.store.appearance.cycleTabs) {
|
||||||
@@ -200,26 +215,30 @@ export class AppService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async duplicateTab (tab: BaseTabComponent) {
|
async duplicateTab (tab: BaseTabComponent) {
|
||||||
let dup = await this.tabsService.duplicate(tab)
|
const dup = await this.tabsService.duplicate(tab)
|
||||||
if (dup) {
|
if (dup) {
|
||||||
this.addTabRaw(dup)
|
this.addTabRaw(dup)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async closeAllTabs () {
|
/**
|
||||||
for (let tab of this.tabs) {
|
* Attempts to close all tabs, returns false if one of the tabs blocked closure
|
||||||
|
*/
|
||||||
|
async closeAllTabs (): Promise<boolean> {
|
||||||
|
for (const tab of this.tabs) {
|
||||||
if (!await tab.canClose()) {
|
if (!await tab.canClose()) {
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let tab of this.tabs) {
|
for (const tab of this.tabs) {
|
||||||
tab.destroy()
|
tab.destroy(true)
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
emitReady () {
|
emitReady () {
|
||||||
this.ready.next(null)
|
this.ready.next()
|
||||||
this.ready.complete()
|
this.ready.complete()
|
||||||
this.hostApp.emitReady()
|
this.hostApp.emitReady()
|
||||||
}
|
}
|
||||||
@@ -230,13 +249,13 @@ export class AppService {
|
|||||||
*/
|
*/
|
||||||
observeTabCompletion (tab: BaseTabComponent): Observable<void> {
|
observeTabCompletion (tab: BaseTabComponent): Observable<void> {
|
||||||
if (!this.completionObservers.has(tab)) {
|
if (!this.completionObservers.has(tab)) {
|
||||||
let observer = new CompletionObserver(tab)
|
const observer = new CompletionObserver(tab)
|
||||||
observer.destroyed$.subscribe(() => {
|
observer.destroyed$.subscribe(() => {
|
||||||
this.stopObservingTabCompletion(tab)
|
this.stopObservingTabCompletion(tab)
|
||||||
})
|
})
|
||||||
this.completionObservers.set(tab, observer)
|
this.completionObservers.set(tab, observer)
|
||||||
}
|
}
|
||||||
return this.completionObservers.get(tab).done$
|
return this.completionObservers.get(tab)!.done$
|
||||||
}
|
}
|
||||||
|
|
||||||
stopObservingTabCompletion (tab: BaseTabComponent) {
|
stopObservingTabCompletion (tab: BaseTabComponent) {
|
||||||
|
@@ -7,26 +7,26 @@ import { ConfigProvider } from '../api/configProvider'
|
|||||||
import { ElectronService } from './electron.service'
|
import { ElectronService } from './electron.service'
|
||||||
import { HostAppService } from './hostApp.service'
|
import { HostAppService } from './hostApp.service'
|
||||||
|
|
||||||
const configMerge = (a, b) => require('deepmerge')(a, b, { arrayMerge: (_d, s) => s })
|
const configMerge = (a, b) => require('deepmerge')(a, b, { arrayMerge: (_d, s) => s }) // eslint-disable-line @typescript-eslint/no-var-requires
|
||||||
|
|
||||||
function isStructuralMember (v) {
|
function isStructuralMember (v) {
|
||||||
return v instanceof Object && !(v instanceof Array) &&
|
return v instanceof Object && !(v instanceof Array) &&
|
||||||
Object.keys(v).length > 0 && !v.__nonStructural
|
Object.keys(v).length > 0 && !v.__nonStructural
|
||||||
}
|
}
|
||||||
|
|
||||||
function isNonStructuralObjectMember (v) {
|
function isNonStructuralObjectMember (v): boolean {
|
||||||
return v instanceof Object && !(v instanceof Array) && v.__nonStructural
|
return v instanceof Object && !(v instanceof Array) && v.__nonStructural
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
export class ConfigProxy {
|
export class ConfigProxy {
|
||||||
constructor (real: any, defaults: any) {
|
constructor (real: any, defaults: any) {
|
||||||
for (let key in defaults) {
|
for (const key in defaults) {
|
||||||
if (isStructuralMember(defaults[key])) {
|
if (isStructuralMember(defaults[key])) {
|
||||||
if (!real[key]) {
|
if (!real[key]) {
|
||||||
real[key] = {}
|
real[key] = {}
|
||||||
}
|
}
|
||||||
let proxy = new ConfigProxy(real[key], defaults[key])
|
const proxy = new ConfigProxy(real[key], defaults[key])
|
||||||
Object.defineProperty(
|
Object.defineProperty(
|
||||||
this,
|
this,
|
||||||
key,
|
key,
|
||||||
@@ -46,13 +46,13 @@ export class ConfigProxy {
|
|||||||
get: () => this.getValue(key),
|
get: () => this.getValue(key),
|
||||||
set: (value) => {
|
set: (value) => {
|
||||||
this.setValue(key, value)
|
this.setValue(key, value)
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getValue = (key: string) => {
|
this.getValue = (key: string) => { // eslint-disable-line @typescript-eslint/unbound-method
|
||||||
if (real[key] !== undefined) {
|
if (real[key] !== undefined) {
|
||||||
return real[key]
|
return real[key]
|
||||||
} else {
|
} else {
|
||||||
@@ -66,13 +66,13 @@ export class ConfigProxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setValue = (key: string, value: any) => {
|
this.setValue = (key: string, value: any) => { // eslint-disable-line @typescript-eslint/unbound-method
|
||||||
real[key] = value
|
real[key] = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getValue (key: string): any { } // tslint:disable-line
|
getValue (_key: string): any { } // eslint-disable-line @typescript-eslint/no-empty-function
|
||||||
setValue (key: string, value: any) { } // tslint:disable-line
|
setValue (_key: string, _value: any) { } // eslint-disable-line @typescript-eslint/no-empty-function
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
@@ -95,7 +95,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
|
private servicesCache: { [id: string]: Function[] }|null = null
|
||||||
|
|
||||||
get changed$ (): Observable<void> { return this.changed }
|
get changed$ (): Observable<void> { return this.changed }
|
||||||
|
|
||||||
@@ -160,10 +160,6 @@ export class ConfigService {
|
|||||||
this.emitChange()
|
this.emitChange()
|
||||||
}
|
}
|
||||||
|
|
||||||
private emitChange (): void {
|
|
||||||
this.changed.next()
|
|
||||||
}
|
|
||||||
|
|
||||||
requestRestart (): void {
|
requestRestart (): void {
|
||||||
this.restartRequested = true
|
this.restartRequested = true
|
||||||
}
|
}
|
||||||
@@ -174,12 +170,12 @@ export class ConfigService {
|
|||||||
*
|
*
|
||||||
* @typeparam T Base provider type
|
* @typeparam T Base provider type
|
||||||
*/
|
*/
|
||||||
enabledServices<T> (services: T[]): T[] {
|
enabledServices<T extends object> (services: T[]): T[] {
|
||||||
if (!this.servicesCache) {
|
if (!this.servicesCache) {
|
||||||
this.servicesCache = {}
|
this.servicesCache = {}
|
||||||
let ngModule = window['rootModule'].ngInjectorDef
|
const ngModule = window['rootModule'].ngInjectorDef
|
||||||
for (let imp of ngModule.imports) {
|
for (const imp of ngModule.imports) {
|
||||||
let module = (imp['ngModule'] || imp)
|
const module = imp['ngModule'] || imp
|
||||||
if (module.ngInjectorDef && module.ngInjectorDef.providers) {
|
if (module.ngInjectorDef && module.ngInjectorDef.providers) {
|
||||||
this.servicesCache[module['pluginName']] = module.ngInjectorDef.providers.map(provider => {
|
this.servicesCache[module['pluginName']] = module.ngInjectorDef.providers.map(provider => {
|
||||||
return provider['useClass'] || provider
|
return provider['useClass'] || provider
|
||||||
@@ -188,7 +184,7 @@ export class ConfigService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return services.filter(service => {
|
return services.filter(service => {
|
||||||
for (let pluginName in this.servicesCache) {
|
for (const pluginName in this.servicesCache) {
|
||||||
if (this.servicesCache[pluginName].includes(service.constructor)) {
|
if (this.servicesCache[pluginName].includes(service.constructor)) {
|
||||||
return !this.store.pluginBlacklist.includes(pluginName)
|
return !this.store.pluginBlacklist.includes(pluginName)
|
||||||
}
|
}
|
||||||
@@ -196,4 +192,8 @@ export class ConfigService {
|
|||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private emitChange (): void {
|
||||||
|
this.changed.next()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,11 +3,6 @@ import { ConfigService } from '../services/config.service'
|
|||||||
import { ElectronService } from '../services/electron.service'
|
import { ElectronService } from '../services/electron.service'
|
||||||
import { HostAppService, Bounds } from '../services/hostApp.service'
|
import { HostAppService, Bounds } from '../services/hostApp.service'
|
||||||
|
|
||||||
export interface IScreen {
|
|
||||||
id: string
|
|
||||||
name: string
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class DockingService {
|
export class DockingService {
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@@ -21,7 +16,7 @@ export class DockingService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dock () {
|
dock () {
|
||||||
let dockSide = this.config.store.appearance.dock
|
const dockSide = this.config.store.appearance.dock
|
||||||
|
|
||||||
if (dockSide === 'off') {
|
if (dockSide === 'off') {
|
||||||
this.hostApp.setAlwaysOnTop(false)
|
this.hostApp.setAlwaysOnTop(false)
|
||||||
@@ -29,14 +24,15 @@ 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]
|
||||||
if (!display) {
|
if (!display) {
|
||||||
display = this.getCurrentScreen()
|
display = this.getCurrentScreen()
|
||||||
}
|
}
|
||||||
|
|
||||||
let newBounds: Bounds = { x: 0, y: 0, width: 0, height: 0 }
|
const newBounds: Bounds = { x: 0, y: 0, width: 0, height: 0 }
|
||||||
let fill = this.config.store.appearance.dockFill
|
|
||||||
let [minWidth, minHeight] = this.hostApp.getWindow().getMinimumSize()
|
const fill = this.config.store.appearance.dockFill <= 1 ? this.config.store.appearance.dockFill : 1
|
||||||
|
const [minWidth, minHeight] = this.hostApp.getWindow().getMinimumSize()
|
||||||
|
|
||||||
if (dockSide === 'left' || dockSide === 'right') {
|
if (dockSide === 'left' || dockSide === 'right') {
|
||||||
newBounds.width = Math.max(minWidth, Math.round(fill * display.bounds.width))
|
newBounds.width = Math.max(minWidth, Math.round(fill * display.bounds.width))
|
||||||
@@ -68,26 +64,26 @@ export class DockingService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getScreens () {
|
getScreens () {
|
||||||
return this.electron.screen.getAllDisplays().map((display, index) => {
|
const primaryDisplayID = this.electron.screen.getPrimaryDisplay().id
|
||||||
|
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
|
||||||
|
).map((display,index) => {
|
||||||
return {
|
return {
|
||||||
id: display.id,
|
id: display.id,
|
||||||
name: {
|
name: display.id === primaryDisplayID ? 'Primary Display' : `Display ${index +1}`,
|
||||||
0: 'Primary display',
|
|
||||||
1: 'Secondary display',
|
|
||||||
}[index] || `Display ${index + 1}`
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private repositionWindow () {
|
private repositionWindow () {
|
||||||
let [x, y] = this.hostApp.getWindow().getPosition()
|
const [x, y] = this.hostApp.getWindow().getPosition()
|
||||||
for (let screen of this.electron.screen.getAllDisplays()) {
|
for (const screen of this.electron.screen.getAllDisplays()) {
|
||||||
let bounds = screen.bounds
|
const bounds = screen.bounds
|
||||||
if (x >= bounds.x && x <= bounds.x + bounds.width && y >= bounds.y && y <= bounds.y + bounds.height) {
|
if (x >= bounds.x && x <= bounds.x + bounds.width && y >= bounds.y && y <= bounds.y + bounds.height) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let screen = this.electron.screen.getPrimaryDisplay()
|
const screen = this.electron.screen.getPrimaryDisplay()
|
||||||
this.hostApp.getWindow().setPosition(screen.bounds.x, screen.bounds.y)
|
this.hostApp.getWindow().setPosition(screen.bounds.x, screen.bounds.y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { TouchBar, BrowserWindow, Menu, MenuItem } from 'electron'
|
import { TouchBar, BrowserWindow, Menu, MenuItem, NativeImage } 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: any
|
app: Electron.App
|
||||||
ipcRenderer: any
|
ipcRenderer: Electron.IpcRenderer
|
||||||
shell: any
|
shell: Electron.Shell
|
||||||
dialog: any
|
dialog: Electron.Dialog
|
||||||
clipboard: any
|
clipboard: Electron.Clipboard
|
||||||
globalShortcut: any
|
globalShortcut: Electron.GlobalShortcut
|
||||||
nativeImage: any
|
nativeImage: typeof NativeImage
|
||||||
screen: any
|
screen: Electron.Screen
|
||||||
remote: any
|
remote: Electron.Remote
|
||||||
autoUpdater: any
|
autoUpdater: Electron.AutoUpdater
|
||||||
TouchBar: typeof TouchBar
|
TouchBar: typeof TouchBar
|
||||||
BrowserWindow: typeof BrowserWindow
|
BrowserWindow: typeof BrowserWindow
|
||||||
Menu: typeof Menu
|
Menu: typeof Menu
|
||||||
@@ -52,14 +52,10 @@ export class ElectronService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showMessageBox (
|
async showMessageBox (
|
||||||
browserWindow: Electron.BrowserWindow,
|
browserWindow: Electron.BrowserWindow,
|
||||||
options: Electron.MessageBoxOptions
|
options: Electron.MessageBoxOptions
|
||||||
): Promise<MessageBoxResponse> {
|
): Promise<MessageBoxResponse> {
|
||||||
return new Promise(resolve => {
|
return this.dialog.showMessageBox(browserWindow, options)
|
||||||
this.dialog.showMessageBox(browserWindow, options, (response, checkboxChecked) => {
|
|
||||||
resolve({ response, checkboxChecked })
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,12 +2,13 @@ import * as os from 'os'
|
|||||||
import { Injectable } from '@angular/core'
|
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 ua = require('universal-analytics')
|
import * as mixpanel from 'mixpanel'
|
||||||
import uuidv4 = require('uuid/v4')
|
import * as uuidv4 from 'uuid/v4'
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class HomeBaseService {
|
export class HomeBaseService {
|
||||||
appVersion: string
|
appVersion: string
|
||||||
|
mixpanel: any
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
constructor (
|
constructor (
|
||||||
@@ -28,12 +29,12 @@ export class HomeBaseService {
|
|||||||
reportBug () {
|
reportBug () {
|
||||||
let body = `Version: ${this.appVersion}\n`
|
let body = `Version: ${this.appVersion}\n`
|
||||||
body += `Platform: ${os.platform()} ${os.release()}\n`
|
body += `Platform: ${os.platform()} ${os.release()}\n`
|
||||||
let label = {
|
const label = {
|
||||||
darwin: 'OS: macOS',
|
darwin: 'OS: macOS',
|
||||||
windows: 'OS: Windows',
|
windows: 'OS: Windows',
|
||||||
linux: 'OS: Linux',
|
linux: 'OS: Linux',
|
||||||
}[os.platform()]
|
}[os.platform()]
|
||||||
let plugins = (window as any).installedPlugins.filter(x => !x.isBuiltin).map(x => x.name)
|
const plugins = (window as any).installedPlugins.filter(x => !x.isBuiltin).map(x => x.name)
|
||||||
body += `Plugins: ${plugins.join(', ') || 'none'}\n\n`
|
body += `Plugins: ${plugins.join(', ') || 'none'}\n\n`
|
||||||
this.electron.shell.openExternal(`https://github.com/eugeny/terminus/issues/new?body=${encodeURIComponent(body)}&labels=${label}`)
|
this.electron.shell.openExternal(`https://github.com/eugeny/terminus/issues/new?body=${encodeURIComponent(body)}&labels=${label}`)
|
||||||
}
|
}
|
||||||
@@ -42,9 +43,20 @@ export class HomeBaseService {
|
|||||||
if (!window.localStorage.analyticsUserID) {
|
if (!window.localStorage.analyticsUserID) {
|
||||||
window.localStorage.analyticsUserID = uuidv4()
|
window.localStorage.analyticsUserID = uuidv4()
|
||||||
}
|
}
|
||||||
const session = ua('UA-3278102-20', window.localStorage.analyticsUserID)
|
this.mixpanel = mixpanel.init('bb4638b0860eef14c04d4fbc5eb365fa')
|
||||||
session.set('cd1', this.appVersion)
|
if (!window.localStorage.installEventSent) {
|
||||||
session.set('cd2', process.platform)
|
this.mixpanel.track('freshInstall', this.getAnalyticsProperties())
|
||||||
session.pageview('/').send()
|
window.localStorage.installEventSent = true
|
||||||
|
}
|
||||||
|
this.mixpanel.track('launch', this.getAnalyticsProperties())
|
||||||
|
}
|
||||||
|
|
||||||
|
getAnalyticsProperties () {
|
||||||
|
return {
|
||||||
|
distinct_id: window.localStorage.analyticsUserID, // eslint-disable-line @typescript-eslint/camelcase
|
||||||
|
platform: process.platform,
|
||||||
|
os: os.release(),
|
||||||
|
version: this.appVersion,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
import shellEscape = require('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'
|
||||||
@@ -87,8 +87,7 @@ export class HostAppService {
|
|||||||
|
|
||||||
get displayMetricsChanged$ (): Observable<void> { return this.displayMetricsChanged }
|
get displayMetricsChanged$ (): Observable<void> { return this.displayMetricsChanged }
|
||||||
|
|
||||||
/** @hidden */
|
private constructor (
|
||||||
constructor (
|
|
||||||
private zone: NgZone,
|
private zone: NgZone,
|
||||||
private electron: ElectronService,
|
private electron: ElectronService,
|
||||||
log: LogService,
|
log: LogService,
|
||||||
@@ -97,7 +96,7 @@ export class HostAppService {
|
|||||||
this.platform = {
|
this.platform = {
|
||||||
win32: Platform.Windows,
|
win32: Platform.Windows,
|
||||||
darwin: Platform.macOS,
|
darwin: Platform.macOS,
|
||||||
linux: Platform.Linux
|
linux: Platform.Linux,
|
||||||
}[process.platform]
|
}[process.platform]
|
||||||
|
|
||||||
this.windowId = parseInt(location.search.substring(1))
|
this.windowId = parseInt(location.search.substring(1))
|
||||||
@@ -148,6 +147,8 @@ export class HostAppService {
|
|||||||
this.cliPaste.next(text)
|
this.cliPaste.next(text)
|
||||||
} else if (op === 'profile') {
|
} else if (op === 'profile') {
|
||||||
this.cliOpenProfile.next(argv.profileName)
|
this.cliOpenProfile.next(argv.profileName)
|
||||||
|
} else if (op === undefined) {
|
||||||
|
this.newWindow()
|
||||||
} else {
|
} else {
|
||||||
this.secondInstance.next()
|
this.secondInstance.next()
|
||||||
}
|
}
|
||||||
@@ -170,7 +171,7 @@ export class HostAppService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toggleFullscreen () {
|
toggleFullscreen () {
|
||||||
let window = this.getWindow()
|
const window = this.getWindow()
|
||||||
window.setFullScreen(!this.isFullScreen)
|
window.setFullScreen(!this.isFullScreen)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,7 +215,7 @@ export class HostAppService {
|
|||||||
setVibrancy (enable: boolean, type: string) {
|
setVibrancy (enable: boolean, type: string) {
|
||||||
document.body.classList.toggle('vibrant', enable)
|
document.body.classList.toggle('vibrant', enable)
|
||||||
if (this.platform === Platform.macOS) {
|
if (this.platform === Platform.macOS) {
|
||||||
this.getWindow().setVibrancy(enable ? 'dark' : null)
|
this.getWindow().setVibrancy(enable ? 'dark' : null as any) // electron issue 20269
|
||||||
}
|
}
|
||||||
if (this.platform === Platform.Windows) {
|
if (this.platform === Platform.Windows) {
|
||||||
this.electron.ipcRenderer.send('window-set-vibrancy', enable, type)
|
this.electron.ipcRenderer.send('window-set-vibrancy', enable, type)
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { Injectable, Inject, NgZone, EventEmitter } from '@angular/core'
|
import { Injectable, Inject, NgZone, EventEmitter } from '@angular/core'
|
||||||
import { IHotkeyDescription, HotkeyProvider } from '../api/hotkeyProvider'
|
import { HotkeyDescription, HotkeyProvider } from '../api/hotkeyProvider'
|
||||||
import { NativeKeyEvent, stringifyKeySequence } from './hotkeys.util'
|
import { stringifyKeySequence } from './hotkeys.util'
|
||||||
import { ConfigService } from '../services/config.service'
|
import { ConfigService } from '../services/config.service'
|
||||||
import { ElectronService } from '../services/electron.service'
|
import { ElectronService } from '../services/electron.service'
|
||||||
|
|
||||||
@@ -13,29 +13,28 @@ export interface PartialHotkeyMatch {
|
|||||||
const KEY_TIMEOUT = 2000
|
const KEY_TIMEOUT = 2000
|
||||||
|
|
||||||
interface EventBufferEntry {
|
interface EventBufferEntry {
|
||||||
event: NativeKeyEvent
|
event: KeyboardEvent
|
||||||
time: number
|
time: number
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class HotkeysService {
|
export class HotkeysService {
|
||||||
key = new EventEmitter<NativeKeyEvent>()
|
key = new EventEmitter<KeyboardEvent>()
|
||||||
matchedHotkey = new EventEmitter<string>()
|
matchedHotkey = new EventEmitter<string>()
|
||||||
globalHotkey = new EventEmitter()
|
globalHotkey = new EventEmitter<void>()
|
||||||
private currentKeystrokes: EventBufferEntry[] = []
|
private currentKeystrokes: EventBufferEntry[] = []
|
||||||
private disabledLevel = 0
|
private disabledLevel = 0
|
||||||
private hotkeyDescriptions: IHotkeyDescription[] = []
|
private hotkeyDescriptions: HotkeyDescription[] = []
|
||||||
|
|
||||||
/** @hidden */
|
private constructor (
|
||||||
constructor (
|
|
||||||
private zone: NgZone,
|
private zone: NgZone,
|
||||||
private electron: ElectronService,
|
private electron: ElectronService,
|
||||||
private config: ConfigService,
|
private config: ConfigService,
|
||||||
@Inject(HotkeyProvider) private hotkeyProviders: HotkeyProvider[],
|
@Inject(HotkeyProvider) private hotkeyProviders: HotkeyProvider[],
|
||||||
) {
|
) {
|
||||||
let events = ['keydown', 'keyup']
|
const events = ['keydown', 'keyup']
|
||||||
events.forEach((event) => {
|
events.forEach(event => {
|
||||||
document.addEventListener(event, (nativeEvent) => {
|
document.addEventListener(event, (nativeEvent: KeyboardEvent) => {
|
||||||
if (document.querySelectorAll('input:focus').length === 0) {
|
if (document.querySelectorAll('input:focus').length === 0) {
|
||||||
this.pushKeystroke(event, nativeEvent)
|
this.pushKeystroke(event, nativeEvent)
|
||||||
this.processKeystrokes()
|
this.processKeystrokes()
|
||||||
@@ -58,8 +57,8 @@ export class HotkeysService {
|
|||||||
* @param name DOM event name
|
* @param name DOM event name
|
||||||
* @param nativeEvent event object
|
* @param nativeEvent event object
|
||||||
*/
|
*/
|
||||||
pushKeystroke (name, nativeEvent) {
|
pushKeystroke (name: string, nativeEvent: KeyboardEvent) {
|
||||||
nativeEvent.event = name
|
(nativeEvent as any).event = name
|
||||||
this.currentKeystrokes.push({ event: nativeEvent, time: performance.now() })
|
this.currentKeystrokes.push({ event: nativeEvent, time: performance.now() })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,7 +68,7 @@ export class HotkeysService {
|
|||||||
processKeystrokes () {
|
processKeystrokes () {
|
||||||
if (this.isEnabled()) {
|
if (this.isEnabled()) {
|
||||||
this.zone.run(() => {
|
this.zone.run(() => {
|
||||||
let matched = this.getCurrentFullyMatchedHotkey()
|
const matched = this.getCurrentFullyMatchedHotkey()
|
||||||
if (matched) {
|
if (matched) {
|
||||||
console.log('Matched hotkey', matched)
|
console.log('Matched hotkey', matched)
|
||||||
this.matchedHotkey.emit(matched)
|
this.matchedHotkey.emit(matched)
|
||||||
@@ -79,7 +78,7 @@ export class HotkeysService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emitKeyEvent (nativeEvent) {
|
emitKeyEvent (nativeEvent: KeyboardEvent) {
|
||||||
this.zone.run(() => {
|
this.zone.run(() => {
|
||||||
this.key.emit(nativeEvent)
|
this.key.emit(nativeEvent)
|
||||||
})
|
})
|
||||||
@@ -94,61 +93,16 @@ export class HotkeysService {
|
|||||||
return stringifyKeySequence(this.currentKeystrokes.map(x => x.event))
|
return stringifyKeySequence(this.currentKeystrokes.map(x => x.event))
|
||||||
}
|
}
|
||||||
|
|
||||||
private registerGlobalHotkey () {
|
getCurrentFullyMatchedHotkey (): string|null {
|
||||||
this.electron.globalShortcut.unregisterAll()
|
const currentStrokes = this.getCurrentKeystrokes()
|
||||||
let value = this.config.store.hotkeys['toggle-window'] || []
|
const config = this.getHotkeysConfig()
|
||||||
if (typeof value === 'string') {
|
for (const id in config) {
|
||||||
value = [value]
|
for (const sequence of config[id]) {
|
||||||
}
|
|
||||||
value.forEach(item => {
|
|
||||||
item = (typeof item === 'string') ? [item] : item
|
|
||||||
|
|
||||||
try {
|
|
||||||
this.electron.globalShortcut.register(item[0].replace(/-/g, '+'), () => {
|
|
||||||
this.globalHotkey.emit()
|
|
||||||
})
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Could not register the global hotkey:', err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private getHotkeysConfig () {
|
|
||||||
return this.getHotkeysConfigRecursive(this.config.store.hotkeys)
|
|
||||||
}
|
|
||||||
|
|
||||||
private getHotkeysConfigRecursive (branch) {
|
|
||||||
let keys = {}
|
|
||||||
for (let key in branch) {
|
|
||||||
let value = branch[key]
|
|
||||||
if (value instanceof Object && !(value instanceof Array)) {
|
|
||||||
let subkeys = this.getHotkeysConfigRecursive(value)
|
|
||||||
for (let subkey in subkeys) {
|
|
||||||
keys[key + '.' + subkey] = subkeys[subkey]
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (typeof value === 'string') {
|
|
||||||
value = [value]
|
|
||||||
}
|
|
||||||
if (value) {
|
|
||||||
value = value.map((item) => (typeof item === 'string') ? [item] : item)
|
|
||||||
keys[key] = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return keys
|
|
||||||
}
|
|
||||||
|
|
||||||
private getCurrentFullyMatchedHotkey (): string {
|
|
||||||
let currentStrokes = this.getCurrentKeystrokes()
|
|
||||||
let config = this.getHotkeysConfig()
|
|
||||||
for (let id in config) {
|
|
||||||
for (let sequence of config[id]) {
|
|
||||||
if (currentStrokes.length < sequence.length) {
|
if (currentStrokes.length < sequence.length) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (sequence.every(
|
if (sequence.every(
|
||||||
(x, index) =>
|
(x: string, index: number) =>
|
||||||
x.toLowerCase() ===
|
x.toLowerCase() ===
|
||||||
currentStrokes[currentStrokes.length - sequence.length + index].toLowerCase()
|
currentStrokes[currentStrokes.length - sequence.length + index].toLowerCase()
|
||||||
)) {
|
)) {
|
||||||
@@ -160,21 +114,21 @@ export class HotkeysService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getCurrentPartiallyMatchedHotkeys (): PartialHotkeyMatch[] {
|
getCurrentPartiallyMatchedHotkeys (): PartialHotkeyMatch[] {
|
||||||
let currentStrokes = this.getCurrentKeystrokes()
|
const currentStrokes = this.getCurrentKeystrokes()
|
||||||
let config = this.getHotkeysConfig()
|
const config = this.getHotkeysConfig()
|
||||||
let result = []
|
const result: PartialHotkeyMatch[] = []
|
||||||
for (let id in config) {
|
for (const id in config) {
|
||||||
for (let sequence of config[id]) {
|
for (const sequence of config[id]) {
|
||||||
for (let matchLength = Math.min(currentStrokes.length, sequence.length); matchLength > 0; matchLength--) {
|
for (let matchLength = Math.min(currentStrokes.length, sequence.length); matchLength > 0; matchLength--) {
|
||||||
if (sequence.slice(0, matchLength).every(
|
if (sequence.slice(0, matchLength).every(
|
||||||
(x, index) =>
|
(x: string, index: number) =>
|
||||||
x.toLowerCase() ===
|
x.toLowerCase() ===
|
||||||
currentStrokes[currentStrokes.length - matchLength + index].toLowerCase()
|
currentStrokes[currentStrokes.length - matchLength + index].toLowerCase()
|
||||||
)) {
|
)) {
|
||||||
result.push({
|
result.push({
|
||||||
matchedLength: matchLength,
|
matchedLength: matchLength,
|
||||||
id,
|
id,
|
||||||
strokes: sequence
|
strokes: sequence,
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -184,7 +138,7 @@ export class HotkeysService {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
getHotkeyDescription (id: string): IHotkeyDescription {
|
getHotkeyDescription (id: string): HotkeyDescription {
|
||||||
return this.hotkeyDescriptions.filter((x) => x.id === id)[0]
|
return this.hotkeyDescriptions.filter((x) => x.id === id)[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,7 +154,7 @@ export class HotkeysService {
|
|||||||
return this.disabledLevel === 0
|
return this.disabledLevel === 0
|
||||||
}
|
}
|
||||||
|
|
||||||
async getHotkeyDescriptions (): Promise<IHotkeyDescription[]> {
|
async getHotkeyDescriptions (): Promise<HotkeyDescription[]> {
|
||||||
return (
|
return (
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
this.config.enabledServices(this.hotkeyProviders)
|
this.config.enabledServices(this.hotkeyProviders)
|
||||||
@@ -208,4 +162,53 @@ export class HotkeysService {
|
|||||||
)
|
)
|
||||||
).reduce((a, b) => a.concat(b))
|
).reduce((a, b) => a.concat(b))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private registerGlobalHotkey () {
|
||||||
|
this.electron.globalShortcut.unregisterAll()
|
||||||
|
let value = this.config.store.hotkeys['toggle-window'] || []
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
value = [value]
|
||||||
|
}
|
||||||
|
value.forEach((item: string | string[]) => {
|
||||||
|
item = typeof item === 'string' ? [item] : item
|
||||||
|
|
||||||
|
try {
|
||||||
|
let electronKeySpec = item[0]
|
||||||
|
electronKeySpec = electronKeySpec.replace('⌘', 'Command')
|
||||||
|
electronKeySpec = electronKeySpec.replace('⌥', 'Alt')
|
||||||
|
electronKeySpec = electronKeySpec.replace(/-/g, '+')
|
||||||
|
this.electron.globalShortcut.register(electronKeySpec, () => {
|
||||||
|
this.globalHotkey.emit()
|
||||||
|
})
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Could not register the global hotkey:', err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private getHotkeysConfig () {
|
||||||
|
return this.getHotkeysConfigRecursive(this.config.store.hotkeys)
|
||||||
|
}
|
||||||
|
|
||||||
|
private getHotkeysConfigRecursive (branch: any) {
|
||||||
|
const keys = {}
|
||||||
|
for (const key in branch) {
|
||||||
|
let value = branch[key]
|
||||||
|
if (value instanceof Object && !(value instanceof Array)) {
|
||||||
|
const subkeys = this.getHotkeysConfigRecursive(value)
|
||||||
|
for (const subkey in subkeys) {
|
||||||
|
keys[key + '.' + subkey] = subkeys[subkey]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
value = [value]
|
||||||
|
}
|
||||||
|
if (value) {
|
||||||
|
value = value.map((item: string | string[]) => typeof item === 'string' ? [item] : item)
|
||||||
|
keys[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return keys
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -10,24 +10,14 @@ export const altKeyName = {
|
|||||||
linux: 'Alt',
|
linux: 'Alt',
|
||||||
}[process.platform]
|
}[process.platform]
|
||||||
|
|
||||||
export interface NativeKeyEvent {
|
export function stringifyKeySequence (events: KeyboardEvent[]): string[] {
|
||||||
event?: string
|
const items: string[] = []
|
||||||
altKey: boolean
|
|
||||||
ctrlKey: boolean
|
|
||||||
metaKey: boolean
|
|
||||||
shiftKey: boolean
|
|
||||||
key: string
|
|
||||||
keyCode: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export function stringifyKeySequence (events: NativeKeyEvent[]): string[] {
|
|
||||||
let items: string[] = []
|
|
||||||
events = events.slice()
|
events = events.slice()
|
||||||
|
|
||||||
while (events.length > 0) {
|
while (events.length > 0) {
|
||||||
let event = events.shift()
|
const event = events.shift()!
|
||||||
if (event.event === 'keydown') {
|
if ((event as any).event === 'keydown') {
|
||||||
let itemKeys: string[] = []
|
const itemKeys: string[] = []
|
||||||
if (event.ctrlKey) {
|
if (event.ctrlKey) {
|
||||||
itemKeys.push('Ctrl')
|
itemKeys.push('Ctrl')
|
||||||
}
|
}
|
||||||
@@ -45,13 +35,26 @@ export function stringifyKeySequence (events: NativeKeyEvent[]): string[] {
|
|||||||
// TODO make this optional?
|
// TODO make this optional?
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (event.key === ' ') {
|
|
||||||
itemKeys.push('Space')
|
let key = event.code
|
||||||
} else if (event.key.length === 1) {
|
key = key.replace('Key', '')
|
||||||
itemKeys.push(event.key.toUpperCase())
|
key = key.replace('Arrow', '')
|
||||||
} else {
|
key = key.replace('Digit', '')
|
||||||
itemKeys.push(event.key)
|
key = {
|
||||||
}
|
Comma: ',',
|
||||||
|
Period: '.',
|
||||||
|
Slash: '/',
|
||||||
|
Backslash: '\\',
|
||||||
|
IntlBackslash: '\\',
|
||||||
|
Backquote: '`',
|
||||||
|
Minus: '-',
|
||||||
|
Equal: '=',
|
||||||
|
Semicolon: ';',
|
||||||
|
Quote: '\'',
|
||||||
|
BracketLeft: '[',
|
||||||
|
BracketRight: ']',
|
||||||
|
}[key] || key
|
||||||
|
itemKeys.push(key)
|
||||||
items.push(itemKeys.join('-'))
|
items.push(itemKeys.join('-'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -21,13 +21,8 @@ const initializeWinston = (electron: ElectronService) => {
|
|||||||
maxsize: 5242880,
|
maxsize: 5242880,
|
||||||
maxFiles: 5,
|
maxFiles: 5,
|
||||||
}),
|
}),
|
||||||
new winston.transports.Console({
|
|
||||||
level: 'debug',
|
|
||||||
handleExceptions: false,
|
|
||||||
format: winston.format.colorize(),
|
|
||||||
})
|
|
||||||
],
|
],
|
||||||
exitOnError: false
|
exitOnError: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,18 +32,32 @@ export class Logger {
|
|||||||
private name: string,
|
private name: string,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
debug (...args: any[]) {
|
||||||
|
this.doLog('debug', ...args)
|
||||||
|
}
|
||||||
|
|
||||||
|
info (...args: any[]) {
|
||||||
|
this.doLog('info', ...args)
|
||||||
|
}
|
||||||
|
|
||||||
|
warn (...args: any[]) {
|
||||||
|
this.doLog('warn', ...args)
|
||||||
|
}
|
||||||
|
|
||||||
|
error (...args: any[]) {
|
||||||
|
this.doLog('error', ...args)
|
||||||
|
}
|
||||||
|
|
||||||
|
log (...args: any[]) {
|
||||||
|
this.doLog('log', ...args)
|
||||||
|
}
|
||||||
|
|
||||||
private doLog (level: string, ...args: any[]) {
|
private doLog (level: string, ...args: any[]) {
|
||||||
console[level](`%c[${this.name}]`, 'color: #aaa', ...args)
|
console[level](`%c[${this.name}]`, 'color: #aaa', ...args)
|
||||||
if (this.winstonLogger) {
|
if (this.winstonLogger) {
|
||||||
this.winstonLogger[level](...args)
|
this.winstonLogger[level](...args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debug (...args: any[]) { this.doLog('debug', ...args) }
|
|
||||||
info (...args: any[]) { this.doLog('info', ...args) }
|
|
||||||
warn (...args: any[]) { this.doLog('warn', ...args) }
|
|
||||||
error (...args: any[]) { this.doLog('error', ...args) }
|
|
||||||
log (...args: any[]) { this.doLog('log', ...args) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
|
@@ -5,9 +5,11 @@ import { Injectable } from '@angular/core'
|
|||||||
import { ElectronService } from './electron.service'
|
import { ElectronService } from './electron.service'
|
||||||
import { HostAppService, Platform } from './hostApp.service'
|
import { HostAppService, Platform } from './hostApp.service'
|
||||||
|
|
||||||
|
/* eslint-disable block-scoped-var */
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var wnr = require('windows-native-registry') // tslint:disable-line
|
var wnr = require('windows-native-registry') // eslint-disable-line @typescript-eslint/no-var-requires
|
||||||
} catch (_) { } // tslint:disable-line
|
} catch (_) { }
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class ShellIntegrationService {
|
export class ShellIntegrationService {
|
||||||
@@ -17,11 +19,11 @@ export class ShellIntegrationService {
|
|||||||
private registryKeys = [
|
private registryKeys = [
|
||||||
{
|
{
|
||||||
path: 'Software\\Classes\\Directory\\Background\\shell\\Open Terminus here',
|
path: 'Software\\Classes\\Directory\\Background\\shell\\Open Terminus here',
|
||||||
command: 'open "%V"'
|
command: 'open "%V"',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'Software\\Classes\\*\\shell\\Paste path into Terminus',
|
path: 'Software\\Classes\\*\\shell\\Paste path into Terminus',
|
||||||
command: 'paste "%V"'
|
command: 'paste "%V"',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
constructor (
|
constructor (
|
||||||
@@ -35,20 +37,11 @@ export class ShellIntegrationService {
|
|||||||
'extras',
|
'extras',
|
||||||
'automator-workflows',
|
'automator-workflows',
|
||||||
)
|
)
|
||||||
this.automatorWorkflowsDestination = path.join(process.env.HOME, 'Library', 'Services')
|
this.automatorWorkflowsDestination = path.join(process.env.HOME as string, 'Library', 'Services')
|
||||||
}
|
}
|
||||||
this.updatePaths()
|
this.updatePaths()
|
||||||
}
|
}
|
||||||
|
|
||||||
private async updatePaths (): Promise<void> {
|
|
||||||
// Update paths in case of an update
|
|
||||||
if (this.hostApp.platform === Platform.Windows) {
|
|
||||||
if (await this.isInstalled()) {
|
|
||||||
await this.install()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async isInstalled (): Promise<boolean> {
|
async isInstalled (): Promise<boolean> {
|
||||||
if (this.hostApp.platform === Platform.macOS) {
|
if (this.hostApp.platform === Platform.macOS) {
|
||||||
return fs.exists(path.join(this.automatorWorkflowsDestination, this.automatorWorkflows[0]))
|
return fs.exists(path.join(this.automatorWorkflowsDestination, this.automatorWorkflows[0]))
|
||||||
@@ -59,13 +52,13 @@ export class ShellIntegrationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async install () {
|
async install () {
|
||||||
const exe = 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 (let 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}"`)
|
||||||
}
|
}
|
||||||
} else if (this.hostApp.platform === Platform.Windows) {
|
} else if (this.hostApp.platform === Platform.Windows) {
|
||||||
for (let registryKey of this.registryKeys) {
|
for (const registryKey of this.registryKeys) {
|
||||||
wnr.createRegistryKey(wnr.HK.CU, registryKey.path)
|
wnr.createRegistryKey(wnr.HK.CU, registryKey.path)
|
||||||
wnr.createRegistryKey(wnr.HK.CU, registryKey.path + '\\command')
|
wnr.createRegistryKey(wnr.HK.CU, registryKey.path + '\\command')
|
||||||
wnr.setRegistryValue(wnr.HK.CU, registryKey.path, 'Icon', wnr.REG.SZ, exe)
|
wnr.setRegistryValue(wnr.HK.CU, registryKey.path, 'Icon', wnr.REG.SZ, exe)
|
||||||
@@ -76,13 +69,22 @@ export class ShellIntegrationService {
|
|||||||
|
|
||||||
async remove () {
|
async remove () {
|
||||||
if (this.hostApp.platform === Platform.macOS) {
|
if (this.hostApp.platform === Platform.macOS) {
|
||||||
for (let wf of this.automatorWorkflows) {
|
for (const wf of this.automatorWorkflows) {
|
||||||
await exec(`rm -rf "${this.automatorWorkflowsDestination}/${wf}"`)
|
await exec(`rm -rf "${this.automatorWorkflowsDestination}/${wf}"`)
|
||||||
}
|
}
|
||||||
} else if (this.hostApp.platform === Platform.Windows) {
|
} else if (this.hostApp.platform === Platform.Windows) {
|
||||||
for (let registryKey of this.registryKeys) {
|
for (const registryKey of this.registryKeys) {
|
||||||
wnr.deleteRegistryKey(wnr.HK.CU, registryKey.path)
|
wnr.deleteRegistryKey(wnr.HK.CU, registryKey.path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async updatePaths (): Promise<void> {
|
||||||
|
// Update paths in case of an update
|
||||||
|
if (this.hostApp.platform === Platform.Windows) {
|
||||||
|
if (await this.isInstalled()) {
|
||||||
|
await this.install()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -27,10 +27,10 @@ export class TabRecoveryService {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async recoverTab (token: any): Promise<RecoveredTab> {
|
async recoverTab (token: any): Promise<RecoveredTab|null> {
|
||||||
for (let provider of this.config.enabledServices(this.tabRecoveryProviders)) {
|
for (const provider of this.config.enabledServices(this.tabRecoveryProviders)) {
|
||||||
try {
|
try {
|
||||||
let tab = await provider.recover(token)
|
const tab = await provider.recover(token)
|
||||||
if (tab) {
|
if (tab) {
|
||||||
return tab
|
return tab
|
||||||
}
|
}
|
||||||
@@ -43,9 +43,9 @@ export class TabRecoveryService {
|
|||||||
|
|
||||||
async recoverTabs (): Promise<RecoveredTab[]> {
|
async recoverTabs (): Promise<RecoveredTab[]> {
|
||||||
if (window.localStorage.tabsRecovery) {
|
if (window.localStorage.tabsRecovery) {
|
||||||
let tabs: RecoveredTab[] = []
|
const tabs: RecoveredTab[] = []
|
||||||
for (let token of JSON.parse(window.localStorage.tabsRecovery)) {
|
for (const token of JSON.parse(window.localStorage.tabsRecovery)) {
|
||||||
let tab = await this.recoverTab(token)
|
const tab = await this.recoverTab(token)
|
||||||
if (tab) {
|
if (tab) {
|
||||||
tabs.push(tab)
|
tabs.push(tab)
|
||||||
}
|
}
|
||||||
@@ -54,5 +54,4 @@ export class TabRecoveryService {
|
|||||||
}
|
}
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,8 @@ import { Injectable, ComponentFactoryResolver, Injector } from '@angular/core'
|
|||||||
import { BaseTabComponent } from '../components/baseTab.component'
|
import { BaseTabComponent } from '../components/baseTab.component'
|
||||||
import { TabRecoveryService } from './tabRecovery.service'
|
import { TabRecoveryService } from './tabRecovery.service'
|
||||||
|
|
||||||
export declare type TabComponentType = new (...args: any[]) => BaseTabComponent
|
// eslint-disable-next-line @typescript-eslint/no-type-alias
|
||||||
|
export type TabComponentType = new (...args: any[]) => BaseTabComponent
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class TabsService {
|
export class TabsService {
|
||||||
@@ -17,9 +18,9 @@ export class TabsService {
|
|||||||
* Instantiates a tab component and assigns given inputs
|
* Instantiates a tab component and assigns given inputs
|
||||||
*/
|
*/
|
||||||
create (type: TabComponentType, inputs?: any): BaseTabComponent {
|
create (type: TabComponentType, inputs?: any): BaseTabComponent {
|
||||||
let componentFactory = this.componentFactoryResolver.resolveComponentFactory(type)
|
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(type)
|
||||||
let componentRef = componentFactory.create(this.injector)
|
const componentRef = componentFactory.create(this.injector)
|
||||||
let 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
|
||||||
@@ -28,12 +29,12 @@ export class TabsService {
|
|||||||
/**
|
/**
|
||||||
* Duplicates an existing tab instance (using the tab recovery system)
|
* Duplicates an existing tab instance (using the tab recovery system)
|
||||||
*/
|
*/
|
||||||
async duplicate (tab: BaseTabComponent): Promise<BaseTabComponent> {
|
async duplicate (tab: BaseTabComponent): Promise<BaseTabComponent|null> {
|
||||||
let token = await tab.getRecoveryToken()
|
const token = await tab.getRecoveryToken()
|
||||||
if (!token) {
|
if (!token) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
let dup = await this.tabRecovery.recoverTab(token)
|
const dup = await this.tabRecovery.recoverTab(token)
|
||||||
if (dup) {
|
if (dup) {
|
||||||
return this.create(dup.type, dup.options)
|
return this.create(dup.type, dup.options)
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,7 @@ import { Theme } from '../api/theme'
|
|||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class ThemesService {
|
export class ThemesService {
|
||||||
private styleElement: HTMLElement = null
|
private styleElement: HTMLElement|null = null
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
constructor (
|
constructor (
|
||||||
@@ -17,22 +17,22 @@ export class ThemesService {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
findTheme (name: string): Theme {
|
findTheme (name: string): Theme|null {
|
||||||
return this.config.enabledServices(this.themes).find(x => x.name === name)
|
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 {
|
||||||
if (!this.styleElement) {
|
if (!this.styleElement) {
|
||||||
this.styleElement = document.createElement('style')
|
this.styleElement = document.createElement('style')
|
||||||
this.styleElement.setAttribute('id', 'theme')
|
this.styleElement.setAttribute('id', 'theme')
|
||||||
document.querySelector('head').appendChild(this.styleElement)
|
document.querySelector('head')!.appendChild(this.styleElement)
|
||||||
}
|
}
|
||||||
this.styleElement.textContent = theme.css
|
this.styleElement.textContent = theme.css
|
||||||
document.querySelector('style#custom-css').innerHTML = this.config.store.appearance.css
|
document.querySelector('style#custom-css')!.innerHTML = this.config.store.appearance.css
|
||||||
}
|
}
|
||||||
|
|
||||||
private applyCurrentTheme (): void {
|
private applyCurrentTheme (): void {
|
||||||
|
@@ -4,7 +4,7 @@ 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'
|
||||||
import { HostAppService, Platform } from './hostApp.service'
|
import { HostAppService, Platform } from './hostApp.service'
|
||||||
import { IToolbarButton, ToolbarButtonProvider } from '../api'
|
import { ToolbarButton, ToolbarButtonProvider } from '../api'
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
@@ -28,21 +28,21 @@ export class TouchbarService {
|
|||||||
app.tabsChanged$.subscribe(() => this.updateTabs())
|
app.tabsChanged$.subscribe(() => this.updateTabs())
|
||||||
app.activeTabChange$.subscribe(() => this.updateTabs())
|
app.activeTabChange$.subscribe(() => this.updateTabs())
|
||||||
|
|
||||||
let activityIconPath = `${electron.app.getAppPath()}/assets/activity.png`
|
const activityIconPath = `${electron.app.getAppPath()}/assets/activity.png`
|
||||||
let activityIcon = this.electron.nativeImage.createFromPath(activityIconPath)
|
const activityIcon = this.electron.nativeImage.createFromPath(activityIconPath)
|
||||||
app.tabOpened$.subscribe(tab => {
|
app.tabOpened$.subscribe(tab => {
|
||||||
tab.titleChange$.subscribe(title => {
|
tab.titleChange$.subscribe(title => {
|
||||||
let segment = this.tabSegments[app.tabs.indexOf(tab)]
|
const segment = this.tabSegments[app.tabs.indexOf(tab)]
|
||||||
if (segment) {
|
if (segment) {
|
||||||
segment.label = this.shortenTitle(title)
|
segment.label = this.shortenTitle(title)
|
||||||
this.tabsSegmentedControl.segments = this.tabSegments
|
this.tabsSegmentedControl.segments = this.tabSegments
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
tab.activity$.subscribe(hasActivity => {
|
tab.activity$.subscribe(hasActivity => {
|
||||||
let showIcon = this.app.activeTab !== tab && hasActivity
|
const showIcon = this.app.activeTab !== tab && hasActivity
|
||||||
let segment = this.tabSegments[app.tabs.indexOf(tab)]
|
const segment = this.tabSegments[app.tabs.indexOf(tab)]
|
||||||
if (segment) {
|
if (segment) {
|
||||||
segment.icon = showIcon ? activityIcon : null
|
segment.icon = showIcon ? activityIcon : undefined
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -61,7 +61,7 @@ export class TouchbarService {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let buttons: IToolbarButton[] = []
|
let buttons: ToolbarButton[] = []
|
||||||
this.config.enabledServices(this.toolbarButtonProviders).forEach(provider => {
|
this.config.enabledServices(this.toolbarButtonProviders).forEach(provider => {
|
||||||
buttons = buttons.concat(provider.provide())
|
buttons = buttons.concat(provider.provide())
|
||||||
})
|
})
|
||||||
@@ -76,32 +76,34 @@ export class TouchbarService {
|
|||||||
selectedIndex: this.app.tabs.indexOf(this.app.activeTab),
|
selectedIndex: this.app.tabs.indexOf(this.app.activeTab),
|
||||||
change: (selectedIndex) => this.zone.run(() => {
|
change: (selectedIndex) => this.zone.run(() => {
|
||||||
this.app.selectTab(this.app.tabs[selectedIndex])
|
this.app.selectTab(this.app.tabs[selectedIndex])
|
||||||
})
|
}),
|
||||||
})
|
})
|
||||||
|
|
||||||
this.buttonsSegmentedControl = new this.electron.TouchBar.TouchBarSegmentedControl({
|
this.buttonsSegmentedControl = new this.electron.TouchBar.TouchBarSegmentedControl({
|
||||||
segments: buttons.map(button => this.getButton(button)),
|
segments: buttons.map(button => this.getButton(button)),
|
||||||
mode: 'buttons',
|
mode: 'buttons',
|
||||||
change: (selectedIndex) => this.zone.run(() => {
|
change: (selectedIndex) => this.zone.run(() => {
|
||||||
buttons[selectedIndex].click()
|
if (buttons[selectedIndex].click) {
|
||||||
})
|
buttons[selectedIndex].click!()
|
||||||
|
}
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
|
|
||||||
let touchBar = new this.electron.TouchBar({
|
const touchBar = new this.electron.TouchBar({
|
||||||
items: [
|
items: [
|
||||||
this.tabsSegmentedControl,
|
this.tabsSegmentedControl,
|
||||||
new this.electron.TouchBar.TouchBarSpacer({ size: 'flexible' }),
|
new this.electron.TouchBar.TouchBarSpacer({ size: 'flexible' }),
|
||||||
new this.electron.TouchBar.TouchBarSpacer({ size: 'small' }),
|
new this.electron.TouchBar.TouchBarSpacer({ size: 'small' }),
|
||||||
this.buttonsSegmentedControl,
|
this.buttonsSegmentedControl,
|
||||||
]
|
],
|
||||||
})
|
})
|
||||||
this.hostApp.setTouchBar(touchBar)
|
this.hostApp.setTouchBar(touchBar)
|
||||||
}
|
}
|
||||||
|
|
||||||
private getButton (button: IToolbarButton): Electron.SegmentedControlSegment {
|
private getButton (button: ToolbarButton): Electron.SegmentedControlSegment {
|
||||||
return {
|
return {
|
||||||
label: button.touchBarNSImage ? null : this.shortenTitle(button.touchBarTitle || button.title),
|
label: button.touchBarNSImage ? undefined : this.shortenTitle(button.touchBarTitle || button.title),
|
||||||
icon: button.touchBarNSImage ? this.getCachedNSImage(button.touchBarNSImage) : null,
|
icon: button.touchBarNSImage ? this.getCachedNSImage(button.touchBarNSImage) : undefined,
|
||||||
// click: () => this.zone.run(() => button.click()),
|
// click: () => this.zone.run(() => button.click()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,8 +1,13 @@
|
|||||||
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'
|
||||||
|
|
||||||
const UPDATES_URL = 'https://api.github.com/repos/eugeny/terminus/releases/latest'
|
const UPDATES_URL = 'https://api.github.com/repos/eugeny/terminus/releases/latest'
|
||||||
|
|
||||||
@@ -18,11 +23,14 @@ export class UpdaterService {
|
|||||||
constructor (
|
constructor (
|
||||||
log: LogService,
|
log: LogService,
|
||||||
private electron: ElectronService,
|
private electron: ElectronService,
|
||||||
|
config: ConfigService,
|
||||||
) {
|
) {
|
||||||
this.logger = log.create('updater')
|
this.logger = log.create('updater')
|
||||||
|
|
||||||
this.autoUpdater = electron.remote.require('electron-updater').autoUpdater
|
this.autoUpdater = electron.remote.require('electron-updater').autoUpdater
|
||||||
|
|
||||||
|
this.autoUpdater.autoInstallOnAppQuit = !!config.store.enableAutomaticUpdates
|
||||||
|
|
||||||
this.autoUpdater.on('update-available', () => {
|
this.autoUpdater.on('update-available', () => {
|
||||||
this.logger.info('Update available')
|
this.logger.info('Update available')
|
||||||
})
|
})
|
||||||
@@ -36,7 +44,7 @@ export class UpdaterService {
|
|||||||
|
|
||||||
this.logger.debug('Checking for updates')
|
this.logger.debug('Checking for updates')
|
||||||
|
|
||||||
if (this.electronUpdaterAvailable) {
|
if (this.electronUpdaterAvailable && !process.env.TERMINUS_DEV) {
|
||||||
try {
|
try {
|
||||||
this.autoUpdater.checkForUpdates()
|
this.autoUpdater.checkForUpdates()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -48,10 +56,10 @@ export class UpdaterService {
|
|||||||
|
|
||||||
async check (): Promise<boolean> {
|
async check (): Promise<boolean> {
|
||||||
if (!this.electronUpdaterAvailable) {
|
if (!this.electronUpdaterAvailable) {
|
||||||
this.logger.debug('Checking for updates')
|
this.logger.debug('Checking for updates through fallback method.')
|
||||||
let response = await axios.get(UPDATES_URL)
|
const response = await axios.get(UPDATES_URL)
|
||||||
let data = response.data
|
const data = response.data
|
||||||
let version = data.tag_name.substring(1)
|
const version = data.tag_name.substring(1)
|
||||||
if (this.electron.app.getVersion() !== version) {
|
if (this.electron.app.getVersion() !== version) {
|
||||||
this.logger.info('Update available')
|
this.logger.info('Update available')
|
||||||
this.updateURL = data.html_url
|
this.updateURL = data.html_url
|
||||||
@@ -67,8 +75,21 @@ export class UpdaterService {
|
|||||||
if (!this.electronUpdaterAvailable) {
|
if (!this.electronUpdaterAvailable) {
|
||||||
this.electron.shell.openExternal(this.updateURL)
|
this.electron.shell.openExternal(this.updateURL)
|
||||||
} else {
|
} else {
|
||||||
await this.downloaded
|
if (process.platform === 'win32') {
|
||||||
this.autoUpdater.quitAndInstall()
|
let downloadpath = await this.autoUpdater.downloadUpdate()
|
||||||
|
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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -22,31 +22,31 @@ export class CloseContextMenu extends TabContextMenuItemProvider {
|
|||||||
label: 'Close',
|
label: 'Close',
|
||||||
click: () => this.zone.run(() => {
|
click: () => this.zone.run(() => {
|
||||||
this.app.closeTab(tab, true)
|
this.app.closeTab(tab, true)
|
||||||
})
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Close other tabs',
|
label: 'Close other tabs',
|
||||||
click: () => this.zone.run(() => {
|
click: () => this.zone.run(() => {
|
||||||
for (let t of this.app.tabs.filter(x => x !== tab)) {
|
for (const t of this.app.tabs.filter(x => x !== tab)) {
|
||||||
this.app.closeTab(t, true)
|
this.app.closeTab(t, true)
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Close tabs to the right',
|
label: 'Close tabs to the right',
|
||||||
click: () => this.zone.run(() => {
|
click: () => this.zone.run(() => {
|
||||||
for (let t of this.app.tabs.slice(this.app.tabs.indexOf(tab) + 1)) {
|
for (const t of this.app.tabs.slice(this.app.tabs.indexOf(tab) + 1)) {
|
||||||
this.app.closeTab(t, true)
|
this.app.closeTab(t, true)
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Close tabs to the left',
|
label: 'Close tabs to the left',
|
||||||
click: () => this.zone.run(() => {
|
click: () => this.zone.run(() => {
|
||||||
for (let t of this.app.tabs.slice(0, this.app.tabs.indexOf(tab))) {
|
for (const t of this.app.tabs.slice(0, this.app.tabs.indexOf(tab))) {
|
||||||
this.app.closeTab(t, true)
|
this.app.closeTab(t, true)
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -78,15 +78,15 @@ export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
label: 'Rename',
|
label: 'Rename',
|
||||||
click: () => this.zone.run(() => tabHeader.showRenameTabModal())
|
click: () => this.zone.run(() => tabHeader && tabHeader.showRenameTabModal()),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Duplicate',
|
label: 'Duplicate',
|
||||||
click: () => this.zone.run(() => this.app.duplicateTab(tab))
|
click: () => this.zone.run(() => this.app.duplicateTab(tab)),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
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',
|
||||||
@@ -95,7 +95,7 @@ export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
|
|||||||
tab.color = color.value
|
tab.color = color.value
|
||||||
}),
|
}),
|
||||||
})) as Electron.MenuItemConstructorOptions[],
|
})) as Electron.MenuItemConstructorOptions[],
|
||||||
}
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,7 +111,7 @@ export class TaskCompletionContextMenu extends TabContextMenuItemProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getItems (tab: BaseTabComponent): Promise<Electron.MenuItemConstructorOptions[]> {
|
async getItems (tab: BaseTabComponent): Promise<Electron.MenuItemConstructorOptions[]> {
|
||||||
let process = await tab.getCurrentProcess()
|
const process = await tab.getCurrentProcess()
|
||||||
if (process) {
|
if (process) {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@@ -138,7 +138,7 @@ export class TaskCompletionContextMenu extends TabContextMenuItemProvider {
|
|||||||
} else {
|
} else {
|
||||||
this.app.stopObservingTabCompletion(tab)
|
this.app.stopObservingTabCompletion(tab)
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@@ -138,7 +138,7 @@ app-root {
|
|||||||
background: transparent;
|
background: transparent;
|
||||||
line-height: 42px;
|
line-height: 42px;
|
||||||
|
|
||||||
svg {
|
svg, path {
|
||||||
fill: $black;
|
fill: $black;
|
||||||
fill-opacity: 0.75;
|
fill-opacity: 0.75;
|
||||||
}
|
}
|
||||||
|
@@ -51,13 +51,13 @@ $input-disabled-bg: #333;
|
|||||||
$input-color: $body-color;
|
$input-color: $body-color;
|
||||||
$input-color-placeholder: #333;
|
$input-color-placeholder: #333;
|
||||||
$input-border-color: #344;
|
$input-border-color: #344;
|
||||||
$input-border-width: 0;
|
$input-border-width: 1px;
|
||||||
//$input-box-shadow: inset 0 1px 1px rgba($black,.075);
|
//$input-box-shadow: inset 0 1px 1px rgba($black,.075);
|
||||||
$input-border-radius: 0;
|
$input-border-radius: 0;
|
||||||
$custom-select-border-radius: 0;
|
$custom-select-border-radius: 0;
|
||||||
$input-bg-focus: $input-bg;
|
$input-bg-focus: $input-bg;
|
||||||
//$input-border-focus: lighten($brand-primary, 25%);
|
$input-border-focus: lighten($blue, 25%);
|
||||||
//$input-box-shadow-focus: $input-box-shadow, rgba($input-border-focus, .6);
|
$input-focus-box-shadow: none;
|
||||||
$input-color-focus: $input-color;
|
$input-color-focus: $input-color;
|
||||||
$input-group-addon-bg: $body-bg;
|
$input-group-addon-bg: $body-bg;
|
||||||
$input-group-addon-border-color: $input-border-color;
|
$input-group-addon-border-color: $input-border-color;
|
||||||
@@ -230,6 +230,7 @@ settings-tab > ngb-tabset {
|
|||||||
|
|
||||||
& > .nav {
|
& > .nav {
|
||||||
background: rgba(0, 0, 0, 0.25);
|
background: rgba(0, 0, 0, 0.25);
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
& > .nav-item > .nav-link {
|
& > .nav-item > .nav-link {
|
||||||
border: none;
|
border: none;
|
||||||
|
@@ -2,7 +2,6 @@
|
|||||||
"extends": "../tsconfig.json",
|
"extends": "../tsconfig.json",
|
||||||
"exclude": ["node_modules", "dist"],
|
"exclude": ["node_modules", "dist"],
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"baseUrl": "src",
|
"baseUrl": "src"
|
||||||
"declarationDir": "dist"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
14
terminus-core/tsconfig.typings.json
Normal file
14
terminus-core/tsconfig.typings.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"extends": "../tsconfig.json",
|
||||||
|
"exclude": ["node_modules", "dist", "typings"],
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": "src",
|
||||||
|
"emitDeclarationOnly": true,
|
||||||
|
"declaration": true,
|
||||||
|
"declarationDir": "./typings",
|
||||||
|
"paths": {
|
||||||
|
"terminus-*": ["../../terminus-*"],
|
||||||
|
"*": ["../../app/node_modules/*"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,66 +1,60 @@
|
|||||||
const path = require('path')
|
const path = require('path')
|
||||||
const webpack = require('webpack')
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
target: 'node',
|
target: 'node',
|
||||||
entry: 'src/index.ts',
|
entry: 'src/index.ts',
|
||||||
devtool: 'eval-source-map',
|
context: __dirname,
|
||||||
context: __dirname,
|
devtool: 'eval-cheap-module-source-map',
|
||||||
mode: 'development',
|
output: {
|
||||||
output: {
|
path: path.resolve(__dirname, 'dist'),
|
||||||
path: path.resolve(__dirname, 'dist'),
|
filename: 'index.js',
|
||||||
filename: 'index.js',
|
pathinfo: true,
|
||||||
pathinfo: true,
|
libraryTarget: 'umd',
|
||||||
libraryTarget: 'umd',
|
devtoolModuleFilenameTemplate: 'webpack-terminus-core:///[resource-path]',
|
||||||
devtoolModuleFilenameTemplate: 'webpack-terminus-core:///[resource-path]',
|
},
|
||||||
},
|
mode: process.env.TERMINUS_DEV ? 'development' : 'production',
|
||||||
mode: process.env.TERMINUS_DEV ? 'development' : 'production',
|
optimization:{
|
||||||
optimization:{
|
minimize: false,
|
||||||
minimize: false,
|
},
|
||||||
},
|
resolve: {
|
||||||
resolve: {
|
modules: ['.', 'src', 'node_modules', '../app/node_modules'].map(x => path.join(__dirname, x)),
|
||||||
modules: ['.', 'src', 'node_modules', '../app/node_modules'].map(x => path.join(__dirname, x)),
|
extensions: ['.ts', '.js'],
|
||||||
extensions: ['.ts', '.js'],
|
},
|
||||||
},
|
module: {
|
||||||
module: {
|
rules: [
|
||||||
rules: [
|
{
|
||||||
{
|
test: /\.ts$/,
|
||||||
test: /\.ts$/,
|
use: {
|
||||||
use: {
|
loader: 'awesome-typescript-loader',
|
||||||
loader: 'awesome-typescript-loader',
|
options: {
|
||||||
options: {
|
configFileName: path.resolve(__dirname, 'tsconfig.json'),
|
||||||
configFileName: path.resolve(__dirname, 'tsconfig.json'),
|
typeRoots: [
|
||||||
typeRoots: [path.resolve(__dirname, 'node_modules/@types')],
|
path.resolve(__dirname, 'node_modules/@types'),
|
||||||
paths: {
|
path.resolve(__dirname, '../node_modules/@types'),
|
||||||
"terminus-*": [path.resolve(__dirname, '../terminus-*')],
|
],
|
||||||
"*": [path.resolve(__dirname, '../app/node_modules/*')],
|
paths: {
|
||||||
}
|
"terminus-*": [path.resolve(__dirname, '../terminus-*')],
|
||||||
}
|
"*": [path.resolve(__dirname, '../app/node_modules/*')],
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
{ test: /\.pug$/, use: ['apply-loader', 'pug-loader'] },
|
},
|
||||||
{ test: /\.scss$/, use: ['to-string-loader', 'css-loader', 'sass-loader'] },
|
},
|
||||||
{ test: /\.css$/, use: ['to-string-loader', 'css-loader'], include: /component\.css/ },
|
{ test: /\.pug$/, use: ['apply-loader', 'pug-loader'] },
|
||||||
{ test: /\.css$/, use: ['style-loader', 'css-loader'], exclude: /component\.css/ },
|
{ test: /\.scss$/, use: ['to-string-loader', 'css-loader', 'sass-loader'] },
|
||||||
{ test: /\.yaml$/, use: ['json-loader', 'yaml-loader'] },
|
{ test: /\.css$/, use: ['to-string-loader', 'css-loader'], include: /component\.css/ },
|
||||||
{ test: /\.svg/, use: ['svg-inline-loader'] },
|
{ test: /\.css$/, use: ['style-loader', 'css-loader'], exclude: /component\.css/ },
|
||||||
]
|
{ test: /\.yaml$/, use: ['json-loader', 'yaml-loader'] },
|
||||||
},
|
{ test: /\.svg/, use: ['svg-inline-loader'] },
|
||||||
externals: [
|
],
|
||||||
'electron',
|
},
|
||||||
'fs',
|
externals: [
|
||||||
'os',
|
'electron',
|
||||||
'path',
|
'fs',
|
||||||
'deepmerge',
|
'os',
|
||||||
'untildify',
|
'path',
|
||||||
'winston',
|
'windows-native-registry',
|
||||||
'js-yaml',
|
/^rxjs/,
|
||||||
'windows-native-registry',
|
/^@angular/,
|
||||||
/^rxjs/,
|
/^@ng-bootstrap/,
|
||||||
/^@angular/,
|
],
|
||||||
/^@ng-bootstrap/,
|
|
||||||
],
|
|
||||||
plugins: [
|
|
||||||
new webpack.optimize.ModuleConcatenationPlugin(),
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
|
@@ -7,15 +7,15 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-3.12.1.tgz#5c6f4a1eabca84792fbd916f0cb40847f123c656"
|
resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-3.12.1.tgz#5c6f4a1eabca84792fbd916f0cb40847f123c656"
|
||||||
integrity sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==
|
integrity sha512-SGGAhXLHDx+PK4YLNcNGa6goPf9XRWQNAUUbffkwVGGXIxmDKWyGGL4inzq2sPmExu431Ekb9aEMn9BkPqEYFA==
|
||||||
|
|
||||||
"@types/node@^12.0.2":
|
"@types/semver@^6.0.2":
|
||||||
version "12.0.2"
|
version "6.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.0.2.tgz#3452a24edf9fea138b48fad4a0a028a683da1e40"
|
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-6.2.0.tgz#d688d574400d96c5b0114968705366f431831e1a"
|
||||||
integrity sha512-5tabW/i+9mhrfEOUcLDu2xBPsHJ+X5Orqy9FKpale3SjDA17j5AEpYq5vfy3oAeAHGcvANRCO3NV3d2D6q3NiA==
|
integrity sha512-1OzrNb4RuAzIT7wHSsgZRlMBlNsJl+do6UblR7JMW4oB7bbR+uBEYtUh7gEc/jM84GGilh68lSOokyM/zNUlBA==
|
||||||
|
|
||||||
"@types/webpack-env@^1.13.0":
|
"@types/shell-escape@^0.2.0":
|
||||||
version "1.13.9"
|
version "0.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.13.9.tgz#a67287861c928ebf4159a908d1fb1a2a34d4097a"
|
resolved "https://registry.yarnpkg.com/@types/shell-escape/-/shell-escape-0.2.0.tgz#cd2f0df814388599dd07196dcc510de2669d1ed2"
|
||||||
integrity sha512-p8zp5xqkly3g4cCmo2mKOHI9+Z/kObmDj0BmjbDDJQlgDTiEGTbm17MEwTAusV6XceCy+bNw9q/ZHXHyKo3zkg==
|
integrity sha512-7kUdtJtUylvyISJbe9FMcvMTjRdP0EvNDO1WbT0lT22k/IPBiPRTpmWaKu5HTWLCGLQRWVHrzVHZktTDvvR23g==
|
||||||
|
|
||||||
"@types/winston@^2.3.6":
|
"@types/winston@^2.3.6":
|
||||||
version "2.4.4"
|
version "2.4.4"
|
||||||
@@ -24,35 +24,20 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
winston "*"
|
winston "*"
|
||||||
|
|
||||||
ajv@^6.5.5:
|
agent-base@^4.3.0:
|
||||||
version "6.10.0"
|
version "4.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1"
|
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee"
|
||||||
integrity sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==
|
integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==
|
||||||
dependencies:
|
dependencies:
|
||||||
fast-deep-equal "^2.0.1"
|
es6-promisify "^5.0.0"
|
||||||
fast-json-stable-stringify "^2.0.0"
|
|
||||||
json-schema-traverse "^0.4.1"
|
|
||||||
uri-js "^4.2.2"
|
|
||||||
|
|
||||||
argparse@^1.0.7:
|
argparse@^1.0.7:
|
||||||
version "1.0.9"
|
version "1.0.10"
|
||||||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86"
|
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
|
||||||
integrity sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=
|
integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
|
||||||
dependencies:
|
dependencies:
|
||||||
sprintf-js "~1.0.2"
|
sprintf-js "~1.0.2"
|
||||||
|
|
||||||
asn1@~0.2.3:
|
|
||||||
version "0.2.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
|
|
||||||
integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
|
|
||||||
dependencies:
|
|
||||||
safer-buffer "~2.1.0"
|
|
||||||
|
|
||||||
assert-plus@1.0.0, assert-plus@^1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
|
|
||||||
integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
|
|
||||||
|
|
||||||
async@^2.6.1:
|
async@^2.6.1:
|
||||||
version "2.6.2"
|
version "2.6.2"
|
||||||
resolved "https://registry.yarnpkg.com/async/-/async-2.6.2.tgz#18330ea7e6e313887f5d2f2a904bac6fe4dd5381"
|
resolved "https://registry.yarnpkg.com/async/-/async-2.6.2.tgz#18330ea7e6e313887f5d2f2a904bac6fe4dd5381"
|
||||||
@@ -60,73 +45,27 @@ async@^2.6.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
lodash "^4.17.11"
|
lodash "^4.17.11"
|
||||||
|
|
||||||
asynckit@^0.4.0:
|
axios@^0.19.0:
|
||||||
version "0.4.0"
|
version "0.19.0"
|
||||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8"
|
||||||
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
|
integrity sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==
|
||||||
|
|
||||||
aws-sign2@~0.7.0:
|
|
||||||
version "0.7.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
|
|
||||||
integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
|
|
||||||
|
|
||||||
aws4@^1.8.0:
|
|
||||||
version "1.8.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
|
|
||||||
integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
|
|
||||||
|
|
||||||
axios@^0.18.0:
|
|
||||||
version "0.18.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.0.tgz#32d53e4851efdc0a11993b6cd000789d70c05102"
|
|
||||||
integrity sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=
|
|
||||||
dependencies:
|
dependencies:
|
||||||
follow-redirects "^1.3.0"
|
follow-redirects "1.5.10"
|
||||||
is-buffer "^1.1.5"
|
is-buffer "^2.0.2"
|
||||||
|
|
||||||
bcrypt-pbkdf@^1.0.0:
|
|
||||||
version "1.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
|
|
||||||
integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
|
|
||||||
dependencies:
|
|
||||||
tweetnacl "^0.14.3"
|
|
||||||
|
|
||||||
bluebird-lst@^1.0.6, bluebird-lst@^1.0.7:
|
|
||||||
version "1.0.8"
|
|
||||||
resolved "https://registry.yarnpkg.com/bluebird-lst/-/bluebird-lst-1.0.8.tgz#61b572e8b3eb57e0fff676a0e54566d93597e6a4"
|
|
||||||
integrity sha512-InUDOaBaIjIobOa3O4YRAbFgff907uTJZXW0m0rhk3zhVZ4GvsmdCLEAKC1CTWTtUWCM8iWTTfFX9N/xQR/etw==
|
|
||||||
dependencies:
|
|
||||||
bluebird "^3.5.4"
|
|
||||||
|
|
||||||
bluebird@^3.5.4:
|
|
||||||
version "3.5.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.5.tgz#a8d0afd73251effbbd5fe384a77d73003c17a71f"
|
|
||||||
integrity sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==
|
|
||||||
|
|
||||||
bootstrap@^4.1.3:
|
bootstrap@^4.1.3:
|
||||||
version "4.3.1"
|
version "4.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.3.1.tgz#280ca8f610504d99d7b6b4bfc4b68cec601704ac"
|
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.3.1.tgz#280ca8f610504d99d7b6b4bfc4b68cec601704ac"
|
||||||
integrity sha512-rXqOmH1VilAt2DyPzluTi2blhk17bO7ef+zLLPlWvG494pDxcM234pJ8wTc/6R40UWizAIIMgxjvxZg5kmsbag==
|
integrity sha512-rXqOmH1VilAt2DyPzluTi2blhk17bO7ef+zLLPlWvG494pDxcM234pJ8wTc/6R40UWizAIIMgxjvxZg5kmsbag==
|
||||||
|
|
||||||
buffer-from@^1.0.0:
|
builder-util-runtime@8.4.0:
|
||||||
version "1.1.1"
|
version "8.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
|
resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-8.4.0.tgz#3163fffc078e6b8f3dd5b6eb12a8345573590682"
|
||||||
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
|
integrity sha512-CJB/eKfPf2vHrkmirF5eicVnbDCkMBbwd5tRYlTlgud16zFeqD7QmrVUAOEXdnsrcNkiLg9dbuUsQKtl/AwsYQ==
|
||||||
|
|
||||||
builder-util-runtime@~8.1.0:
|
|
||||||
version "8.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-8.1.1.tgz#f2f6fc43e33d26892bd491667fc746ad69bccc50"
|
|
||||||
integrity sha512-+ieS4PMB33vVE2S3ZNWBEQJ1zKmAs/agrBdh7XadE1lKLjrH4aXYuOh9OOGdxqIRldhlhNBaF+yKMMEFOdNVig==
|
|
||||||
dependencies:
|
dependencies:
|
||||||
bluebird-lst "^1.0.6"
|
|
||||||
debug "^4.1.1"
|
debug "^4.1.1"
|
||||||
fs-extra-p "^7.0.0"
|
|
||||||
sax "^1.2.4"
|
sax "^1.2.4"
|
||||||
|
|
||||||
caseless@~0.12.0:
|
|
||||||
version "0.12.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
|
||||||
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
|
|
||||||
|
|
||||||
color-convert@^1.9.1:
|
color-convert@^1.9.1:
|
||||||
version "1.9.3"
|
version "1.9.3"
|
||||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
|
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
|
||||||
@@ -178,37 +117,30 @@ colorspace@1.1.x:
|
|||||||
color "3.0.x"
|
color "3.0.x"
|
||||||
text-hex "1.0.x"
|
text-hex "1.0.x"
|
||||||
|
|
||||||
combined-stream@^1.0.6, combined-stream@~1.0.6:
|
|
||||||
version "1.0.8"
|
|
||||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
|
|
||||||
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
|
|
||||||
dependencies:
|
|
||||||
delayed-stream "~1.0.0"
|
|
||||||
|
|
||||||
core-js@^3.1.2:
|
core-js@^3.1.2:
|
||||||
version "3.1.2"
|
version "3.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.1.2.tgz#2549a2cfb3ca1a5d851c9f7838e8b282cef2f3ba"
|
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.4.2.tgz#ee2b1a60b50388d8ddcda8cdb44a92c7a9ea76df"
|
||||||
integrity sha512-3poRGjbu56leCtZCZCzCgQ7GcKOflDFnjWIepaPFUsM0IXUBrne10sl3aa2Bkcz3+FjRdIxBe9dAMhIJmEnQNA==
|
integrity sha512-bUTfqFWtNKWp73oNIfRkqwYZJeNT3lstzZcAkhhiuvDraRSgOH1/+F9ZklbpR4zpdKuo4cpXN8tKP7s61yjX+g==
|
||||||
|
|
||||||
core-util-is@1.0.2, core-util-is@~1.0.0:
|
core-util-is@~1.0.0:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||||
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
|
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
|
||||||
|
|
||||||
dashdash@^1.12.0:
|
debug@=3.1.0:
|
||||||
version "1.14.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
|
|
||||||
integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
|
|
||||||
dependencies:
|
|
||||||
assert-plus "^1.0.0"
|
|
||||||
|
|
||||||
debug@=3.1.0, debug@^3.0.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"
|
||||||
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
|
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
|
||||||
dependencies:
|
dependencies:
|
||||||
ms "2.0.0"
|
ms "2.0.0"
|
||||||
|
|
||||||
|
debug@^3.1.0:
|
||||||
|
version "3.2.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
|
||||||
|
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
|
||||||
|
dependencies:
|
||||||
|
ms "^2.1.1"
|
||||||
|
|
||||||
debug@^4.1.1:
|
debug@^4.1.1:
|
||||||
version "4.1.1"
|
version "4.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
|
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
|
||||||
@@ -216,15 +148,10 @@ debug@^4.1.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ms "^2.1.1"
|
ms "^2.1.1"
|
||||||
|
|
||||||
deepmerge@^3.2.0:
|
deepmerge@^4.1.1:
|
||||||
version "3.2.0"
|
version "4.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-3.2.0.tgz#58ef463a57c08d376547f8869fdc5bcee957f44e"
|
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
|
||||||
integrity sha512-6+LuZGU7QCNUnAJyX8cIrlzoEgggTM6B7mm+znKOX4t5ltluT9KLjN6g61ECMS0LTsLW7yDpNoxhix5FZcrIow==
|
integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==
|
||||||
|
|
||||||
delayed-stream@~1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
|
||||||
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
|
|
||||||
|
|
||||||
diagnostics@^1.1.1:
|
diagnostics@^1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
@@ -235,28 +162,19 @@ diagnostics@^1.1.1:
|
|||||||
enabled "1.0.x"
|
enabled "1.0.x"
|
||||||
kuler "1.0.x"
|
kuler "1.0.x"
|
||||||
|
|
||||||
ecc-jsbn@~0.1.1:
|
|
||||||
version "0.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
|
|
||||||
integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=
|
|
||||||
dependencies:
|
|
||||||
jsbn "~0.1.0"
|
|
||||||
safer-buffer "^2.1.0"
|
|
||||||
|
|
||||||
electron-updater@^4.0.6:
|
electron-updater@^4.0.6:
|
||||||
version "4.0.6"
|
version "4.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-4.0.6.tgz#9c4f495ae0e80bf4425e3e1b801c5ed2ab933c2d"
|
resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-4.2.0.tgz#f9ecfc657f65ead737d42b9efecf628d3756b550"
|
||||||
integrity sha512-JPGLME6fxJcHG8hX7HWFl6Aew6iVm0DkcrENreKa5SUJCHG+uUaAhxDGDt+YGcNkyx1uJ6eBGMvFxDTLUv67pg==
|
integrity sha512-GuS3g7HDh17x/SaFjxjswlWUaKHczksYkV2Xc5CKj/bZH0YCvTSHtOmnBAdAmCk99u/71p3zP8f0jIqDfGcjww==
|
||||||
dependencies:
|
dependencies:
|
||||||
bluebird-lst "^1.0.6"
|
"@types/semver" "^6.0.2"
|
||||||
builder-util-runtime "~8.1.0"
|
builder-util-runtime "8.4.0"
|
||||||
fs-extra-p "^7.0.0"
|
fs-extra "^8.1.0"
|
||||||
js-yaml "^3.12.0"
|
js-yaml "^3.13.1"
|
||||||
lazy-val "^1.0.3"
|
lazy-val "^1.0.4"
|
||||||
lodash.isequal "^4.5.0"
|
lodash.isequal "^4.5.0"
|
||||||
pako "^1.0.7"
|
pako "^1.0.10"
|
||||||
semver "^5.6.0"
|
semver "^6.3.0"
|
||||||
source-map-support "^0.5.9"
|
|
||||||
|
|
||||||
enabled@1.0.x:
|
enabled@1.0.x:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
@@ -270,35 +188,22 @@ env-variable@0.0.x:
|
|||||||
resolved "https://registry.yarnpkg.com/env-variable/-/env-variable-0.0.5.tgz#913dd830bef11e96a039c038d4130604eba37f88"
|
resolved "https://registry.yarnpkg.com/env-variable/-/env-variable-0.0.5.tgz#913dd830bef11e96a039c038d4130604eba37f88"
|
||||||
integrity sha512-zoB603vQReOFvTg5xMl9I1P2PnHsHQQKTEowsKKD7nseUfJq6UWzK+4YtlWUO1nhiQUxe6XMkk+JleSZD1NZFA==
|
integrity sha512-zoB603vQReOFvTg5xMl9I1P2PnHsHQQKTEowsKKD7nseUfJq6UWzK+4YtlWUO1nhiQUxe6XMkk+JleSZD1NZFA==
|
||||||
|
|
||||||
|
es6-promise@^4.0.3:
|
||||||
|
version "4.2.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.6.tgz#b685edd8258886365ea62b57d30de28fadcd974f"
|
||||||
|
integrity sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==
|
||||||
|
|
||||||
|
es6-promisify@^5.0.0:
|
||||||
|
version "5.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203"
|
||||||
|
integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=
|
||||||
|
dependencies:
|
||||||
|
es6-promise "^4.0.3"
|
||||||
|
|
||||||
esprima@^4.0.0:
|
esprima@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804"
|
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
|
||||||
integrity sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==
|
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
|
||||||
|
|
||||||
extend@~3.0.2:
|
|
||||||
version "3.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
|
|
||||||
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
|
|
||||||
|
|
||||||
extsprintf@1.3.0:
|
|
||||||
version "1.3.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
|
|
||||||
integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
|
|
||||||
|
|
||||||
extsprintf@^1.2.0:
|
|
||||||
version "1.4.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
|
|
||||||
integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
|
|
||||||
|
|
||||||
fast-deep-equal@^2.0.1:
|
|
||||||
version "2.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
|
|
||||||
integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=
|
|
||||||
|
|
||||||
fast-json-stable-stringify@^2.0.0:
|
|
||||||
version "2.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
|
|
||||||
integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I=
|
|
||||||
|
|
||||||
fast-safe-stringify@^2.0.4:
|
fast-safe-stringify@^2.0.4:
|
||||||
version "2.0.6"
|
version "2.0.6"
|
||||||
@@ -310,77 +215,34 @@ fecha@^2.3.3:
|
|||||||
resolved "https://registry.yarnpkg.com/fecha/-/fecha-2.3.3.tgz#948e74157df1a32fd1b12c3a3c3cdcb6ec9d96cd"
|
resolved "https://registry.yarnpkg.com/fecha/-/fecha-2.3.3.tgz#948e74157df1a32fd1b12c3a3c3cdcb6ec9d96cd"
|
||||||
integrity sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg==
|
integrity sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg==
|
||||||
|
|
||||||
follow-redirects@^1.3.0:
|
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"
|
||||||
integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==
|
integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
debug "=3.1.0"
|
debug "=3.1.0"
|
||||||
|
|
||||||
forever-agent@~0.6.1:
|
fs-extra@^8.1.0:
|
||||||
version "0.6.1"
|
version "8.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
|
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
|
||||||
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
|
integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
|
||||||
|
|
||||||
form-data@~2.3.2:
|
|
||||||
version "2.3.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
|
|
||||||
integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
|
|
||||||
dependencies:
|
dependencies:
|
||||||
asynckit "^0.4.0"
|
graceful-fs "^4.2.0"
|
||||||
combined-stream "^1.0.6"
|
|
||||||
mime-types "^2.1.12"
|
|
||||||
|
|
||||||
fs-extra-p@^7.0.0:
|
|
||||||
version "7.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/fs-extra-p/-/fs-extra-p-7.0.1.tgz#4eec0b6dfa150fa90f6ddd773b4fb1d55cad54e3"
|
|
||||||
integrity sha512-yhd2OV0HnHt2oitlp+X9hl2ReX4X/7kQeL7/72qzPHTZj5eUPGzAKOvEglU02Fa1OeG2rSy/aKB4WGVaLiF8tw==
|
|
||||||
dependencies:
|
|
||||||
bluebird-lst "^1.0.7"
|
|
||||||
fs-extra "^7.0.1"
|
|
||||||
|
|
||||||
fs-extra@^7.0.1:
|
|
||||||
version "7.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9"
|
|
||||||
integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==
|
|
||||||
dependencies:
|
|
||||||
graceful-fs "^4.1.2"
|
|
||||||
jsonfile "^4.0.0"
|
jsonfile "^4.0.0"
|
||||||
universalify "^0.1.0"
|
universalify "^0.1.0"
|
||||||
|
|
||||||
getpass@^0.1.1:
|
graceful-fs@^4.1.6, graceful-fs@^4.2.0:
|
||||||
version "0.1.7"
|
version "4.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
|
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02"
|
||||||
integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=
|
integrity sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==
|
||||||
|
|
||||||
|
https-proxy-agent@3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-3.0.0.tgz#0106efa5d63d6d6f3ab87c999fa4877a3fd1ff97"
|
||||||
|
integrity sha512-y4jAxNEihqvBI5F3SaO2rtsjIOnnNA8sEbuiP+UhJZJHeM2NRm6c09ax2tgqme+SgUUvjao2fJXF4h3D6Cb2HQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
assert-plus "^1.0.0"
|
agent-base "^4.3.0"
|
||||||
|
debug "^3.1.0"
|
||||||
graceful-fs@^4.1.2, graceful-fs@^4.1.6:
|
|
||||||
version "4.1.11"
|
|
||||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
|
|
||||||
integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=
|
|
||||||
|
|
||||||
har-schema@^2.0.0:
|
|
||||||
version "2.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
|
|
||||||
integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
|
|
||||||
|
|
||||||
har-validator@~5.1.0:
|
|
||||||
version "5.1.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080"
|
|
||||||
integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==
|
|
||||||
dependencies:
|
|
||||||
ajv "^6.5.5"
|
|
||||||
har-schema "^2.0.0"
|
|
||||||
|
|
||||||
http-signature@~1.2.0:
|
|
||||||
version "1.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
|
|
||||||
integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
|
|
||||||
dependencies:
|
|
||||||
assert-plus "^1.0.0"
|
|
||||||
jsprim "^1.2.2"
|
|
||||||
sshpk "^1.7.0"
|
|
||||||
|
|
||||||
inherits@^2.0.3, inherits@~2.0.3:
|
inherits@^2.0.3, inherits@~2.0.3:
|
||||||
version "2.0.3"
|
version "2.0.3"
|
||||||
@@ -392,32 +254,22 @@ is-arrayish@^0.3.1:
|
|||||||
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-buffer@^1.1.5:
|
is-buffer@^2.0.2:
|
||||||
version "1.1.6"
|
version "2.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
|
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725"
|
||||||
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
|
integrity sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==
|
||||||
|
|
||||||
is-stream@^1.1.0:
|
is-stream@^1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||||
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
|
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
|
||||||
|
|
||||||
is-typedarray@~1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
|
|
||||||
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
|
|
||||||
|
|
||||||
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=
|
||||||
|
|
||||||
isstream@~0.1.2:
|
js-yaml@^3.13.1, js-yaml@^3.9.0:
|
||||||
version "0.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
|
|
||||||
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
|
|
||||||
|
|
||||||
js-yaml@^3.12.0, js-yaml@^3.9.0:
|
|
||||||
version "3.13.1"
|
version "3.13.1"
|
||||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
|
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
|
||||||
integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
|
integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
|
||||||
@@ -425,26 +277,6 @@ js-yaml@^3.12.0, js-yaml@^3.9.0:
|
|||||||
argparse "^1.0.7"
|
argparse "^1.0.7"
|
||||||
esprima "^4.0.0"
|
esprima "^4.0.0"
|
||||||
|
|
||||||
jsbn@~0.1.0:
|
|
||||||
version "0.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
|
|
||||||
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
|
|
||||||
|
|
||||||
json-schema-traverse@^0.4.1:
|
|
||||||
version "0.4.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
|
|
||||||
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
|
|
||||||
|
|
||||||
json-schema@0.2.3:
|
|
||||||
version "0.2.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
|
|
||||||
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
|
|
||||||
|
|
||||||
json-stringify-safe@~5.0.1:
|
|
||||||
version "5.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
|
|
||||||
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
|
|
||||||
|
|
||||||
jsonfile@^4.0.0:
|
jsonfile@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
|
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
|
||||||
@@ -452,16 +284,6 @@ jsonfile@^4.0.0:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
graceful-fs "^4.1.6"
|
graceful-fs "^4.1.6"
|
||||||
|
|
||||||
jsprim@^1.2.2:
|
|
||||||
version "1.4.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
|
|
||||||
integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=
|
|
||||||
dependencies:
|
|
||||||
assert-plus "1.0.0"
|
|
||||||
extsprintf "1.3.0"
|
|
||||||
json-schema "0.2.3"
|
|
||||||
verror "1.10.0"
|
|
||||||
|
|
||||||
kuler@1.0.x:
|
kuler@1.0.x:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/kuler/-/kuler-1.0.1.tgz#ef7c784f36c9fb6e16dd3150d152677b2b0228a6"
|
resolved "https://registry.yarnpkg.com/kuler/-/kuler-1.0.1.tgz#ef7c784f36c9fb6e16dd3150d152677b2b0228a6"
|
||||||
@@ -469,7 +291,7 @@ kuler@1.0.x:
|
|||||||
dependencies:
|
dependencies:
|
||||||
colornames "^1.1.1"
|
colornames "^1.1.1"
|
||||||
|
|
||||||
lazy-val@^1.0.3:
|
lazy-val@^1.0.4:
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/lazy-val/-/lazy-val-1.0.4.tgz#882636a7245c2cfe6e0a4e3ba6c5d68a137e5c65"
|
resolved "https://registry.yarnpkg.com/lazy-val/-/lazy-val-1.0.4.tgz#882636a7245c2cfe6e0a4e3ba6c5d68a137e5c65"
|
||||||
integrity sha512-u93kb2fPbIrfzBuLjZE+w+fJbUUMhNDXxNmMfaqNgpfQf1CO5ZSe2LfsnBqVAk7i/2NF48OSoRj+Xe2VT+lE8Q==
|
integrity sha512-u93kb2fPbIrfzBuLjZE+w+fJbUUMhNDXxNmMfaqNgpfQf1CO5ZSe2LfsnBqVAk7i/2NF48OSoRj+Xe2VT+lE8Q==
|
||||||
@@ -480,9 +302,9 @@ lodash.isequal@^4.5.0:
|
|||||||
integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
|
integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
|
||||||
|
|
||||||
lodash@^4.17.11:
|
lodash@^4.17.11:
|
||||||
version "4.17.11"
|
version "4.17.14"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba"
|
||||||
integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==
|
integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw==
|
||||||
|
|
||||||
logform@^2.1.1:
|
logform@^2.1.1:
|
||||||
version "2.1.2"
|
version "2.1.2"
|
||||||
@@ -495,29 +317,12 @@ logform@^2.1.1:
|
|||||||
ms "^2.1.1"
|
ms "^2.1.1"
|
||||||
triple-beam "^1.3.0"
|
triple-beam "^1.3.0"
|
||||||
|
|
||||||
mime-db@1.40.0:
|
mixpanel@^0.10.2:
|
||||||
version "1.40.0"
|
version "0.10.3"
|
||||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32"
|
resolved "https://registry.yarnpkg.com/mixpanel/-/mixpanel-0.10.3.tgz#2dff3bc0e17b57d6365547d315cbbf3ecfdb8a00"
|
||||||
integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==
|
integrity sha512-wIYr5o+1XSzJ80o3QED35K/yfPAKi5FigZXTSfcs4vltfeKbilIjNgwxdno7LrqzhjoSjmIyDWkI7D3lr7TwDw==
|
||||||
|
|
||||||
mime-db@~1.35.0:
|
|
||||||
version "1.35.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.35.0.tgz#0569d657466491283709663ad379a99b90d9ab47"
|
|
||||||
integrity sha512-JWT/IcCTsB0Io3AhWUMjRqucrHSPsSf2xKLaRldJVULioggvkJvggZ3VXNNSRkCddE6D+BUI4HEIZIA2OjwIvg==
|
|
||||||
|
|
||||||
mime-types@^2.1.12:
|
|
||||||
version "2.1.19"
|
|
||||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.19.tgz#71e464537a7ef81c15f2db9d97e913fc0ff606f0"
|
|
||||||
integrity sha512-P1tKYHVSZ6uFo26mtnve4HQFE3koh1UWVkp8YUC+ESBHe945xWSoXuHHiGarDqcEZ+whpCDnlNw5LON0kLo+sw==
|
|
||||||
dependencies:
|
dependencies:
|
||||||
mime-db "~1.35.0"
|
https-proxy-agent "3.0.0"
|
||||||
|
|
||||||
mime-types@~2.1.19:
|
|
||||||
version "2.1.24"
|
|
||||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81"
|
|
||||||
integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==
|
|
||||||
dependencies:
|
|
||||||
mime-db "1.40.0"
|
|
||||||
|
|
||||||
ms@2.0.0:
|
ms@2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
@@ -525,78 +330,43 @@ ms@2.0.0:
|
|||||||
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
|
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
|
||||||
|
|
||||||
ms@^2.1.1:
|
ms@^2.1.1:
|
||||||
version "2.1.1"
|
version "2.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
|
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||||
integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
|
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||||
|
|
||||||
nan@^2.13.2:
|
|
||||||
version "2.14.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
|
|
||||||
integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
|
|
||||||
|
|
||||||
ng2-dnd@^5.0.2:
|
ng2-dnd@^5.0.2:
|
||||||
version "5.0.2"
|
version "5.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/ng2-dnd/-/ng2-dnd-5.0.2.tgz#862278ac7dedfa14f5783bbf34014d5d73dfefb4"
|
resolved "https://registry.yarnpkg.com/ng2-dnd/-/ng2-dnd-5.0.2.tgz#862278ac7dedfa14f5783bbf34014d5d73dfefb4"
|
||||||
integrity sha512-5mWWBePwvEPsNd/HkdbD543Q9mPyJofL6zkNydl8/Ah3qrrvZT2DaEPbknY08OgkXpI2qUGksc01OzzVlRQ9dQ==
|
integrity sha512-5mWWBePwvEPsNd/HkdbD543Q9mPyJofL6zkNydl8/Ah3qrrvZT2DaEPbknY08OgkXpI2qUGksc01OzzVlRQ9dQ==
|
||||||
|
|
||||||
ngx-perfect-scrollbar@^6.0.0:
|
ngx-perfect-scrollbar@^8.0.0:
|
||||||
version "6.0.0"
|
version "8.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/ngx-perfect-scrollbar/-/ngx-perfect-scrollbar-6.0.0.tgz#92b51957c04ed6a6d416beca2707bab005667b68"
|
resolved "https://registry.yarnpkg.com/ngx-perfect-scrollbar/-/ngx-perfect-scrollbar-8.0.0.tgz#19c1bbf9b1a36d89b00a68f7834e39427d29182f"
|
||||||
integrity sha512-x4bzfI7AmeZubUN+tJJ99GYniSgHLJbTAg3ecbWd8dG6z59efgx4yxUjN1sDh7UYgimtg3w857qXEZJW/USAhA==
|
integrity sha512-IXoFbULQnxyJj0gdCcKCLE/6OW9HCP9KARzMCKS1kNxTuzG4DghjM2AaCBRM5/sFwdbn6rqOKMCINtHA8W8YCA==
|
||||||
dependencies:
|
dependencies:
|
||||||
perfect-scrollbar "^1.3.0"
|
perfect-scrollbar "^1.4.0"
|
||||||
resize-observer-polyfill "^1.4.0"
|
resize-observer-polyfill "^1.5.0"
|
||||||
|
|
||||||
oauth-sign@~0.9.0:
|
|
||||||
version "0.9.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
|
|
||||||
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
|
|
||||||
|
|
||||||
one-time@0.0.4:
|
one-time@0.0.4:
|
||||||
version "0.0.4"
|
version "0.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/one-time/-/one-time-0.0.4.tgz#f8cdf77884826fe4dff93e3a9cc37b1e4480742e"
|
resolved "https://registry.yarnpkg.com/one-time/-/one-time-0.0.4.tgz#f8cdf77884826fe4dff93e3a9cc37b1e4480742e"
|
||||||
integrity sha1-+M33eISCb+Tf+T46nMN7HkSAdC4=
|
integrity sha1-+M33eISCb+Tf+T46nMN7HkSAdC4=
|
||||||
|
|
||||||
pako@^1.0.7:
|
pako@^1.0.10:
|
||||||
version "1.0.10"
|
version "1.0.10"
|
||||||
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.10.tgz#4328badb5086a426aa90f541977d4955da5c9732"
|
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.10.tgz#4328badb5086a426aa90f541977d4955da5c9732"
|
||||||
integrity sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==
|
integrity sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==
|
||||||
|
|
||||||
perfect-scrollbar@^1.3.0:
|
perfect-scrollbar@^1.4.0:
|
||||||
version "1.3.0"
|
version "1.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/perfect-scrollbar/-/perfect-scrollbar-1.3.0.tgz#61da56f94b58870d8e0a617bce649cee17d1e3b2"
|
resolved "https://registry.yarnpkg.com/perfect-scrollbar/-/perfect-scrollbar-1.4.0.tgz#5d014ef9775e1f43058a1dbae9ed1daf0e7091f1"
|
||||||
integrity sha512-7Ub8YOvZB5k+pTy0K3LYUDnH9Xl3qvHcclJyIX+AV5UxHxll146iVGq4rtc+848nTDBQq89J7QxKKMA++cTXzQ==
|
integrity sha512-/2Sk/khljhdrsamjJYS5NjrH+GKEHEwh7zFSiYyxROyYKagkE4kSn2zDQDRTOMo8mpT2jikxx6yI1dG7lNP/hw==
|
||||||
|
|
||||||
performance-now@^2.1.0:
|
|
||||||
version "2.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
|
|
||||||
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
|
|
||||||
|
|
||||||
process-nextick-args@~2.0.0:
|
process-nextick-args@~2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
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.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"
|
||||||
integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==
|
integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==
|
||||||
|
|
||||||
psl@^1.1.24:
|
|
||||||
version "1.1.31"
|
|
||||||
resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.31.tgz#e9aa86d0101b5b105cbe93ac6b784cd547276184"
|
|
||||||
integrity sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==
|
|
||||||
|
|
||||||
punycode@^1.4.1:
|
|
||||||
version "1.4.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
|
|
||||||
integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
|
|
||||||
|
|
||||||
punycode@^2.1.0:
|
|
||||||
version "2.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
|
||||||
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
|
|
||||||
|
|
||||||
qs@~6.5.2:
|
|
||||||
version "6.5.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
|
|
||||||
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
|
|
||||||
|
|
||||||
readable-stream@^2.3.6:
|
readable-stream@^2.3.6:
|
||||||
version "2.3.6"
|
version "2.3.6"
|
||||||
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.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
|
||||||
@@ -619,56 +389,25 @@ readable-stream@^3.1.1:
|
|||||||
string_decoder "^1.1.1"
|
string_decoder "^1.1.1"
|
||||||
util-deprecate "^1.0.1"
|
util-deprecate "^1.0.1"
|
||||||
|
|
||||||
request@^2.88.0:
|
resize-observer-polyfill@^1.5.0:
|
||||||
version "2.88.0"
|
version "1.5.1"
|
||||||
resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef"
|
resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464"
|
||||||
integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==
|
integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==
|
||||||
dependencies:
|
|
||||||
aws-sign2 "~0.7.0"
|
|
||||||
aws4 "^1.8.0"
|
|
||||||
caseless "~0.12.0"
|
|
||||||
combined-stream "~1.0.6"
|
|
||||||
extend "~3.0.2"
|
|
||||||
forever-agent "~0.6.1"
|
|
||||||
form-data "~2.3.2"
|
|
||||||
har-validator "~5.1.0"
|
|
||||||
http-signature "~1.2.0"
|
|
||||||
is-typedarray "~1.0.0"
|
|
||||||
isstream "~0.1.2"
|
|
||||||
json-stringify-safe "~5.0.1"
|
|
||||||
mime-types "~2.1.19"
|
|
||||||
oauth-sign "~0.9.0"
|
|
||||||
performance-now "^2.1.0"
|
|
||||||
qs "~6.5.2"
|
|
||||||
safe-buffer "^5.1.2"
|
|
||||||
tough-cookie "~2.4.3"
|
|
||||||
tunnel-agent "^0.6.0"
|
|
||||||
uuid "^3.3.2"
|
|
||||||
|
|
||||||
resize-observer-polyfill@^1.4.0:
|
safe-buffer@~5.1.0, safe-buffer@~5.1.1:
|
||||||
version "1.5.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.0.tgz#660ff1d9712a2382baa2cad450a4716209f9ca69"
|
|
||||||
integrity sha512-M2AelyJDVR/oLnToJLtuDJRBBWUGUvvGigj1411hXhAdyFWqMaqHp7TixW3FpiLuVaikIcR1QL+zqoJoZlOgpg==
|
|
||||||
|
|
||||||
safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
|
|
||||||
version "5.1.2"
|
version "5.1.2"
|
||||||
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==
|
||||||
|
|
||||||
safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
|
|
||||||
version "2.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
|
||||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
|
||||||
|
|
||||||
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@^5.6.0:
|
semver@^6.3.0:
|
||||||
version "5.7.0"
|
version "6.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
|
||||||
integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==
|
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
|
||||||
|
|
||||||
shell-escape@^0.2.0:
|
shell-escape@^0.2.0:
|
||||||
version "0.2.0"
|
version "0.2.0"
|
||||||
@@ -682,40 +421,11 @@ simple-swizzle@^0.2.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
is-arrayish "^0.3.1"
|
is-arrayish "^0.3.1"
|
||||||
|
|
||||||
source-map-support@^0.5.9:
|
|
||||||
version "0.5.12"
|
|
||||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599"
|
|
||||||
integrity sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==
|
|
||||||
dependencies:
|
|
||||||
buffer-from "^1.0.0"
|
|
||||||
source-map "^0.6.0"
|
|
||||||
|
|
||||||
source-map@^0.6.0:
|
|
||||||
version "0.6.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
|
||||||
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
|
||||||
|
|
||||||
sprintf-js@~1.0.2:
|
sprintf-js@~1.0.2:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||||
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
|
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
|
||||||
|
|
||||||
sshpk@^1.7.0:
|
|
||||||
version "1.14.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.14.2.tgz#c6fc61648a3d9c4e764fd3fcdf4ea105e492ba98"
|
|
||||||
integrity sha1-xvxhZIo9nE52T9P8306hBeSSupg=
|
|
||||||
dependencies:
|
|
||||||
asn1 "~0.2.3"
|
|
||||||
assert-plus "^1.0.0"
|
|
||||||
dashdash "^1.12.0"
|
|
||||||
getpass "^0.1.1"
|
|
||||||
safer-buffer "^2.0.2"
|
|
||||||
optionalDependencies:
|
|
||||||
bcrypt-pbkdf "^1.0.0"
|
|
||||||
ecc-jsbn "~0.1.1"
|
|
||||||
jsbn "~0.1.0"
|
|
||||||
tweetnacl "~0.14.0"
|
|
||||||
|
|
||||||
stack-trace@0.0.x:
|
stack-trace@0.0.x:
|
||||||
version "0.0.10"
|
version "0.0.10"
|
||||||
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
|
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
|
||||||
@@ -740,77 +450,25 @@ text-hex@1.0.x:
|
|||||||
resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5"
|
resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5"
|
||||||
integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==
|
integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==
|
||||||
|
|
||||||
tough-cookie@~2.4.3:
|
|
||||||
version "2.4.3"
|
|
||||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781"
|
|
||||||
integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==
|
|
||||||
dependencies:
|
|
||||||
psl "^1.1.24"
|
|
||||||
punycode "^1.4.1"
|
|
||||||
|
|
||||||
triple-beam@^1.2.0, triple-beam@^1.3.0:
|
triple-beam@^1.2.0, triple-beam@^1.3.0:
|
||||||
version "1.3.0"
|
version "1.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9"
|
resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9"
|
||||||
integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==
|
integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==
|
||||||
|
|
||||||
tunnel-agent@^0.6.0:
|
|
||||||
version "0.6.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
|
|
||||||
integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=
|
|
||||||
dependencies:
|
|
||||||
safe-buffer "^5.0.1"
|
|
||||||
|
|
||||||
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
|
||||||
version "0.14.5"
|
|
||||||
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
|
|
||||||
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
|
|
||||||
|
|
||||||
universal-analytics@^0.4.17:
|
|
||||||
version "0.4.20"
|
|
||||||
resolved "https://registry.yarnpkg.com/universal-analytics/-/universal-analytics-0.4.20.tgz#d6b64e5312bf74f7c368e3024a922135dbf24b03"
|
|
||||||
integrity sha512-gE91dtMvNkjO+kWsPstHRtSwHXz0l2axqptGYp5ceg4MsuurloM0PU3pdOfpb5zBXUvyjT4PwhWK2m39uczZuw==
|
|
||||||
dependencies:
|
|
||||||
debug "^3.0.0"
|
|
||||||
request "^2.88.0"
|
|
||||||
uuid "^3.0.0"
|
|
||||||
|
|
||||||
universalify@^0.1.0:
|
universalify@^0.1.0:
|
||||||
version "0.1.1"
|
version "0.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7"
|
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
|
||||||
integrity sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=
|
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
|
||||||
|
|
||||||
uri-js@^4.2.2:
|
|
||||||
version "4.2.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
|
|
||||||
integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==
|
|
||||||
dependencies:
|
|
||||||
punycode "^2.1.0"
|
|
||||||
|
|
||||||
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@^3.0.0, uuid@^3.3.2:
|
uuid@^3.3.2:
|
||||||
version "3.3.2"
|
version "3.3.3"
|
||||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
|
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.3.tgz#4568f0216e78760ee1dbf3a4d2cf53e224112866"
|
||||||
integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==
|
integrity sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==
|
||||||
|
|
||||||
verror@1.10.0:
|
|
||||||
version "1.10.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
|
|
||||||
integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
|
|
||||||
dependencies:
|
|
||||||
assert-plus "^1.0.0"
|
|
||||||
core-util-is "1.0.2"
|
|
||||||
extsprintf "^1.2.0"
|
|
||||||
|
|
||||||
windows-native-registry@^1.0.14:
|
|
||||||
version "1.0.14"
|
|
||||||
resolved "https://registry.yarnpkg.com/windows-native-registry/-/windows-native-registry-1.0.14.tgz#35c742b1278473127cbfb3b76e0db3d1ef626872"
|
|
||||||
integrity sha512-C2UgyZYJYcPFjkhfNuy09CUa6wXAti4x/tLPgzudDDrqpTyczcgnBEpiablmE6j7E7ownouWTqgVcHW8HJyqhw==
|
|
||||||
dependencies:
|
|
||||||
nan "^2.13.2"
|
|
||||||
|
|
||||||
winston-transport@^4.3.0:
|
winston-transport@^4.3.0:
|
||||||
version "4.3.0"
|
version "4.3.0"
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "terminus-plugin-manager",
|
"name": "terminus-plugin-manager",
|
||||||
"version": "1.0.73-c4-ga7d62b0",
|
"version": "1.0.93-nightly.0",
|
||||||
"description": "Terminus' plugin manager",
|
"description": "Terminus' plugin manager",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"terminus-builtin-plugin"
|
"terminus-builtin-plugin"
|
||||||
],
|
],
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"typings": "dist/index.d.ts",
|
"typings": "typings/index.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "webpack --progress --color --display-modules",
|
"build": "webpack --progress --color --display-modules",
|
||||||
"watch": "webpack --progress --color --watch"
|
"watch": "webpack --progress --color --watch"
|
||||||
@@ -17,28 +17,19 @@
|
|||||||
"author": "Eugene Pankov",
|
"author": "Eugene Pankov",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/mz": "0.0.32",
|
|
||||||
"@types/node": "12.0.2",
|
|
||||||
"@types/semver": "^6.0.0",
|
"@types/semver": "^6.0.0",
|
||||||
"@types/webpack-env": "1.13.9",
|
"axios": "^0.19.0",
|
||||||
"css-loader": "^0.28.0",
|
"mz": "^2.6.0",
|
||||||
"ngx-pipes": "^1.6.1",
|
|
||||||
"semver": "^6.1.0"
|
"semver": "^6.1.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@angular/common": "4.0.1",
|
"@angular/common": "^7",
|
||||||
"@angular/core": "4.0.1",
|
"@angular/core": "^7",
|
||||||
"@angular/forms": "4.0.1",
|
"@angular/forms": "^7",
|
||||||
"@angular/platform-browser": "4.0.1",
|
"@angular/platform-browser": "^7",
|
||||||
"@ng-bootstrap/ng-bootstrap": "1.0.0-alpha.22",
|
"@ng-bootstrap/ng-bootstrap": "^1",
|
||||||
"rxjs": "5.3.0",
|
"rxjs": "^5",
|
||||||
"terminus-core": "*",
|
"terminus-core": "*",
|
||||||
"terminus-settings": "*"
|
"terminus-settings": "*"
|
||||||
},
|
}
|
||||||
"dependencies": {
|
|
||||||
"axios": "^0.18.0",
|
|
||||||
"mz": "^2.6.0",
|
|
||||||
"npm": "~6.7.0"
|
|
||||||
},
|
|
||||||
"false": {}
|
|
||||||
}
|
}
|
||||||
|
@@ -8,9 +8,9 @@
|
|||||||
button.btn.btn-outline-info.btn-sm.ml-auto((click)='openPluginsFolder()')
|
button.btn.btn-outline-info.btn-sm.ml-auto((click)='openPluginsFolder()')
|
||||||
i.fas.fa-folder
|
i.fas.fa-folder
|
||||||
span Plugins folder
|
span Plugins folder
|
||||||
|
|
||||||
.list-group.list-group-flush.mt-2
|
.list-group.list-group-flush.mt-2
|
||||||
.list-group-item.d-flex.align-items-center(*ngFor='let plugin of pluginManager.installedPlugins|orderBy:"name"')
|
.list-group-item.d-flex.align-items-center(*ngFor='let plugin of pluginManager.installedPlugins')
|
||||||
.mr-auto.d-flex.flex-column
|
.mr-auto.d-flex.flex-column
|
||||||
div
|
div
|
||||||
strong {{plugin.name}}
|
strong {{plugin.name}}
|
||||||
@@ -33,15 +33,15 @@
|
|||||||
(click)='enablePlugin(plugin)'
|
(click)='enablePlugin(plugin)'
|
||||||
)
|
)
|
||||||
i.fas.fa-fw.fa-play
|
i.fas.fa-fw.fa-play
|
||||||
|
|
||||||
button.btn.btn-secondary.ml-2(
|
button.btn.btn-secondary.ml-2(
|
||||||
*ngIf='!config.store.pluginBlacklist.includes(plugin.name)',
|
*ngIf='!config.store.pluginBlacklist.includes(plugin.name)',
|
||||||
(click)='disablePlugin(plugin)'
|
(click)='disablePlugin(plugin)'
|
||||||
)
|
)
|
||||||
i.fas.fa-fw.fa-pause
|
i.fas.fa-fw.fa-pause
|
||||||
|
|
||||||
button.btn.btn-danger.ml-2(
|
button.btn.btn-danger.ml-2(
|
||||||
(click)='uninstallPlugin(plugin)',
|
(click)='uninstallPlugin(plugin)',
|
||||||
*ngIf='!plugin.isBuiltin',
|
*ngIf='!plugin.isBuiltin',
|
||||||
[disabled]='busy[plugin.name] != undefined'
|
[disabled]='busy[plugin.name] != undefined'
|
||||||
)
|
)
|
||||||
@@ -65,7 +65,7 @@ div
|
|||||||
|
|
||||||
|
|
||||||
.list-group.list-group-flush.mb-4(*ngIf='availablePlugins$')
|
.list-group.list-group-flush.mb-4(*ngIf='availablePlugins$')
|
||||||
ng-container(*ngFor='let plugin of (availablePlugins$|async|orderBy:"name")')
|
ng-container(*ngFor='let plugin of (availablePlugins$|async)')
|
||||||
.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)',
|
||||||
@@ -73,7 +73,7 @@ div
|
|||||||
)
|
)
|
||||||
i.fas.fa-fw.fa-download(*ngIf='busy[plugin.name] != BusyState.Installing')
|
i.fas.fa-fw.fa-download(*ngIf='busy[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[plugin.name] == BusyState.Installing')
|
||||||
|
|
||||||
div((click)='showPluginInfo(plugin)')
|
div((click)='showPluginInfo(plugin)')
|
||||||
div
|
div
|
||||||
strong {{plugin.name}}
|
strong {{plugin.name}}
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
import { BehaviorSubject, Observable } from 'rxjs'
|
import { BehaviorSubject, Observable } from 'rxjs'
|
||||||
import { debounceTime, distinctUntilChanged, first, tap, flatMap } from 'rxjs/operators'
|
import { debounceTime, distinctUntilChanged, first, tap, flatMap, map } from 'rxjs/operators'
|
||||||
import * as semver from 'semver'
|
import * as semver from 'semver'
|
||||||
|
|
||||||
import { Component, Input } from '@angular/core'
|
import { Component, Input } from '@angular/core'
|
||||||
import { ConfigService, ElectronService } from 'terminus-core'
|
import { ConfigService, ElectronService } from 'terminus-core'
|
||||||
import { IPluginInfo, PluginManagerService } from '../services/pluginManager.service'
|
import { PluginInfo, PluginManagerService } from '../services/pluginManager.service'
|
||||||
|
|
||||||
enum BusyState { Installing, Uninstalling }
|
enum BusyState { Installing, Uninstalling }
|
||||||
|
|
||||||
@@ -15,10 +15,10 @@ enum BusyState { Installing, Uninstalling }
|
|||||||
})
|
})
|
||||||
export class PluginsSettingsTabComponent {
|
export class PluginsSettingsTabComponent {
|
||||||
BusyState = BusyState
|
BusyState = BusyState
|
||||||
@Input() availablePlugins$: Observable<IPluginInfo[]>
|
@Input() availablePlugins$: Observable<PluginInfo[]>
|
||||||
@Input() availablePluginsQuery$ = new BehaviorSubject<string>('')
|
@Input() availablePluginsQuery$ = new BehaviorSubject<string>('')
|
||||||
@Input() availablePluginsReady = false
|
@Input() availablePluginsReady = false
|
||||||
@Input() knownUpgrades: {[id: string]: IPluginInfo} = {}
|
@Input() knownUpgrades: {[id: string]: PluginInfo|null} = {}
|
||||||
@Input() busy: {[id: string]: BusyState} = {}
|
@Input() busy: {[id: string]: BusyState} = {}
|
||||||
@Input() erroredPlugin: string
|
@Input() erroredPlugin: string
|
||||||
@Input() errorMessage: string
|
@Input() errorMessage: string
|
||||||
@@ -43,9 +43,12 @@ export class PluginsSettingsTabComponent {
|
|||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
this.availablePlugins$.pipe(first()).subscribe(available => {
|
this.availablePlugins$.pipe(first(), map((plugins: PluginInfo[]) => {
|
||||||
for (let plugin of this.pluginManager.installedPlugins) {
|
plugins.sort((a, b) => a.name > b.name ? 1 : -1)
|
||||||
this.knownUpgrades[plugin.name] = available.find(x => x.name === plugin.name && semver.gt(x.version, plugin.version))
|
return plugins
|
||||||
|
})).subscribe(available => {
|
||||||
|
for (const plugin of this.pluginManager.installedPlugins) {
|
||||||
|
this.knownUpgrades[plugin.name] = available.find(x => x.name === plugin.name && semver.gt(x.version, plugin.version)) || null
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -58,11 +61,11 @@ export class PluginsSettingsTabComponent {
|
|||||||
this.availablePluginsQuery$.next(query)
|
this.availablePluginsQuery$.next(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
isAlreadyInstalled (plugin: IPluginInfo): boolean {
|
isAlreadyInstalled (plugin: PluginInfo): boolean {
|
||||||
return this.pluginManager.installedPlugins.some(x => x.name === plugin.name)
|
return this.pluginManager.installedPlugins.some(x => x.name === plugin.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
async installPlugin (plugin: IPluginInfo): Promise<void> {
|
async installPlugin (plugin: PluginInfo): Promise<void> {
|
||||||
this.busy[plugin.name] = BusyState.Installing
|
this.busy[plugin.name] = BusyState.Installing
|
||||||
try {
|
try {
|
||||||
await this.pluginManager.installPlugin(plugin)
|
await this.pluginManager.installPlugin(plugin)
|
||||||
@@ -76,7 +79,7 @@ export class PluginsSettingsTabComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async uninstallPlugin (plugin: IPluginInfo): Promise<void> {
|
async uninstallPlugin (plugin: PluginInfo): Promise<void> {
|
||||||
this.busy[plugin.name] = BusyState.Uninstalling
|
this.busy[plugin.name] = BusyState.Uninstalling
|
||||||
try {
|
try {
|
||||||
await this.pluginManager.uninstallPlugin(plugin)
|
await this.pluginManager.uninstallPlugin(plugin)
|
||||||
@@ -90,21 +93,21 @@ export class PluginsSettingsTabComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async upgradePlugin (plugin: IPluginInfo): Promise<void> {
|
async upgradePlugin (plugin: PluginInfo): Promise<void> {
|
||||||
return this.installPlugin(this.knownUpgrades[plugin.name])
|
return this.installPlugin(this.knownUpgrades[plugin.name]!)
|
||||||
}
|
}
|
||||||
|
|
||||||
showPluginInfo (plugin: IPluginInfo) {
|
showPluginInfo (plugin: PluginInfo) {
|
||||||
this.electron.shell.openExternal('https://www.npmjs.com/package/' + plugin.packageName)
|
this.electron.shell.openExternal('https://www.npmjs.com/package/' + plugin.packageName)
|
||||||
}
|
}
|
||||||
|
|
||||||
enablePlugin (plugin: IPluginInfo) {
|
enablePlugin (plugin: PluginInfo) {
|
||||||
this.config.store.pluginBlacklist = this.config.store.pluginBlacklist.filter(x => x !== plugin.name)
|
this.config.store.pluginBlacklist = this.config.store.pluginBlacklist.filter(x => x !== plugin.name)
|
||||||
this.config.save()
|
this.config.save()
|
||||||
this.config.requestRestart()
|
this.config.requestRestart()
|
||||||
}
|
}
|
||||||
|
|
||||||
disablePlugin (plugin: IPluginInfo) {
|
disablePlugin (plugin: PluginInfo) {
|
||||||
this.config.store.pluginBlacklist = [...this.config.store.pluginBlacklist, plugin.name]
|
this.config.store.pluginBlacklist = [...this.config.store.pluginBlacklist, plugin.name]
|
||||||
this.config.save()
|
this.config.save()
|
||||||
this.config.requestRestart()
|
this.config.requestRestart()
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
import { NgModule } from '@angular/core'
|
import { NgModule } from '@angular/core'
|
||||||
import { BrowserModule } from '@angular/platform-browser'
|
import { BrowserModule } from '@angular/platform-browser'
|
||||||
import { FormsModule } from '@angular/forms'
|
import { FormsModule } from '@angular/forms'
|
||||||
import { NgPipesModule } from 'ngx-pipes'
|
|
||||||
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbModule } from '@ng-bootstrap/ng-bootstrap'
|
||||||
|
|
||||||
import { SettingsTabProvider } from 'terminus-settings'
|
import { SettingsTabProvider } from 'terminus-settings'
|
||||||
@@ -15,7 +14,6 @@ import { PluginsSettingsTabProvider } from './settings'
|
|||||||
BrowserModule,
|
BrowserModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
NgbModule,
|
NgbModule,
|
||||||
NgPipesModule,
|
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: SettingsTabProvider, useClass: PluginsSettingsTabProvider, multi: true },
|
{ provide: SettingsTabProvider, useClass: PluginsSettingsTabProvider, multi: true },
|
||||||
@@ -27,6 +25,6 @@ import { PluginsSettingsTabProvider } from './settings'
|
|||||||
PluginsSettingsTabComponent,
|
PluginsSettingsTabComponent,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export default class PluginManagerModule { }
|
export default class PluginManagerModule { } // eslint-disable-line @typescript-eslint/no-extraneous-class
|
||||||
|
|
||||||
export { PluginManagerService }
|
export { PluginManagerService }
|
||||||
|
@@ -8,7 +8,7 @@ const NAME_PREFIX = 'terminus-'
|
|||||||
const KEYWORD = 'terminus-plugin'
|
const KEYWORD = 'terminus-plugin'
|
||||||
const OFFICIAL_NPM_ACCOUNT = 'eugenepankov'
|
const OFFICIAL_NPM_ACCOUNT = 'eugenepankov'
|
||||||
|
|
||||||
export interface IPluginInfo {
|
export interface PluginInfo {
|
||||||
name: string
|
name: string
|
||||||
description: string
|
description: string
|
||||||
packageName: string
|
packageName: string
|
||||||
@@ -25,7 +25,7 @@ export class PluginManagerService {
|
|||||||
logger: Logger
|
logger: Logger
|
||||||
builtinPluginsPath: string = (window as any).builtinPluginsPath
|
builtinPluginsPath: string = (window as any).builtinPluginsPath
|
||||||
userPluginsPath: string = (window as any).userPluginsPath
|
userPluginsPath: string = (window as any).userPluginsPath
|
||||||
installedPlugins: IPluginInfo[] = (window as any).installedPlugins
|
installedPlugins: PluginInfo[] = (window as any).installedPlugins
|
||||||
|
|
||||||
private npmReady: Promise<void>
|
private npmReady: Promise<void>
|
||||||
private npm: any
|
private npm: any
|
||||||
@@ -40,7 +40,7 @@ export class PluginManagerService {
|
|||||||
if (!this.npm) {
|
if (!this.npm) {
|
||||||
if (!this.npmReady) {
|
if (!this.npmReady) {
|
||||||
this.npmReady = new Promise(resolve => {
|
this.npmReady = new Promise(resolve => {
|
||||||
const npm = require('npm')
|
const npm = (global as any).require('npm')
|
||||||
npm.load({
|
npm.load({
|
||||||
prefix: this.userPluginsPath,
|
prefix: this.userPluginsPath,
|
||||||
}, err => {
|
}, err => {
|
||||||
@@ -57,12 +57,12 @@ export class PluginManagerService {
|
|||||||
return this.npm
|
return this.npm
|
||||||
}
|
}
|
||||||
|
|
||||||
listAvailable (query?: string): Observable<IPluginInfo[]> {
|
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',
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
).pipe(
|
).pipe(
|
||||||
map(response => response.data.objects.map(item => ({
|
map(response => response.data.objects.map(item => ({
|
||||||
@@ -78,7 +78,7 @@ export class PluginManagerService {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async installPlugin (plugin: IPluginInfo) {
|
async installPlugin (plugin: PluginInfo) {
|
||||||
(await this.getNPM()).commands.install([`${plugin.packageName}@${plugin.version}`], err => {
|
(await this.getNPM()).commands.install([`${plugin.packageName}@${plugin.version}`], err => {
|
||||||
if (err) {
|
if (err) {
|
||||||
this.logger.error(err)
|
this.logger.error(err)
|
||||||
@@ -88,7 +88,7 @@ export class PluginManagerService {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async uninstallPlugin (plugin: IPluginInfo) {
|
async uninstallPlugin (plugin: PluginInfo) {
|
||||||
(await this.getNPM()).commands.remove([plugin.packageName], err => {
|
(await this.getNPM()).commands.remove([plugin.packageName], err => {
|
||||||
if (err) {
|
if (err) {
|
||||||
this.logger.error(err)
|
this.logger.error(err)
|
||||||
|
@@ -3,6 +3,5 @@
|
|||||||
"exclude": ["node_modules", "dist"],
|
"exclude": ["node_modules", "dist"],
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"baseUrl": "src",
|
"baseUrl": "src",
|
||||||
"declarationDir": "dist"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user