mirror of
https://github.com/Eugeny/tabby.git
synced 2025-08-02 23:46:59 +00:00
Compare commits
290 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c64654991b | ||
![]() |
1fc531ecf4 | ||
![]() |
4c7e7f5fae | ||
![]() |
7b07a67947 | ||
![]() |
fe5193d9f1 | ||
![]() |
b6a3af80fa | ||
![]() |
46a9b655fc | ||
![]() |
762ee85773 | ||
![]() |
650e362c42 | ||
![]() |
136ec1035b | ||
![]() |
f27e1ec62d | ||
![]() |
c736a84835 | ||
![]() |
b3a07e5f99 | ||
![]() |
c408154137 | ||
![]() |
c0988e58b4 | ||
![]() |
d6e906c107 | ||
![]() |
d77a91b3e1 | ||
![]() |
80f82296a0 | ||
![]() |
6e9f497d22 | ||
![]() |
50f01b6794 | ||
![]() |
b068070825 | ||
![]() |
194342d6fa | ||
![]() |
d7eeac6af7 | ||
![]() |
98a08b92a2 | ||
![]() |
fef8638ade | ||
![]() |
34ff0c45cb | ||
![]() |
1896155ad9 | ||
![]() |
bbcbad0e77 | ||
![]() |
ce435056a2 | ||
![]() |
fe9b14ad9c | ||
![]() |
fc72e5005c | ||
![]() |
f5c428d73b | ||
![]() |
b396060965 | ||
![]() |
c752a18f3c | ||
![]() |
805ee0af09 | ||
![]() |
ad9ad4d418 | ||
![]() |
d5c4088cc1 | ||
![]() |
483a0472b9 | ||
![]() |
1bbf9d4294 | ||
![]() |
10c8502fbd | ||
![]() |
8f3f6f591d | ||
![]() |
656d275801 | ||
![]() |
9c53503c0f | ||
![]() |
9ea99f1ace | ||
![]() |
126d14dfb7 | ||
![]() |
68803b5f14 | ||
![]() |
e0273126de | ||
![]() |
0ced498b6e | ||
![]() |
510682438e | ||
![]() |
762874c400 | ||
![]() |
b7e2e0875e | ||
![]() |
9cfd02bff6 | ||
![]() |
9082fe5c06 | ||
![]() |
43786fda83 | ||
![]() |
1677285ea9 | ||
![]() |
aaa0a0f69a | ||
![]() |
cb8832fbad | ||
![]() |
e39321c8cb | ||
![]() |
3ef7697be8 | ||
![]() |
8927717654 | ||
![]() |
3a8168917a | ||
![]() |
9249c48ecc | ||
![]() |
6d1150d08a | ||
![]() |
b234300bd8 | ||
![]() |
be3bae3a6f | ||
![]() |
767f9f3215 | ||
![]() |
d6e69f5bf5 | ||
![]() |
5c644e5e23 | ||
![]() |
5b905af5d3 | ||
![]() |
28f4a052d7 | ||
![]() |
948251e326 | ||
![]() |
2203661f19 | ||
![]() |
8f4e28fba4 | ||
![]() |
a413bbaf07 | ||
![]() |
4e05adeb66 | ||
![]() |
59ac4a858e | ||
![]() |
55ae5b27b9 | ||
![]() |
b0aa20b387 | ||
![]() |
0f01aaf44d | ||
![]() |
54531e234e | ||
![]() |
3bda4a9871 | ||
![]() |
c7e3ab42d9 | ||
![]() |
5d2956568e | ||
![]() |
8b3f482682 | ||
![]() |
f38f9882f8 | ||
![]() |
54d71adb26 | ||
![]() |
13eebd8957 | ||
![]() |
6c4f8d2611 | ||
![]() |
897bc77d05 | ||
![]() |
8b5b53ab26 | ||
![]() |
448fe29f50 | ||
![]() |
70ae9f875f | ||
![]() |
75764cd725 | ||
![]() |
bb00f2f033 | ||
![]() |
5ae2d17cc8 | ||
![]() |
109a83db5b | ||
![]() |
9fe8d2a7df | ||
![]() |
d3bbd045dc | ||
![]() |
eb0fa29fad | ||
![]() |
6289229bf2 | ||
![]() |
b664b9eed9 | ||
![]() |
e80c3ce693 | ||
![]() |
2569f9e322 | ||
![]() |
b9b6c63d57 | ||
![]() |
95152456ce | ||
![]() |
918761bbdc | ||
![]() |
ceb1b59409 | ||
![]() |
63374f532c | ||
![]() |
c57fe48e73 | ||
![]() |
02a3a8200b | ||
![]() |
3e8e3f7ccd | ||
![]() |
1ec218775e | ||
![]() |
cc8c200da0 | ||
![]() |
0a20716efd | ||
![]() |
9893fb51a7 | ||
![]() |
3466d42cb1 | ||
![]() |
9e9066d3cd | ||
![]() |
bee62f3001 | ||
![]() |
b469dd603b | ||
![]() |
f6eaff355b | ||
![]() |
7ff2b31a9f | ||
![]() |
dbf67e77e0 | ||
![]() |
b45769d379 | ||
![]() |
1695c0b522 | ||
![]() |
15d7be05f1 | ||
![]() |
a759c40ec8 | ||
![]() |
a8e977d34c | ||
![]() |
527a951b1e | ||
![]() |
afe9c9a84c | ||
![]() |
372662c787 | ||
![]() |
ca9e6a118e | ||
![]() |
b412bce37d | ||
![]() |
6622cbc550 | ||
![]() |
d3361b6f34 | ||
![]() |
13f715ddfd | ||
![]() |
ccea3572a7 | ||
![]() |
c24c752b76 | ||
![]() |
8751b9831f | ||
![]() |
d4d93cf236 | ||
![]() |
9b305026f7 | ||
![]() |
91fcdbf9b5 | ||
![]() |
b17e23a69e | ||
![]() |
88bbdd0da1 | ||
![]() |
53cbb8a7e3 | ||
![]() |
9df8a1b904 | ||
![]() |
0a0e451e97 | ||
![]() |
5376ac0f07 | ||
![]() |
238482932e | ||
![]() |
d4332ea361 | ||
![]() |
eb49499f09 | ||
![]() |
445a3d02da | ||
![]() |
06e5571812 | ||
![]() |
510edaabb5 | ||
![]() |
5ef36896c5 | ||
![]() |
5d22c15a78 | ||
![]() |
a33e11502b | ||
![]() |
4c9456d98d | ||
![]() |
e1ee818932 | ||
![]() |
e83210f0e6 | ||
![]() |
1d176047c4 | ||
![]() |
bd3ac21fb3 | ||
![]() |
559dd3955c | ||
![]() |
0ed05cb783 | ||
![]() |
87e8eefd49 | ||
![]() |
609b527a7c | ||
![]() |
fee163835f | ||
![]() |
c8b25cf911 | ||
![]() |
eb9698fa66 | ||
![]() |
eb60c3c3c6 | ||
![]() |
f2a48fc0c0 | ||
![]() |
8d01a9ad8d | ||
![]() |
4d8ddba8ea | ||
![]() |
91a7dd8b1d | ||
![]() |
2f35ae203d | ||
![]() |
38423eb139 | ||
![]() |
bde6fd6231 | ||
![]() |
14200f848f | ||
![]() |
f6895d7696 | ||
![]() |
64410a9302 | ||
![]() |
45274f9691 | ||
![]() |
54ab2a1f03 | ||
![]() |
782128308c | ||
![]() |
f2b6cdf97c | ||
![]() |
c025c44258 | ||
![]() |
9483d20994 | ||
![]() |
ff25e7fe2e | ||
![]() |
d12a48f3fc | ||
![]() |
1796ce4f1c | ||
![]() |
d404067e77 | ||
![]() |
f7544d0a2e | ||
![]() |
cbdce5c30e | ||
![]() |
d7ab8a00dc | ||
![]() |
6e0ded9a5e | ||
![]() |
f660ece383 | ||
![]() |
b692347c4e | ||
![]() |
9520d31f12 | ||
![]() |
f2afac6ead | ||
![]() |
0dd460a6d7 | ||
![]() |
7c0aacf0ad | ||
![]() |
57bf79ec56 | ||
![]() |
8cfdd43ee1 | ||
![]() |
21f245ddaf | ||
![]() |
00a19769e1 | ||
![]() |
d2a22763de | ||
![]() |
da75e34b95 | ||
![]() |
08a564588c | ||
![]() |
a639d65ed6 | ||
![]() |
b42314b29e | ||
![]() |
17c93aa3fc | ||
![]() |
5b4a1a5581 | ||
![]() |
d82f78a026 | ||
![]() |
9414be9ce0 | ||
![]() |
f2ed1b3df3 | ||
![]() |
f41abea747 | ||
![]() |
21e5d68994 | ||
![]() |
a6a9c149dc | ||
![]() |
61c11abda2 | ||
![]() |
3a11b51729 | ||
![]() |
00ffa24e7d | ||
![]() |
b156752106 | ||
![]() |
6159d0ba9a | ||
![]() |
bf2ab87c44 | ||
![]() |
ff1e2871d4 | ||
![]() |
2d9f3d8216 | ||
![]() |
e7a9b2317d | ||
![]() |
0ab02d032a | ||
![]() |
ab8622c9fd | ||
![]() |
70a12e36e1 | ||
![]() |
9706108185 | ||
![]() |
5138873f43 | ||
![]() |
d8625d6b9f | ||
![]() |
ec4f200435 | ||
![]() |
91f3b78b80 | ||
![]() |
3b321858d2 | ||
![]() |
0814d44207 | ||
![]() |
04010b58bb | ||
![]() |
a68dc35a23 | ||
![]() |
40c4f57b37 | ||
![]() |
652084a140 | ||
![]() |
c29d5bc98a | ||
![]() |
42b5d0824a | ||
![]() |
7226b09214 | ||
![]() |
b97053daee | ||
![]() |
d5d6a486d2 | ||
![]() |
889ab0f147 | ||
![]() |
604e5e37a8 | ||
![]() |
e6a1f98cf1 | ||
![]() |
5f81a47db9 | ||
![]() |
5d16bb99c7 | ||
![]() |
f24439d580 | ||
![]() |
6d3334543e | ||
![]() |
62019e3ac1 | ||
![]() |
adc9bce844 | ||
![]() |
26b70447da | ||
![]() |
832e408952 | ||
![]() |
b64c2ae14e | ||
![]() |
e63d296457 | ||
![]() |
909c99d1c0 | ||
![]() |
cbd8609c97 | ||
![]() |
b8c1b5e428 | ||
![]() |
cb1b0ac669 | ||
![]() |
bbe7d2186e | ||
![]() |
d0469685d9 | ||
![]() |
32ecd48375 | ||
![]() |
33a715c8c3 | ||
![]() |
eba3d2709e | ||
![]() |
b3af7184e7 | ||
![]() |
54411e59ad | ||
![]() |
f9da76f07e | ||
![]() |
af0ecd2400 | ||
![]() |
f3f730b32e | ||
![]() |
076b1c7129 | ||
![]() |
3298840454 | ||
![]() |
b0c300be43 | ||
![]() |
e86b3cde6f | ||
![]() |
ff55d3d1ef | ||
![]() |
e024390028 | ||
![]() |
c314e4638d | ||
![]() |
bcd2cc50ec | ||
![]() |
8e1f6f894f | ||
![]() |
eab8841cca | ||
![]() |
a78f3399fd | ||
![]() |
44cbc9298f | ||
![]() |
87ad435a13 | ||
![]() |
9e3961b83d | ||
![]() |
5a7b5346ae | ||
![]() |
e4037d5aac | ||
![]() |
6998a61f37 | ||
![]() |
4986730f44 | ||
![]() |
824f995209 |
@@ -1,6 +1,9 @@
|
|||||||
{
|
{
|
||||||
"files": [
|
"files": [
|
||||||
"README.md"
|
"README.md",
|
||||||
|
"README.zh-CN.md",
|
||||||
|
"README.ru-RU.md",
|
||||||
|
"README.ko-KR.md"
|
||||||
],
|
],
|
||||||
"imageSize": 100,
|
"imageSize": 100,
|
||||||
"commit": false,
|
"commit": false,
|
||||||
@@ -496,6 +499,115 @@
|
|||||||
"contributions": [
|
"contributions": [
|
||||||
"code"
|
"code"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "jaimeadf",
|
||||||
|
"name": "Marmota",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/40345645?v=4",
|
||||||
|
"profile": "https://discord.gg/4c5EVTBhtp",
|
||||||
|
"contributions": [
|
||||||
|
"design"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "TENX-S",
|
||||||
|
"name": "Ares Andrew",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/40336192?v=4",
|
||||||
|
"profile": "https://ares.zone",
|
||||||
|
"contributions": [
|
||||||
|
"doc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "gkor",
|
||||||
|
"name": "George Korsnick",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/780052?v=4",
|
||||||
|
"profile": "https://usual.io/",
|
||||||
|
"contributions": [
|
||||||
|
"financial"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "uluhonolulu",
|
||||||
|
"name": "Artem Smirnov",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/872764?v=4",
|
||||||
|
"profile": "https://about.me/ulu",
|
||||||
|
"contributions": [
|
||||||
|
"financial"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "nevotheless",
|
||||||
|
"name": "Tim Kopplow",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/779797?v=4",
|
||||||
|
"profile": "https://github.com/nevotheless",
|
||||||
|
"contributions": [
|
||||||
|
"financial"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "mrthock",
|
||||||
|
"name": "mrthock",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/88901709?v=4",
|
||||||
|
"profile": "https://github.com/mrthock",
|
||||||
|
"contributions": [
|
||||||
|
"financial"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "lrottach",
|
||||||
|
"name": "Lukas Rottach",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/50323692?v=4",
|
||||||
|
"profile": "https://github.com/lrottach",
|
||||||
|
"contributions": [
|
||||||
|
"financial"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "boonkerz",
|
||||||
|
"name": "boonkerz",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/277321?v=4",
|
||||||
|
"profile": "https://github.com/boonkerz",
|
||||||
|
"contributions": [
|
||||||
|
"code",
|
||||||
|
"translation"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "milotype",
|
||||||
|
"name": "Milo Ivir",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/43657314?v=4",
|
||||||
|
"profile": "https://github.com/milotype",
|
||||||
|
"contributions": [
|
||||||
|
"translation"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "JasonCubic",
|
||||||
|
"name": "JasonCubic",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/8921015?v=4",
|
||||||
|
"profile": "https://github.com/JasonCubic",
|
||||||
|
"contributions": [
|
||||||
|
"design"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "MaxWaldorf",
|
||||||
|
"name": "MaxWaldorf",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/15877853?v=4",
|
||||||
|
"profile": "https://github.com/MaxWaldorf",
|
||||||
|
"contributions": [
|
||||||
|
"infra"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "mwz",
|
||||||
|
"name": "Michael Wizner",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/1190768?v=4",
|
||||||
|
"profile": "https://github.com/mwz",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"contributorsPerLine": 7,
|
"contributorsPerLine": 7,
|
||||||
|
7
.github/ISSUE_TEMPLATE/feature_request.md
vendored
7
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -7,6 +7,13 @@ assignees: ''
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
# RULES:
|
||||||
|
|
||||||
|
* **ENGLISH ONLY** - this issue tracker is English-only. Please respect the people who take time to help you with your problems.
|
||||||
|
* Search existing issues first: https://github.com/Eugeny/tabby/issues
|
||||||
|
-->
|
||||||
|
|
||||||
**Is your feature request related to a problem? Please describe.**
|
**Is your feature request related to a problem? Please describe.**
|
||||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
10
.github/ISSUE_TEMPLATE/issue-report.md
vendored
10
.github/ISSUE_TEMPLATE/issue-report.md
vendored
@@ -8,12 +8,12 @@ assignees: ''
|
|||||||
---
|
---
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Before submitting an issue, make sure that:
|
# READ CAREFULLY:
|
||||||
* You're running the latest Tabby version: https://github.com/Eugeny/tabby/releases
|
|
||||||
* You've searched the existing issues: https://github.com/Eugeny/tabby/issues
|
|
||||||
* Your problem is not caused by third-party plugins (disable _third-party_ plugins, restart and try to reproduce the problem).
|
|
||||||
|
|
||||||
*Reports are accepted in English ONLY.*
|
* **ENGLISH ONLY** - this issue tracker is English-only. Please respect the people who take time to help you with your problems.
|
||||||
|
* Search existing issues first: https://github.com/Eugeny/tabby/issues
|
||||||
|
* Test with the latest Tabby version: https://github.com/Eugeny/tabby/releases
|
||||||
|
* Disable third-party plugins.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
**Describe the problem**:
|
**Describe the problem**:
|
||||||
|
10
.github/workflows/build.yml
vendored
10
.github/workflows/build.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Installing Node
|
- name: Installing Node
|
||||||
uses: actions/setup-node@v2.5.0
|
uses: actions/setup-node@v2.5.1
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 16
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Installing Node
|
- name: Installing Node
|
||||||
uses: actions/setup-node@v2.5.0
|
uses: actions/setup-node@v2.5.1
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 16
|
||||||
|
|
||||||
@@ -139,7 +139,7 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Install Node
|
- name: Install Node
|
||||||
uses: actions/setup-node@v2.5.0
|
uses: actions/setup-node@v2.5.1
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 16
|
||||||
|
|
||||||
@@ -183,7 +183,7 @@ jobs:
|
|||||||
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
|
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
|
||||||
|
|
||||||
- name: Upload packages to packagecloud.io
|
- name: Upload packages to packagecloud.io
|
||||||
uses: TykTechnologies/packagecloud-action@main
|
uses: Eugeny/packagecloud-action@main
|
||||||
if: github.repository == 'Eugeny/tabby' && github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
|
if: github.repository == 'Eugeny/tabby' && github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
|
||||||
env:
|
env:
|
||||||
PACKAGECLOUD_TOKEN: ${{ secrets.PACKAGECLOUD_TOKEN }}
|
PACKAGECLOUD_TOKEN: ${{ secrets.PACKAGECLOUD_TOKEN }}
|
||||||
@@ -253,7 +253,7 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Installing Node
|
- name: Installing Node
|
||||||
uses: actions/setup-node@v2.5.0
|
uses: actions/setup-node@v2.5.1
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 16
|
||||||
|
|
||||||
|
2
.github/workflows/docs.yml
vendored
2
.github/workflows/docs.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
|||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Installing Node
|
- name: Installing Node
|
||||||
uses: actions/setup-node@v2.5.0
|
uses: actions/setup-node@v2.5.1
|
||||||
with:
|
with:
|
||||||
node-version: 14
|
node-version: 14
|
||||||
|
|
||||||
|
15
.github/workflows/issue-translator.yml
vendored
Normal file
15
.github/workflows/issue-translator.yml
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
name: 'issue-translator'
|
||||||
|
on:
|
||||||
|
issue_comment:
|
||||||
|
types: [created]
|
||||||
|
issues:
|
||||||
|
types: [opened]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: tomsun28/issues-translate-action@v2.6
|
||||||
|
with:
|
||||||
|
IS_MODIFY_TITLE: true
|
||||||
|
CUSTOM_BOT_NOTE: The translator bot has detected that this issue body's language is not English, and has translated it automatically.
|
2
.gitignore
vendored
2
.gitignore
vendored
@@ -34,3 +34,5 @@ sentry-symbols.js
|
|||||||
|
|
||||||
tabby-ssh/util/pagent.exe
|
tabby-ssh/util/pagent.exe
|
||||||
*.psd
|
*.psd
|
||||||
|
|
||||||
|
crowdin.yml
|
||||||
|
@@ -204,6 +204,30 @@ Pull requests and plugins are welcome!
|
|||||||
<td align="center"><a href="https://github.com/cypherbits"><img src="https://avatars.githubusercontent.com/u/10424900?v=4?s=100" width="100px;" alt=""/><br /><sub><b>cypherbits</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=cypherbits" title="Documentation">📖</a></td>
|
<td align="center"><a href="https://github.com/cypherbits"><img src="https://avatars.githubusercontent.com/u/10424900?v=4?s=100" width="100px;" alt=""/><br /><sub><b>cypherbits</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=cypherbits" title="Documentation">📖</a></td>
|
||||||
<td align="center"><a href="https://modulolotus.net"><img src="https://avatars.githubusercontent.com/u/946421?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Matthew Davidson</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=KingMob" title="Code">💻</a></td>
|
<td align="center"><a href="https://modulolotus.net"><img src="https://avatars.githubusercontent.com/u/946421?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Matthew Davidson</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=KingMob" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="https://github.com/al-wi"><img src="https://avatars.githubusercontent.com/u/11092199?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alexander Wiedemann</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=al-wi" title="Code">💻</a></td>
|
<td align="center"><a href="https://github.com/al-wi"><img src="https://avatars.githubusercontent.com/u/11092199?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alexander Wiedemann</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=al-wi" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://www.notion.so/3d45c6bd2cbd4f938873a4bd12e23375"><img src="https://avatars.githubusercontent.com/u/59506394?v=4?s=100" width="100px;" alt=""/><br /><sub><b>장보연</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=BoYeonJang" title="Documentation">📖</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://github.com/Me1onRind"><img src="https://avatars.githubusercontent.com/u/19531270?v=4?s=100" width="100px;" alt=""/><br /><sub><b>zZ</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Me1onRind" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/tainoNZ"><img src="https://avatars.githubusercontent.com/u/49261322?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Aaron Davison</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=tainoNZ" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/composer404"><img src="https://avatars.githubusercontent.com/u/58251560?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Przemyslaw Kozik</b></sub></a><br /><a href="#design-composer404" title="Design">🎨</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/highfredo"><img src="https://avatars.githubusercontent.com/u/5951524?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alfredo Arellano de la Fuente</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=highfredo" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/NessunKim"><img src="https://avatars.githubusercontent.com/u/12974079?v=4?s=100" width="100px;" alt=""/><br /><sub><b>MH Kim</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=NessunKim" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://discord.gg/4c5EVTBhtp"><img src="https://avatars.githubusercontent.com/u/40345645?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Marmota</b></sub></a><br /><a href="#design-jaimeadf" title="Design">🎨</a></td>
|
||||||
|
<td align="center"><a href="https://ares.zone"><img src="https://avatars.githubusercontent.com/u/40336192?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ares Andrew</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=TENX-S" title="Documentation">📖</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://usual.io/"><img src="https://avatars.githubusercontent.com/u/780052?v=4?s=100" width="100px;" alt=""/><br /><sub><b>George Korsnick</b></sub></a><br /><a href="#financial-gkor" title="Financial">💵</a></td>
|
||||||
|
<td align="center"><a href="https://about.me/ulu"><img src="https://avatars.githubusercontent.com/u/872764?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Artem Smirnov</b></sub></a><br /><a href="#financial-uluhonolulu" title="Financial">💵</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/nevotheless"><img src="https://avatars.githubusercontent.com/u/779797?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tim Kopplow</b></sub></a><br /><a href="#financial-nevotheless" title="Financial">💵</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/mrthock"><img src="https://avatars.githubusercontent.com/u/88901709?v=4?s=100" width="100px;" alt=""/><br /><sub><b>mrthock</b></sub></a><br /><a href="#financial-mrthock" title="Financial">💵</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/lrottach"><img src="https://avatars.githubusercontent.com/u/50323692?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Lukas Rottach</b></sub></a><br /><a href="#financial-lrottach" title="Financial">💵</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/boonkerz"><img src="https://avatars.githubusercontent.com/u/277321?v=4?s=100" width="100px;" alt=""/><br /><sub><b>boonkerz</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=boonkerz" title="Code">💻</a> <a href="#translation-boonkerz" title="Translation">🌍</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/milotype"><img src="https://avatars.githubusercontent.com/u/43657314?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Milo Ivir</b></sub></a><br /><a href="#translation-milotype" title="Translation">🌍</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://github.com/JasonCubic"><img src="https://avatars.githubusercontent.com/u/8921015?v=4?s=100" width="100px;" alt=""/><br /><sub><b>JasonCubic</b></sub></a><br /><a href="#design-JasonCubic" title="Design">🎨</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/MaxWaldorf"><img src="https://avatars.githubusercontent.com/u/15877853?v=4?s=100" width="100px;" alt=""/><br /><sub><b>MaxWaldorf</b></sub></a><br /><a href="#infra-MaxWaldorf" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/mwz"><img src="https://avatars.githubusercontent.com/u/1190768?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Michael Wizner</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mwz" title="Code">💻</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
23
README.md
23
README.md
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://github.com/Eugeny/tabby/releases/latest"><img alt="GitHub All Releases" src="https://img.shields.io/github/downloads/eugeny/tabby/total.svg?label=DOWNLOADS&logo=github&style=for-the-badge"></a> <a href="https://nightly.link/Eugeny/tabby/workflows/build/master"><img src="https://shields.io/badge/-Nightly%20Builds-orange?logo=hackthebox&logoColor=fff&style=for-the-badge"/></a> <a href="https://matrix.to/#/#tabby-general:matrix.org"><img alt="Matrix" src="https://img.shields.io/matrix/tabby-general:matrix.org?logo=matrix&style=for-the-badge&color=magenta"></a> <a href="https://twitter.com/eugeeeeny"><img alt="Twitter" src="https://shields.io/badge/Subscribe-News-blue?logo=twitter&style=for-the-badge&color=blue"></a>
|
<a href="https://github.com/Eugeny/tabby/releases/latest"><img alt="GitHub All Releases" src="https://img.shields.io/github/downloads/eugeny/tabby/total.svg?label=DOWNLOADS&logo=github&style=for-the-badge"></a> <a href="https://nightly.link/Eugeny/tabby/workflows/build/master"><img src="https://shields.io/badge/-Nightly%20Builds-orange?logo=hackthebox&logoColor=fff&style=for-the-badge"/></a> <a href="https://matrix.to/#/#tabby-general:matrix.org"><img alt="Matrix" src="https://img.shields.io/matrix/tabby-general:matrix.org?logo=matrix&style=for-the-badge&color=magenta"></a>   <a href="https://translate.tabby.sh/"><img alt="Translate" src="https://shields.io/badge/Translate-UI-white?logo=googletranslate&style=for-the-badge&color=white&logoColor=fff"></a> <a href="https://twitter.com/eugeeeeny"><img alt="Twitter" src="https://shields.io/badge/Subscribe-News-blue?logo=twitter&style=for-the-badge&color=blue"></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
<p align="center">
|
<p align="center">
|
||||||
This README is also available in: <a href="./README.ko-KR.md">Korean</a>
|
This README is also available in: <a href="./README.ru-RU.md">Русский</a> <a href="./README.ko-KR.md">한국어</a> <a href="./README.zh-CN.md">简体中文</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
----
|
----
|
||||||
@@ -108,7 +108,6 @@ Tabby will run as a portable app on Windows, if you create a `data` folder in th
|
|||||||
|
|
||||||
Plugins and themes can be installed directly from the Settings view inside Tabby.
|
Plugins and themes can be installed directly from the Settings view inside Tabby.
|
||||||
|
|
||||||
* [clickable-links](https://github.com/Eugeny/tabby-clickable-links) - makes paths and URLs in the terminal clickable
|
|
||||||
* [docker](https://github.com/Eugeny/tabby-docker) - connect to Docker containers
|
* [docker](https://github.com/Eugeny/tabby-docker) - connect to Docker containers
|
||||||
* [title-control](https://github.com/kbjr/terminus-title-control) - allows modifying the title of the terminal tabs by providing a prefix, suffix, and/or strings to be removed
|
* [title-control](https://github.com/kbjr/terminus-title-control) - allows modifying the title of the terminal tabs by providing a prefix, suffix, and/or strings to be removed
|
||||||
* [quick-cmds](https://github.com/Domain/terminus-quick-cmds) - quickly send commands to one or all terminal tabs
|
* [quick-cmds](https://github.com/Domain/terminus-quick-cmds) - quickly send commands to one or all terminal tabs
|
||||||
@@ -218,6 +217,22 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|||||||
<td align="center"><a href="https://github.com/composer404"><img src="https://avatars.githubusercontent.com/u/58251560?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Przemyslaw Kozik</b></sub></a><br /><a href="#design-composer404" title="Design">🎨</a></td>
|
<td align="center"><a href="https://github.com/composer404"><img src="https://avatars.githubusercontent.com/u/58251560?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Przemyslaw Kozik</b></sub></a><br /><a href="#design-composer404" title="Design">🎨</a></td>
|
||||||
<td align="center"><a href="https://github.com/highfredo"><img src="https://avatars.githubusercontent.com/u/5951524?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alfredo Arellano de la Fuente</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=highfredo" title="Code">💻</a></td>
|
<td align="center"><a href="https://github.com/highfredo"><img src="https://avatars.githubusercontent.com/u/5951524?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alfredo Arellano de la Fuente</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=highfredo" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="https://github.com/NessunKim"><img src="https://avatars.githubusercontent.com/u/12974079?v=4?s=100" width="100px;" alt=""/><br /><sub><b>MH Kim</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=NessunKim" title="Code">💻</a></td>
|
<td align="center"><a href="https://github.com/NessunKim"><img src="https://avatars.githubusercontent.com/u/12974079?v=4?s=100" width="100px;" alt=""/><br /><sub><b>MH Kim</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=NessunKim" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://discord.gg/4c5EVTBhtp"><img src="https://avatars.githubusercontent.com/u/40345645?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Marmota</b></sub></a><br /><a href="#design-jaimeadf" title="Design">🎨</a></td>
|
||||||
|
<td align="center"><a href="https://ares.zone"><img src="https://avatars.githubusercontent.com/u/40336192?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ares Andrew</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=TENX-S" title="Documentation">📖</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://usual.io/"><img src="https://avatars.githubusercontent.com/u/780052?v=4?s=100" width="100px;" alt=""/><br /><sub><b>George Korsnick</b></sub></a><br /><a href="#financial-gkor" title="Financial">💵</a></td>
|
||||||
|
<td align="center"><a href="https://about.me/ulu"><img src="https://avatars.githubusercontent.com/u/872764?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Artem Smirnov</b></sub></a><br /><a href="#financial-uluhonolulu" title="Financial">💵</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/nevotheless"><img src="https://avatars.githubusercontent.com/u/779797?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tim Kopplow</b></sub></a><br /><a href="#financial-nevotheless" title="Financial">💵</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/mrthock"><img src="https://avatars.githubusercontent.com/u/88901709?v=4?s=100" width="100px;" alt=""/><br /><sub><b>mrthock</b></sub></a><br /><a href="#financial-mrthock" title="Financial">💵</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/lrottach"><img src="https://avatars.githubusercontent.com/u/50323692?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Lukas Rottach</b></sub></a><br /><a href="#financial-lrottach" title="Financial">💵</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/boonkerz"><img src="https://avatars.githubusercontent.com/u/277321?v=4?s=100" width="100px;" alt=""/><br /><sub><b>boonkerz</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=boonkerz" title="Code">💻</a> <a href="#translation-boonkerz" title="Translation">🌍</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/milotype"><img src="https://avatars.githubusercontent.com/u/43657314?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Milo Ivir</b></sub></a><br /><a href="#translation-milotype" title="Translation">🌍</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://github.com/JasonCubic"><img src="https://avatars.githubusercontent.com/u/8921015?v=4?s=100" width="100px;" alt=""/><br /><sub><b>JasonCubic</b></sub></a><br /><a href="#design-JasonCubic" title="Design">🎨</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/MaxWaldorf"><img src="https://avatars.githubusercontent.com/u/15877853?v=4?s=100" width="100px;" alt=""/><br /><sub><b>MaxWaldorf</b></sub></a><br /><a href="#infra-MaxWaldorf" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/mwz"><img src="https://avatars.githubusercontent.com/u/1190768?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Michael Wizner</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mwz" title="Code">💻</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
@@ -227,5 +242,3 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|||||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||||
|
|
||||||
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
||||||
|
|
||||||
<img src="https://ga-beacon.appspot.com/UA-3278102-18/github/readme" width="1"/>
|
|
||||||
|
247
README.ru-RU.md
Normal file
247
README.ru-RU.md
Normal file
@@ -0,0 +1,247 @@
|
|||||||
|
[](https://tabby.sh)
|
||||||
|
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://github.com/Eugeny/tabby/releases/latest"><img alt="GitHub All Releases" src="https://img.shields.io/github/downloads/eugeny/tabby/total.svg?label=DOWNLOADS&logo=github&style=for-the-badge"></a> <a href="https://nightly.link/Eugeny/tabby/workflows/build/master"><img src="https://shields.io/badge/-Nightly%20Builds-orange?logo=hackthebox&logoColor=fff&style=for-the-badge"/></a> <a href="https://matrix.to/#/#tabby-general:matrix.org"><img alt="Matrix" src="https://img.shields.io/matrix/tabby-general:matrix.org?logo=matrix&style=for-the-badge&color=magenta"></a>   <a href="https://translate.tabby.sh/"><img alt="Translate" src="https://shields.io/badge/Translate-UI-white?logo=googletranslate&style=for-the-badge&color=white&logoColor=fff"></a> <a href="https://twitter.com/eugeeeeny"><img alt="Twitter" src="https://shields.io/badge/Subscribe-News-blue?logo=twitter&style=for-the-badge&color=blue"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://ko-fi.com/J3J8KWTF">
|
||||||
|
<img src="https://cdn.ko-fi.com/cdn/kofi3.png?v=2" width="150">
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
### Загрузки:
|
||||||
|
|
||||||
|
* [Последняя версия](https://github.com/Eugeny/tabby/releases/latest)
|
||||||
|
* [Репозитории](https://packagecloud.io/eugeny/tabby): [Debian/Ubuntu](https://packagecloud.io/eugeny/tabby/install#bash-deb), [RPM](https://packagecloud.io/eugeny/tabby/install#bash-rpm)
|
||||||
|
* [Последний nightly-билд](https://nightly.link/Eugeny/tabby/workflows/build/master)
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
<p align="center">
|
||||||
|
Этот README также доступен на: <a href="./README.md">Английском</a> <a href="./README.ko-KR.md">Корейском</a> <a href="./README.zh-CN.md">Китайском</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
[**Tabby**](https://tabby.sh) (ранее **Terminus**) — широко конфигурируемый эмулятор терминала, SSH- и COM-клиент для Windows, macOS и Linux:
|
||||||
|
|
||||||
|
* Встроенный SSH- и Telnet-клиент и менеджер подключений;
|
||||||
|
* Встроенный последовтаельный терминал;
|
||||||
|
* Темы и цветовые схемы;
|
||||||
|
* Полностью настраеваемые сочетания клавиш;
|
||||||
|
* Панели;
|
||||||
|
* Запоминание вкладок;
|
||||||
|
* Поддержка PowerShell (and PS Core), WSL, Git-Bash, Cygwin, MSYS2, Cmder и CMD;
|
||||||
|
* Прямая передача файлов из и в SSH-сессии через Zmodem;
|
||||||
|
* Полная поддержка Unicode, включая символы двойной ширины;
|
||||||
|
* Не задыхается при быстром выводе;
|
||||||
|
* Полноценный опыт работы с shell на Windows, включая дополнение слов и команд по Tab (при помощи Clink);
|
||||||
|
* Втроенное защищённое хранилище для SSH-ключей и настроек;
|
||||||
|
* SSH-, SFTP- и Telnet-клиент доступен как [веб-приложение](https://tabby.sh/app) (также для [самостоятелньного хостинга](https://github.com/Eugeny/tabby-web)).
|
||||||
|
|
||||||
|
# Содержание <!-- omit in toc -->
|
||||||
|
|
||||||
|
- [Правда и ложь про Tabby](#правда-и-ложь-про-tabby)
|
||||||
|
- [Функции терминала](#функции-терминала)
|
||||||
|
- [SSH-клиент](#ssh-клиент)
|
||||||
|
- [Терминал последовательного порта](#терминал-последовательного-порта)
|
||||||
|
- [Портативность](#портативность)
|
||||||
|
- [Плагины](#плагины)
|
||||||
|
- [Темы](#темы)
|
||||||
|
- [Внести свой вклад](#внести-свой-вклад)
|
||||||
|
|
||||||
|
<a name="about"></a>
|
||||||
|
|
||||||
|
# Правда и ложь про Tabby
|
||||||
|
|
||||||
|
* **Правда:** Tabby — это альтернатива стандартному терминалу Windows (conhost), PowerShell ISE, PuTTY, macOS Terminal.app и iTerm.
|
||||||
|
|
||||||
|
* **Ложь:** Tabby — это не новая оболочка или замена MinGW или Cygwin. Также он нелёгок — если потребление ОЗУ крайне важно для вас, лучше взгляните на [Conemu](https://conemu.github.io) или [Alacritty](https://github.com/jwilm/alacritty).
|
||||||
|
|
||||||
|
<a name="terminal"></a>
|
||||||
|
|
||||||
|
# Функции терминала
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
* Терминал V220 + различные дополнения;
|
||||||
|
* Деление окна на несколько панелей;
|
||||||
|
* Вкладки на любой стороне окна;
|
||||||
|
* Опционально закрепляемое окно с глобальной горячей клавишей для вызова («Quake console»);
|
||||||
|
* Определение прогресса процесса;
|
||||||
|
* Уведомления о завершении процессов;
|
||||||
|
* Защита от выполнения команд при вставке, предупреждения о вставке нескольких строк;
|
||||||
|
* Лигатуры шрифтов;
|
||||||
|
* Пользовательские профили оболочки;
|
||||||
|
* Опциональная ПКМ-вставка и копирование при выделении (в стиле PuTTY).
|
||||||
|
|
||||||
|
<a name="ssh"></a>
|
||||||
|
# SSH-клиент
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
* SSH2-клиент с менеджером соединений;
|
||||||
|
* Проброс портов и X11;
|
||||||
|
* Управление автоматическими джамп-хостами;
|
||||||
|
* Проброс агента (включая Pageant и встроеный в Windows OpenSSH Agent);
|
||||||
|
* Скрипты для входа.
|
||||||
|
|
||||||
|
<a name="serial"></a>
|
||||||
|
# Терминал последовательного порта
|
||||||
|
|
||||||
|
* Сохранение соединений;
|
||||||
|
* Поддержка ввода readline;
|
||||||
|
* Опциональый побатный ввод HEX и вывод hexdump;
|
||||||
|
* Преобразование newline;
|
||||||
|
* Автоматическое восстановление соединения.
|
||||||
|
|
||||||
|
<a name="portable"></a>
|
||||||
|
# Портативность
|
||||||
|
|
||||||
|
На Windows Tabby будет работать в портативном режиме, если создать папку `data` там же, где расположен файл `Tabby.exe`.
|
||||||
|
|
||||||
|
<a name="plugins"></a>
|
||||||
|
# Плагины
|
||||||
|
|
||||||
|
Плагины и темы можно установить напрямую из Настроек Tabby.
|
||||||
|
|
||||||
|
* [clickable-links](https://github.com/Eugeny/tabby-clickable-links) — делает пути и URL в терминале гиперссылками;
|
||||||
|
* [docker](https://github.com/Eugeny/tabby-docker) — подключения к Docker-контейнерам;
|
||||||
|
* [title-control](https://github.com/kbjr/terminus-title-control) — позволяет изменять названия вкладок, добавляя префиксы, суффиксы и позволяя удалять строки;
|
||||||
|
* [quick-cmds](https://github.com/Domain/terminus-quick-cmds) — быстро передаёт команды в одну или все вкладки терминала;
|
||||||
|
* [save-output](https://github.com/Eugeny/tabby-save-output) — запись вывода терминала в файл;
|
||||||
|
* [sync-config](https://github.com/starxg/terminus-sync-config) — синхронизация конфига в Gist или Gitee;
|
||||||
|
* [clippy](https://github.com/Eugeny/tabby-clippy) — плагин-пример, который постоянно будет вас бесить;
|
||||||
|
* [workspace-manager](https://github.com/composer404/tabby-workspace-manager) — позволяет создавать пользовательские провили рабочего окружеиня на основе конфига;
|
||||||
|
* [search-in-browser](https://github.com/composer404/tabby-search-in-browser) — открывает браузер по умолчанию с текстом, выделенном во вкладке Tabby.
|
||||||
|
|
||||||
|
<a name="themes"></a>
|
||||||
|
# Темы
|
||||||
|
|
||||||
|
* [hype](https://github.com/Eugeny/tabby-theme-hype) — тема, вдохновлённая Hyper;
|
||||||
|
* [relaxed](https://github.com/Relaxed-Theme/relaxed-terminal-themes#terminus) — тема Relaxed для Tabby;
|
||||||
|
* [gruvbox](https://github.com/porkloin/terminus-theme-gruvbox);
|
||||||
|
* [windows10](https://www.npmjs.com/package/terminus-theme-windows10);
|
||||||
|
* [altair](https://github.com/yxuko/terminus-altair).
|
||||||
|
|
||||||
|
# Спонсоры <!-- omit in toc -->
|
||||||
|
|
||||||
|
[](https://packagecloud.io)
|
||||||
|
|
||||||
|
[**packagecloud**](https://packagecloud.io) предоставил бесплатный хостинг для Debian/RPM репозитория.
|
||||||
|
|
||||||
|
<a name="contributing"></a>
|
||||||
|
# Внести свой вклад
|
||||||
|
|
||||||
|
Pull-запросы и плагины приветствуются!
|
||||||
|
|
||||||
|
Взгляните на [HACKING.md](https://github.com/Eugeny/tabby/blob/master/HACKING.md) и [API docs](https://docs.tabby.sh/), чтобы понять, как устроен проект, и ради очень краткого туториала по созданию плагинов.
|
||||||
|
|
||||||
|
---
|
||||||
|
<a name="contributors"></a>
|
||||||
|
|
||||||
|
Огромное спасибо этим прекрасным людям ([описание эмодзи](https://allcontributors.org/docs/en/emoji-key)):
|
||||||
|
|
||||||
|
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
<!-- markdownlint-disable -->
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="http://www.russellmyers.com"><img src="https://avatars2.githubusercontent.com/u/184085?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Russell Myers</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Austin Warren</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Felicia Hummel</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Mike MacCana</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Yacine Kanzari</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>BBJip</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><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?s=100" width="100px;" alt=""/><br /><sub><b>Levin Rickert</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>OJ Kwon</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>domain</b></sub></a><br /><a href="#plugin-Domain" title="Plugin/utility libraries">🔌</a> <a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>James Brumond</b></sub></a><br /><a href="#plugin-kbjr" title="Plugin/utility libraries">🔌</a></td>
|
||||||
|
<td align="center"><a href="http://www.growingwiththeweb.com"><img src="https://avatars0.githubusercontent.com/u/2193314?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Daniel Imms</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Tyriar" title="Code">💻</a> <a href="#plugin-Tyriar" title="Plugin/utility libraries">🔌</a> <a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Florian Bachmann</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Michael Kühnel</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Tilmann Meyer</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>PM Extra</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Jonathan</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Hans Koch</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Dak Smyth</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Wang Zhi</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>jack1142</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Howie Douglas</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Chris Kaczor</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Johannes Kadak</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=boxmein" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/LeSeulArtichaut"><img src="https://avatars1.githubusercontent.com/u/38361244?v=4?s=100" width="100px;" alt=""/><br /><sub><b>LeSeulArtichaut</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=LeSeulArtichaut" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/CyrilTaylor"><img src="https://avatars0.githubusercontent.com/u/12631466?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Cyril Taylor</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=CyrilTaylor" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/nstefanou"><img src="https://avatars3.githubusercontent.com/u/51129173?v=4?s=100" width="100px;" alt=""/><br /><sub><b>nstefanou</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=nstefanou" title="Code">💻</a> <a href="#plugin-nstefanou" title="Plugin/utility libraries">🔌</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/orin220444"><img src="https://avatars3.githubusercontent.com/u/30747229?v=4?s=100" width="100px;" alt=""/><br /><sub><b>orin220444</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=orin220444" title="Code">💻</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://github.com/Goobles"><img src="https://avatars3.githubusercontent.com/u/8776771?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Gobius Dolhain</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Goobles" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/3l0w"><img src="https://avatars2.githubusercontent.com/u/37798980?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Gwilherm Folliot</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=3l0w" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/Dimitory"><img src="https://avatars0.githubusercontent.com/u/475955?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dmitry Pronin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=dimitory" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/JonathanBeverley"><img src="https://avatars1.githubusercontent.com/u/20328966?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jonathan Beverley</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=JonathanBeverley" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/zend"><img src="https://avatars1.githubusercontent.com/u/25160?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Zenghai Liang</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=zend" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://about.me/matishadow"><img src="https://avatars0.githubusercontent.com/u/9083085?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mateusz Tracz</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=matishadow" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://zergpool.com"><img src="https://avatars3.githubusercontent.com/u/36234677?v=4?s=100" width="100px;" alt=""/><br /><sub><b>pinpin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=pinpins" title="Code">💻</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://github.com/TakuroOnoda"><img src="https://avatars0.githubusercontent.com/u/1407926?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Takuro Onoda</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=TakuroOnoda" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/frauhottelmann"><img src="https://avatars2.githubusercontent.com/u/902705?v=4?s=100" width="100px;" alt=""/><br /><sub><b>frauhottelmann</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=frauhottelmann" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="http://patalong.pl"><img src="https://avatars.githubusercontent.com/u/29167842?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Piotr Patalong</b></sub></a><br /><a href="#design-VectorKappa" title="Design">🎨</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/clarkwang"><img src="https://avatars.githubusercontent.com/u/157076?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Clark Wang</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=clarkwang" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/iamchating"><img src="https://avatars.githubusercontent.com/u/7088153?v=4?s=100" width="100px;" alt=""/><br /><sub><b>iamchating</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=iamchating" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/starxg"><img src="https://avatars.githubusercontent.com/u/34997494?v=4?s=100" width="100px;" alt=""/><br /><sub><b>starxg</b></sub></a><br /><a href="#plugin-starxg" title="Plugin/utility libraries">🔌</a></td>
|
||||||
|
<td align="center"><a href="http://hashnote.net/"><img src="https://avatars.githubusercontent.com/u/546312?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alisue</b></sub></a><br /><a href="#design-lambdalisue" title="Design">🎨</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://github.com/ydcool"><img src="https://avatars.githubusercontent.com/u/5668295?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dominic Yin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=ydcool" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/bdr99"><img src="https://avatars.githubusercontent.com/u/2292715?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Brandon Rothweiler</b></sub></a><br /><a href="#design-bdr99" title="Design">🎨</a></td>
|
||||||
|
<td align="center"><a href="https://git.io/JnP49"><img src="https://avatars.githubusercontent.com/u/63876444?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Logic Machine</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=logicmachine123" title="Documentation">📖</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/cypherbits"><img src="https://avatars.githubusercontent.com/u/10424900?v=4?s=100" width="100px;" alt=""/><br /><sub><b>cypherbits</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=cypherbits" title="Documentation">📖</a></td>
|
||||||
|
<td align="center"><a href="https://modulolotus.net"><img src="https://avatars.githubusercontent.com/u/946421?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Matthew Davidson</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=KingMob" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/al-wi"><img src="https://avatars.githubusercontent.com/u/11092199?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alexander Wiedemann</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=al-wi" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://www.notion.so/3d45c6bd2cbd4f938873a4bd12e23375"><img src="https://avatars.githubusercontent.com/u/59506394?v=4?s=100" width="100px;" alt=""/><br /><sub><b>장보연</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=BoYeonJang" title="Documentation">📖</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://github.com/Me1onRind"><img src="https://avatars.githubusercontent.com/u/19531270?v=4?s=100" width="100px;" alt=""/><br /><sub><b>zZ</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Me1onRind" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/tainoNZ"><img src="https://avatars.githubusercontent.com/u/49261322?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Aaron Davison</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=tainoNZ" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/composer404"><img src="https://avatars.githubusercontent.com/u/58251560?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Przemyslaw Kozik</b></sub></a><br /><a href="#design-composer404" title="Design">🎨</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/highfredo"><img src="https://avatars.githubusercontent.com/u/5951524?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alfredo Arellano de la Fuente</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=highfredo" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/NessunKim"><img src="https://avatars.githubusercontent.com/u/12974079?v=4?s=100" width="100px;" alt=""/><br /><sub><b>MH Kim</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=NessunKim" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://discord.gg/4c5EVTBhtp"><img src="https://avatars.githubusercontent.com/u/40345645?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Marmota</b></sub></a><br /><a href="#design-jaimeadf" title="Design">🎨</a></td>
|
||||||
|
<td align="center"><a href="https://ares.zone"><img src="https://avatars.githubusercontent.com/u/40336192?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ares Andrew</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=TENX-S" title="Documentation">📖</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://usual.io/"><img src="https://avatars.githubusercontent.com/u/780052?v=4?s=100" width="100px;" alt=""/><br /><sub><b>George Korsnick</b></sub></a><br /><a href="#financial-gkor" title="Financial">💵</a></td>
|
||||||
|
<td align="center"><a href="https://about.me/ulu"><img src="https://avatars.githubusercontent.com/u/872764?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Artem Smirnov</b></sub></a><br /><a href="#financial-uluhonolulu" title="Financial">💵</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/nevotheless"><img src="https://avatars.githubusercontent.com/u/779797?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tim Kopplow</b></sub></a><br /><a href="#financial-nevotheless" title="Financial">💵</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/mrthock"><img src="https://avatars.githubusercontent.com/u/88901709?v=4?s=100" width="100px;" alt=""/><br /><sub><b>mrthock</b></sub></a><br /><a href="#financial-mrthock" title="Financial">💵</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/lrottach"><img src="https://avatars.githubusercontent.com/u/50323692?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Lukas Rottach</b></sub></a><br /><a href="#financial-lrottach" title="Financial">💵</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/boonkerz"><img src="https://avatars.githubusercontent.com/u/277321?v=4?s=100" width="100px;" alt=""/><br /><sub><b>boonkerz</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=boonkerz" title="Code">💻</a> <a href="#translation-boonkerz" title="Translation">🌍</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/milotype"><img src="https://avatars.githubusercontent.com/u/43657314?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Milo Ivir</b></sub></a><br /><a href="#translation-milotype" title="Translation">🌍</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://github.com/JasonCubic"><img src="https://avatars.githubusercontent.com/u/8921015?v=4?s=100" width="100px;" alt=""/><br /><sub><b>JasonCubic</b></sub></a><br /><a href="#design-JasonCubic" title="Design">🎨</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/MaxWaldorf"><img src="https://avatars.githubusercontent.com/u/15877853?v=4?s=100" width="100px;" alt=""/><br /><sub><b>MaxWaldorf</b></sub></a><br /><a href="#infra-MaxWaldorf" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/mwz"><img src="https://avatars.githubusercontent.com/u/1190768?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Michael Wizner</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mwz" title="Code">💻</a></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- markdownlint-restore -->
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
|
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||||
|
|
||||||
|
Данный проект следует заветам [all-contributors](https://github.com/all-contributors/all-contributors). Любые созидатели приветствуются!
|
||||||
|
|
||||||
|
<img src="https://ga-beacon.appspot.com/UA-3278102-18/github/readme" width="1"/>
|
244
README.zh-CN.md
Normal file
244
README.zh-CN.md
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
[](https://tabby.sh)
|
||||||
|
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://github.com/Eugeny/tabby/releases/latest"><img alt="GitHub All Releases" src="https://img.shields.io/github/downloads/eugeny/tabby/total.svg?label=DOWNLOADS&logo=github&style=for-the-badge"></a> <a href="https://nightly.link/Eugeny/tabby/workflows/build/master"><img src="https://shields.io/badge/-Nightly%20Builds-orange?logo=hackthebox&logoColor=fff&style=for-the-badge"/></a> <a href="https://matrix.to/#/#tabby-general:matrix.org"><img alt="Matrix" src="https://img.shields.io/matrix/tabby-general:matrix.org?logo=matrix&style=for-the-badge&color=magenta"></a>   <a href="https://translate.tabby.sh/"><img alt="Translate" src="https://shields.io/badge/Translate-UI-white?logo=googletranslate&style=for-the-badge&color=white&logoColor=fff"></a> <a href="https://twitter.com/eugeeeeny"><img alt="Twitter" src="https://shields.io/badge/Subscribe-News-blue?logo=twitter&style=for-the-badge&color=blue"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://ko-fi.com/J3J8KWTF">
|
||||||
|
<img src="https://cdn.ko-fi.com/cdn/kofi3.png?v=2" width="150">
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
### 下载
|
||||||
|
|
||||||
|
* [Latest release](https://github.com/Eugeny/tabby/releases/latest)
|
||||||
|
* [Repositories](https://packagecloud.io/eugeny/tabby): [Debian/Ubuntu-based](https://packagecloud.io/eugeny/tabby/install#bash-deb), [RPM-based](https://packagecloud.io/eugeny/tabby/install#bash-rpm)
|
||||||
|
* [Latest nightly build](https://nightly.link/Eugeny/tabby/workflows/build/master)
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
<p align="center">
|
||||||
|
本 README 还适用于以下语言: <a href="./README.ru-RU.md">Русский</a> <a href="./README.ko-KR.md">한국어</a> <a href="./README.zh-CN.md">简体中文</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
|
[**Tabby**](https://tabby.sh) (前身是 **Terminus**) 是一个可高度配置的终端模拟器和 SSH 或串口客户端,支持 Windows,macOS 和 Linux
|
||||||
|
|
||||||
|
* 集成 SSH,Telnet 客户端和连接管理器
|
||||||
|
* 集成串行终端
|
||||||
|
* 定制主题和配色方案
|
||||||
|
* 完全可配置的快捷键和多键快捷键
|
||||||
|
* 分体式窗格
|
||||||
|
* 自动保存标签页
|
||||||
|
* 支持 PowerShell(和 PS Core)、WSL、Git-Bash、Cygwin、MSYS2、Cmder 和 CMD
|
||||||
|
* 在 SSH 会话中通过 Zmodem 进行直接文件传输
|
||||||
|
* 完整的 Unicode 支持,包括双角字符
|
||||||
|
* 不会因快速的输出而卡住
|
||||||
|
* Windows 上舒适的 shell 体验,包括 tab 自动补全(通过 Clink)
|
||||||
|
* 为 SSH secrets 和设置集成了加密容器
|
||||||
|
* SSH、SFTP 和 Telnet 客户端可用作 [Web 应用](https://tabby.sh/app)(也可[托管](https://github.com/Eugeny/tabby-web))
|
||||||
|
|
||||||
|
# 目录 <!-- omit in toc -->
|
||||||
|
|
||||||
|
- [Tabby的正确用途](#tabby的正确用途)
|
||||||
|
- [终端特性](#终端特性)
|
||||||
|
- [SSH 客户端](#ssh-客户端)
|
||||||
|
- [串行终端](#串行终端)
|
||||||
|
- [便携式应用](#便携式应用)
|
||||||
|
- [插件](#插件)
|
||||||
|
- [主题](#主题)
|
||||||
|
- [贡献](#贡献)
|
||||||
|
|
||||||
|
<a name="about"></a>
|
||||||
|
|
||||||
|
# Tabby的正确用途
|
||||||
|
|
||||||
|
* **Tabby 是** Windows 标准终端 (conhost)、PowerShell ISE、PuTTY、macOS Terminal.app 和 iTerm 的替代品
|
||||||
|
|
||||||
|
* **Tabby 不是**一个全新的 shell,也不是 MinGW 或 Cygwin 的替代品。它也不是轻量级的 - 如果你对内存的占用很敏感,请考虑 [Conemu](https://conemu.github.io) 或 [Alacritty](https://github.com/jwilm/alacritty)
|
||||||
|
<a name="terminal"></a>
|
||||||
|
|
||||||
|
# 终端特性
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
* 一个 V220 终端 + 各种插件
|
||||||
|
* 多个嵌套的拆分窗格
|
||||||
|
* 可以将标签页设置在窗口的任意一侧
|
||||||
|
* 带有全局生成热键的可选可停靠窗口(“Quake console”)
|
||||||
|
* 进度检测
|
||||||
|
* 流程完成通知
|
||||||
|
* 带括号的粘贴,多行粘贴提示
|
||||||
|
* 连体字
|
||||||
|
* 自定义 shell 配置文件
|
||||||
|
* 可选的 RMB 粘贴和复制选择(PuTTY 风格)
|
||||||
|
|
||||||
|
<a name="ssh"></a>
|
||||||
|
# SSH 客户端
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
* 带有连接管理器的 SSH2 客户端
|
||||||
|
* X11和端口转发
|
||||||
|
* 自动跳转主机管理
|
||||||
|
* 代理转发(包括 Pageant 和 Windows 原生 OpenSSH 代理)
|
||||||
|
* 登录脚本
|
||||||
|
|
||||||
|
<a name="serial"></a>
|
||||||
|
# 串行终端
|
||||||
|
|
||||||
|
* 保存连接
|
||||||
|
* 逐行读取的输入支持
|
||||||
|
* 可选的十六进制逐字节输入和十六进制转储输出
|
||||||
|
* 换行转换
|
||||||
|
* 自动重连
|
||||||
|
|
||||||
|
<a name="portable"></a>
|
||||||
|
# 便携式应用
|
||||||
|
|
||||||
|
如果在 Tabby.exe 所在的目录创建一个名为`data`文件夹,Tabby 将可以在 Windows 上作为便携式的应用程序运行。
|
||||||
|
|
||||||
|
<a name="plugins"></a>
|
||||||
|
# 插件
|
||||||
|
|
||||||
|
插件和主题可以直接在 Tabby 设置中安装。
|
||||||
|
|
||||||
|
* [clickable-links](https://github.com/Eugeny/tabby-clickable-links) - 使终端中的路径和 URL 可点击
|
||||||
|
* [docker](https://github.com/Eugeny/tabby-docker) - 连接 Docker 容器
|
||||||
|
* [title-control](https://github.com/kbjr/terminus-title-control) - 允许通过提供要删除的前缀、后缀和/或字符串来修改标签页的标题
|
||||||
|
* [quick-cmds](https://github.com/Domain/terminus-quick-cmds) - 快速向一个或所有标签页发送命令
|
||||||
|
* [save-output](https://github.com/Eugeny/tabby-save-output) - 将终端输出记录到文件中
|
||||||
|
* [sync-config](https://github.com/starxg/terminus-sync-config) - 将配置同步到 Gist 或 Gitee
|
||||||
|
* [clippy](https://github.com/Eugeny/tabby-clippy) - 一个可以一直烦你的示例插件
|
||||||
|
* [workspace-manager](https://github.com/composer404/tabby-workspace-manager) - 允许根据给定的配置创建自定义工作区配置文件
|
||||||
|
* [search-in-browser](https://github.com/composer404/tabby-search-in-browser) - 从 Tabby 标签页带有选中的文本来打开系统默认浏览器
|
||||||
|
|
||||||
|
<a name="themes"></a>
|
||||||
|
# 主题
|
||||||
|
|
||||||
|
* [hype](https://github.com/Eugeny/tabby-theme-hype) - 受 Hyper 启发的主题
|
||||||
|
* [relaxed](https://github.com/Relaxed-Theme/relaxed-terminal-themes#terminus) - 为 Tabby 打造的 Relaxed 主题
|
||||||
|
* [gruvbox](https://github.com/porkloin/terminus-theme-gruvbox)
|
||||||
|
* [windows10](https://www.npmjs.com/package/terminus-theme-windows10)
|
||||||
|
* [altair](https://github.com/yxuko/terminus-altair)
|
||||||
|
|
||||||
|
# Sponsors <!-- omit in toc -->
|
||||||
|
|
||||||
|
[](https://packagecloud.io)
|
||||||
|
|
||||||
|
[**packagecloud**](https://packagecloud.io) 提供了免费的 Debian/RPM 存储库托管
|
||||||
|
|
||||||
|
<a name="contributing"></a>
|
||||||
|
# 贡献
|
||||||
|
|
||||||
|
欢迎提交 PR 和插件!
|
||||||
|
|
||||||
|
请参阅 [HACKING.md](https://github.com/Eugeny/tabby/blob/master/HACKING.md) 和 [API 文档](https://docs.tabby.sh/) 以获取有关项目布局的信息以及非常简短的插件开发教程。
|
||||||
|
|
||||||
|
---
|
||||||
|
<a name="contributors"></a>
|
||||||
|
|
||||||
|
感谢这些人,他们棒极了!([emoji key](https://allcontributors.org/docs/en/emoji-key)):
|
||||||
|
|
||||||
|
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
<!-- markdownlint-disable -->
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="http://www.russellmyers.com"><img src="https://avatars2.githubusercontent.com/u/184085?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Russell Myers</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Austin Warren</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Felicia Hummel</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Mike MacCana</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Yacine Kanzari</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>BBJip</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><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?s=100" width="100px;" alt=""/><br /><sub><b>Levin Rickert</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>OJ Kwon</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>domain</b></sub></a><br /><a href="#plugin-Domain" title="Plugin/utility libraries">🔌</a> <a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>James Brumond</b></sub></a><br /><a href="#plugin-kbjr" title="Plugin/utility libraries">🔌</a></td>
|
||||||
|
<td align="center"><a href="http://www.growingwiththeweb.com"><img src="https://avatars0.githubusercontent.com/u/2193314?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Daniel Imms</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Tyriar" title="Code">💻</a> <a href="#plugin-Tyriar" title="Plugin/utility libraries">🔌</a> <a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Florian Bachmann</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Michael Kühnel</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Tilmann Meyer</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>PM Extra</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Jonathan</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Hans Koch</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Dak Smyth</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Wang Zhi</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>jack1142</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Howie Douglas</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Chris Kaczor</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/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?s=100" width="100px;" alt=""/><br /><sub><b>Johannes Kadak</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=boxmein" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/LeSeulArtichaut"><img src="https://avatars1.githubusercontent.com/u/38361244?v=4?s=100" width="100px;" alt=""/><br /><sub><b>LeSeulArtichaut</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=LeSeulArtichaut" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/CyrilTaylor"><img src="https://avatars0.githubusercontent.com/u/12631466?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Cyril Taylor</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=CyrilTaylor" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/nstefanou"><img src="https://avatars3.githubusercontent.com/u/51129173?v=4?s=100" width="100px;" alt=""/><br /><sub><b>nstefanou</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=nstefanou" title="Code">💻</a> <a href="#plugin-nstefanou" title="Plugin/utility libraries">🔌</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/orin220444"><img src="https://avatars3.githubusercontent.com/u/30747229?v=4?s=100" width="100px;" alt=""/><br /><sub><b>orin220444</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=orin220444" title="Code">💻</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://github.com/Goobles"><img src="https://avatars3.githubusercontent.com/u/8776771?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Gobius Dolhain</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Goobles" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/3l0w"><img src="https://avatars2.githubusercontent.com/u/37798980?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Gwilherm Folliot</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=3l0w" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/Dimitory"><img src="https://avatars0.githubusercontent.com/u/475955?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dmitry Pronin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=dimitory" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/JonathanBeverley"><img src="https://avatars1.githubusercontent.com/u/20328966?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jonathan Beverley</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=JonathanBeverley" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/zend"><img src="https://avatars1.githubusercontent.com/u/25160?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Zenghai Liang</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=zend" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://about.me/matishadow"><img src="https://avatars0.githubusercontent.com/u/9083085?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mateusz Tracz</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=matishadow" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://zergpool.com"><img src="https://avatars3.githubusercontent.com/u/36234677?v=4?s=100" width="100px;" alt=""/><br /><sub><b>pinpin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=pinpins" title="Code">💻</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://github.com/TakuroOnoda"><img src="https://avatars0.githubusercontent.com/u/1407926?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Takuro Onoda</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=TakuroOnoda" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/frauhottelmann"><img src="https://avatars2.githubusercontent.com/u/902705?v=4?s=100" width="100px;" alt=""/><br /><sub><b>frauhottelmann</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=frauhottelmann" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="http://patalong.pl"><img src="https://avatars.githubusercontent.com/u/29167842?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Piotr Patalong</b></sub></a><br /><a href="#design-VectorKappa" title="Design">🎨</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/clarkwang"><img src="https://avatars.githubusercontent.com/u/157076?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Clark Wang</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=clarkwang" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/iamchating"><img src="https://avatars.githubusercontent.com/u/7088153?v=4?s=100" width="100px;" alt=""/><br /><sub><b>iamchating</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=iamchating" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/starxg"><img src="https://avatars.githubusercontent.com/u/34997494?v=4?s=100" width="100px;" alt=""/><br /><sub><b>starxg</b></sub></a><br /><a href="#plugin-starxg" title="Plugin/utility libraries">🔌</a></td>
|
||||||
|
<td align="center"><a href="http://hashnote.net/"><img src="https://avatars.githubusercontent.com/u/546312?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alisue</b></sub></a><br /><a href="#design-lambdalisue" title="Design">🎨</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://github.com/ydcool"><img src="https://avatars.githubusercontent.com/u/5668295?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dominic Yin</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=ydcool" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/bdr99"><img src="https://avatars.githubusercontent.com/u/2292715?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Brandon Rothweiler</b></sub></a><br /><a href="#design-bdr99" title="Design">🎨</a></td>
|
||||||
|
<td align="center"><a href="https://git.io/JnP49"><img src="https://avatars.githubusercontent.com/u/63876444?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Logic Machine</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=logicmachine123" title="Documentation">📖</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/cypherbits"><img src="https://avatars.githubusercontent.com/u/10424900?v=4?s=100" width="100px;" alt=""/><br /><sub><b>cypherbits</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=cypherbits" title="Documentation">📖</a></td>
|
||||||
|
<td align="center"><a href="https://modulolotus.net"><img src="https://avatars.githubusercontent.com/u/946421?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Matthew Davidson</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=KingMob" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/al-wi"><img src="https://avatars.githubusercontent.com/u/11092199?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alexander Wiedemann</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=al-wi" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://www.notion.so/3d45c6bd2cbd4f938873a4bd12e23375"><img src="https://avatars.githubusercontent.com/u/59506394?v=4?s=100" width="100px;" alt=""/><br /><sub><b>장보연</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=BoYeonJang" title="Documentation">📖</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://github.com/Me1onRind"><img src="https://avatars.githubusercontent.com/u/19531270?v=4?s=100" width="100px;" alt=""/><br /><sub><b>zZ</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=Me1onRind" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/tainoNZ"><img src="https://avatars.githubusercontent.com/u/49261322?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Aaron Davison</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=tainoNZ" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/composer404"><img src="https://avatars.githubusercontent.com/u/58251560?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Przemyslaw Kozik</b></sub></a><br /><a href="#design-composer404" title="Design">🎨</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/highfredo"><img src="https://avatars.githubusercontent.com/u/5951524?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alfredo Arellano de la Fuente</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=highfredo" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/NessunKim"><img src="https://avatars.githubusercontent.com/u/12974079?v=4?s=100" width="100px;" alt=""/><br /><sub><b>MH Kim</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=NessunKim" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://discord.gg/4c5EVTBhtp"><img src="https://avatars.githubusercontent.com/u/40345645?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Marmota</b></sub></a><br /><a href="#design-jaimeadf" title="Design">🎨</a></td>
|
||||||
|
<td align="center"><a href="https://ares.zone"><img src="https://avatars.githubusercontent.com/u/40336192?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ares Andrew</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=TENX-S" title="Documentation">📖</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://usual.io/"><img src="https://avatars.githubusercontent.com/u/780052?v=4?s=100" width="100px;" alt=""/><br /><sub><b>George Korsnick</b></sub></a><br /><a href="#financial-gkor" title="Financial">💵</a></td>
|
||||||
|
<td align="center"><a href="https://about.me/ulu"><img src="https://avatars.githubusercontent.com/u/872764?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Artem Smirnov</b></sub></a><br /><a href="#financial-uluhonolulu" title="Financial">💵</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/nevotheless"><img src="https://avatars.githubusercontent.com/u/779797?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tim Kopplow</b></sub></a><br /><a href="#financial-nevotheless" title="Financial">💵</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/mrthock"><img src="https://avatars.githubusercontent.com/u/88901709?v=4?s=100" width="100px;" alt=""/><br /><sub><b>mrthock</b></sub></a><br /><a href="#financial-mrthock" title="Financial">💵</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/lrottach"><img src="https://avatars.githubusercontent.com/u/50323692?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Lukas Rottach</b></sub></a><br /><a href="#financial-lrottach" title="Financial">💵</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/boonkerz"><img src="https://avatars.githubusercontent.com/u/277321?v=4?s=100" width="100px;" alt=""/><br /><sub><b>boonkerz</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=boonkerz" title="Code">💻</a> <a href="#translation-boonkerz" title="Translation">🌍</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/milotype"><img src="https://avatars.githubusercontent.com/u/43657314?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Milo Ivir</b></sub></a><br /><a href="#translation-milotype" title="Translation">🌍</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://github.com/JasonCubic"><img src="https://avatars.githubusercontent.com/u/8921015?v=4?s=100" width="100px;" alt=""/><br /><sub><b>JasonCubic</b></sub></a><br /><a href="#design-JasonCubic" title="Design">🎨</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/MaxWaldorf"><img src="https://avatars.githubusercontent.com/u/15877853?v=4?s=100" width="100px;" alt=""/><br /><sub><b>MaxWaldorf</b></sub></a><br /><a href="#infra-MaxWaldorf" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/mwz"><img src="https://avatars.githubusercontent.com/u/1190768?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Michael Wizner</b></sub></a><br /><a href="https://github.com/Eugeny/tabby/commits?author=mwz" title="Code">💻</a></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- markdownlint-restore -->
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
|
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||||
|
|
||||||
|
本项目遵循 [all-contributors](https://github.com/all-contributors/all-contributors) 规范。 欢迎任何形式的贡献!
|
@@ -70,10 +70,10 @@ export class Application {
|
|||||||
app.commandLine.appendSwitch('enable-transparent-visuals')
|
app.commandLine.appendSwitch('enable-transparent-visuals')
|
||||||
app.disableHardwareAcceleration()
|
app.disableHardwareAcceleration()
|
||||||
}
|
}
|
||||||
if (this.configStore.hacks?.disableGPU) {
|
}
|
||||||
app.commandLine.appendSwitch('disable-gpu')
|
if (this.configStore.hacks?.disableGPU) {
|
||||||
app.disableHardwareAcceleration()
|
app.commandLine.appendSwitch('disable-gpu')
|
||||||
}
|
app.disableHardwareAcceleration()
|
||||||
}
|
}
|
||||||
|
|
||||||
this.userPluginsPath = path.join(
|
this.userPluginsPath = path.join(
|
||||||
@@ -94,7 +94,7 @@ export class Application {
|
|||||||
}
|
}
|
||||||
|
|
||||||
app.on('window-all-closed', () => {
|
app.on('window-all-closed', () => {
|
||||||
if (this.quitRequested || process.platform !== 'darwin') {
|
if (this.quitRequested) {
|
||||||
app.quit()
|
app.quit()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -130,7 +130,6 @@ export class Application {
|
|||||||
this.setupMenu()
|
this.setupMenu()
|
||||||
}
|
}
|
||||||
await window.ready
|
await window.ready
|
||||||
window.present()
|
|
||||||
return window
|
return window
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -27,7 +27,7 @@ abstract class GlasstronWindow extends BrowserWindow {
|
|||||||
abstract setBlur (_: boolean)
|
abstract setBlur (_: boolean)
|
||||||
}
|
}
|
||||||
|
|
||||||
const macOSVibrancyType = process.platform === 'darwin' ? compareVersions(macOSRelease().version, '10.14', '>=') ? 'fullscreen-ui' : 'dark' : null
|
const macOSVibrancyType = process.platform === 'darwin' ? compareVersions(macOSRelease().version, '10.14', '>=') ? 'under-window' : 'dark' : null
|
||||||
|
|
||||||
const activityIcon = nativeImage.createFromPath(`${app.getAppPath()}/assets/activity.png`)
|
const activityIcon = nativeImage.createFromPath(`${app.getAppPath()}/assets/activity.png`)
|
||||||
|
|
||||||
@@ -135,6 +135,8 @@ export class Window {
|
|||||||
|
|
||||||
this.window.webContents.setVisualZoomLevelLimits(1, 1)
|
this.window.webContents.setVisualZoomLevelLimits(1, 1)
|
||||||
this.window.webContents.setZoomFactor(1)
|
this.window.webContents.setZoomFactor(1)
|
||||||
|
this.window.webContents.session.setPermissionCheckHandler(() => true)
|
||||||
|
this.window.webContents.session.setDevicePermissionHandler(() => true)
|
||||||
|
|
||||||
if (process.platform === 'darwin') {
|
if (process.platform === 'darwin') {
|
||||||
this.touchBarControl = new TouchBar.TouchBarSegmentedControl({
|
this.touchBarControl = new TouchBar.TouchBarSegmentedControl({
|
||||||
@@ -303,6 +305,9 @@ export class Window {
|
|||||||
this.window.on('enter-full-screen', () => this.send('host:window-enter-full-screen'))
|
this.window.on('enter-full-screen', () => this.send('host:window-enter-full-screen'))
|
||||||
this.window.on('leave-full-screen', () => this.send('host:window-leave-full-screen'))
|
this.window.on('leave-full-screen', () => this.send('host:window-leave-full-screen'))
|
||||||
|
|
||||||
|
this.window.on('maximize', () => this.send('host:window-maximized'))
|
||||||
|
this.window.on('unmaximize', () => this.send('host:window-unmaximized'))
|
||||||
|
|
||||||
this.window.on('close', event => {
|
this.window.on('close', event => {
|
||||||
if (!this.closing) {
|
if (!this.closing) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
@@ -15,30 +15,30 @@
|
|||||||
"watch": "webpack --progress --color --watch"
|
"watch": "webpack --progress --color --watch"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/cdk": "^12.2.9",
|
|
||||||
"@electron/remote": "2.0.1",
|
"@electron/remote": "2.0.1",
|
||||||
"@tabby-gang/node-pty": "^0.11.0-beta.200",
|
"@tabby-gang/node-pty": "^0.11.0-beta.200",
|
||||||
"any-promise": "^1.3.0",
|
"any-promise": "^1.3.0",
|
||||||
"electron-config": "2.0.0",
|
"electron-config": "2.0.0",
|
||||||
"electron-debug": "^3.2.0",
|
"electron-debug": "^3.2.0",
|
||||||
"electron-promise-ipc": "^2.2.4",
|
"electron-promise-ipc": "^2.2.4",
|
||||||
"electron-updater": "^4.6.1",
|
"electron-updater": "^4.6.5",
|
||||||
"fontmanager-redux": "1.1.0",
|
"fontmanager-redux": "1.1.0",
|
||||||
"glasstron": "0.0.7",
|
"glasstron": "0.0.7",
|
||||||
"js-yaml": "4.1.0",
|
"js-yaml": "4.1.0",
|
||||||
"keytar": "^7.7.0",
|
"keytar": "^7.8.0",
|
||||||
"mz": "^2.7.0",
|
"mz": "^2.7.0",
|
||||||
"native-process-working-directory": "^1.0.2",
|
"native-process-working-directory": "^1.0.2",
|
||||||
"npm": "6",
|
"npm": "6",
|
||||||
"rxjs": "^7.4.0",
|
"rxjs": "^7.5.1",
|
||||||
"source-map-support": "^0.5.20",
|
"source-map-support": "^0.5.20",
|
||||||
"v8-compile-cache": "^2.3.0",
|
"v8-compile-cache": "^2.3.0",
|
||||||
"yargs": "^17.2.1"
|
"yargs": "^17.3.1"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@tabby-gang/windows-blurbehind": "^3.0.0",
|
"@tabby-gang/windows-blurbehind": "^3.0.0",
|
||||||
"macos-native-processlist": "^2.0.0",
|
"macos-native-processlist": "^2.0.0",
|
||||||
"serialport": "^10.0.0",
|
"serialport": "10.2.2",
|
||||||
|
"serialport-binding-webserialapi": "^1.0.3",
|
||||||
"windows-native-registry": "^3.1.0",
|
"windows-native-registry": "^3.1.0",
|
||||||
"windows-process-tree": "^0.3.2"
|
"windows-process-tree": "^0.3.2"
|
||||||
},
|
},
|
||||||
|
@@ -1,14 +0,0 @@
|
|||||||
diff --git a/node_modules/@serialport/bindings/src/serialport.cpp b/node_modules/@serialport/bindings/src/serialport.cpp
|
|
||||||
index c48e150..00a5f5a 100644
|
|
||||||
--- a/node_modules/@serialport/bindings/src/serialport.cpp
|
|
||||||
+++ b/node_modules/@serialport/bindings/src/serialport.cpp
|
|
||||||
@@ -269,7 +269,8 @@ Napi::Value Drain(const Napi::CallbackInfo& info) {
|
|
||||||
}
|
|
||||||
|
|
||||||
inline SerialPortParity ToParityEnum(const Napi::String& napistr) {
|
|
||||||
- const char* str = napistr.Utf8Value().c_str();
|
|
||||||
+ auto tmp = napistr.Utf8Value();
|
|
||||||
+ const char* str = tmp.c_str();
|
|
||||||
size_t count = strlen(str);
|
|
||||||
SerialPortParity parity = SERIALPORT_PARITY_NONE;
|
|
||||||
if (!strncasecmp(str, "none", count)) {
|
|
@@ -1,7 +1,7 @@
|
|||||||
body {
|
body {
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: #1D272D;
|
background: transparent !important;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -3,4 +3,5 @@ export const PLUGIN_BLACKLIST = [
|
|||||||
'terminus-scrollbar', // now useless
|
'terminus-scrollbar', // now useless
|
||||||
'terminus-clickable-links', // now bundled with Tabby
|
'terminus-clickable-links', // now bundled with Tabby
|
||||||
'tabby-clickable-links', // now bundled with Tabby
|
'tabby-clickable-links', // now bundled with Tabby
|
||||||
|
'terminus-clickable-ips', // broken, functionality now bundled with Tabby
|
||||||
]
|
]
|
||||||
|
@@ -21,6 +21,8 @@ const builtinPluginsPath = process.env.TABBY_DEV ? path.dirname(remote.app.getAp
|
|||||||
|
|
||||||
const cachedBuiltinModules = {
|
const cachedBuiltinModules = {
|
||||||
'@angular/animations': require('@angular/animations'),
|
'@angular/animations': require('@angular/animations'),
|
||||||
|
'@angular/cdk/drag-drop': require('@angular/cdk/drag-drop'),
|
||||||
|
'@angular/cdk/clipboard': require('@angular/cdk/clipboard'),
|
||||||
'@angular/common': require('@angular/common'),
|
'@angular/common': require('@angular/common'),
|
||||||
'@angular/compiler': require('@angular/compiler'),
|
'@angular/compiler': require('@angular/compiler'),
|
||||||
'@angular/core': require('@angular/core'),
|
'@angular/core': require('@angular/core'),
|
||||||
@@ -64,18 +66,23 @@ export type ProgressCallback = (current: number, total: number) => void
|
|||||||
export function initModuleLookup (userPluginsPath: string): void {
|
export function initModuleLookup (userPluginsPath: string): void {
|
||||||
global['module'].paths.map((x: string) => nodeModule.globalPaths.push(normalizePath(x)))
|
global['module'].paths.map((x: string) => nodeModule.globalPaths.push(normalizePath(x)))
|
||||||
|
|
||||||
nodeModule.globalPaths.unshift(path.join(userPluginsPath, 'node_modules'))
|
const paths = []
|
||||||
|
paths.unshift(path.join(userPluginsPath, 'node_modules'))
|
||||||
|
paths.unshift(path.join(remote.app.getAppPath(), 'node_modules'))
|
||||||
|
|
||||||
if (process.env.TABBY_DEV) {
|
if (process.env.TABBY_DEV) {
|
||||||
nodeModule.globalPaths.unshift(path.dirname(remote.app.getAppPath()))
|
paths.unshift(path.dirname(remote.app.getAppPath()))
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeModule.globalPaths.unshift(builtinPluginsPath)
|
paths.unshift(builtinPluginsPath)
|
||||||
// nodeModule.globalPaths.unshift(path.join((process as any).resourcesPath, 'app.asar', 'node_modules'))
|
// paths.unshift(path.join((process as any).resourcesPath, 'app.asar', 'node_modules'))
|
||||||
if (process.env.TABBY_PLUGINS) {
|
if (process.env.TABBY_PLUGINS) {
|
||||||
process.env.TABBY_PLUGINS.split(':').map(x => nodeModule.globalPaths.push(normalizePath(x)))
|
process.env.TABBY_PLUGINS.split(':').map(x => paths.push(normalizePath(x)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
process.env.NODE_PATH += path.delimiter + paths.join(path.delimiter)
|
||||||
|
nodeModule._initPaths()
|
||||||
|
|
||||||
builtinModules.forEach(m => {
|
builtinModules.forEach(m => {
|
||||||
if (!cachedBuiltinModules[m]) {
|
if (!cachedBuiltinModules[m]) {
|
||||||
cachedBuiltinModules[m] = nodeRequire(m)
|
cachedBuiltinModules[m] = nodeRequire(m)
|
||||||
|
@@ -1,3 +1,7 @@
|
|||||||
|
app-root {
|
||||||
|
background: #1D272D;
|
||||||
|
}
|
||||||
|
|
||||||
.preload-logo {
|
.preload-logo {
|
||||||
-webkit-app-region: drag;
|
-webkit-app-region: drag;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
417
app/yarn.lock
417
app/yarn.lock
@@ -2,15 +2,6 @@
|
|||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
"@angular/cdk@^12.2.9":
|
|
||||||
version "12.2.9"
|
|
||||||
resolved "https://registry.yarnpkg.com/@angular/cdk/-/cdk-12.2.9.tgz#f39e4d7cdb3568ad8e1d412e3500772e2d4c605c"
|
|
||||||
integrity sha512-9Wgj69iGAZ4teQqW/zPbVg2RGna+m9i3v0zkWGx/+Uo95rikJCUZBQM4bfeOe+bSJrS77jV5EisBWG7ayNUSzQ==
|
|
||||||
dependencies:
|
|
||||||
tslib "^2.2.0"
|
|
||||||
optionalDependencies:
|
|
||||||
parse5 "^5.0.0"
|
|
||||||
|
|
||||||
"@electron/remote@2.0.1":
|
"@electron/remote@2.0.1":
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/@electron/remote/-/remote-2.0.1.tgz#810cbc595a21f0f94641eb2d7e8264063a3f84de"
|
resolved "https://registry.yarnpkg.com/@electron/remote/-/remote-2.0.1.tgz#810cbc595a21f0f94641eb2d7e8264063a3f84de"
|
||||||
@@ -25,74 +16,101 @@
|
|||||||
update-notifier "^2.2.0"
|
update-notifier "^2.2.0"
|
||||||
yargs "^8.0.2"
|
yargs "^8.0.2"
|
||||||
|
|
||||||
"@serialport/binding-abstract@10.0.0":
|
"@serialport/binding-abstract@^9.0.2":
|
||||||
version "10.0.0"
|
version "9.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/@serialport/binding-abstract/-/binding-abstract-10.0.0.tgz#c5aea29de3721de80640e290f52217d00d927e4e"
|
resolved "https://registry.yarnpkg.com/@serialport/binding-abstract/-/binding-abstract-9.2.3.tgz#e7dd273357b6a698af7ad58db6f57f62443a0acb"
|
||||||
integrity sha512-1IwOMDOWqKO0csrTOv95Ah0Av012DZB8C0OF11SmE3eyh8ab1+y4/Yah/8byMAMG7TXw+2LqkNs1oZtOJGlY1Q==
|
integrity sha512-cQs9tbIlG3P0IrOWyVirqlhWuJ7Ms2Zh9m2108z6Y5UW/iVj6wEOiW8EmK9QX9jmJXYllE7wgGgvVozP5oCj3w==
|
||||||
dependencies:
|
dependencies:
|
||||||
debug "^4.3.2"
|
debug "^4.3.2"
|
||||||
|
|
||||||
"@serialport/binding-mock@10.0.0":
|
"@serialport/binding-mock@10.2.2":
|
||||||
version "10.0.0"
|
version "10.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/@serialport/binding-mock/-/binding-mock-10.0.0.tgz#dc850c3e06f2be4b0c5e0461d2e12a2506cca573"
|
resolved "https://registry.yarnpkg.com/@serialport/binding-mock/-/binding-mock-10.2.2.tgz#d322a8116a97806addda13c62f50e73d16125874"
|
||||||
integrity sha512-X+lJqU/GbXxxqA4b3T+YK9vQLtoNSjRF+hz1gyYHpNxDFX0dSLU1OVnQUZ2Zi8aa6IBdk/4DcuGN0tDNAlmtKg==
|
integrity sha512-HAFzGhk9OuFMpuor7aT5G1ChPgn5qSsklTFOTUX72Rl6p0xwcSVsRtG/xaGp6bxpN7fI9D/S8THLBWbBgS6ldw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@serialport/binding-abstract" "10.0.0"
|
"@serialport/bindings-interface" "^1.2.1"
|
||||||
|
debug "^4.3.3"
|
||||||
|
|
||||||
|
"@serialport/bindings-cpp@10.6.2":
|
||||||
|
version "10.6.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@serialport/bindings-cpp/-/bindings-cpp-10.6.2.tgz#2ecb0a958d69d9d9e72cbf46481472937954adb5"
|
||||||
|
integrity sha512-vhId2K4Y4WOgy/UJE8NOHX6GZpozORCCMh6GM5UQeIzXihoYLxt4eomgl1eXasFipcRs06n71lAToqixb7NPpA==
|
||||||
|
dependencies:
|
||||||
|
"@serialport/bindings-interface" "1.2.1"
|
||||||
|
"@serialport/parser-readline" "^10.2.1"
|
||||||
|
debug "^4.3.2"
|
||||||
|
node-addon-api "^4.3.0"
|
||||||
|
node-gyp-build "^4.3.0"
|
||||||
|
|
||||||
|
"@serialport/bindings-interface@1.2.1", "@serialport/bindings-interface@^1.2.1":
|
||||||
|
version "1.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@serialport/bindings-interface/-/bindings-interface-1.2.1.tgz#1ee80b0951ef4e4fd8a5a186621feff046aa2faf"
|
||||||
|
integrity sha512-63Dyqz2gtryRDDckFusOYqLYhR3Hq/M4sEdbF9i/VsvDb6T+tNVgoAKUZ+FMrXXKnCSu+hYbk+MTc0XQANszxw==
|
||||||
|
|
||||||
|
"@serialport/parser-byte-length@10.2.2":
|
||||||
|
version "10.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@serialport/parser-byte-length/-/parser-byte-length-10.2.2.tgz#10129fb83fb0bd5e4c673d866534ea714022708e"
|
||||||
|
integrity sha512-3xqaRbNiqDo8Gf1jPgrZr2nObKfAjhFihINZLJfPG7skWXfDKuF0zXuStzixre26N8GYWnkn4j/oEnI0RZjVDA==
|
||||||
|
|
||||||
|
"@serialport/parser-cctalk@10.2.2":
|
||||||
|
version "10.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@serialport/parser-cctalk/-/parser-cctalk-10.2.2.tgz#7009b245cf7f6d9fa0e1a8039fcf2ed4292199da"
|
||||||
|
integrity sha512-WK+82D10y+vL2Rv1Hs2MRNKeY18uVC0+eH9QCfD9e2o+4+jPHfN2boJQFxVGtrlss8j5DmQ5Sc5Qe6Ep+f20/Q==
|
||||||
|
|
||||||
|
"@serialport/parser-delimiter@10.2.2":
|
||||||
|
version "10.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@serialport/parser-delimiter/-/parser-delimiter-10.2.2.tgz#e305ad321ebc6dd2739cc919b66602c6c5bc4f8c"
|
||||||
|
integrity sha512-VsepMDIjbHbANMxH4IkXIJY0Tds8XsDo0mgtWK3DrV+IJGXp+2b0pHOuQlSLSfEUmdw7F5drI17fkxc9mxn+pg==
|
||||||
|
|
||||||
|
"@serialport/parser-inter-byte-timeout@10.2.2":
|
||||||
|
version "10.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@serialport/parser-inter-byte-timeout/-/parser-inter-byte-timeout-10.2.2.tgz#22293882c9bd7ae9b18be9a30ca2fcd7a0617dc9"
|
||||||
|
integrity sha512-J9895aJ+3cHp2Q9qMH3UulfaifHDbDHjLPbO2H0vqjI8gZemL0DGql5ooFI6zsgJStXYT1MjqIhIb8dBIE0nxA==
|
||||||
|
|
||||||
|
"@serialport/parser-packet-length@10.2.2":
|
||||||
|
version "10.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@serialport/parser-packet-length/-/parser-packet-length-10.2.2.tgz#24790ba057090b8c7f5067a229b98d273fa6b71f"
|
||||||
|
integrity sha512-AEh/4pOoolUgCwg7ZW5M81isPjOhSf+Fq7OdyaR0GEHHrRgaY7ma2xkyp+sgjcYoeBzlxe3pPdi7LGtBJEFDnw==
|
||||||
|
|
||||||
|
"@serialport/parser-readline@10.2.2", "@serialport/parser-readline@^10.2.1":
|
||||||
|
version "10.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@serialport/parser-readline/-/parser-readline-10.2.2.tgz#94bfbf4a76760141ce8c7efddbc76d00dfe6dd55"
|
||||||
|
integrity sha512-OcWoTsUJeLKWw+rdTuqXFZhii2liE6LeoFK2rtS6L00pB0cd2FGt2Rsx76oTCTyrub6AAUqaS9PRrAI+AUJJpg==
|
||||||
|
dependencies:
|
||||||
|
"@serialport/parser-delimiter" "10.2.2"
|
||||||
|
|
||||||
|
"@serialport/parser-ready@10.2.2":
|
||||||
|
version "10.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@serialport/parser-ready/-/parser-ready-10.2.2.tgz#5d057f7d65fece8ea3c7f2cacf4026768a34e53d"
|
||||||
|
integrity sha512-Y5NA/kMb27afeFvSHhQ0Ov7PUt6vPSUqm7y+u6gajMpYOhKMjbLyQHuYMkgtGgk/PsryaOerd4OCVaYCEj0C+Q==
|
||||||
|
|
||||||
|
"@serialport/parser-regex@10.2.2":
|
||||||
|
version "10.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@serialport/parser-regex/-/parser-regex-10.2.2.tgz#0275c207485f7cbd4787ef54e835eab6a7126b15"
|
||||||
|
integrity sha512-+fAchSfl65Ix1BbyNPBu0SreZg2Tc2JJkvXsKsWFpoaOEsuxbCthrNmyvjt3AZ228pay6kKvF2PkRd/z+BFSfw==
|
||||||
|
|
||||||
|
"@serialport/parser-slip-encoder@10.2.2":
|
||||||
|
version "10.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@serialport/parser-slip-encoder/-/parser-slip-encoder-10.2.2.tgz#ba3b4d3d6f172b0a22b82b86db5e1cd00e3ef22f"
|
||||||
|
integrity sha512-cDJvco/exmQ7xgISVNbNb73r8l0j7eQDTVXxa8whUt8tdkf/J5y8jZLZgboh/iXbEcrNtohwUhIfb633NotNxg==
|
||||||
|
|
||||||
|
"@serialport/parser-spacepacket@10.2.2":
|
||||||
|
version "10.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@serialport/parser-spacepacket/-/parser-spacepacket-10.2.2.tgz#e0b9186d6239f97a615cb8990db153e1bb564bf7"
|
||||||
|
integrity sha512-TdfDYfIg41lXXuFsbdTZ2IHKhb3MgLJMMRhutoc/q6wX7LFhFD7FhdlkX3w85x15p1Et+iekGW5I/b48s47gXQ==
|
||||||
|
|
||||||
|
"@serialport/stream@10.2.2":
|
||||||
|
version "10.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@serialport/stream/-/stream-10.2.2.tgz#80e3acd7a54c5da16659b3c34d419ca7302eff14"
|
||||||
|
integrity sha512-xKO5f73KbqZYadKYbtlDHE5RUwqSK8dF2brQRA6dikeyHWbVNhjwNtjWglwgzPl4SLB1A1uT97hMxrBrSCs6/w==
|
||||||
|
dependencies:
|
||||||
|
"@serialport/bindings-interface" "1.2.1"
|
||||||
debug "^4.3.2"
|
debug "^4.3.2"
|
||||||
|
|
||||||
"@serialport/bindings@10.0.0":
|
"@serialport/stream@^9.0.2":
|
||||||
version "10.0.0"
|
version "9.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/@serialport/bindings/-/bindings-10.0.0.tgz#718b105adae977886967ab0edc68a067be9183f8"
|
resolved "https://registry.yarnpkg.com/@serialport/stream/-/stream-9.2.4.tgz#9fce093d0b46ed4599953b4fae81718e050d2b33"
|
||||||
integrity sha512-t415A6clhsUX0dBRzN0NRN7Yb6y9U1jA4oGzxL2fWCy7XxQq8beI0GnMebEUaZDWKZ7IAVwGnAPUunk7QdlWlA==
|
integrity sha512-bLye8Ub4vUFQGmkh8qEqehr7SE7EJs2yDs0h9jzuL5oKi+F34CFmWkEErO8GAOQ8YNn7p6b3GxUgs+0BrHHDZQ==
|
||||||
dependencies:
|
|
||||||
"@serialport/binding-abstract" "10.0.0"
|
|
||||||
"@serialport/parser-readline" "10.0.0"
|
|
||||||
bindings "^1.5.0"
|
|
||||||
debug "^4.3.2"
|
|
||||||
node-addon-api "4.2.0"
|
|
||||||
prebuild-install "^7.0.0"
|
|
||||||
|
|
||||||
"@serialport/parser-byte-length@10.0.0":
|
|
||||||
version "10.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@serialport/parser-byte-length/-/parser-byte-length-10.0.0.tgz#05ca2721a50dcdc93f68f3f1e72e10fd82362e84"
|
|
||||||
integrity sha512-QmZw7oTt6LBHBFbMIPLIZM4WuXpMeK5EpCpXKFtw4a7+yF0yLPwz6uSV2Cf3SvunCfI3eWvucMKpgYNOvglsgA==
|
|
||||||
|
|
||||||
"@serialport/parser-cctalk@10.0.0":
|
|
||||||
version "10.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@serialport/parser-cctalk/-/parser-cctalk-10.0.0.tgz#de42e6952c086da3e384756502f9aaca0e97f881"
|
|
||||||
integrity sha512-jCxzY2IPghNMaJ+GsUgSOoPCI2v1FZg7RvpSJ/b/igK+M/z/p7oRyWf1LqMyjZT7rP4Ha8ZfsQQy5qGzQ3kuzw==
|
|
||||||
|
|
||||||
"@serialport/parser-delimiter@10.0.0":
|
|
||||||
version "10.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@serialport/parser-delimiter/-/parser-delimiter-10.0.0.tgz#43eb2e3b4c4cf8633eb1200b3af5488ba9a7ecb6"
|
|
||||||
integrity sha512-s7j+RIxxmyb7xJ3WVcf+IfjFqyoh7k7Edqwqvk2sQLU6UOBNAktNQDHIM/vksQ9QkjJjvl8rIo0YznfBkWbZOQ==
|
|
||||||
|
|
||||||
"@serialport/parser-inter-byte-timeout@10.0.0":
|
|
||||||
version "10.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@serialport/parser-inter-byte-timeout/-/parser-inter-byte-timeout-10.0.0.tgz#07fe7c42e77c9a6379daa6939de55fef99c06ce4"
|
|
||||||
integrity sha512-ygax3PHuPxi58D3/crCDENSFagvG5EsWjXj6AQRUisExPAAiD02RbZaRqTZluFvDbzMJ/29YJdcdIqnllzGVsw==
|
|
||||||
|
|
||||||
"@serialport/parser-readline@10.0.0":
|
|
||||||
version "10.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@serialport/parser-readline/-/parser-readline-10.0.0.tgz#a87b0d92864e917e07010477057b66efe92d3af9"
|
|
||||||
integrity sha512-NI3oRY1+fLg94CZm887rgj4V6KyxaJmbmoRgua9bqRv7v/o0SqN9lSQwdYLHQVHpf03zTX9ziuoCV8w5CI3DQQ==
|
|
||||||
dependencies:
|
|
||||||
"@serialport/parser-delimiter" "10.0.0"
|
|
||||||
|
|
||||||
"@serialport/parser-ready@10.0.0":
|
|
||||||
version "10.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@serialport/parser-ready/-/parser-ready-10.0.0.tgz#eae67e9c0806f5b2d9750c1ef910a3cedb549119"
|
|
||||||
integrity sha512-pmMjRVy0wwVSzRt27AtMV/FJdSL6CdKvLUNx+ziDL9Lt30n85ZzrSdYJOwOB63HVIMg8+JRgiyxKNLs+JgMK2g==
|
|
||||||
|
|
||||||
"@serialport/parser-regex@10.0.0":
|
|
||||||
version "10.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@serialport/parser-regex/-/parser-regex-10.0.0.tgz#a5dd648baf0952253a995bf0174ba2c19649e279"
|
|
||||||
integrity sha512-kLvK6bbDtpnVMagCK95m08W+XaXXzJpDvjzrMNSAtpaL+yeBu4XlEhHpt9+9S/MOetbz4vgWdZx2buYyw9iiGQ==
|
|
||||||
|
|
||||||
"@serialport/stream@10.0.0":
|
|
||||||
version "10.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@serialport/stream/-/stream-10.0.0.tgz#482580b9bdad468ac2a60c41c7fb933f7dc7436f"
|
|
||||||
integrity sha512-KFBGWH6BEn4gXUYHEfbywplDX+sVhlL/Yzn/r7hn+qYnwVjhvQo8Vi35CPKESOUKnMKU48sGSUvNaOwU5znw2g==
|
|
||||||
dependencies:
|
dependencies:
|
||||||
debug "^4.3.2"
|
debug "^4.3.2"
|
||||||
|
|
||||||
@@ -208,6 +226,11 @@ ansi-regex@^5.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz"
|
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz"
|
||||||
integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
|
integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
|
||||||
|
|
||||||
|
ansi-regex@^5.0.1:
|
||||||
|
version "5.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
|
||||||
|
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
|
||||||
|
|
||||||
ansi-styles@^3.2.0, ansi-styles@^3.2.1:
|
ansi-styles@^3.2.0, ansi-styles@^3.2.1:
|
||||||
version "3.2.1"
|
version "3.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
|
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
|
||||||
@@ -326,13 +349,6 @@ bin-links@^1.1.2, bin-links@^1.1.8:
|
|||||||
npm-normalize-package-bin "^1.0.0"
|
npm-normalize-package-bin "^1.0.0"
|
||||||
write-file-atomic "^2.3.0"
|
write-file-atomic "^2.3.0"
|
||||||
|
|
||||||
bindings@^1.5.0:
|
|
||||||
version "1.5.0"
|
|
||||||
resolved "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz"
|
|
||||||
integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==
|
|
||||||
dependencies:
|
|
||||||
file-uri-to-path "1.0.0"
|
|
||||||
|
|
||||||
bl@^4.0.3:
|
bl@^4.0.3:
|
||||||
version "4.0.3"
|
version "4.0.3"
|
||||||
resolved "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz"
|
resolved "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz"
|
||||||
@@ -388,10 +404,10 @@ buffer@^5.5.0:
|
|||||||
base64-js "^1.3.1"
|
base64-js "^1.3.1"
|
||||||
ieee754 "^1.1.13"
|
ieee754 "^1.1.13"
|
||||||
|
|
||||||
builder-util-runtime@8.9.1:
|
builder-util-runtime@8.9.2:
|
||||||
version "8.9.1"
|
version "8.9.2"
|
||||||
resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-8.9.1.tgz#25f066b3fbc20b3e6236a9b956b1ebb0e33ff66a"
|
resolved "https://registry.yarnpkg.com/builder-util-runtime/-/builder-util-runtime-8.9.2.tgz#a9669ae5b5dcabfe411ded26678e7ae997246c28"
|
||||||
integrity sha512-c8a8J3wK6BIVLW7ls+7TRK9igspTbzWmUqxFbgK0m40Ggm6efUbxtWVCGIjc+dtchyr5qAMAUL6iEGRdS/6vwg==
|
integrity sha512-rhuKm5vh7E0aAmT6i8aoSfEjxzdYEFX7zDApK+eNgOhjofnWb74d9SRJv0H/8nsgOkos0TZ4zxW0P8J4N7xQ2A==
|
||||||
dependencies:
|
dependencies:
|
||||||
debug "^4.3.2"
|
debug "^4.3.2"
|
||||||
sax "^1.2.4"
|
sax "^1.2.4"
|
||||||
@@ -741,6 +757,13 @@ debug@^4.0.1, debug@^4.3.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ms "2.1.2"
|
ms "2.1.2"
|
||||||
|
|
||||||
|
debug@^4.3.3:
|
||||||
|
version "4.3.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664"
|
||||||
|
integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==
|
||||||
|
dependencies:
|
||||||
|
ms "2.1.2"
|
||||||
|
|
||||||
debuglog@^1.0.1:
|
debuglog@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz"
|
resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz"
|
||||||
@@ -756,13 +779,6 @@ decode-uri-component@^0.2.0:
|
|||||||
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
|
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
|
||||||
integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=
|
integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=
|
||||||
|
|
||||||
decompress-response@^4.2.0:
|
|
||||||
version "4.2.1"
|
|
||||||
resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz"
|
|
||||||
integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==
|
|
||||||
dependencies:
|
|
||||||
mimic-response "^2.0.0"
|
|
||||||
|
|
||||||
decompress-response@^6.0.0:
|
decompress-response@^6.0.0:
|
||||||
version "6.0.0"
|
version "6.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc"
|
resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc"
|
||||||
@@ -804,10 +820,10 @@ detect-indent@~5.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d"
|
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d"
|
||||||
integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50=
|
integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50=
|
||||||
|
|
||||||
detect-libc@^1.0.3:
|
detect-libc@^2.0.0:
|
||||||
version "1.0.3"
|
version "2.0.0"
|
||||||
resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz"
|
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.0.tgz#c528bc09bc6d1aa30149228240917c225448f204"
|
||||||
integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=
|
integrity sha512-S55LzUl8HUav8l9E2PBTlC5PAJrHK7tkM+XXFGD+fbsbkTzhCpG6K05LxJcUOEWzMa4v6ptcMZ9s3fOdJDu0Zw==
|
||||||
|
|
||||||
detect-newline@^2.1.0:
|
detect-newline@^2.1.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
@@ -907,13 +923,13 @@ electron-promise-ipc@^2.2.4:
|
|||||||
serialize-error "^5.0.0"
|
serialize-error "^5.0.0"
|
||||||
uuid "^3.0.1"
|
uuid "^3.0.1"
|
||||||
|
|
||||||
electron-updater@^4.6.1:
|
electron-updater@^4.6.5:
|
||||||
version "4.6.1"
|
version "4.6.5"
|
||||||
resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-4.6.1.tgz#80ca805c4f51b2e682aac29d18fed75d6a533d32"
|
resolved "https://registry.yarnpkg.com/electron-updater/-/electron-updater-4.6.5.tgz#e9a75458bbfd6bb41a58a829839e150ad2eb2d3d"
|
||||||
integrity sha512-YsU1mHqXLrXXmBMsxhxy24PrbaB8rnpZDPmFa2gOkTYk/Ch13+R0fjsRSpPYvqtskVVY0ux8fu+HnUkVkqc7og==
|
integrity sha512-kdTly8O9mSZfm9fslc1mnCY+mYOeaYRy7ERa2Fed240u01BKll3aiupzkd07qKw69KvhBSzuHroIW3mF0D8DWA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/semver" "^7.3.6"
|
"@types/semver" "^7.3.6"
|
||||||
builder-util-runtime "8.9.1"
|
builder-util-runtime "8.9.2"
|
||||||
fs-extra "^10.0.0"
|
fs-extra "^10.0.0"
|
||||||
js-yaml "^4.1.0"
|
js-yaml "^4.1.0"
|
||||||
lazy-val "^1.0.5"
|
lazy-val "^1.0.5"
|
||||||
@@ -1066,11 +1082,6 @@ figgy-pudding@^3.4.1, figgy-pudding@^3.5.1:
|
|||||||
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e"
|
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e"
|
||||||
integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==
|
integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==
|
||||||
|
|
||||||
file-uri-to-path@1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz"
|
|
||||||
integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==
|
|
||||||
|
|
||||||
"filesize@>= 4.0.0":
|
"filesize@>= 4.0.0":
|
||||||
version "6.3.0"
|
version "6.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/filesize/-/filesize-6.3.0.tgz#dff53cfb3f104c9e422f346d53be8dbcc971bf11"
|
resolved "https://registry.yarnpkg.com/filesize/-/filesize-6.3.0.tgz#dff53cfb3f104c9e422f346d53be8dbcc971bf11"
|
||||||
@@ -1758,13 +1769,13 @@ keyboardevents-areequal@^0.2.1:
|
|||||||
resolved "https://registry.npmjs.org/keyboardevents-areequal/-/keyboardevents-areequal-0.2.2.tgz"
|
resolved "https://registry.npmjs.org/keyboardevents-areequal/-/keyboardevents-areequal-0.2.2.tgz"
|
||||||
integrity sha512-Nv+Kr33T0mEjxR500q+I6IWisOQ0lK1GGOncV0kWE6n4KFmpcu7RUX5/2B0EUtX51Cb0HjZ9VJsSY3u4cBa0kw==
|
integrity sha512-Nv+Kr33T0mEjxR500q+I6IWisOQ0lK1GGOncV0kWE6n4KFmpcu7RUX5/2B0EUtX51Cb0HjZ9VJsSY3u4cBa0kw==
|
||||||
|
|
||||||
keytar@^7.7.0:
|
keytar@^7.8.0:
|
||||||
version "7.7.0"
|
version "7.8.0"
|
||||||
resolved "https://registry.yarnpkg.com/keytar/-/keytar-7.7.0.tgz#3002b106c01631aa79b1aa9ee0493b94179bbbd2"
|
resolved "https://registry.yarnpkg.com/keytar/-/keytar-7.8.0.tgz#28cf5ceeb1275350888870022869b8b4fe6a87f9"
|
||||||
integrity sha512-YEY9HWqThQc5q5xbXbRwsZTh2PJ36OSYRjSv3NN2xf5s5dpLTjEZnC2YikR29OaVybf9nQ0dJ/80i40RS97t/A==
|
integrity sha512-mR+BqtAOIW8j+T5FtLVyckCbvROWQD+4FzPeFMuk5njEZkXLpVPCGF26Y3mTyxMAAL1XCfswR7S6kIf+THSRFA==
|
||||||
dependencies:
|
dependencies:
|
||||||
node-addon-api "^3.0.0"
|
node-addon-api "^4.3.0"
|
||||||
prebuild-install "^6.0.0"
|
prebuild-install "^7.0.1"
|
||||||
|
|
||||||
klaw-sync@^6.0.0:
|
klaw-sync@^6.0.0:
|
||||||
version "6.0.0"
|
version "6.0.0"
|
||||||
@@ -2116,11 +2127,6 @@ mimic-fn@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
|
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
|
||||||
integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==
|
integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==
|
||||||
|
|
||||||
mimic-response@^2.0.0:
|
|
||||||
version "2.1.0"
|
|
||||||
resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz"
|
|
||||||
integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==
|
|
||||||
|
|
||||||
mimic-response@^3.1.0:
|
mimic-response@^3.1.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9"
|
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9"
|
||||||
@@ -2252,7 +2258,7 @@ nice-try@^1.0.4:
|
|||||||
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
||||||
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
|
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
|
||||||
|
|
||||||
node-abi@^2.20.0, node-abi@^2.7.0:
|
node-abi@^2.20.0:
|
||||||
version "2.30.1"
|
version "2.30.1"
|
||||||
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.30.1.tgz#c437d4b1fe0e285aaf290d45b45d4d7afedac4cf"
|
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.30.1.tgz#c437d4b1fe0e285aaf290d45b45d4d7afedac4cf"
|
||||||
integrity sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==
|
integrity sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w==
|
||||||
@@ -2260,9 +2266,9 @@ node-abi@^2.20.0, node-abi@^2.7.0:
|
|||||||
semver "^5.4.1"
|
semver "^5.4.1"
|
||||||
|
|
||||||
node-abi@^3.3.0:
|
node-abi@^3.3.0:
|
||||||
version "3.5.0"
|
version "3.8.0"
|
||||||
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.5.0.tgz#26e8b7b251c3260a5ac5ba5aef3b4345a0229248"
|
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.8.0.tgz#679957dc8e7aa47b0a02589dbfde4f77b29ccb32"
|
||||||
integrity sha512-LtHvNIBgOy5mO8mPEUtkCW/YCRWYEKshIvqhe1GHHyXEHEB5mgICyYnAcl4qan3uFeRROErKGzatFHPf6kDxWw==
|
integrity sha512-tzua9qWWi7iW4I42vUPKM+SfaF0vQSLAm4yO5J83mSwB7GeoWrDKC/K+8YCnYNwqP5duwazbw2X9l4m8SC2cUw==
|
||||||
dependencies:
|
dependencies:
|
||||||
semver "^7.3.5"
|
semver "^7.3.5"
|
||||||
|
|
||||||
@@ -2271,16 +2277,16 @@ node-addon-api@3.0.0:
|
|||||||
resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.0.0.tgz"
|
resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.0.0.tgz"
|
||||||
integrity sha512-sSHCgWfJ+Lui/u+0msF3oyCgvdkhxDbkCS6Q8uiJquzOimkJBvX6hl5aSSA7DR1XbMpdM8r7phjcF63sF4rkKg==
|
integrity sha512-sSHCgWfJ+Lui/u+0msF3oyCgvdkhxDbkCS6Q8uiJquzOimkJBvX6hl5aSSA7DR1XbMpdM8r7phjcF63sF4rkKg==
|
||||||
|
|
||||||
node-addon-api@4.2.0:
|
|
||||||
version "4.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.2.0.tgz#117cbb5a959dff0992e1c586ae0393573e4d2a87"
|
|
||||||
integrity sha512-eazsqzwG2lskuzBqCGPi7Ac2UgOoMz8JVOXVhTvvPDYhthvNpefx8jWD8Np7Gv+2Sz0FlPWZk0nJV0z598Wn8Q==
|
|
||||||
|
|
||||||
node-addon-api@^3.0.0, node-addon-api@^3.0.2, node-addon-api@^3.1.0:
|
node-addon-api@^3.0.0, node-addon-api@^3.0.2, node-addon-api@^3.1.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.1.0.tgz"
|
resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.1.0.tgz"
|
||||||
integrity sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw==
|
integrity sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw==
|
||||||
|
|
||||||
|
node-addon-api@^4.3.0:
|
||||||
|
version "4.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.3.0.tgz#52a1a0b475193e0928e98e0426a0d1254782b77f"
|
||||||
|
integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==
|
||||||
|
|
||||||
node-fetch-npm@^2.0.2:
|
node-fetch-npm@^2.0.2:
|
||||||
version "2.0.4"
|
version "2.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/node-fetch-npm/-/node-fetch-npm-2.0.4.tgz#6507d0e17a9ec0be3bec516958a497cec54bf5a4"
|
resolved "https://registry.yarnpkg.com/node-fetch-npm/-/node-fetch-npm-2.0.4.tgz#6507d0e17a9ec0be3bec516958a497cec54bf5a4"
|
||||||
@@ -2290,6 +2296,11 @@ node-fetch-npm@^2.0.2:
|
|||||||
json-parse-better-errors "^1.0.0"
|
json-parse-better-errors "^1.0.0"
|
||||||
safe-buffer "^5.1.1"
|
safe-buffer "^5.1.1"
|
||||||
|
|
||||||
|
node-gyp-build@^4.3.0:
|
||||||
|
version "4.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3"
|
||||||
|
integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==
|
||||||
|
|
||||||
node-gyp@^5.0.2, node-gyp@^5.1.0:
|
node-gyp@^5.0.2, node-gyp@^5.1.0:
|
||||||
version "5.1.1"
|
version "5.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-5.1.1.tgz#eb915f7b631c937d282e33aed44cb7a025f62a3e"
|
resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-5.1.1.tgz#eb915f7b631c937d282e33aed44cb7a025f62a3e"
|
||||||
@@ -2307,11 +2318,6 @@ node-gyp@^5.0.2, node-gyp@^5.1.0:
|
|||||||
tar "^4.4.12"
|
tar "^4.4.12"
|
||||||
which "^1.3.1"
|
which "^1.3.1"
|
||||||
|
|
||||||
noop-logger@^0.1.1:
|
|
||||||
version "0.1.1"
|
|
||||||
resolved "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz"
|
|
||||||
integrity sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=
|
|
||||||
|
|
||||||
nopt@^4.0.1, nopt@^4.0.3:
|
nopt@^4.0.1, nopt@^4.0.3:
|
||||||
version "4.0.3"
|
version "4.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48"
|
resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48"
|
||||||
@@ -2780,11 +2786,6 @@ parse-json@^2.2.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
error-ex "^1.2.0"
|
error-ex "^1.2.0"
|
||||||
|
|
||||||
parse5@^5.0.0:
|
|
||||||
version "5.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178"
|
|
||||||
integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==
|
|
||||||
|
|
||||||
patch-package@^6.4.7:
|
patch-package@^6.4.7:
|
||||||
version "6.4.7"
|
version "6.4.7"
|
||||||
resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.4.7.tgz#2282d53c397909a0d9ef92dae3fdeb558382b148"
|
resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.4.7.tgz#2282d53c397909a0d9ef92dae3fdeb558382b148"
|
||||||
@@ -2863,33 +2864,12 @@ pkg-up@^2.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
find-up "^2.1.0"
|
find-up "^2.1.0"
|
||||||
|
|
||||||
prebuild-install@^6.0.0:
|
prebuild-install@^7.0.1:
|
||||||
version "6.0.1"
|
version "7.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-6.0.1.tgz#5902172f7a40eb67305b96c2a695db32636ee26d"
|
resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.0.1.tgz#c10075727c318efe72412f333e0ef625beaf3870"
|
||||||
integrity sha512-7GOJrLuow8yeiyv75rmvZyeMGzl8mdEX5gY69d6a6bHWmiPevwqFw+tQavhK0EYMaSg3/KD24cWqeQv1EWsqDQ==
|
integrity sha512-QBSab31WqkyxpnMWQxubYAHR5S9B2+r81ucocew34Fkl98FhvKIF50jIJnNOBmAZfyNV7vE5T6gd3hTVWgY6tg==
|
||||||
dependencies:
|
dependencies:
|
||||||
detect-libc "^1.0.3"
|
detect-libc "^2.0.0"
|
||||||
expand-template "^2.0.3"
|
|
||||||
github-from-package "0.0.0"
|
|
||||||
minimist "^1.2.3"
|
|
||||||
mkdirp-classic "^0.5.3"
|
|
||||||
napi-build-utils "^1.0.1"
|
|
||||||
node-abi "^2.7.0"
|
|
||||||
noop-logger "^0.1.1"
|
|
||||||
npmlog "^4.0.1"
|
|
||||||
pump "^3.0.0"
|
|
||||||
rc "^1.2.7"
|
|
||||||
simple-get "^3.0.3"
|
|
||||||
tar-fs "^2.0.0"
|
|
||||||
tunnel-agent "^0.6.0"
|
|
||||||
which-pm-runs "^1.0.0"
|
|
||||||
|
|
||||||
prebuild-install@^7.0.0:
|
|
||||||
version "7.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.0.0.tgz#3c5ce3902f1cb9d6de5ae94ca53575e4af0c1574"
|
|
||||||
integrity sha512-IvSenf33K7JcgddNz2D5w521EgO+4aMMjFt73Uk9FRzQ7P+QZPKrp7qPsDydsSwjGt3T5xRNnM1bj1zMTD5fTA==
|
|
||||||
dependencies:
|
|
||||||
detect-libc "^1.0.3"
|
|
||||||
expand-template "^2.0.3"
|
expand-template "^2.0.3"
|
||||||
github-from-package "0.0.0"
|
github-from-package "0.0.0"
|
||||||
minimist "^1.2.3"
|
minimist "^1.2.3"
|
||||||
@@ -3223,12 +3203,12 @@ run-queue@^1.0.0, run-queue@^1.0.3:
|
|||||||
dependencies:
|
dependencies:
|
||||||
aproba "^1.1.1"
|
aproba "^1.1.1"
|
||||||
|
|
||||||
rxjs@^7.4.0:
|
rxjs@^7.5.1:
|
||||||
version "7.4.0"
|
version "7.5.1"
|
||||||
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.4.0.tgz#a12a44d7eebf016f5ff2441b87f28c9a51cebc68"
|
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.1.tgz#af73df343cbcab37628197f43ea0c8256f54b157"
|
||||||
integrity sha512-7SQDi7xeTMCJpqViXh8gL/lebcwlp3d831F05+9B44A4B0WfsEwUQHR64gsH1kvJ+Ep/J9K2+n1hVl1CsGN23w==
|
integrity sha512-KExVEeZWxMZnZhUZtsJcFwz8IvPvgu4G2Z2QyqjZQzUGr32KDYuSxrEYO4w3tFFNbfLozcrKUTvTPi+E9ywJkQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib "~2.1.0"
|
tslib "^2.1.0"
|
||||||
|
|
||||||
safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1:
|
safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1:
|
||||||
version "5.2.1"
|
version "5.2.1"
|
||||||
@@ -3276,21 +3256,32 @@ serialize-error@^5.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
type-fest "^0.8.0"
|
type-fest "^0.8.0"
|
||||||
|
|
||||||
serialport@^10.0.0:
|
serialport-binding-webserialapi@^1.0.3:
|
||||||
version "10.0.0"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/serialport/-/serialport-10.0.0.tgz#75ec9fd25683dc1acb9d8e24433608f641b0b9e0"
|
resolved "https://registry.yarnpkg.com/serialport-binding-webserialapi/-/serialport-binding-webserialapi-1.0.3.tgz#cf4348c075da2de8f6cf9936c0b95645f3ae657b"
|
||||||
integrity sha512-fqOs6u4buZLbTpAPYZP4j2qwcOJ5Jxtg0x+llJFuMc4AVwrxx+iQc68/46aHCr+qJ2Wo2N86AZ/DDY5acSOODA==
|
integrity sha512-TS7dsvetVoTeiWlzpsT/akjtljiYPO56FoJWSFyJSoO/E8icYJ2neQ7CW5NW/sHZDnMqAxULyAny47UFhWz9oQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@serialport/binding-mock" "10.0.0"
|
"@serialport/binding-abstract" "^9.0.2"
|
||||||
"@serialport/bindings" "10.0.0"
|
"@serialport/stream" "^9.0.2"
|
||||||
"@serialport/parser-byte-length" "10.0.0"
|
|
||||||
"@serialport/parser-cctalk" "10.0.0"
|
serialport@10.2.2:
|
||||||
"@serialport/parser-delimiter" "10.0.0"
|
version "10.2.2"
|
||||||
"@serialport/parser-inter-byte-timeout" "10.0.0"
|
resolved "https://registry.yarnpkg.com/serialport/-/serialport-10.2.2.tgz#ab12a423046df6b64cb3144fdb2d00fb3062ab75"
|
||||||
"@serialport/parser-readline" "10.0.0"
|
integrity sha512-yYp8UM915g8C3+lYZ7GU1Em1BnMeaH9c2bN2/A8ptQH5ttD7E+k9PuDEVOuyxONuyiBOp+vHfIPnje1evnslEw==
|
||||||
"@serialport/parser-ready" "10.0.0"
|
dependencies:
|
||||||
"@serialport/parser-regex" "10.0.0"
|
"@serialport/binding-mock" "10.2.2"
|
||||||
"@serialport/stream" "10.0.0"
|
"@serialport/bindings-cpp" "10.6.2"
|
||||||
|
"@serialport/parser-byte-length" "10.2.2"
|
||||||
|
"@serialport/parser-cctalk" "10.2.2"
|
||||||
|
"@serialport/parser-delimiter" "10.2.2"
|
||||||
|
"@serialport/parser-inter-byte-timeout" "10.2.2"
|
||||||
|
"@serialport/parser-packet-length" "10.2.2"
|
||||||
|
"@serialport/parser-readline" "10.2.2"
|
||||||
|
"@serialport/parser-ready" "10.2.2"
|
||||||
|
"@serialport/parser-regex" "10.2.2"
|
||||||
|
"@serialport/parser-slip-encoder" "10.2.2"
|
||||||
|
"@serialport/parser-spacepacket" "10.2.2"
|
||||||
|
"@serialport/stream" "10.2.2"
|
||||||
debug "^4.3.2"
|
debug "^4.3.2"
|
||||||
|
|
||||||
set-blocking@^2.0.0, set-blocking@~2.0.0:
|
set-blocking@^2.0.0, set-blocking@~2.0.0:
|
||||||
@@ -3327,19 +3318,10 @@ simple-concat@^1.0.0:
|
|||||||
resolved "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz"
|
resolved "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz"
|
||||||
integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==
|
integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==
|
||||||
|
|
||||||
simple-get@^3.0.3:
|
|
||||||
version "3.1.0"
|
|
||||||
resolved "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz"
|
|
||||||
integrity sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==
|
|
||||||
dependencies:
|
|
||||||
decompress-response "^4.2.0"
|
|
||||||
once "^1.3.1"
|
|
||||||
simple-concat "^1.0.0"
|
|
||||||
|
|
||||||
simple-get@^4.0.0:
|
simple-get@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.0.tgz#73fa628278d21de83dadd5512d2cc1f4872bd675"
|
resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543"
|
||||||
integrity sha512-ZalZGexYr3TA0SwySsr5HlgOOinS4Jsa8YB2GJ6lUNAazyAu4KG/VmzMTwAt2YVXzzVj8QmefmAonZIK2BSGcQ==
|
integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==
|
||||||
dependencies:
|
dependencies:
|
||||||
decompress-response "^6.0.0"
|
decompress-response "^6.0.0"
|
||||||
once "^1.3.1"
|
once "^1.3.1"
|
||||||
@@ -3507,14 +3489,14 @@ string-width@^3.0.0, string-width@^3.1.0:
|
|||||||
is-fullwidth-code-point "^2.0.0"
|
is-fullwidth-code-point "^2.0.0"
|
||||||
strip-ansi "^5.1.0"
|
strip-ansi "^5.1.0"
|
||||||
|
|
||||||
string-width@^4.1.0, string-width@^4.2.0:
|
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
||||||
version "4.2.0"
|
version "4.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz"
|
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||||
integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==
|
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||||
dependencies:
|
dependencies:
|
||||||
emoji-regex "^8.0.0"
|
emoji-regex "^8.0.0"
|
||||||
is-fullwidth-code-point "^3.0.0"
|
is-fullwidth-code-point "^3.0.0"
|
||||||
strip-ansi "^6.0.0"
|
strip-ansi "^6.0.1"
|
||||||
|
|
||||||
string.prototype.trimend@^1.0.1:
|
string.prototype.trimend@^1.0.1:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
@@ -3577,6 +3559,13 @@ strip-ansi@^6.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ansi-regex "^5.0.0"
|
ansi-regex "^5.0.0"
|
||||||
|
|
||||||
|
strip-ansi@^6.0.1:
|
||||||
|
version "6.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||||
|
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||||
|
dependencies:
|
||||||
|
ansi-regex "^5.0.1"
|
||||||
|
|
||||||
strip-bom@^3.0.0:
|
strip-bom@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
|
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
|
||||||
@@ -3704,15 +3693,10 @@ tough-cookie@~2.5.0:
|
|||||||
psl "^1.1.28"
|
psl "^1.1.28"
|
||||||
punycode "^2.1.1"
|
punycode "^2.1.1"
|
||||||
|
|
||||||
tslib@^2.0.0, tslib@^2.2.0:
|
tslib@^2.0.0, tslib@^2.1.0:
|
||||||
version "2.3.0"
|
version "2.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e"
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01"
|
||||||
integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==
|
integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
|
||||||
|
|
||||||
tslib@~2.1.0:
|
|
||||||
version "2.1.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a"
|
|
||||||
integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==
|
|
||||||
|
|
||||||
tunnel-agent@^0.6.0:
|
tunnel-agent@^0.6.0:
|
||||||
version "0.6.0"
|
version "0.6.0"
|
||||||
@@ -3880,11 +3864,6 @@ which-module@^2.0.0:
|
|||||||
resolved "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz"
|
resolved "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz"
|
||||||
integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
|
integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
|
||||||
|
|
||||||
which-pm-runs@^1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz"
|
|
||||||
integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=
|
|
||||||
|
|
||||||
which@^1.2.9, which@^1.3.0, which@^1.3.1:
|
which@^1.2.9, which@^1.3.0, which@^1.3.1:
|
||||||
version "1.3.1"
|
version "1.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
|
resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
|
||||||
@@ -4022,10 +4001,10 @@ yargs-parser@^15.0.1:
|
|||||||
camelcase "^5.0.0"
|
camelcase "^5.0.0"
|
||||||
decamelize "^1.2.0"
|
decamelize "^1.2.0"
|
||||||
|
|
||||||
yargs-parser@^20.2.2:
|
yargs-parser@^21.0.0:
|
||||||
version "20.2.7"
|
version "21.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a"
|
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.0.0.tgz#a485d3966be4317426dd56bdb6a30131b281dc55"
|
||||||
integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==
|
integrity sha512-z9kApYUOCwoeZ78rfRYYWdiU/iNL6mwwYlkkZfJoyMR1xps+NEBX5X7XmRpxkZHhXJ6+Ey00IwKxBBSW9FIjyA==
|
||||||
|
|
||||||
yargs-parser@^7.0.0:
|
yargs-parser@^7.0.0:
|
||||||
version "7.0.0"
|
version "7.0.0"
|
||||||
@@ -4051,18 +4030,18 @@ yargs@^14.2.3:
|
|||||||
y18n "^4.0.0"
|
y18n "^4.0.0"
|
||||||
yargs-parser "^15.0.1"
|
yargs-parser "^15.0.1"
|
||||||
|
|
||||||
yargs@^17.2.1:
|
yargs@^17.3.1:
|
||||||
version "17.2.1"
|
version "17.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.2.1.tgz#e2c95b9796a0e1f7f3bf4427863b42e0418191ea"
|
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.3.1.tgz#da56b28f32e2fd45aefb402ed9c26f42be4c07b9"
|
||||||
integrity sha512-XfR8du6ua4K6uLGm5S6fA+FIJom/MdJcFNVY8geLlp2v8GYbOXD4EB1tPNZsRn4vBzKGMgb5DRZMeWuFc2GO8Q==
|
integrity sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==
|
||||||
dependencies:
|
dependencies:
|
||||||
cliui "^7.0.2"
|
cliui "^7.0.2"
|
||||||
escalade "^3.1.1"
|
escalade "^3.1.1"
|
||||||
get-caller-file "^2.0.5"
|
get-caller-file "^2.0.5"
|
||||||
require-directory "^2.1.1"
|
require-directory "^2.1.1"
|
||||||
string-width "^4.2.0"
|
string-width "^4.2.3"
|
||||||
y18n "^5.0.5"
|
y18n "^5.0.5"
|
||||||
yargs-parser "^20.2.2"
|
yargs-parser "^21.0.0"
|
||||||
|
|
||||||
yargs@^8.0.2:
|
yargs@^8.0.2:
|
||||||
version "8.0.2"
|
version "8.0.2"
|
||||||
|
@@ -40,7 +40,7 @@ publish:
|
|||||||
win:
|
win:
|
||||||
icon: "./build/windows/icon.ico"
|
icon: "./build/windows/icon.ico"
|
||||||
artifactName: tabby-${version}-portable.${ext}
|
artifactName: tabby-${version}-portable.${ext}
|
||||||
rfc3161TimeStampServer: http://sha256timestamp.ws.symantec.com/sha256/timestamp
|
rfc3161TimeStampServer: http://timestamp.sectigo.com
|
||||||
nsis:
|
nsis:
|
||||||
oneClick: false
|
oneClick: false
|
||||||
artifactName: tabby-${version}-setup.${ext}
|
artifactName: tabby-${version}-setup.${ext}
|
||||||
@@ -66,7 +66,7 @@ mac:
|
|||||||
NSRemovableVolumesUsageDescription: 'A subprocess requests access to files on a removable volume.'
|
NSRemovableVolumesUsageDescription: 'A subprocess requests access to files on a removable volume.'
|
||||||
|
|
||||||
linux:
|
linux:
|
||||||
category: Utility
|
category: "Utility;TerminalEmulator;System"
|
||||||
icon: "./build/icons"
|
icon: "./build/icons"
|
||||||
artifactName: tabby-${version}-linux.${ext}
|
artifactName: tabby-${version}-linux.${ext}
|
||||||
executableArgs:
|
executableArgs:
|
||||||
|
3
locale/STOP.txt
Normal file
3
locale/STOP.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Do not submit pull requests for translations.
|
||||||
|
|
||||||
|
Translations are managed at https://crowdin.com/project/tabby
|
2100
locale/app.pot
Normal file
2100
locale/app.pot
Normal file
File diff suppressed because it is too large
Load Diff
2111
locale/da-DK.po
Normal file
2111
locale/da-DK.po
Normal file
File diff suppressed because it is too large
Load Diff
2111
locale/de-DE.po
Normal file
2111
locale/de-DE.po
Normal file
File diff suppressed because it is too large
Load Diff
5
locale/en-US.po
Normal file
5
locale/en-US.po
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
msgid "id.port-forwarding.dynamic"
|
||||||
|
msgstr "Dynamic"
|
||||||
|
|
||||||
|
msgid "id.tab-width.dynamic"
|
||||||
|
msgstr "Dynamic"
|
2111
locale/es-ES.po
Normal file
2111
locale/es-ES.po
Normal file
File diff suppressed because it is too large
Load Diff
2111
locale/fr-FR.po
Normal file
2111
locale/fr-FR.po
Normal file
File diff suppressed because it is too large
Load Diff
2111
locale/hr-HR.po
Normal file
2111
locale/hr-HR.po
Normal file
File diff suppressed because it is too large
Load Diff
2111
locale/it-IT.po
Normal file
2111
locale/it-IT.po
Normal file
File diff suppressed because it is too large
Load Diff
2111
locale/ja-JP.po
Normal file
2111
locale/ja-JP.po
Normal file
File diff suppressed because it is too large
Load Diff
2111
locale/pl-PL.po
Normal file
2111
locale/pl-PL.po
Normal file
File diff suppressed because it is too large
Load Diff
2111
locale/ru-RU.po
Normal file
2111
locale/ru-RU.po
Normal file
File diff suppressed because it is too large
Load Diff
2111
locale/zh-CN.po
Normal file
2111
locale/zh-CN.po
Normal file
File diff suppressed because it is too large
Load Diff
2111
locale/zh-TW.po
Normal file
2111
locale/zh-TW.po
Normal file
File diff suppressed because it is too large
Load Diff
60
package.json
60
package.json
@@ -1,85 +1,92 @@
|
|||||||
{
|
{
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular/animations": "^12.0.0",
|
"@angular/animations": "^12.0.0",
|
||||||
|
"@angular/cdk": "^12.2.9",
|
||||||
"@angular/common": "^12.0.0",
|
"@angular/common": "^12.0.0",
|
||||||
"@angular/compiler": "^12.0.0",
|
"@angular/compiler": "^12.0.0",
|
||||||
"@angular/core": "^12.0.0",
|
"@angular/core": "^12.0.0",
|
||||||
"@angular/forms": "^12.0.0",
|
"@angular/forms": "^12.0.0",
|
||||||
"@angular/platform-browser": "^12.0.0",
|
"@angular/platform-browser": "^12.0.0",
|
||||||
"@angular/platform-browser-dynamic": "^12.0.0",
|
"@angular/platform-browser-dynamic": "^12.0.0",
|
||||||
"@fortawesome/fontawesome-free": "^6.0.0-beta.2",
|
"@biesbjerg/ngx-translate-extract-marker": "^1.0.0",
|
||||||
|
"@fortawesome/fontawesome-free": "^6.0.0",
|
||||||
"@ng-bootstrap/ng-bootstrap": "^10.0.0",
|
"@ng-bootstrap/ng-bootstrap": "^10.0.0",
|
||||||
"@sentry/cli": "^1.71.0",
|
"@sentry/cli": "^1.72.1",
|
||||||
"@sentry/electron": "^2.5.4",
|
"@sentry/electron": "^2.5.4",
|
||||||
"@tabby-gang/to-string-loader": "^1.1.7-beta.2",
|
"@tabby-gang/to-string-loader": "^1.1.7-beta.2",
|
||||||
"@types/deep-equal": "1.0.1",
|
"@types/deep-equal": "1.0.1",
|
||||||
"@types/electron-config": "^3.2.2",
|
"@types/electron-config": "^3.2.2",
|
||||||
"@types/electron-debug": "^2.1.0",
|
"@types/electron-debug": "^2.1.0",
|
||||||
"@types/fs-extra": "^9.0.12",
|
"@types/fs-extra": "^9.0.13",
|
||||||
"@types/js-yaml": "^4.0.4",
|
"@types/js-yaml": "^4.0.5",
|
||||||
"@types/node": "16.0.1",
|
"@types/node": "16.0.1",
|
||||||
"@types/sortablejs": "^1.10.7",
|
"@types/sortablejs": "^1.10.7",
|
||||||
"@types/webpack-env": "^1.16.2",
|
"@types/webpack-env": "^1.16.3",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.33.0",
|
"@typescript-eslint/eslint-plugin": "^4.33.0",
|
||||||
"@typescript-eslint/parser": "^4.33.0",
|
"@typescript-eslint/parser": "^4.33.0",
|
||||||
"apply-loader": "2.0.0",
|
"apply-loader": "2.0.0",
|
||||||
"axios": "^0.21.1",
|
"axios": "^0.25.0",
|
||||||
|
"browserify-sign": "^4.2.1",
|
||||||
"clone-deep": "^4.0.1",
|
"clone-deep": "^4.0.1",
|
||||||
"compare-versions": "^4",
|
"compare-versions": "^4",
|
||||||
"core-js": "^3.18.2",
|
"core-js": "^3.20.3",
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"css-loader": "^6.5.1",
|
"css-loader": "^6.5.1",
|
||||||
"deep-equal": "2.0.5",
|
"deep-equal": "2.0.5",
|
||||||
"electron": "16.0.5",
|
"electron": "17.0.0",
|
||||||
"electron-builder": "^22.14.5",
|
"electron-builder": "^22.14.13",
|
||||||
"electron-download": "^4.1.1",
|
"electron-download": "^4.1.1",
|
||||||
"electron-installer-snap": "^5.1.0",
|
"electron-installer-snap": "^5.1.0",
|
||||||
"electron-notarize": "^1.1.1",
|
"electron-notarize": "^1.1.1",
|
||||||
"electron-rebuild": "^3.2.5",
|
"electron-rebuild": "^3.2.7",
|
||||||
"eslint": "^7.32.0",
|
"eslint": "^7.32.0",
|
||||||
"file-loader": "^6.2.0",
|
"file-loader": "^6.2.0",
|
||||||
"graceful-fs": "^4.2.8",
|
"gettext-extractor": "^3.5.3",
|
||||||
|
"graceful-fs": "^4.2.9",
|
||||||
"html-loader": "2.1.2",
|
"html-loader": "2.1.2",
|
||||||
"json-loader": "0.5.7",
|
"json-loader": "^0.5.7",
|
||||||
"lru-cache": "^6.0.0",
|
"lru-cache": "^6.0.0",
|
||||||
"macos-release": "^3.0.1",
|
"macos-release": "^3.0.1",
|
||||||
"ngx-sortablejs": "^11.1.0",
|
"ngx-sortablejs": "^11.1.0",
|
||||||
"ngx-toastr": "^14.0.0",
|
"ngx-toastr": "^14.0.0",
|
||||||
"node-abi": "^3.2.0",
|
"node-abi": "^3.8.0",
|
||||||
"node-sass": "^7.0.0",
|
"node-sass": "^7.0.1",
|
||||||
"npmlog": "5.0.1",
|
"npmlog": "6.0.0",
|
||||||
"npx": "^10.2.2",
|
"npx": "^10.2.2",
|
||||||
"patch-package": "^6.4.7",
|
"patch-package": "^6.4.7",
|
||||||
"pug": "^3.0.2",
|
"po-gettext-loader": "^1.0.0",
|
||||||
|
"pug": "3",
|
||||||
|
"pug-cli": "^1.0.0-alpha6",
|
||||||
"pug-html-loader": "1.1.5",
|
"pug-html-loader": "1.1.5",
|
||||||
"pug-lint": "^2.6.0",
|
"pug-lint": "^2.6.0",
|
||||||
"pug-loader": "^2.4.0",
|
"pug-loader": "^2.4.0",
|
||||||
"pug-static-loader": "2.0.0",
|
"pug-static-loader": "2.0.0",
|
||||||
"raw-loader": "4.0.2",
|
"raw-loader": "4.0.2",
|
||||||
"sass-loader": "^12.3.0",
|
"sass-loader": "^12.4.0",
|
||||||
"shell-quote": "^1.7.3",
|
"shell-quote": "^1.7.3",
|
||||||
"shelljs": "0.8.4",
|
"shelljs": "0.8.5",
|
||||||
"slugify": "^1.6.1",
|
"slugify": "^1.6.5",
|
||||||
"sortablejs": "^1.14.0",
|
"sortablejs": "^1.14.0",
|
||||||
"source-code-pro": "^2.38.0",
|
"source-code-pro": "^2.38.0",
|
||||||
"source-map-loader": "^3.0.0",
|
"source-map-loader": "^3.0.1",
|
||||||
"source-sans-pro": "3.6.0",
|
"source-sans-pro": "3.6.0",
|
||||||
"ssh2": "^1.5.0",
|
"ssh2": "^1.6.0",
|
||||||
"style-loader": "^3.2.1",
|
"style-loader": "^3.2.1",
|
||||||
"svg-inline-loader": "^0.8.2",
|
"svg-inline-loader": "^0.8.2",
|
||||||
"ts-loader": "^9.2.3",
|
"ts-loader": "^9.2.3",
|
||||||
"tslib": "^2.3.1",
|
"tslib": "^2.3.1",
|
||||||
"typedoc": "^0.22.10",
|
"typedoc": "^0.22.11",
|
||||||
"typescript": "^4.3.5",
|
"typescript": "^4.3.5",
|
||||||
"utils-decorators": "^1.10.4",
|
"utils-decorators": "^1.10.4",
|
||||||
"val-loader": "4.0.0",
|
"val-loader": "4.0.0",
|
||||||
"webpack": "^5.64.4",
|
"webpack": "^5.68.0",
|
||||||
"webpack-bundle-analyzer": "^4.5.0",
|
"webpack-bundle-analyzer": "^4.5.0",
|
||||||
"webpack-cli": "^4.9.1",
|
"webpack-cli": "^4.9.2",
|
||||||
"yaml-loader": "0.6.0",
|
"yaml-loader": "0.6.0",
|
||||||
"zone.js": "^0.11.4"
|
"zone.js": "^0.11.4"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
|
"*/pug": "^3",
|
||||||
"lzma-native": "^8.0.0",
|
"lzma-native": "^8.0.0",
|
||||||
"*/node-abi": "^3.5.0",
|
"*/node-abi": "^3.5.0",
|
||||||
"**/graceful-fs": "^4.2.4"
|
"**/graceful-fs": "^4.2.4"
|
||||||
@@ -93,7 +100,10 @@
|
|||||||
"prod": "cross-env TABBY_DEV=1 electron app",
|
"prod": "cross-env TABBY_DEV=1 electron app",
|
||||||
"docs": "node scripts/build-docs.js",
|
"docs": "node scripts/build-docs.js",
|
||||||
"lint": "eslint --ext ts */src */lib",
|
"lint": "eslint --ext ts */src */lib",
|
||||||
"postinstall": "patch-package && node ./scripts/install-deps.js"
|
"postinstall": "patch-package && node ./scripts/install-deps.js",
|
||||||
|
"i18n:pull": "crowdin pull --skip-untranslated-strings",
|
||||||
|
"i18n:extract": "node scripts/i18n-extract.js",
|
||||||
|
"i18n:push": "crowdin push"
|
||||||
},
|
},
|
||||||
"private": true
|
"private": true
|
||||||
}
|
}
|
||||||
|
13
patches/gettext-extractor+3.5.3.patch
Normal file
13
patches/gettext-extractor+3.5.3.patch
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
diff --git a/node_modules/gettext-extractor/dist/html/selector.js b/node_modules/gettext-extractor/dist/html/selector.js
|
||||||
|
index e290d12..cdb1d0b 100644
|
||||||
|
--- a/node_modules/gettext-extractor/dist/html/selector.js
|
||||||
|
+++ b/node_modules/gettext-extractor/dist/html/selector.js
|
||||||
|
@@ -120,7 +120,7 @@ class ElementSelector {
|
||||||
|
if (elementAttributeValue === null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
- if (attribute.value) {
|
||||||
|
+ if (attribute.value !== undefined) {
|
||||||
|
switch (attribute.operator) {
|
||||||
|
case '^=':
|
||||||
|
if (elementAttributeValue.slice(0, attribute.value.length) !== attribute.value) {
|
39
patches/ssh2+1.6.0.patch
Normal file
39
patches/ssh2+1.6.0.patch
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
diff --git a/node_modules/ssh2/lib/protocol/keyParser.js b/node_modules/ssh2/lib/protocol/keyParser.js
|
||||||
|
index 9860e3f..ee82e51 100644
|
||||||
|
--- a/node_modules/ssh2/lib/protocol/keyParser.js
|
||||||
|
+++ b/node_modules/ssh2/lib/protocol/keyParser.js
|
||||||
|
@@ -15,6 +15,7 @@ const {
|
||||||
|
sign: sign_,
|
||||||
|
verify: verify_,
|
||||||
|
} = require('crypto');
|
||||||
|
+const { createVerify: createVerifyDSS } = require('browserify-sign')
|
||||||
|
const supportedOpenSSLCiphers = getCiphers();
|
||||||
|
|
||||||
|
const { Ber } = require('asn1');
|
||||||
|
@@ -404,6 +405,17 @@ const BaseKey = {
|
||||||
|
return new Error('No public key available');
|
||||||
|
if (!algo || typeof algo !== 'string')
|
||||||
|
algo = this[SYM_HASH_ALGO];
|
||||||
|
+
|
||||||
|
+ if (algo === 'dss1') {
|
||||||
|
+ const verifier = createVerifyDSS('DSA-SHA1');
|
||||||
|
+ verifier.update(data);
|
||||||
|
+ try {
|
||||||
|
+ return verifier.verify(pem, signature);
|
||||||
|
+ } catch (ex) {
|
||||||
|
+ return ex;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
try {
|
||||||
|
return verify_(algo, data, pem, signature);
|
||||||
|
} catch (ex) {
|
||||||
|
@@ -1343,7 +1355,7 @@ function parseDER(data, baseType, comment, fullType) {
|
||||||
|
return new Error('Malformed OpenSSH public key');
|
||||||
|
pubPEM = genOpenSSLDSAPub(p, q, g, y);
|
||||||
|
pubSSH = genOpenSSHDSAPub(p, q, g, y);
|
||||||
|
- algo = 'sha1';
|
||||||
|
+ algo = 'dss1';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'ssh-ed25519': {
|
@@ -5,5 +5,5 @@ const log = require('npmlog')
|
|||||||
|
|
||||||
vars.packagesWithDocs.forEach(([dest, src]) => {
|
vars.packagesWithDocs.forEach(([dest, src]) => {
|
||||||
log.info('docs', src)
|
log.info('docs', src)
|
||||||
sh.exec(`yarn typedoc --out docs/api/${dest} --tsconfig ${src}/tsconfig.typings.json ${src}/src/index.ts`)
|
sh.exec(`yarn typedoc --out docs/api/${dest} --tsconfig ${src}/tsconfig.typings.json ${src}/src/index.ts`, { fatal: true })
|
||||||
})
|
})
|
||||||
|
@@ -5,5 +5,5 @@ const log = require('npmlog')
|
|||||||
|
|
||||||
vars.builtinPlugins.forEach(plugin => {
|
vars.builtinPlugins.forEach(plugin => {
|
||||||
log.info('typings', plugin)
|
log.info('typings', plugin)
|
||||||
sh.exec(`npx tsc --project ${plugin}/tsconfig.typings.json`)
|
sh.exec(`yarn tsc --project ${plugin}/tsconfig.typings.json`, { fatal: true })
|
||||||
})
|
})
|
||||||
|
53
scripts/i18n-extract.js
Executable file
53
scripts/i18n-extract.js
Executable file
@@ -0,0 +1,53 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
const sh = require('shelljs')
|
||||||
|
const fs = require('fs/promises')
|
||||||
|
const vars = require('./vars')
|
||||||
|
const log = require('npmlog')
|
||||||
|
const { GettextExtractor, JsExtractors, HtmlExtractors } = require('gettext-extractor')
|
||||||
|
|
||||||
|
let extractor = new GettextExtractor()
|
||||||
|
|
||||||
|
const tempOutput = 'locale/app.new.pot'
|
||||||
|
const pot = 'locale/app.pot'
|
||||||
|
const tempHtml = 'locale/tmp-html'
|
||||||
|
|
||||||
|
;(async () => {
|
||||||
|
sh.mkdir('-p', tempHtml)
|
||||||
|
for (const plugin of vars.builtinPlugins) {
|
||||||
|
log.info('compile-pug', plugin)
|
||||||
|
|
||||||
|
sh.exec(`yarn pug --doctype html -s --pretty -O '{require: function(){}}' -o ${tempHtml}/${plugin} ${plugin}`, { fatal: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info('extract-ts')
|
||||||
|
extractor.createJsParser([
|
||||||
|
JsExtractors.callExpression('this.translate.instant', {
|
||||||
|
arguments: { text: 0 },
|
||||||
|
}),
|
||||||
|
JsExtractors.callExpression('translate.instant', {
|
||||||
|
arguments: { text: 0 },
|
||||||
|
}),
|
||||||
|
JsExtractors.callExpression('_', {
|
||||||
|
arguments: { text: 0 },
|
||||||
|
}),
|
||||||
|
]).parseFilesGlob('./tabby-*/src/**/*.ts')
|
||||||
|
|
||||||
|
log.info('extract-pug')
|
||||||
|
const options = {
|
||||||
|
attributes: {
|
||||||
|
context: 'translatecontext',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
extractor.createHtmlParser([
|
||||||
|
HtmlExtractors.elementContent('translate, [translate=""]', options),
|
||||||
|
HtmlExtractors.elementAttribute('[translate*=" "]', 'translate', options),
|
||||||
|
]).parseFilesGlob(`${tempHtml}/**/*.html`)
|
||||||
|
|
||||||
|
extractor.savePotFile(tempOutput)
|
||||||
|
extractor.printStats()
|
||||||
|
|
||||||
|
sh.rm('-r', tempHtml)
|
||||||
|
sh.exec(`msgcat -s ${tempOutput} > ${pot}`, { fatal: true })
|
||||||
|
|
||||||
|
await fs.rename(tempOutput, pot)
|
||||||
|
})()
|
@@ -1,30 +1,26 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
const sh = require('shelljs')
|
const sh = require('shelljs')
|
||||||
const path = require('path')
|
|
||||||
const vars = require('./vars')
|
const vars = require('./vars')
|
||||||
const log = require('npmlog')
|
const log = require('npmlog')
|
||||||
|
|
||||||
const localBinPath = path.resolve(__dirname, '../node_modules/.bin')
|
|
||||||
const npx = `${localBinPath}/npx`
|
|
||||||
|
|
||||||
log.info('patch')
|
log.info('patch')
|
||||||
sh.exec(`${npx} patch-package`)
|
sh.exec(`yarn patch-package`, { fatal: true })
|
||||||
|
|
||||||
log.info('deps', 'app')
|
log.info('deps', 'app')
|
||||||
|
|
||||||
sh.cd('app')
|
sh.cd('app')
|
||||||
sh.exec(`${npx} yarn install --force`)
|
sh.exec(`yarn install --force`, { fatal: true })
|
||||||
sh.cd('..')
|
sh.cd('..')
|
||||||
|
|
||||||
sh.cd('web')
|
sh.cd('web')
|
||||||
sh.exec(`${npx} yarn install --force`)
|
sh.exec(`yarn install --force`, { fatal: true })
|
||||||
sh.exec(`${npx} patch-package`)
|
sh.exec(`yarn patch-package`, { fatal: true })
|
||||||
sh.cd('..')
|
sh.cd('..')
|
||||||
|
|
||||||
vars.allPackages.forEach(plugin => {
|
vars.allPackages.forEach(plugin => {
|
||||||
log.info('deps', plugin)
|
log.info('deps', plugin)
|
||||||
sh.cd(plugin)
|
sh.cd(plugin)
|
||||||
sh.exec(`${npx} yarn install --force`)
|
sh.exec(`yarn install --force`, { fatal: true })
|
||||||
sh.cd('..')
|
sh.cd('..')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@@ -11,25 +11,25 @@ sh.mkdir('-p', target)
|
|||||||
fs.writeFileSync(path.join(target, 'package.json'), '{}')
|
fs.writeFileSync(path.join(target, 'package.json'), '{}')
|
||||||
sh.cd(target)
|
sh.cd(target)
|
||||||
vars.builtinPlugins.forEach(plugin => {
|
vars.builtinPlugins.forEach(plugin => {
|
||||||
if (plugin === 'tabby-web') {
|
if (plugin === 'tabby-web') {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.info('install', plugin)
|
log.info('install', plugin)
|
||||||
sh.cp('-r', path.join('..', plugin), '.')
|
sh.cp('-r', path.join('..', plugin), '.')
|
||||||
sh.rm('-rf', path.join(plugin, 'node_modules'))
|
sh.rm('-rf', path.join(plugin, 'node_modules'))
|
||||||
sh.cd(plugin)
|
sh.cd(plugin)
|
||||||
sh.exec(`yarn install --force --production`)
|
sh.exec(`yarn install --force --production`, { fatal: true })
|
||||||
|
|
||||||
|
|
||||||
log.info('rebuild', 'native')
|
log.info('rebuild', 'native')
|
||||||
if (fs.existsSync('node_modules')) {
|
if (fs.existsSync('node_modules')) {
|
||||||
rebuild({
|
rebuild({
|
||||||
buildPath: path.resolve('.'),
|
buildPath: path.resolve('.'),
|
||||||
electronVersion: vars.electronVersion,
|
electronVersion: vars.electronVersion,
|
||||||
arch: process.env.ARCH ?? process.arch,
|
arch: process.env.ARCH ?? process.arch,
|
||||||
force: true,
|
force: true,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
sh.cd('..')
|
sh.cd('..')
|
||||||
})
|
})
|
||||||
fs.unlinkSync(path.join(target, 'package.json'), '{}')
|
fs.unlinkSync(path.join(target, 'package.json'), '{}')
|
||||||
|
@@ -7,7 +7,7 @@ const { execSync } = require('child_process')
|
|||||||
vars.allPackages.forEach(plugin => {
|
vars.allPackages.forEach(plugin => {
|
||||||
log.info('bump', plugin)
|
log.info('bump', plugin)
|
||||||
sh.cd(plugin)
|
sh.cd(plugin)
|
||||||
sh.exec('npm --no-git-tag-version version ' + vars.version)
|
sh.exec('npm --no-git-tag-version version ' + vars.version, { fatal: true })
|
||||||
execSync('npm publish', { stdio: 'inherit' })
|
execSync('npm publish', { stdio: 'inherit' })
|
||||||
sh.cd('..')
|
sh.cd('..')
|
||||||
})
|
})
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "tabby-community-color-schemes",
|
"name": "tabby-community-color-schemes",
|
||||||
"version": "1.0.165-nightly.0",
|
"version": "1.0.171-nightly.3",
|
||||||
"description": "Community color schemes for Tabby",
|
"description": "Community color schemes for Tabby",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"tabby-builtin-plugin"
|
"tabby-builtin-plugin"
|
||||||
|
44
tabby-community-color-schemes/schemes/Light Owl
Normal file
44
tabby-community-color-schemes/schemes/Light Owl
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
!
|
||||||
|
! Light Owl
|
||||||
|
! https://github.com/sdras/night-owl-vscode-theme
|
||||||
|
!
|
||||||
|
*.foreground: #403f53
|
||||||
|
*.background: #fbfbfb
|
||||||
|
*.cursorColor: #90a7b2
|
||||||
|
!
|
||||||
|
! Black
|
||||||
|
*.color0: #403f53
|
||||||
|
*.color8: #403f53
|
||||||
|
!
|
||||||
|
! Red
|
||||||
|
*.color1: #de3d3b
|
||||||
|
*.color9: #de3d3b
|
||||||
|
!
|
||||||
|
! Green
|
||||||
|
*.color2: #08916a
|
||||||
|
*.color10: #08916a
|
||||||
|
!
|
||||||
|
! Yellow
|
||||||
|
*.color3: #e0af02
|
||||||
|
*.color11: #daaa01
|
||||||
|
!
|
||||||
|
! Blue
|
||||||
|
*.color4: #288ed7
|
||||||
|
*.color12: #288ed7
|
||||||
|
!
|
||||||
|
! Magenta
|
||||||
|
*.color5: #d6438a
|
||||||
|
*.color13: #d6438a
|
||||||
|
!
|
||||||
|
! Cyan
|
||||||
|
*.color6: #2aa298
|
||||||
|
*.color14: #2aa298
|
||||||
|
!
|
||||||
|
! White
|
||||||
|
*.color7: #f0f0f0
|
||||||
|
*.color15: #979797
|
||||||
|
!
|
||||||
|
! Bold, Italic, Underline
|
||||||
|
!*.colorBD:
|
||||||
|
!*.colorIT:
|
||||||
|
!*.colorUL:
|
44
tabby-community-color-schemes/schemes/Night Owl
Normal file
44
tabby-community-color-schemes/schemes/Night Owl
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
!
|
||||||
|
! Night Owl
|
||||||
|
! https://github.com/sdras/night-owl-vscode-theme
|
||||||
|
!
|
||||||
|
*.foreground: #d6deeb
|
||||||
|
*.background: #011627
|
||||||
|
*.cursorColor: #80a4c2
|
||||||
|
!
|
||||||
|
! Black
|
||||||
|
*.color0: #011627
|
||||||
|
*.color8: #969696
|
||||||
|
!
|
||||||
|
! Red
|
||||||
|
*.color1: #ef5350
|
||||||
|
*.color9: #ef5350
|
||||||
|
!
|
||||||
|
! Green
|
||||||
|
*.color2: #22da6e
|
||||||
|
*.color10: #22da6e
|
||||||
|
!
|
||||||
|
! Yellow
|
||||||
|
*.color3: #addb67
|
||||||
|
*.color11: #ffeb95
|
||||||
|
!
|
||||||
|
! Blue
|
||||||
|
*.color4: #82aaff
|
||||||
|
*.color12: #82aaff
|
||||||
|
!
|
||||||
|
! Magenta
|
||||||
|
*.color5: #c792ea
|
||||||
|
*.color13: #c792ea
|
||||||
|
!
|
||||||
|
! Cyan
|
||||||
|
*.color6: #21c7a8
|
||||||
|
*.color14: #7fdbca
|
||||||
|
!
|
||||||
|
! White
|
||||||
|
*.color7: #ffffff
|
||||||
|
*.color15: #ffffff
|
||||||
|
!
|
||||||
|
! Bold, Italic, Underline
|
||||||
|
!*.colorBD:
|
||||||
|
!*.colorIT:
|
||||||
|
!*.colorUL:
|
44
tabby-community-color-schemes/schemes/Rose Pine
Normal file
44
tabby-community-color-schemes/schemes/Rose Pine
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
!
|
||||||
|
! Rosé Pine
|
||||||
|
! https://rosepinetheme.com/
|
||||||
|
!
|
||||||
|
*.foreground: #e0def4
|
||||||
|
*.background: #191724
|
||||||
|
*.cursorColor: #555169
|
||||||
|
!
|
||||||
|
! Black
|
||||||
|
*.color0: #26233a
|
||||||
|
*.color8: #6e6a86
|
||||||
|
!
|
||||||
|
! Red
|
||||||
|
*.color1: #eb6f92
|
||||||
|
*.color9: #eb6f92
|
||||||
|
!
|
||||||
|
! Green
|
||||||
|
*.color2: #31748f
|
||||||
|
*.color10: #31748f
|
||||||
|
!
|
||||||
|
! Yellow
|
||||||
|
*.color3: #f6c177
|
||||||
|
*.color11: #f6c177
|
||||||
|
!
|
||||||
|
! Blue
|
||||||
|
*.color4: #9ccfd8
|
||||||
|
*.color12: #9ccfd8
|
||||||
|
|
||||||
|
! Magenta
|
||||||
|
*.color5: #c4a7e7
|
||||||
|
*.color13: #c4a7e7
|
||||||
|
!
|
||||||
|
! Cyan
|
||||||
|
*.color6: #ebbcba
|
||||||
|
*.color14: #ebbcba
|
||||||
|
!
|
||||||
|
! White
|
||||||
|
*.color7: #e0def4
|
||||||
|
*.color15: #e0def4
|
||||||
|
!
|
||||||
|
! Bold, Italic, Underline
|
||||||
|
!*.colorBD:
|
||||||
|
!*.colorIT:
|
||||||
|
!*.colorUL:
|
44
tabby-community-color-schemes/schemes/Rose Pine Dawn
Normal file
44
tabby-community-color-schemes/schemes/Rose Pine Dawn
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
!
|
||||||
|
! Rosé Pine Dawn
|
||||||
|
! https://rosepinetheme.com/
|
||||||
|
!
|
||||||
|
*.foreground: #575279
|
||||||
|
*.background: #faf4ed
|
||||||
|
*.cursorColor: #9893a5
|
||||||
|
!
|
||||||
|
! Black
|
||||||
|
*.color0: #f2e9de
|
||||||
|
*.color8: #6e6a86
|
||||||
|
!
|
||||||
|
! Red
|
||||||
|
*.color1: #b4637a
|
||||||
|
*.color9: #b4637a
|
||||||
|
!
|
||||||
|
! Green
|
||||||
|
*.color2: #286983
|
||||||
|
*.color10: #286983
|
||||||
|
!
|
||||||
|
! Yellow
|
||||||
|
*.color3: #ea9d34
|
||||||
|
*.color11: #ea9d34
|
||||||
|
!
|
||||||
|
! Blue
|
||||||
|
*.color4: #56949f
|
||||||
|
*.color12: #56949f
|
||||||
|
!
|
||||||
|
! Magenta
|
||||||
|
*.color5: #907aa9
|
||||||
|
*.color13: #907aa9
|
||||||
|
!
|
||||||
|
! Cyan
|
||||||
|
*.color6: #d7827e
|
||||||
|
*.color14: #d7827e
|
||||||
|
!
|
||||||
|
! White
|
||||||
|
*.color7: #575279
|
||||||
|
*.color15: #575279
|
||||||
|
!
|
||||||
|
! Bold, Italic, Underline
|
||||||
|
!*.colorBD:
|
||||||
|
!*.colorIT:
|
||||||
|
!*.colorUL:
|
44
tabby-community-color-schemes/schemes/Rose Pine Moon
Normal file
44
tabby-community-color-schemes/schemes/Rose Pine Moon
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
!
|
||||||
|
! Rosé Pine Moon
|
||||||
|
! https://rosepinetheme.com/
|
||||||
|
!
|
||||||
|
*.foreground: #e0def4
|
||||||
|
*.background: #232136
|
||||||
|
*.cursorColor: #59546d
|
||||||
|
!
|
||||||
|
! Black
|
||||||
|
*.color0: #393552
|
||||||
|
*.color8: #817c9c
|
||||||
|
!
|
||||||
|
! Red
|
||||||
|
*.color1: #eb6f92
|
||||||
|
*.color9: #eb6f92
|
||||||
|
!
|
||||||
|
! Green
|
||||||
|
*.color2: #3e8fb0
|
||||||
|
*.color10: #3e8fb0
|
||||||
|
!
|
||||||
|
! Yellow
|
||||||
|
*.color3: #f6c177
|
||||||
|
*.color11: #f6c177
|
||||||
|
!
|
||||||
|
! Blue
|
||||||
|
*.color4: #9ccfd8
|
||||||
|
*.color12: #9ccfd8
|
||||||
|
!
|
||||||
|
! Magenta
|
||||||
|
*.color5: #c4a7e7
|
||||||
|
*.color13: #c4a7e7
|
||||||
|
!
|
||||||
|
! Cyan
|
||||||
|
*.color6: #ea9a97
|
||||||
|
*.color14: #ea9a97
|
||||||
|
!
|
||||||
|
! White
|
||||||
|
*.color7: #e0def4
|
||||||
|
*.color15: #e0def4
|
||||||
|
!
|
||||||
|
! Bold, Italic, Underline
|
||||||
|
!*.colorBD:
|
||||||
|
!*.colorIT:
|
||||||
|
!*.colorUL:
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "tabby-core",
|
"name": "tabby-core",
|
||||||
"version": "1.0.165-nightly.0",
|
"version": "1.0.171-nightly.3",
|
||||||
"description": "Tabby core",
|
"description": "Tabby core",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"tabby-builtin-plugin"
|
"tabby-builtin-plugin"
|
||||||
@@ -17,12 +17,15 @@
|
|||||||
"author": "Eugene Pankov",
|
"author": "Eugene Pankov",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@ngx-translate/core": "^14.0.0",
|
||||||
"bootstrap": "^4.1.3",
|
"bootstrap": "^4.1.3",
|
||||||
"deepmerge": "^4.1.1",
|
"deepmerge": "^4.1.1",
|
||||||
"js-yaml": "^4.0.0",
|
"js-yaml": "^4.0.0",
|
||||||
|
"messageformat": "^2.3.0",
|
||||||
"mixpanel": "^0.13.0",
|
"mixpanel": "^0.13.0",
|
||||||
"ngx-filesize": "^2.0.16",
|
"ngx-filesize": "^2.0.16",
|
||||||
"ngx-perfect-scrollbar": "^10.1.0",
|
"ngx-perfect-scrollbar": "^10.1.0",
|
||||||
|
"ngx-translate-messageformat-compiler": "^4.11.0",
|
||||||
"readable-stream": "3.6.0",
|
"readable-stream": "3.6.0",
|
||||||
"uuid": "^8.0.0"
|
"uuid": "^8.0.0"
|
||||||
},
|
},
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
export { BaseComponent, SubscriptionContainer } from '../components/base.component'
|
export { BaseComponent, SubscriptionContainer } from '../components/base.component'
|
||||||
export { BaseTabComponent, BaseTabProcess } from '../components/baseTab.component'
|
export { BaseTabComponent, BaseTabProcess, GetRecoveryTokenOptions } from '../components/baseTab.component'
|
||||||
export { TabHeaderComponent } from '../components/tabHeader.component'
|
export { TabHeaderComponent } from '../components/tabHeader.component'
|
||||||
export { SplitTabComponent, SplitContainer, SplitDirection, SplitOrientation } from '../components/splitTab.component'
|
export { SplitTabComponent, SplitContainer, SplitDirection, SplitOrientation } from '../components/splitTab.component'
|
||||||
export { TabRecoveryProvider, RecoveryToken } from './tabRecovery'
|
export { TabRecoveryProvider, RecoveryToken } from './tabRecovery'
|
||||||
@@ -35,4 +35,5 @@ export { TabsService, NewTabParameters, TabComponentType } from '../services/tab
|
|||||||
export { UpdaterService } from '../services/updater.service'
|
export { UpdaterService } from '../services/updater.service'
|
||||||
export { VaultService, Vault, VaultSecret, VaultFileSecret, VAULT_SECRET_TYPE_FILE, StoredVault, VaultSecretKey } from '../services/vault.service'
|
export { VaultService, Vault, VaultSecret, VaultFileSecret, VAULT_SECRET_TYPE_FILE, StoredVault, VaultSecretKey } from '../services/vault.service'
|
||||||
export { FileProvidersService } from '../services/fileProviders.service'
|
export { FileProvidersService } from '../services/fileProviders.service'
|
||||||
|
export { LocaleService, TranslateServiceWrapper as TranslateService } from '../services/locale.service'
|
||||||
export * from '../utils'
|
export * from '../utils'
|
||||||
|
@@ -1,4 +1,3 @@
|
|||||||
import deepClone from 'clone-deep'
|
|
||||||
import { BaseTabComponent } from '../components/baseTab.component'
|
import { BaseTabComponent } from '../components/baseTab.component'
|
||||||
import { NewTabParameters } from '../services/tabs.service'
|
import { NewTabParameters } from '../services/tabs.service'
|
||||||
|
|
||||||
@@ -38,14 +37,4 @@ export abstract class TabRecoveryProvider <T extends BaseTabComponent> {
|
|||||||
* 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 recover (recoveryToken: RecoveryToken): Promise<NewTabParameters<T>>
|
abstract recover (recoveryToken: RecoveryToken): Promise<NewTabParameters<T>>
|
||||||
|
|
||||||
/**
|
|
||||||
* @param recoveryToken a recovery token found in the saved tabs list
|
|
||||||
* @returns [[RecoveryToken]] a new recovery token to create the duplicate tab from
|
|
||||||
*
|
|
||||||
* The default implementation just returns a deep copy of the original token
|
|
||||||
*/
|
|
||||||
duplicate (recoveryToken: RecoveryToken): RecoveryToken {
|
|
||||||
return deepClone(recoveryToken)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
|
import { TranslateService } from '@ngx-translate/core'
|
||||||
|
|
||||||
import { ToolbarButton, ToolbarButtonProvider } from './api/toolbarButtonProvider'
|
import { ToolbarButton, ToolbarButtonProvider } from './api/toolbarButtonProvider'
|
||||||
import { HostAppService, Platform } from './api/hostApp'
|
import { HostAppService, Platform } from './api/hostApp'
|
||||||
@@ -12,6 +13,7 @@ export class ButtonProvider extends ToolbarButtonProvider {
|
|||||||
constructor (
|
constructor (
|
||||||
private hostApp: HostAppService,
|
private hostApp: HostAppService,
|
||||||
private profilesService: ProfilesService,
|
private profilesService: ProfilesService,
|
||||||
|
private translate: TranslateService,
|
||||||
hotkeys: HotkeysService,
|
hotkeys: HotkeysService,
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
@@ -35,7 +37,7 @@ export class ButtonProvider extends ToolbarButtonProvider {
|
|||||||
icon: this.hostApp.platform === Platform.Web
|
icon: this.hostApp.platform === Platform.Web
|
||||||
? require('./icons/plus.svg')
|
? require('./icons/plus.svg')
|
||||||
: require('./icons/profiles.svg'),
|
: require('./icons/profiles.svg'),
|
||||||
title: 'Profiles and connections',
|
title: this.translate.instant('Profiles & connections'),
|
||||||
click: () => this.activate(),
|
click: () => this.activate(),
|
||||||
},
|
},
|
||||||
...this.profilesService.getRecentProfiles().map(profile => ({
|
...this.profilesService.getRecentProfiles().map(profile => ({
|
||||||
|
@@ -88,7 +88,7 @@ $side-tab-width: 200px;
|
|||||||
padding: 0 12px;
|
padding: 0 12px;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
border-bottom: 2px solid transparent;
|
border-bottom: 2px solid transparent;
|
||||||
transition: 0.25s all;
|
transition: 0.125s all ease-out;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
|
@@ -14,6 +14,7 @@ import { UpdaterService } from '../services/updater.service'
|
|||||||
import { BaseTabComponent } from './baseTab.component'
|
import { BaseTabComponent } from './baseTab.component'
|
||||||
import { SafeModeModalComponent } from './safeModeModal.component'
|
import { SafeModeModalComponent } from './safeModeModal.component'
|
||||||
import { TabBodyComponent } from './tabBody.component'
|
import { TabBodyComponent } from './tabBody.component'
|
||||||
|
import { SplitTabComponent } from './splitTab.component'
|
||||||
import { AppService, FileTransfer, HostWindowService, PlatformService, ToolbarButton, ToolbarButtonProvider } from '../api'
|
import { AppService, FileTransfer, HostWindowService, PlatformService, ToolbarButton, ToolbarButtonProvider } from '../api'
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@@ -196,6 +197,13 @@ export class AppRootComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onTabsReordered (event: CdkDragDrop<BaseTabComponent[]>) {
|
onTabsReordered (event: CdkDragDrop<BaseTabComponent[]>) {
|
||||||
|
const tab: BaseTabComponent = event.item.data
|
||||||
|
if (!this.app.tabs.includes(tab)) {
|
||||||
|
if (tab.parent instanceof SplitTabComponent) {
|
||||||
|
tab.parent.removeTab(tab)
|
||||||
|
this.app.wrapAndAddTab(tab)
|
||||||
|
}
|
||||||
|
}
|
||||||
moveItemInArray(this.app.tabs, event.previousIndex, event.currentIndex)
|
moveItemInArray(this.app.tabs, event.previousIndex, event.currentIndex)
|
||||||
this.app.emitTabsChanged()
|
this.app.emitTabsChanged()
|
||||||
}
|
}
|
||||||
@@ -206,6 +214,10 @@ export class AppRootComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@HostBinding('class.vibrant') get isVibrant () {
|
||||||
|
return this.config.store?.appearance.vibrancy
|
||||||
|
}
|
||||||
|
|
||||||
private getToolbarButtons (aboveZero: boolean): ToolbarButton[] {
|
private getToolbarButtons (aboveZero: boolean): ToolbarButton[] {
|
||||||
let buttons: ToolbarButton[] = []
|
let buttons: ToolbarButton[] = []
|
||||||
this.config.enabledServices(this.toolbarButtonProviders).forEach(provider => {
|
this.config.enabledServices(this.toolbarButtonProviders).forEach(provider => {
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { Observable, Subject, distinctUntilChanged } from 'rxjs'
|
import { Observable, Subject, distinctUntilChanged, filter, debounceTime } from 'rxjs'
|
||||||
import { EmbeddedViewRef, ViewContainerRef, ViewRef } from '@angular/core'
|
import { EmbeddedViewRef, ViewContainerRef, ViewRef } from '@angular/core'
|
||||||
import { RecoveryToken } from '../api/tabRecovery'
|
import { RecoveryToken } from '../api/tabRecovery'
|
||||||
import { BaseComponent } from './base.component'
|
import { BaseComponent } from './base.component'
|
||||||
@@ -11,6 +11,10 @@ export interface BaseTabProcess {
|
|||||||
name: string
|
name: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface GetRecoveryTokenOptions {
|
||||||
|
includeState: boolean
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract base class for custom tab components
|
* Abstract base class for custom tab components
|
||||||
*/
|
*/
|
||||||
@@ -43,7 +47,9 @@ export abstract class BaseTabComponent extends BaseComponent {
|
|||||||
/**
|
/**
|
||||||
* CSS color override for the tab's header
|
* CSS color override for the tab's header
|
||||||
*/
|
*/
|
||||||
color: string|null = null
|
get color (): string|null { return this._color }
|
||||||
|
set color (value: string|null) { this._color = value }
|
||||||
|
private _color: string|null = null
|
||||||
|
|
||||||
hasFocus = false
|
hasFocus = false
|
||||||
|
|
||||||
@@ -57,7 +63,6 @@ export abstract class BaseTabComponent extends BaseComponent {
|
|||||||
/* @hidden */
|
/* @hidden */
|
||||||
viewContainerEmbeddedRef?: EmbeddedViewRef<any>
|
viewContainerEmbeddedRef?: EmbeddedViewRef<any>
|
||||||
|
|
||||||
private progressClearTimeout: number
|
|
||||||
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>()
|
||||||
@@ -83,6 +88,12 @@ export abstract class BaseTabComponent extends BaseComponent {
|
|||||||
this.blurred$.subscribe(() => {
|
this.blurred$.subscribe(() => {
|
||||||
this.hasFocus = false
|
this.hasFocus = false
|
||||||
})
|
})
|
||||||
|
this.subscribeUntilDestroyed(this.progress.pipe(
|
||||||
|
filter(x => x !== null),
|
||||||
|
debounceTime(5000),
|
||||||
|
), () => {
|
||||||
|
this.setProgress(null)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
setTitle (title: string): void {
|
setTitle (title: string): void {
|
||||||
@@ -99,14 +110,6 @@ export abstract class BaseTabComponent extends BaseComponent {
|
|||||||
*/
|
*/
|
||||||
setProgress (progress: number|null): void {
|
setProgress (progress: number|null): void {
|
||||||
this.progress.next(progress)
|
this.progress.next(progress)
|
||||||
if (progress) {
|
|
||||||
if (this.progressClearTimeout) {
|
|
||||||
clearTimeout(this.progressClearTimeout)
|
|
||||||
}
|
|
||||||
this.progressClearTimeout = setTimeout(() => {
|
|
||||||
this.setProgress(null)
|
|
||||||
}, 5000) as any
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -136,7 +139,7 @@ export abstract class BaseTabComponent extends BaseComponent {
|
|||||||
* @return JSON serializable tab state representation
|
* @return JSON serializable tab state representation
|
||||||
* for your [[TabRecoveryProvider]] to parse
|
* for your [[TabRecoveryProvider]] to parse
|
||||||
*/
|
*/
|
||||||
async getRecoveryToken (): Promise<RecoveryToken|null> {
|
async getRecoveryToken (options?: GetRecoveryTokenOptions): Promise<RecoveryToken|null> { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2,5 +2,5 @@
|
|||||||
input.form-control(type='text', #input, [(ngModel)]='value', (keyup.enter)='save()', autofocus)
|
input.form-control(type='text', #input, [(ngModel)]='value', (keyup.enter)='save()', autofocus)
|
||||||
|
|
||||||
.modal-footer
|
.modal-footer
|
||||||
button.btn.btn-primary((click)='save()') Save
|
button.btn.btn-primary((click)='save()', translate) Save
|
||||||
button.btn.btn-secondary((click)='close()') Cancel
|
button.btn.btn-secondary((click)='close()', translate) Cancel
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
.modal-body
|
.modal-body
|
||||||
.alert.alert-danger Tabby could not start with your plugins, so all third party plugins have been disabled in this session. The error was:
|
.alert.alert-danger(translate) Tabby could not start with your plugins, so all third party plugins have been disabled in this session. The error was:
|
||||||
|
|
||||||
pre {{error}}
|
pre {{error}}
|
||||||
|
|
||||||
.modal-footer
|
.modal-footer
|
||||||
button.btn.btn-primary((click)='close()') Close
|
button.btn.btn-primary((click)='close()', translate) Close
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { Observable, Subject } from 'rxjs'
|
import { Observable, Subject } from 'rxjs'
|
||||||
import { Component, Injectable, ViewChild, ViewContainerRef, EmbeddedViewRef, AfterViewInit, OnDestroy } from '@angular/core'
|
import { Component, Injectable, ViewChild, ViewContainerRef, EmbeddedViewRef, AfterViewInit, OnDestroy } from '@angular/core'
|
||||||
import { BaseTabComponent, BaseTabProcess } from './baseTab.component'
|
import { BaseTabComponent, BaseTabProcess, GetRecoveryTokenOptions } from './baseTab.component'
|
||||||
import { TabRecoveryProvider, RecoveryToken } from '../api/tabRecovery'
|
import { TabRecoveryProvider, RecoveryToken } from '../api/tabRecovery'
|
||||||
import { TabsService, NewTabParameters } from '../services/tabs.service'
|
import { TabsService, NewTabParameters } from '../services/tabs.service'
|
||||||
import { HotkeysService } from '../services/hotkeys.service'
|
import { HotkeysService } from '../services/hotkeys.service'
|
||||||
@@ -93,13 +93,13 @@ export class SplitContainer {
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
async serialize (tabsRecovery: TabRecoveryService): Promise<RecoveryToken> {
|
async serialize (tabsRecovery: TabRecoveryService, options?: GetRecoveryTokenOptions): Promise<RecoveryToken> {
|
||||||
const children: any[] = []
|
const children: any[] = []
|
||||||
for (const child of this.children) {
|
for (const child of this.children) {
|
||||||
if (child instanceof SplitContainer) {
|
if (child instanceof SplitContainer) {
|
||||||
children.push(await child.serialize(tabsRecovery))
|
children.push(await child.serialize(tabsRecovery, options))
|
||||||
} else {
|
} else {
|
||||||
children.push(await tabsRecovery.getFullRecoveryToken(child))
|
children.push(await tabsRecovery.getFullRecoveryToken(child, options))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
@@ -253,6 +253,9 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
})
|
})
|
||||||
this.blurred$.subscribe(() => this.getAllTabs().forEach(x => x.emitBlurred()))
|
this.blurred$.subscribe(() => this.getAllTabs().forEach(x => x.emitBlurred()))
|
||||||
|
|
||||||
|
this.tabAdded$.subscribe(() => this.updateTitle())
|
||||||
|
this.tabRemoved$.subscribe(() => this.updateTitle())
|
||||||
|
|
||||||
this.subscribeUntilDestroyed(this.hotkeys.hotkey$, hotkey => {
|
this.subscribeUntilDestroyed(this.hotkeys.hotkey$, hotkey => {
|
||||||
if (!this.hasFocus || !this.focusedTab) {
|
if (!this.hasFocus || !this.focusedTab) {
|
||||||
return
|
return
|
||||||
@@ -305,7 +308,7 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
/** @hidden */
|
/** @hidden */
|
||||||
async ngAfterViewInit (): Promise<void> {
|
async ngAfterViewInit (): Promise<void> {
|
||||||
if (this._recoveredState) {
|
if (this._recoveredState) {
|
||||||
await this.recoverContainer(this.root, this._recoveredState, this._recoveredState.duplicate)
|
await this.recoverContainer(this.root, this._recoveredState)
|
||||||
this.updateTitle()
|
this.updateTitle()
|
||||||
this.layout()
|
this.layout()
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -571,8 +574,8 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
async getRecoveryToken (): Promise<any> {
|
async getRecoveryToken (options?: GetRecoveryTokenOptions): Promise<any> {
|
||||||
return this.root.serialize(this.tabRecovery)
|
return this.root.serialize(this.tabRecovery, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@@ -621,8 +624,18 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
super.clearActivity()
|
super.clearActivity()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get color (): string|null {
|
||||||
|
return this.getFocusedTab()?.color ?? null
|
||||||
|
}
|
||||||
|
|
||||||
|
set color (color: string|null) {
|
||||||
|
for (const t of this.getAllTabs()) {
|
||||||
|
t.color = color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private updateTitle (): void {
|
private updateTitle (): void {
|
||||||
this.setTitle(this.getAllTabs().map(x => x.title).join(' | '))
|
this.setTitle([...new Set(this.getAllTabs().map(x => x.title))].join(' | '))
|
||||||
}
|
}
|
||||||
|
|
||||||
private attachTabView (tab: BaseTabComponent) {
|
private attachTabView (tab: BaseTabComponent) {
|
||||||
@@ -792,7 +805,7 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private async recoverContainer (root: SplitContainer, state: any, duplicate = false) {
|
private async recoverContainer (root: SplitContainer, state: any) {
|
||||||
const children: (SplitContainer | BaseTabComponent)[] = []
|
const children: (SplitContainer | BaseTabComponent)[] = []
|
||||||
root.orientation = state.orientation
|
root.orientation = state.orientation
|
||||||
root.ratios = state.ratios
|
root.ratios = state.ratios
|
||||||
@@ -803,10 +816,10 @@ export class SplitTabComponent extends BaseTabComponent implements AfterViewInit
|
|||||||
}
|
}
|
||||||
if (childState.type === 'app:split-tab') {
|
if (childState.type === 'app:split-tab') {
|
||||||
const child = new SplitContainer()
|
const child = new SplitContainer()
|
||||||
await this.recoverContainer(child, childState, duplicate)
|
await this.recoverContainer(child, childState)
|
||||||
children.push(child)
|
children.push(child)
|
||||||
} else {
|
} else {
|
||||||
const recovered = await this.tabRecovery.recoverTab(childState, duplicate)
|
const recovered = await this.tabRecovery.recoverTab(childState)
|
||||||
if (recovered) {
|
if (recovered) {
|
||||||
const tab = this.tabsService.create(recovered)
|
const tab = this.tabsService.create(recovered)
|
||||||
children.push(tab)
|
children.push(tab)
|
||||||
@@ -837,11 +850,4 @@ export class SplitTabRecoveryProvider extends TabRecoveryProvider<SplitTabCompon
|
|||||||
inputs: { _recoveredState: recoveryToken },
|
inputs: { _recoveredState: recoveryToken },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
duplicate (recoveryToken: RecoveryToken): RecoveryToken {
|
|
||||||
return {
|
|
||||||
...recoveryToken,
|
|
||||||
duplicate: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -3,7 +3,7 @@ import { Component, Input, HostBinding, ElementRef, Output, EventEmitter } from
|
|||||||
import { AppService } from '../services/app.service'
|
import { AppService } from '../services/app.service'
|
||||||
import { BaseTabComponent } from './baseTab.component'
|
import { BaseTabComponent } from './baseTab.component'
|
||||||
import { SelfPositioningComponent } from './selfPositioning.component'
|
import { SelfPositioningComponent } from './selfPositioning.component'
|
||||||
import { SplitDropZoneInfo } from './splitTab.component'
|
import { SplitDropZoneInfo, SplitTabComponent } from './splitTab.component'
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@Component({
|
@Component({
|
||||||
@@ -22,7 +22,7 @@ import { SplitDropZoneInfo } from './splitTab.component'
|
|||||||
})
|
})
|
||||||
export class SplitTabDropZoneComponent extends SelfPositioningComponent {
|
export class SplitTabDropZoneComponent extends SelfPositioningComponent {
|
||||||
@Input() dropZone: SplitDropZoneInfo
|
@Input() dropZone: SplitDropZoneInfo
|
||||||
@Input() parent: BaseTabComponent
|
@Input() parent: SplitTabComponent
|
||||||
@Output() tabDropped = new EventEmitter<BaseTabComponent>()
|
@Output() tabDropped = new EventEmitter<BaseTabComponent>()
|
||||||
@HostBinding('class.active') isActive = false
|
@HostBinding('class.active') isActive = false
|
||||||
@HostBinding('class.highlighted') isHighlighted = false
|
@HostBinding('class.highlighted') isHighlighted = false
|
||||||
@@ -34,11 +34,21 @@ export class SplitTabDropZoneComponent extends SelfPositioningComponent {
|
|||||||
) {
|
) {
|
||||||
super(element)
|
super(element)
|
||||||
this.subscribeUntilDestroyed(app.tabDragActive$, tab => {
|
this.subscribeUntilDestroyed(app.tabDragActive$, tab => {
|
||||||
this.isActive = !!tab && tab !== this.parent && (this.dropZone.type === 'relative' || tab !== this.dropZone.container.children[this.dropZone.position])
|
this.isActive = !!tab && this.canActivateFor(tab)
|
||||||
this.layout()
|
this.layout()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
canActivateFor (tab: BaseTabComponent): boolean {
|
||||||
|
const allTabs = this.parent.getAllTabs()
|
||||||
|
return !(
|
||||||
|
tab === this.parent ||
|
||||||
|
allTabs.length === 1 && allTabs.includes(tab) ||
|
||||||
|
this.dropZone.type === 'relative' && tab === this.dropZone.relativeTo ||
|
||||||
|
this.dropZone.type === 'absolute' && tab === this.dropZone.container.children[this.dropZone.position]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
ngOnChanges () {
|
ngOnChanges () {
|
||||||
this.layout()
|
this.layout()
|
||||||
}
|
}
|
||||||
|
@@ -18,6 +18,9 @@ footer.d-flex.align-items-center
|
|||||||
span GitHub
|
span GitHub
|
||||||
button.btn.btn-dark((click)='homeBase.reportBug()')
|
button.btn.btn-dark((click)='homeBase.reportBug()')
|
||||||
i.fas.fa-bug
|
i.fas.fa-bug
|
||||||
span Report a problem
|
span(translate) Report a problem
|
||||||
|
|
||||||
.form-control-static.selectable.no-drag Version: {{homeBase.appVersion}}
|
.form-control-static.selectable.no-drag(
|
||||||
|
translate='Version: {version}',
|
||||||
|
[translateParams]='{ version: this.homeBase.appVersion }'
|
||||||
|
)
|
||||||
|
@@ -37,6 +37,7 @@ $tabs-height: 38px;
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
transition: 0.25s all;
|
transition: 0.25s all;
|
||||||
align-self: center;
|
align-self: center;
|
||||||
|
margin-top: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||||
import { Component, Input, Optional, Inject, HostBinding, HostListener, NgZone } from '@angular/core'
|
import { Component, Input, Optional, Inject, HostBinding, HostListener, NgZone } from '@angular/core'
|
||||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
|
import { auditTime } from 'rxjs'
|
||||||
import { TabContextMenuItemProvider } from '../api/tabContextMenuProvider'
|
import { TabContextMenuItemProvider } from '../api/tabContextMenuProvider'
|
||||||
import { BaseTabComponent } from './baseTab.component'
|
import { BaseTabComponent } from './baseTab.component'
|
||||||
import { RenameTabModalComponent } from './renameTabModal.component'
|
import { RenameTabModalComponent } from './renameTabModal.component'
|
||||||
@@ -47,7 +48,9 @@ export class TabHeaderComponent extends BaseComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit () {
|
ngOnInit () {
|
||||||
this.subscribeUntilDestroyed(this.tab.progress$, progress => {
|
this.subscribeUntilDestroyed(this.tab.progress$.pipe(
|
||||||
|
auditTime(300),
|
||||||
|
), progress => {
|
||||||
this.zone.run(() => {
|
this.zone.run(() => {
|
||||||
this.progress = progress
|
this.progress = progress
|
||||||
})
|
})
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
.d-flex.align-items-center
|
.d-flex.align-items-center
|
||||||
.dropdown-header File transfers
|
.dropdown-header(translate) File transfers
|
||||||
button.btn.btn-link.ml-auto((click)='removeAll(); $event.stopPropagation()') !{require('../icons/times.svg')}
|
button.btn.btn-link.ml-auto((click)='removeAll(); $event.stopPropagation()') !{require('../icons/times.svg')}
|
||||||
.transfer(*ngFor='let transfer of transfers', (click)='showTransfer(transfer)')
|
.transfer(*ngFor='let transfer of transfers', (click)='showTransfer(transfer)')
|
||||||
.icon(*ngIf='isDownload(transfer)') !{require('../icons/download.svg')}
|
.icon(*ngIf='isDownload(transfer)') !{require('../icons/download.svg')}
|
||||||
@@ -16,4 +16,11 @@
|
|||||||
.size {{transfer.getSize()|filesize}}
|
.size {{transfer.getSize()|filesize}}
|
||||||
.speed(*ngIf='transfer.getSpeed()') {{transfer.getSpeed()|filesize}}/s
|
.speed(*ngIf='transfer.getSpeed()') {{transfer.getSpeed()|filesize}}/s
|
||||||
|
|
||||||
button.btn.btn-link((click)='removeTransfer(transfer); $event.stopPropagation()') !{require('../icons/times.svg')}
|
button.btn.btn-link(
|
||||||
|
*ngIf='!transfer.isComplete()',
|
||||||
|
(click)='removeTransfer(transfer); $event.stopPropagation()'
|
||||||
|
) !{require('../icons/times.svg')}
|
||||||
|
button.btn.btn-link(
|
||||||
|
*ngIf='transfer.isComplete()',
|
||||||
|
(click)='removeTransfer(transfer); $event.stopPropagation()'
|
||||||
|
) !{require('../icons/check.svg')}
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import { Component, Input, Output, EventEmitter } from '@angular/core'
|
import { Component, Input, Output, EventEmitter } from '@angular/core'
|
||||||
|
import { TranslateService } from '@ngx-translate/core'
|
||||||
import { FileDownload, FileTransfer, PlatformService } from '../api/platform'
|
import { FileDownload, FileTransfer, PlatformService } from '../api/platform'
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@@ -11,7 +12,10 @@ export class TransfersMenuComponent {
|
|||||||
@Input() transfers: FileTransfer[]
|
@Input() transfers: FileTransfer[]
|
||||||
@Output() transfersChange = new EventEmitter<FileTransfer[]>()
|
@Output() transfersChange = new EventEmitter<FileTransfer[]>()
|
||||||
|
|
||||||
constructor (private platform: PlatformService) { }
|
constructor (
|
||||||
|
private platform: PlatformService,
|
||||||
|
private translate: TranslateService,
|
||||||
|
) { }
|
||||||
|
|
||||||
isDownload (transfer: FileTransfer): boolean {
|
isDownload (transfer: FileTransfer): boolean {
|
||||||
return transfer instanceof FileDownload
|
return transfer instanceof FileDownload
|
||||||
@@ -40,8 +44,11 @@ export class TransfersMenuComponent {
|
|||||||
if (this.transfers.some(x => !x.isComplete())) {
|
if (this.transfers.some(x => !x.isComplete())) {
|
||||||
if ((await this.platform.showMessageBox({
|
if ((await this.platform.showMessageBox({
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
message: 'There are active file transfers',
|
message: this.translate.instant('There are active file transfers'),
|
||||||
buttons: ['Abort all', 'Do not abort'],
|
buttons: [
|
||||||
|
this.translate.instant('Abort all'),
|
||||||
|
this.translate.instant('Do not abort'),
|
||||||
|
],
|
||||||
defaultId: 1,
|
defaultId: 1,
|
||||||
cancelId: 1,
|
cancelId: 1,
|
||||||
})).response === 1) {
|
})).response === 1) {
|
||||||
|
@@ -1,13 +1,18 @@
|
|||||||
.modal-body
|
.modal-body
|
||||||
.d-flex.align-items-center.mb-3
|
.d-flex.align-items-center.mb-3
|
||||||
h3.m-0 Vault is locked
|
h3.m-0(translate) Vault is locked
|
||||||
.ml-auto(ngbDropdown, placement='bottom-right')
|
.ml-auto(ngbDropdown, placement='bottom-right')
|
||||||
button.btn.btn-link(ngbDropdownToggle, (click)='$event.stopPropagation()')
|
button.btn.btn-link(ngbDropdownToggle, (click)='$event.stopPropagation()')
|
||||||
span(*ngIf='rememberFor') Remember for {{getRememberForDisplay(rememberFor)}}
|
span(
|
||||||
span(*ngIf='!rememberFor') Do not remember
|
*ngIf='rememberFor',
|
||||||
|
translate='Remember for {time}',
|
||||||
|
[translateParams]='{time: getRememberForDisplay(rememberFor)}'
|
||||||
|
)
|
||||||
|
span(*ngIf='!rememberFor', translate) Do not remember
|
||||||
div(ngbDropdownMenu)
|
div(ngbDropdownMenu)
|
||||||
button.dropdown-item(
|
button.dropdown-item(
|
||||||
(click)='rememberFor = 0',
|
(click)='rememberFor = 0',
|
||||||
|
translate
|
||||||
) Do not remember
|
) Do not remember
|
||||||
button.dropdown-item(
|
button.dropdown-item(
|
||||||
*ngFor='let x of rememberOptions',
|
*ngFor='let x of rememberOptions',
|
||||||
|
@@ -4,21 +4,31 @@
|
|||||||
h1.tabby-title Tabby
|
h1.tabby-title Tabby
|
||||||
sup α
|
sup α
|
||||||
|
|
||||||
.text-center.mb-5 Thank you for downloading Tabby!
|
.text-center.mb-5(translate) Thank you for downloading Tabby!
|
||||||
|
|
||||||
.form-line
|
.form-line
|
||||||
.header
|
.header
|
||||||
.title Enable analytics
|
.title(translate) Language
|
||||||
.description Help track the number of Tabby installs across the world!
|
select.form-control([(ngModel)]='config.store.language', (ngModelChange)='config.save()')
|
||||||
|
option([ngValue]='null', translate) Automatic
|
||||||
|
option(
|
||||||
|
[value]='lang.code',
|
||||||
|
*ngFor='let lang of allLanguages'
|
||||||
|
) {{lang.name}}
|
||||||
|
|
||||||
|
.form-line
|
||||||
|
.header
|
||||||
|
.title(translate) Enable analytics
|
||||||
|
.description(translate) Help track the number of Tabby installs across the world!
|
||||||
toggle([(ngModel)]='config.store.enableAnalytics')
|
toggle([(ngModel)]='config.store.enableAnalytics')
|
||||||
|
|
||||||
|
|
||||||
.form-line
|
.form-line
|
||||||
.header
|
.header
|
||||||
.title Enable global hotkey (#[strong Ctrl-Space])
|
.title(translate) Enable global hotkey (Ctrl-Space)
|
||||||
.description Toggles the Tabby window visibility
|
.description(translate) Toggles the Tabby window visibility
|
||||||
toggle([(ngModel)]='enableGlobalHotkey')
|
toggle([(ngModel)]='enableGlobalHotkey')
|
||||||
|
|
||||||
|
|
||||||
.text-center.mt-5
|
.text-center.mt-5
|
||||||
button.btn.btn-primary((click)='closeAndDisable()') Close and never show again
|
button.btn.btn-primary((click)='closeAndDisable()', translate) Close and never show again
|
||||||
|
@@ -1,8 +1,9 @@
|
|||||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||||
import { Component } from '@angular/core'
|
import { Component } from '@angular/core'
|
||||||
|
import { TranslateService } from '@ngx-translate/core'
|
||||||
import { BaseTabComponent } from './baseTab.component'
|
import { BaseTabComponent } from './baseTab.component'
|
||||||
import { ConfigService } from '../services/config.service'
|
import { ConfigService } from '../services/config.service'
|
||||||
import { HostWindowService } from '../api/hostWindow'
|
import { LocaleService } from '../services/locale.service'
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@Component({
|
@Component({
|
||||||
@@ -12,13 +13,15 @@ import { HostWindowService } from '../api/hostWindow'
|
|||||||
})
|
})
|
||||||
export class WelcomeTabComponent extends BaseTabComponent {
|
export class WelcomeTabComponent extends BaseTabComponent {
|
||||||
enableGlobalHotkey = true
|
enableGlobalHotkey = true
|
||||||
|
allLanguages = LocaleService.allLanguages
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
private hostWindow: HostWindowService,
|
|
||||||
public config: ConfigService,
|
public config: ConfigService,
|
||||||
|
public locale: LocaleService,
|
||||||
|
translate: TranslateService,
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
this.setTitle('Welcome')
|
this.setTitle(translate.instant('Welcome'))
|
||||||
}
|
}
|
||||||
|
|
||||||
async closeAndDisable () {
|
async closeAndDisable () {
|
||||||
@@ -28,6 +31,6 @@ export class WelcomeTabComponent extends BaseTabComponent {
|
|||||||
this.config.store.hotkeys['toggle-window'] = []
|
this.config.store.hotkeys['toggle-window'] = []
|
||||||
}
|
}
|
||||||
await this.config.save()
|
await this.config.save()
|
||||||
this.hostWindow.reload()
|
this.destroy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -75,3 +75,5 @@ hotkeys:
|
|||||||
- '⌘-E'
|
- '⌘-E'
|
||||||
switch-profile:
|
switch-profile:
|
||||||
- '⌘-Shift-E'
|
- '⌘-Shift-E'
|
||||||
|
appearance:
|
||||||
|
vibrancy: true
|
||||||
|
@@ -38,3 +38,4 @@ enableExperimentalFeatures: false
|
|||||||
pluginBlacklist: []
|
pluginBlacklist: []
|
||||||
hacks:
|
hacks:
|
||||||
disableGPU: false
|
disableGPU: false
|
||||||
|
language: null
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
|
import { TranslateService } from '@ngx-translate/core'
|
||||||
import { ProfilesService } from './services/profiles.service'
|
import { ProfilesService } from './services/profiles.service'
|
||||||
import { HotkeyDescription, HotkeyProvider } from './api/hotkeyProvider'
|
import { HotkeyDescription, HotkeyProvider } from './api/hotkeyProvider'
|
||||||
import { PartialProfile, Profile } from './api'
|
import { PartialProfile, Profile } from './api'
|
||||||
@@ -9,188 +10,189 @@ export class AppHotkeyProvider extends HotkeyProvider {
|
|||||||
hotkeys: HotkeyDescription[] = [
|
hotkeys: HotkeyDescription[] = [
|
||||||
{
|
{
|
||||||
id: 'profile-selector',
|
id: 'profile-selector',
|
||||||
name: 'Show profile selector',
|
name: this.translate.instant('Show profile selector'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'toggle-fullscreen',
|
id: 'toggle-fullscreen',
|
||||||
name: 'Toggle fullscreen mode',
|
name: this.translate.instant('Toggle fullscreen mode'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'rename-tab',
|
id: 'rename-tab',
|
||||||
name: 'Rename Tab',
|
name: this.translate.instant('Rename Tab'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'close-tab',
|
id: 'close-tab',
|
||||||
name: 'Close tab',
|
name: this.translate.instant('Close tab'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'reopen-tab',
|
id: 'reopen-tab',
|
||||||
name: 'Reopen last tab',
|
name: this.translate.instant('Reopen last tab'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'toggle-last-tab',
|
id: 'toggle-last-tab',
|
||||||
name: 'Toggle last tab',
|
name: this.translate.instant('Toggle last tab'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'next-tab',
|
id: 'next-tab',
|
||||||
name: 'Next tab',
|
name: this.translate.instant('Next tab'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'previous-tab',
|
id: 'previous-tab',
|
||||||
name: 'Previous tab',
|
name: this.translate.instant('Previous tab'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'move-tab-left',
|
id: 'move-tab-left',
|
||||||
name: 'Move tab to the left',
|
name: this.translate.instant('Move tab to the left'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'move-tab-right',
|
id: 'move-tab-right',
|
||||||
name: 'Move tab to the right',
|
name: this.translate.instant('Move tab to the right'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'rearrange-panes',
|
id: 'rearrange-panes',
|
||||||
name: 'Show pane labels (for rearranging)',
|
name: this.translate.instant('Show pane labels (for rearranging)'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'duplicate-tab',
|
id: 'duplicate-tab',
|
||||||
name: 'Duplicate tab',
|
name: this.translate.instant('Duplicate tab'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'tab-1',
|
id: 'tab-1',
|
||||||
name: 'Tab 1',
|
name: this.translate.instant('Tab {number}', { number: 1 }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'tab-2',
|
id: 'tab-2',
|
||||||
name: 'Tab 2',
|
name: this.translate.instant('Tab {number}', { number: 2 }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'tab-3',
|
id: 'tab-3',
|
||||||
name: 'Tab 3',
|
name: this.translate.instant('Tab {number}', { number: 3 }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'tab-4',
|
id: 'tab-4',
|
||||||
name: 'Tab 4',
|
name: this.translate.instant('Tab {number}', { number: 4 }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'tab-5',
|
id: 'tab-5',
|
||||||
name: 'Tab 5',
|
name: this.translate.instant('Tab {number}', { number: 5 }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'tab-6',
|
id: 'tab-6',
|
||||||
name: 'Tab 6',
|
name: this.translate.instant('Tab {number}', { number: 6 }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'tab-7',
|
id: 'tab-7',
|
||||||
name: 'Tab 7',
|
name: this.translate.instant('Tab {number}', { number: 7 }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'tab-8',
|
id: 'tab-8',
|
||||||
name: 'Tab 8',
|
name: this.translate.instant('Tab {number}', { number: 8 }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'tab-9',
|
id: 'tab-9',
|
||||||
name: 'Tab 9',
|
name: this.translate.instant('Tab {number}', { number: 9 }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'tab-10',
|
id: 'tab-10',
|
||||||
name: 'Tab 10',
|
name: this.translate.instant('Tab {number}', { number: 10 }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'tab-11',
|
id: 'tab-11',
|
||||||
name: 'Tab 11',
|
name: this.translate.instant('Tab {number}', { number: 11 }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'tab-12',
|
id: 'tab-12',
|
||||||
name: 'Tab 12',
|
name: this.translate.instant('Tab {number}', { number: 12 }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'tab-13',
|
id: 'tab-13',
|
||||||
name: 'Tab 13',
|
name: this.translate.instant('Tab {number}', { number: 13 }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'tab-14',
|
id: 'tab-14',
|
||||||
name: 'Tab 14',
|
name: this.translate.instant('Tab {number}', { number: 14 }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'tab-15',
|
id: 'tab-15',
|
||||||
name: 'Tab 15',
|
name: this.translate.instant('Tab {number}', { number: 15 }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'tab-16',
|
id: 'tab-16',
|
||||||
name: 'Tab 16',
|
name: this.translate.instant('Tab {number}', { number: 16 }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'tab-17',
|
id: 'tab-17',
|
||||||
name: 'Tab 17',
|
name: this.translate.instant('Tab {number}', { number: 17 }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'tab-18',
|
id: 'tab-18',
|
||||||
name: 'Tab 18',
|
name: this.translate.instant('Tab {number}', { number: 18 }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'tab-19',
|
id: 'tab-19',
|
||||||
name: 'Tab 19',
|
name: this.translate.instant('Tab {number}', { number: 19 }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'tab-20',
|
id: 'tab-20',
|
||||||
name: 'Tab 20',
|
name: this.translate.instant('Tab {number}', { number: 20 }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'split-right',
|
id: 'split-right',
|
||||||
name: 'Split to the right',
|
name: this.translate.instant('Split to the right'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'split-bottom',
|
id: 'split-bottom',
|
||||||
name: 'Split to the bottom',
|
name: this.translate.instant('Split to the bottom'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'split-left',
|
id: 'split-left',
|
||||||
name: 'Split to the left',
|
name: this.translate.instant('Split to the left'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'split-top',
|
id: 'split-top',
|
||||||
name: 'Split to the top',
|
name: this.translate.instant('Split to the top'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'pane-maximize',
|
id: 'pane-maximize',
|
||||||
name: 'Maximize the active pane',
|
name: this.translate.instant('Maximize the active pane'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'pane-nav-up',
|
id: 'pane-nav-up',
|
||||||
name: 'Focus the pane above',
|
name: this.translate.instant('Focus the pane above'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'pane-nav-down',
|
id: 'pane-nav-down',
|
||||||
name: 'Focus the pane below',
|
name: this.translate.instant('Focus the pane below'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'pane-nav-left',
|
id: 'pane-nav-left',
|
||||||
name: 'Focus the pane on the left',
|
name: this.translate.instant('Focus the pane on the left'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'pane-nav-right',
|
id: 'pane-nav-right',
|
||||||
name: 'Focus the pane on the right',
|
name: this.translate.instant('Focus the pane on the right'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'pane-nav-previous',
|
id: 'pane-nav-previous',
|
||||||
name: 'Focus previous pane',
|
name: this.translate.instant('Focus previous pane'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'pane-nav-next',
|
id: 'pane-nav-next',
|
||||||
name: 'Focus next pane',
|
name: this.translate.instant('Focus next pane'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'switch-profile',
|
id: 'switch-profile',
|
||||||
name: 'Switch profile in the active pane',
|
name: this.translate.instant('Switch profile in the active pane'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'close-pane',
|
id: 'close-pane',
|
||||||
name: 'Close focused pane',
|
name: this.translate.instant('Close focused pane'),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
private profilesService: ProfilesService,
|
private profilesService: ProfilesService,
|
||||||
|
private translate: TranslateService,
|
||||||
) { super() }
|
) { super() }
|
||||||
|
|
||||||
async provide (): Promise<HotkeyDescription[]> {
|
async provide (): Promise<HotkeyDescription[]> {
|
||||||
@@ -199,11 +201,11 @@ export class AppHotkeyProvider extends HotkeyProvider {
|
|||||||
...this.hotkeys,
|
...this.hotkeys,
|
||||||
...profiles.map(profile => ({
|
...profiles.map(profile => ({
|
||||||
id: `profile.${AppHotkeyProvider.getProfileHotkeyName(profile)}`,
|
id: `profile.${AppHotkeyProvider.getProfileHotkeyName(profile)}`,
|
||||||
name: `New tab: ${profile.name}`,
|
name: this.translate.instant('New tab: {profile}', { profile: profile.name }),
|
||||||
})),
|
})),
|
||||||
...this.profilesService.getProviders().map(provider => ({
|
...this.profilesService.getProviders().map(provider => ({
|
||||||
id: `profile-selectors.${provider.id}`,
|
id: `profile-selectors.${provider.id}`,
|
||||||
name: `Show ${provider.name} profile selector`,
|
name: this.translate.instant('Show {type} profile selector', { type: provider.name }),
|
||||||
})),
|
})),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
1
tabby-core/src/icons/check.svg
Normal file
1
tabby-core/src/icons/check.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg aria-hidden="true" focusable="false" data-prefix="far" data-icon="check" class="svg-inline--fa fa-check" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M480.1 128.1l-272 272C204.3 405.7 198.2 408 192 408s-12.28-2.344-16.97-7.031l-144-144c-9.375-9.375-9.375-24.56 0-33.94s24.56-9.375 33.94 0L192 350.1l255-255c9.375-9.375 24.56-9.375 33.94 0S490.3 119.6 480.1 128.1z"></path></svg>
|
After Width: | Height: | Size: 436 B |
@@ -1,4 +1,4 @@
|
|||||||
import { NgModule, ModuleWithProviders } from '@angular/core'
|
import { NgModule, ModuleWithProviders, LOCALE_ID } from '@angular/core'
|
||||||
import { BrowserModule } from '@angular/platform-browser'
|
import { BrowserModule } from '@angular/platform-browser'
|
||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
|
||||||
import { FormsModule } from '@angular/forms'
|
import { FormsModule } from '@angular/forms'
|
||||||
@@ -7,6 +7,8 @@ import { PerfectScrollbarModule, PERFECT_SCROLLBAR_CONFIG } from 'ngx-perfect-sc
|
|||||||
import { NgxFilesizeModule } from 'ngx-filesize'
|
import { NgxFilesizeModule } from 'ngx-filesize'
|
||||||
import { SortablejsModule } from 'ngx-sortablejs'
|
import { SortablejsModule } from 'ngx-sortablejs'
|
||||||
import { DragDropModule } from '@angular/cdk/drag-drop'
|
import { DragDropModule } from '@angular/cdk/drag-drop'
|
||||||
|
import { TranslateModule, TranslateCompiler, TranslateService } from '@ngx-translate/core'
|
||||||
|
import { TranslateMessageFormatCompiler, MESSAGE_FORMAT_CONFIG } from 'ngx-translate-messageformat-compiler'
|
||||||
|
|
||||||
import { AppRootComponent } from './components/appRoot.component'
|
import { AppRootComponent } from './components/appRoot.component'
|
||||||
import { CheckboxComponent } from './components/checkbox.component'
|
import { CheckboxComponent } from './components/checkbox.component'
|
||||||
@@ -40,6 +42,7 @@ import { AppService } from './services/app.service'
|
|||||||
import { ConfigService } from './services/config.service'
|
import { ConfigService } from './services/config.service'
|
||||||
import { VaultFileProvider } from './services/vault.service'
|
import { VaultFileProvider } from './services/vault.service'
|
||||||
import { HotkeysService } from './services/hotkeys.service'
|
import { HotkeysService } from './services/hotkeys.service'
|
||||||
|
import { LocaleService, TranslateServiceWrapper } from './services/locale.service'
|
||||||
|
|
||||||
import { StandardTheme, StandardCompactTheme, PaperTheme } from './theme'
|
import { StandardTheme, StandardCompactTheme, PaperTheme } from './theme'
|
||||||
import { CoreConfigProvider } from './config'
|
import { CoreConfigProvider } from './config'
|
||||||
@@ -51,6 +54,10 @@ import { SplitLayoutProfilesService } from './profiles'
|
|||||||
|
|
||||||
import 'perfect-scrollbar/css/perfect-scrollbar.css'
|
import 'perfect-scrollbar/css/perfect-scrollbar.css'
|
||||||
|
|
||||||
|
export function TranslateMessageFormatCompilerFactory (): TranslateMessageFormatCompiler {
|
||||||
|
return new TranslateMessageFormatCompiler()
|
||||||
|
}
|
||||||
|
|
||||||
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 },
|
||||||
@@ -68,6 +75,19 @@ const PROVIDERS = [
|
|||||||
{ provide: FileProvider, useClass: VaultFileProvider, multi: true },
|
{ provide: FileProvider, useClass: VaultFileProvider, multi: true },
|
||||||
{ provide: ToolbarButtonProvider, useClass: ButtonProvider, multi: true },
|
{ provide: ToolbarButtonProvider, useClass: ButtonProvider, multi: true },
|
||||||
{ provide: ProfileProvider, useExisting: SplitLayoutProfilesService, multi: true },
|
{ provide: ProfileProvider, useExisting: SplitLayoutProfilesService, multi: true },
|
||||||
|
{
|
||||||
|
provide: LOCALE_ID,
|
||||||
|
deps: [LocaleService],
|
||||||
|
useFactory: locale => locale.getLocale(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: MESSAGE_FORMAT_CONFIG,
|
||||||
|
useValue: LocaleService.allLanguages.map(x => x.code),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: TranslateService,
|
||||||
|
useClass: TranslateServiceWrapper,
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@@ -81,6 +101,7 @@ const PROVIDERS = [
|
|||||||
PerfectScrollbarModule,
|
PerfectScrollbarModule,
|
||||||
DragDropModule,
|
DragDropModule,
|
||||||
SortablejsModule.forRoot({ animation: 150 }),
|
SortablejsModule.forRoot({ animation: 150 }),
|
||||||
|
TranslateModule,
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
AppRootComponent,
|
AppRootComponent,
|
||||||
@@ -127,6 +148,8 @@ const PROVIDERS = [
|
|||||||
AlwaysVisibleTypeaheadDirective,
|
AlwaysVisibleTypeaheadDirective,
|
||||||
SortablejsModule,
|
SortablejsModule,
|
||||||
DragDropModule,
|
DragDropModule,
|
||||||
|
TranslateModule,
|
||||||
|
CdkAutoDropGroup,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export default class AppModule { // eslint-disable-line @typescript-eslint/no-extraneous-class
|
export default class AppModule { // eslint-disable-line @typescript-eslint/no-extraneous-class
|
||||||
@@ -135,6 +158,8 @@ export default class AppModule { // eslint-disable-line @typescript-eslint/no-ex
|
|||||||
config: ConfigService,
|
config: ConfigService,
|
||||||
platform: PlatformService,
|
platform: PlatformService,
|
||||||
hotkeys: HotkeysService,
|
hotkeys: HotkeysService,
|
||||||
|
public locale: LocaleService,
|
||||||
|
private translate: TranslateService,
|
||||||
private profilesService: ProfilesService,
|
private profilesService: ProfilesService,
|
||||||
private selector: SelectorService,
|
private selector: SelectorService,
|
||||||
) {
|
) {
|
||||||
@@ -182,8 +207,8 @@ export default class AppModule { // eslint-disable-line @typescript-eslint/no-ex
|
|||||||
|
|
||||||
if (provider.supportsQuickConnect) {
|
if (provider.supportsQuickConnect) {
|
||||||
options.push({
|
options.push({
|
||||||
name: 'Quick connect',
|
name: this.translate.instant('Quick connect'),
|
||||||
freeInputPattern: 'Connect to "%s"...',
|
freeInputPattern: this.translate.instant('Connect to "%s"...'),
|
||||||
icon: 'fas fa-arrow-right',
|
icon: 'fas fa-arrow-right',
|
||||||
callback: query => {
|
callback: query => {
|
||||||
const p = provider.quickConnect(query)
|
const p = provider.quickConnect(query)
|
||||||
@@ -194,13 +219,23 @@ export default class AppModule { // eslint-disable-line @typescript-eslint/no-ex
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.selector.show('Select profile', options)
|
await this.selector.show(this.translate.instant('Select profile'), options)
|
||||||
}
|
}
|
||||||
|
|
||||||
static forRoot (): ModuleWithProviders<AppModule> {
|
static forRoot (): ModuleWithProviders<AppModule> {
|
||||||
|
const translateModule = TranslateModule.forRoot({
|
||||||
|
defaultLanguage: 'en',
|
||||||
|
compiler: {
|
||||||
|
provide: TranslateCompiler,
|
||||||
|
useFactory: TranslateMessageFormatCompilerFactory,
|
||||||
|
},
|
||||||
|
})
|
||||||
return {
|
return {
|
||||||
ngModule: AppModule,
|
ngModule: AppModule,
|
||||||
providers: PROVIDERS,
|
providers: [
|
||||||
|
...PROVIDERS,
|
||||||
|
...translateModule.providers!.filter(x => x !== TranslateService),
|
||||||
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
import slugify from 'slugify'
|
import slugify from 'slugify'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
|
import { TranslateService } from '@ngx-translate/core'
|
||||||
import { ConfigService, NewTabParameters, PartialProfile, Profile, ProfileProvider } from './api'
|
import { ConfigService, NewTabParameters, PartialProfile, Profile, ProfileProvider } from './api'
|
||||||
import { SplitTabComponent, SplitTabRecoveryProvider } from './components/splitTab.component'
|
import { SplitTabComponent, SplitTabRecoveryProvider } from './components/splitTab.component'
|
||||||
|
|
||||||
@@ -15,7 +16,7 @@ export interface SplitLayoutProfile extends Profile {
|
|||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class SplitLayoutProfilesService extends ProfileProvider<SplitLayoutProfile> {
|
export class SplitLayoutProfilesService extends ProfileProvider<SplitLayoutProfile> {
|
||||||
id = 'split-layout'
|
id = 'split-layout'
|
||||||
name = 'Saved layout'
|
name = this.translate.instant('Saved layout')
|
||||||
configDefaults = {
|
configDefaults = {
|
||||||
options: {
|
options: {
|
||||||
recoveryToken: null,
|
recoveryToken: null,
|
||||||
@@ -25,6 +26,7 @@ export class SplitLayoutProfilesService extends ProfileProvider<SplitLayoutProfi
|
|||||||
constructor (
|
constructor (
|
||||||
private splitTabRecoveryProvider: SplitTabRecoveryProvider,
|
private splitTabRecoveryProvider: SplitTabRecoveryProvider,
|
||||||
private config: ConfigService,
|
private config: ConfigService,
|
||||||
|
private translate: TranslateService,
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
}
|
}
|
||||||
@@ -42,7 +44,7 @@ export class SplitLayoutProfilesService extends ProfileProvider<SplitLayoutProfi
|
|||||||
}
|
}
|
||||||
|
|
||||||
async createProfile (tab: SplitTabComponent, name: string): Promise<void> {
|
async createProfile (tab: SplitTabComponent, name: string): Promise<void> {
|
||||||
const token = await tab.getRecoveryToken()
|
const token = await tab.getRecoveryToken({ includeState: false })
|
||||||
const profile: PartialProfile<SplitLayoutProfile> = {
|
const profile: PartialProfile<SplitLayoutProfile> = {
|
||||||
id: `${this.id}:custom:${slugify(name)}:${uuidv4()}`,
|
id: `${this.id}:custom:${slugify(name)}:${uuidv4()}`,
|
||||||
type: this.id,
|
type: this.id,
|
||||||
|
@@ -170,11 +170,19 @@ export class AppService {
|
|||||||
if (params.type as any === SplitTabComponent) {
|
if (params.type as any === SplitTabComponent) {
|
||||||
return this.openNewTabRaw(params)
|
return this.openNewTabRaw(params)
|
||||||
}
|
}
|
||||||
const splitTab = this.tabsService.create({ type: SplitTabComponent })
|
|
||||||
const tab = this.tabsService.create(params)
|
const tab = this.tabsService.create(params)
|
||||||
|
this.wrapAndAddTab(tab)
|
||||||
|
return tab
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an existing tab while wrapping it in a SplitTabComponent
|
||||||
|
*/
|
||||||
|
wrapAndAddTab (tab: BaseTabComponent): SplitTabComponent {
|
||||||
|
const splitTab = this.tabsService.create({ type: SplitTabComponent })
|
||||||
splitTab.addTab(tab, null, 'r')
|
splitTab.addTab(tab, null, 'r')
|
||||||
this.addTabRaw(splitTab)
|
this.addTabRaw(splitTab)
|
||||||
return tab
|
return splitTab
|
||||||
}
|
}
|
||||||
|
|
||||||
async reopenLastTab (): Promise<BaseTabComponent|null> {
|
async reopenLastTab (): Promise<BaseTabComponent|null> {
|
||||||
@@ -310,9 +318,10 @@ export class AppService {
|
|||||||
if (checkCanClose && !await tab.canClose()) {
|
if (checkCanClose && !await tab.canClose()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const token = await this.tabRecovery.getFullRecoveryToken(tab)
|
const token = await this.tabRecovery.getFullRecoveryToken(tab, { includeState: true })
|
||||||
if (token) {
|
if (token) {
|
||||||
this.closedTabsStack.push(token)
|
this.closedTabsStack.push(token)
|
||||||
|
this.closedTabsStack = this.closedTabsStack.slice(-5)
|
||||||
}
|
}
|
||||||
tab.destroy()
|
tab.destroy()
|
||||||
}
|
}
|
||||||
|
@@ -2,8 +2,9 @@ import deepClone from 'clone-deep'
|
|||||||
import deepEqual from 'deep-equal'
|
import deepEqual from 'deep-equal'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
import * as yaml from 'js-yaml'
|
import * as yaml from 'js-yaml'
|
||||||
import { Observable, Subject, AsyncSubject } from 'rxjs'
|
import { Observable, Subject, AsyncSubject, lastValueFrom } from 'rxjs'
|
||||||
import { Injectable, Inject } from '@angular/core'
|
import { Injectable, Inject } from '@angular/core'
|
||||||
|
import { TranslateService } from '@ngx-translate/core'
|
||||||
import { ConfigProvider } from '../api/configProvider'
|
import { ConfigProvider } from '../api/configProvider'
|
||||||
import { PlatformService } from '../api/platform'
|
import { PlatformService } from '../api/platform'
|
||||||
import { HostAppService } from '../api/hostApp'
|
import { HostAppService } from '../api/hostApp'
|
||||||
@@ -136,6 +137,7 @@ export class ConfigService {
|
|||||||
private hostApp: HostAppService,
|
private hostApp: HostAppService,
|
||||||
private platform: PlatformService,
|
private platform: PlatformService,
|
||||||
private vault: VaultService,
|
private vault: VaultService,
|
||||||
|
private translate: TranslateService,
|
||||||
@Inject(ConfigProvider) private configProviders: ConfigProvider[],
|
@Inject(ConfigProvider) private configProviders: ConfigProvider[],
|
||||||
) {
|
) {
|
||||||
this.defaults = this.mergeDefaults()
|
this.defaults = this.mergeDefaults()
|
||||||
@@ -194,7 +196,7 @@ export class ConfigService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async save (): Promise<void> {
|
async save (): Promise<void> {
|
||||||
await this.ready$
|
await lastValueFrom(this.ready$)
|
||||||
if (!this._store) {
|
if (!this._store) {
|
||||||
throw new Error('Cannot save an empty store')
|
throw new Error('Cannot save an empty store')
|
||||||
}
|
}
|
||||||
@@ -268,8 +270,8 @@ export class ConfigService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private emitChange (): void {
|
private emitChange (): void {
|
||||||
this.changed.next()
|
|
||||||
this.vault.setStore(this.store.vault)
|
this.vault.setStore(this.store.vault)
|
||||||
|
this.changed.next()
|
||||||
}
|
}
|
||||||
|
|
||||||
private migrate (config) {
|
private migrate (config) {
|
||||||
@@ -360,9 +362,13 @@ export class ConfigService {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
let result = await this.platform.showMessageBox({
|
let result = await this.platform.showMessageBox({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message: 'Could not decrypt config',
|
message: this.translate.instant('Could not decrypt config'),
|
||||||
detail: e.toString(),
|
detail: e.toString(),
|
||||||
buttons: ['Try again', 'Erase config', 'Quit'],
|
buttons: [
|
||||||
|
this.translate.instant('Try again'),
|
||||||
|
this.translate.instant('Erase config'),
|
||||||
|
this.translate.instant('Quit'),
|
||||||
|
],
|
||||||
defaultId: 0,
|
defaultId: 0,
|
||||||
})
|
})
|
||||||
if (result.response === 2) {
|
if (result.response === 2) {
|
||||||
@@ -371,9 +377,12 @@ export class ConfigService {
|
|||||||
if (result.response === 1) {
|
if (result.response === 1) {
|
||||||
result = await this.platform.showMessageBox({
|
result = await this.platform.showMessageBox({
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
message: 'Are you sure?',
|
message: this.translate.instant('Are you sure?'),
|
||||||
detail: e.toString(),
|
detail: e.toString(),
|
||||||
buttons: ['Erase config', 'Quit'],
|
buttons: [
|
||||||
|
this.translate.instant('Erase config'),
|
||||||
|
this.translate.instant('Quit'),
|
||||||
|
],
|
||||||
defaultId: 1,
|
defaultId: 1,
|
||||||
cancelId: 1,
|
cancelId: 1,
|
||||||
})
|
})
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import { Inject, Injectable } from '@angular/core'
|
import { Inject, Injectable } from '@angular/core'
|
||||||
|
import { TranslateService } from '@ngx-translate/core'
|
||||||
import { FileProvider, NotificationsService, SelectorService } from '../api'
|
import { FileProvider, NotificationsService, SelectorService } from '../api'
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
@@ -7,6 +8,7 @@ export class FileProvidersService {
|
|||||||
private constructor (
|
private constructor (
|
||||||
private selector: SelectorService,
|
private selector: SelectorService,
|
||||||
private notifications: NotificationsService,
|
private notifications: NotificationsService,
|
||||||
|
private translate: TranslateService,
|
||||||
@Inject(FileProvider) private fileProviders: FileProvider[],
|
@Inject(FileProvider) private fileProviders: FileProvider[],
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
@@ -34,15 +36,18 @@ export class FileProvidersService {
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
if (!providers.length) {
|
if (!providers.length) {
|
||||||
this.notifications.error('Vault master passphrase needs to be set to allow storing secrets')
|
this.notifications.error(this.translate.instant('Vault master passphrase needs to be set to allow storing secrets'))
|
||||||
throw new Error('No available file providers')
|
throw new Error('No available file providers')
|
||||||
}
|
}
|
||||||
if (providers.length === 1) {
|
if (providers.length === 1) {
|
||||||
return providers[0]
|
return providers[0]
|
||||||
}
|
}
|
||||||
return this.selector.show('Select file storage', providers.map(p => ({
|
return this.selector.show(
|
||||||
name: p.name,
|
this.translate.instant('Select file storage'),
|
||||||
result: p,
|
providers.map(p => ({
|
||||||
})))
|
name: p.name,
|
||||||
|
result: p,
|
||||||
|
}))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -130,9 +130,7 @@ export class HotkeysService {
|
|||||||
const keyName = getKeyName(eventData)
|
const keyName = getKeyName(eventData)
|
||||||
if (eventName === 'keydown') {
|
if (eventName === 'keydown') {
|
||||||
this.addPressedKey(keyName, eventData)
|
this.addPressedKey(keyName, eventData)
|
||||||
if (!nativeEvent.repeat) {
|
this.recognitionPhase = true
|
||||||
this.recognitionPhase = true
|
|
||||||
}
|
|
||||||
this.updateModifiers(eventData)
|
this.updateModifiers(eventData)
|
||||||
}
|
}
|
||||||
if (eventName === 'keyup') {
|
if (eventName === 'keyup') {
|
||||||
@@ -158,8 +156,10 @@ export class HotkeysService {
|
|||||||
|
|
||||||
const matched = this.matchActiveHotkey()
|
const matched = this.matchActiveHotkey()
|
||||||
this.zone.run(() => {
|
this.zone.run(() => {
|
||||||
if (matched && this.recognitionPhase) {
|
if (matched) {
|
||||||
this.emitHotkeyOn(matched)
|
if (this.recognitionPhase) {
|
||||||
|
this.emitHotkeyOn(matched)
|
||||||
|
}
|
||||||
} else if (this.pressedHotkey) {
|
} else if (this.pressedHotkey) {
|
||||||
this.emitHotkeyOff(this.pressedHotkey)
|
this.emitHotkeyOff(this.pressedHotkey)
|
||||||
}
|
}
|
||||||
@@ -288,10 +288,9 @@ export class HotkeysService {
|
|||||||
|
|
||||||
private emitHotkeyOn (hotkey: string) {
|
private emitHotkeyOn (hotkey: string) {
|
||||||
if (this.pressedHotkey) {
|
if (this.pressedHotkey) {
|
||||||
if (this.pressedHotkey === hotkey) {
|
if (this.pressedHotkey !== hotkey) {
|
||||||
return
|
this.emitHotkeyOff(this.pressedHotkey)
|
||||||
}
|
}
|
||||||
this.emitHotkeyOff(this.pressedHotkey)
|
|
||||||
}
|
}
|
||||||
if (document.querySelectorAll('input:focus').length === 0) {
|
if (document.querySelectorAll('input:focus').length === 0) {
|
||||||
console.debug('Matched hotkey', hotkey)
|
console.debug('Matched hotkey', hotkey)
|
||||||
|
168
tabby-core/src/services/locale.service.ts
Normal file
168
tabby-core/src/services/locale.service.ts
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
import { Injectable } from '@angular/core'
|
||||||
|
import { registerLocaleData } from '@angular/common'
|
||||||
|
import { TranslateService } from '@ngx-translate/core'
|
||||||
|
|
||||||
|
import localeEN from '@angular/common/locales/en'
|
||||||
|
import localeDA from '@angular/common/locales/da'
|
||||||
|
import localeDE from '@angular/common/locales/de'
|
||||||
|
import localeES from '@angular/common/locales/es'
|
||||||
|
import localeFR from '@angular/common/locales/fr'
|
||||||
|
import localeHR from '@angular/common/locales/hr'
|
||||||
|
import localeIT from '@angular/common/locales/it'
|
||||||
|
import localeJA from '@angular/common/locales/ja'
|
||||||
|
import localePL from '@angular/common/locales/pl'
|
||||||
|
import localeRU from '@angular/common/locales/ru'
|
||||||
|
import localeZH from '@angular/common/locales/zh'
|
||||||
|
import { Observable, Subject } from 'rxjs'
|
||||||
|
import { distinctUntilChanged } from 'rxjs/operators'
|
||||||
|
import { ConfigService } from './config.service'
|
||||||
|
import { LogService, Logger } from './log.service'
|
||||||
|
|
||||||
|
registerLocaleData(localeEN)
|
||||||
|
registerLocaleData(localeDA)
|
||||||
|
registerLocaleData(localeDE)
|
||||||
|
registerLocaleData(localeES)
|
||||||
|
registerLocaleData(localeFR)
|
||||||
|
registerLocaleData(localeHR)
|
||||||
|
registerLocaleData(localeIT)
|
||||||
|
registerLocaleData(localeJA)
|
||||||
|
registerLocaleData(localePL)
|
||||||
|
registerLocaleData(localeRU)
|
||||||
|
registerLocaleData(localeZH)
|
||||||
|
|
||||||
|
function flattenMessageFormatTranslation (po: any) {
|
||||||
|
const translation = {}
|
||||||
|
po = po.translations['']
|
||||||
|
for (const k of Object.keys(po)) {
|
||||||
|
translation[k] = po[k].msgstr[0] || k
|
||||||
|
}
|
||||||
|
return translation
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class TranslateServiceWrapper extends TranslateService {
|
||||||
|
private _defaultTranslation: Record<string, string>|null
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||||
|
getParsedResult (translations: any, key: any, interpolateParams?: any): any {
|
||||||
|
if (!this._defaultTranslation) {
|
||||||
|
const po = require(`../../../locale/en-US.po`)
|
||||||
|
this._defaultTranslation = flattenMessageFormatTranslation(po)
|
||||||
|
}
|
||||||
|
this.translations[this.defaultLang][key] ??= this.compiler.compile(
|
||||||
|
this._defaultTranslation[key] || key,
|
||||||
|
this.defaultLang
|
||||||
|
)
|
||||||
|
return super.getParsedResult(translations, key, interpolateParams ?? {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class LocaleService {
|
||||||
|
private logger: Logger
|
||||||
|
|
||||||
|
static allLanguages = [
|
||||||
|
{
|
||||||
|
code: 'da-DK',
|
||||||
|
name: 'Dansk',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'de-DE',
|
||||||
|
name: 'Deutsch',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'en-US',
|
||||||
|
name: 'English',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'es-ES',
|
||||||
|
name: 'Español',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'fr-FR',
|
||||||
|
name: 'Français',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'hr-HR',
|
||||||
|
name: 'Hrvatski',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'it-IT',
|
||||||
|
name: 'Italiano',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'pl-PL',
|
||||||
|
name: 'Polski',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'ru-RU',
|
||||||
|
name: 'Русский',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'ja-JP',
|
||||||
|
name: '日本語',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'zh-CN',
|
||||||
|
name: '中文(简体)',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'zh-TW',
|
||||||
|
name: '中文 (繁體)',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
get localeChanged$ (): Observable<string> {
|
||||||
|
return this.localeChanged.pipe(distinctUntilChanged())
|
||||||
|
}
|
||||||
|
|
||||||
|
private locale = 'en-US'
|
||||||
|
private localeChanged = new Subject<string>()
|
||||||
|
|
||||||
|
constructor (
|
||||||
|
private config: ConfigService,
|
||||||
|
private translate: TranslateService,
|
||||||
|
log: LogService,
|
||||||
|
) {
|
||||||
|
this.logger = log.create('translate')
|
||||||
|
config.changed$.subscribe(() => {
|
||||||
|
this.refresh()
|
||||||
|
})
|
||||||
|
config.ready$.subscribe(() => {
|
||||||
|
this.refresh()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
refresh (): void {
|
||||||
|
let lang = this.config.store.language
|
||||||
|
if (!lang) {
|
||||||
|
for (const systemLanguage of navigator.languages) {
|
||||||
|
if (!lang && LocaleService.allLanguages.some(x => x.code === systemLanguage)) {
|
||||||
|
lang = systemLanguage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lang ??= 'en-US'
|
||||||
|
this.setLocale(lang)
|
||||||
|
}
|
||||||
|
|
||||||
|
async setLocale (lang: string): Promise<void> {
|
||||||
|
if (!this.translate.langs.includes(lang)) {
|
||||||
|
this.translate.addLangs([lang])
|
||||||
|
|
||||||
|
const po = require(`../../../locale/${lang}.po`)
|
||||||
|
const translation = flattenMessageFormatTranslation(po)
|
||||||
|
this.translate.setTranslation(lang, translation)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.translate.setDefaultLang(lang)
|
||||||
|
|
||||||
|
this.locale = lang
|
||||||
|
this.localeChanged.next(lang)
|
||||||
|
this.logger.debug('Setting language to', lang)
|
||||||
|
}
|
||||||
|
|
||||||
|
getLocale (): string {
|
||||||
|
return this.locale
|
||||||
|
}
|
||||||
|
}
|
@@ -1,4 +1,5 @@
|
|||||||
import { Injectable, Inject } from '@angular/core'
|
import { Injectable, Inject } from '@angular/core'
|
||||||
|
import { TranslateService } from '@ngx-translate/core'
|
||||||
import { NewTabParameters } from './tabs.service'
|
import { NewTabParameters } from './tabs.service'
|
||||||
import { BaseTabComponent } from '../components/baseTab.component'
|
import { BaseTabComponent } from '../components/baseTab.component'
|
||||||
import { PartialProfile, Profile, ProfileProvider } from '../api/profileProvider'
|
import { PartialProfile, Profile, ProfileProvider } from '../api/profileProvider'
|
||||||
@@ -29,15 +30,14 @@ export class ProfilesService {
|
|||||||
private config: ConfigService,
|
private config: ConfigService,
|
||||||
private notifications: NotificationsService,
|
private notifications: NotificationsService,
|
||||||
private selector: SelectorService,
|
private selector: SelectorService,
|
||||||
|
private translate: TranslateService,
|
||||||
@Inject(ProfileProvider) private profileProviders: ProfileProvider<Profile>[],
|
@Inject(ProfileProvider) private profileProviders: ProfileProvider<Profile>[],
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
async openNewTabForProfile <P extends Profile> (profile: PartialProfile<P>): Promise<BaseTabComponent|null> {
|
async openNewTabForProfile <P extends Profile> (profile: PartialProfile<P>): Promise<BaseTabComponent|null> {
|
||||||
const params = await this.newTabParametersForProfile(profile)
|
const params = await this.newTabParametersForProfile(profile)
|
||||||
if (params) {
|
if (params) {
|
||||||
const tab = this.app.openNewTab(params)
|
return this.app.openNewTab(params)
|
||||||
;(this.app.getParentTab(tab) ?? tab).color = profile.color ?? null
|
|
||||||
return tab
|
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -48,9 +48,12 @@ export class ProfilesService {
|
|||||||
if (params) {
|
if (params) {
|
||||||
params.inputs ??= {}
|
params.inputs ??= {}
|
||||||
params.inputs['title'] = profile.name
|
params.inputs['title'] = profile.name
|
||||||
if (profile.disableDynamicTitle) {
|
if (fullProfile.disableDynamicTitle) {
|
||||||
params.inputs['disableDynamicTitle'] = true
|
params.inputs['disableDynamicTitle'] = true
|
||||||
}
|
}
|
||||||
|
if (fullProfile.color) {
|
||||||
|
params.inputs['color'] = fullProfile.color
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return params
|
return params
|
||||||
}
|
}
|
||||||
@@ -103,7 +106,7 @@ export class ProfilesService {
|
|||||||
|
|
||||||
let options: SelectorOption<void>[] = recentProfiles.map(p => ({
|
let options: SelectorOption<void>[] = recentProfiles.map(p => ({
|
||||||
...this.selectorOptionForProfile(p),
|
...this.selectorOptionForProfile(p),
|
||||||
group: 'Recent',
|
group: this.translate.instant('Recent'),
|
||||||
icon: 'fas fa-history',
|
icon: 'fas fa-history',
|
||||||
color: p.color,
|
color: p.color,
|
||||||
callback: async () => {
|
callback: async () => {
|
||||||
@@ -115,8 +118,8 @@ export class ProfilesService {
|
|||||||
}))
|
}))
|
||||||
if (recentProfiles.length) {
|
if (recentProfiles.length) {
|
||||||
options.push({
|
options.push({
|
||||||
name: 'Clear recent profiles',
|
name: this.translate.instant('Clear recent profiles'),
|
||||||
group: 'Recent',
|
group: this.translate.instant('Recent'),
|
||||||
icon: 'fas fa-eraser',
|
icon: 'fas fa-eraser',
|
||||||
callback: async () => {
|
callback: async () => {
|
||||||
window.localStorage.removeItem('recentProfiles')
|
window.localStorage.removeItem('recentProfiles')
|
||||||
@@ -142,7 +145,7 @@ export class ProfilesService {
|
|||||||
try {
|
try {
|
||||||
const { SettingsTabComponent } = window['nodeRequire']('tabby-settings')
|
const { SettingsTabComponent } = window['nodeRequire']('tabby-settings')
|
||||||
options.push({
|
options.push({
|
||||||
name: 'Manage profiles',
|
name: this.translate.instant('Manage profiles'),
|
||||||
icon: 'fas fa-window-restore',
|
icon: 'fas fa-window-restore',
|
||||||
callback: () => {
|
callback: () => {
|
||||||
this.app.openNewTabRaw({
|
this.app.openNewTabRaw({
|
||||||
@@ -156,8 +159,8 @@ export class ProfilesService {
|
|||||||
|
|
||||||
if (this.getProviders().some(x => x.supportsQuickConnect)) {
|
if (this.getProviders().some(x => x.supportsQuickConnect)) {
|
||||||
options.push({
|
options.push({
|
||||||
name: 'Quick connect',
|
name: this.translate.instant('Quick connect'),
|
||||||
freeInputPattern: 'Connect to "%s"...',
|
freeInputPattern: this.translate.instant('Connect to "%s"...'),
|
||||||
icon: 'fas fa-arrow-right',
|
icon: 'fas fa-arrow-right',
|
||||||
callback: query => {
|
callback: query => {
|
||||||
const profile = this.quickConnect(query)
|
const profile = this.quickConnect(query)
|
||||||
@@ -165,7 +168,7 @@ export class ProfilesService {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
await this.selector.show('Select profile or enter an address', options)
|
await this.selector.show(this.translate.instant('Select profile or enter an address'), options)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
reject(err)
|
reject(err)
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { Injectable, Inject } from '@angular/core'
|
import { Injectable, Inject } from '@angular/core'
|
||||||
import { TabRecoveryProvider, RecoveryToken } from '../api/tabRecovery'
|
import { TabRecoveryProvider, RecoveryToken } from '../api/tabRecovery'
|
||||||
import { BaseTabComponent } from '../components/baseTab.component'
|
import { BaseTabComponent, GetRecoveryTokenOptions } from '../components/baseTab.component'
|
||||||
import { Logger, LogService } from './log.service'
|
import { Logger, LogService } from './log.service'
|
||||||
import { ConfigService } from './config.service'
|
import { ConfigService } from './config.service'
|
||||||
import { NewTabParameters } from './tabs.service'
|
import { NewTabParameters } from './tabs.service'
|
||||||
@@ -25,13 +25,13 @@ export class TabRecoveryService {
|
|||||||
}
|
}
|
||||||
window.localStorage.tabsRecovery = JSON.stringify(
|
window.localStorage.tabsRecovery = JSON.stringify(
|
||||||
(await Promise.all(
|
(await Promise.all(
|
||||||
tabs.map(async tab => this.getFullRecoveryToken(tab))
|
tabs.map(async tab => this.getFullRecoveryToken(tab, { includeState: true }))
|
||||||
)).filter(token => !!token)
|
)).filter(token => !!token)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFullRecoveryToken (tab: BaseTabComponent): Promise<RecoveryToken|null> {
|
async getFullRecoveryToken (tab: BaseTabComponent, options?: GetRecoveryTokenOptions): Promise<RecoveryToken|null> {
|
||||||
const token = await tab.getRecoveryToken()
|
const token = await tab.getRecoveryToken(options)
|
||||||
if (token) {
|
if (token) {
|
||||||
token.tabTitle = tab.title
|
token.tabTitle = tab.title
|
||||||
token.tabCustomTitle = tab.customTitle
|
token.tabCustomTitle = tab.customTitle
|
||||||
@@ -43,15 +43,12 @@ export class TabRecoveryService {
|
|||||||
return token
|
return token
|
||||||
}
|
}
|
||||||
|
|
||||||
async recoverTab (token: RecoveryToken, duplicate = false): Promise<NewTabParameters<BaseTabComponent>|null> {
|
async recoverTab (token: RecoveryToken): Promise<NewTabParameters<BaseTabComponent>|null> {
|
||||||
for (const provider of this.config.enabledServices(this.tabRecoveryProviders ?? [])) {
|
for (const provider of this.config.enabledServices(this.tabRecoveryProviders ?? [])) {
|
||||||
try {
|
try {
|
||||||
if (!await provider.applicableTo(token)) {
|
if (!await provider.applicableTo(token)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (duplicate) {
|
|
||||||
token = provider.duplicate(token)
|
|
||||||
}
|
|
||||||
const tab = await provider.recover(token)
|
const tab = await provider.recover(token)
|
||||||
tab.inputs = tab.inputs ?? {}
|
tab.inputs = tab.inputs ?? {}
|
||||||
tab.inputs.color = token.tabColor ?? null
|
tab.inputs.color = token.tabColor ?? null
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
import deepClone from 'clone-deep'
|
||||||
import { Injectable, ComponentFactoryResolver, Injector } from '@angular/core'
|
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'
|
||||||
@@ -48,7 +49,7 @@ export class TabsService {
|
|||||||
if (!token) {
|
if (!token) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
const dup = await this.tabRecovery.recoverTab(token, true)
|
const dup = await this.tabRecovery.recoverTab(deepClone(token))
|
||||||
if (dup) {
|
if (dup) {
|
||||||
return this.create(dup)
|
return this.create(dup)
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
|
import { TranslateService } from '@ngx-translate/core'
|
||||||
import { Subscription } from 'rxjs'
|
import { Subscription } from 'rxjs'
|
||||||
import { AppService } from './services/app.service'
|
import { AppService } from './services/app.service'
|
||||||
import { BaseTabComponent } from './components/baseTab.component'
|
import { BaseTabComponent } from './components/baseTab.component'
|
||||||
@@ -22,6 +23,7 @@ export class TabManagementContextMenu extends TabContextMenuItemProvider {
|
|||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
private app: AppService,
|
private app: AppService,
|
||||||
|
private translate: TranslateService,
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
}
|
}
|
||||||
@@ -29,7 +31,7 @@ export class TabManagementContextMenu extends TabContextMenuItemProvider {
|
|||||||
async getItems (tab: BaseTabComponent, tabHeader?: TabHeaderComponent): Promise<MenuItemOptions[]> {
|
async getItems (tab: BaseTabComponent, tabHeader?: TabHeaderComponent): Promise<MenuItemOptions[]> {
|
||||||
let items: MenuItemOptions[] = [
|
let items: MenuItemOptions[] = [
|
||||||
{
|
{
|
||||||
label: 'Close',
|
label: this.translate.instant('Close'),
|
||||||
click: () => {
|
click: () => {
|
||||||
if (this.app.tabs.includes(tab)) {
|
if (this.app.tabs.includes(tab)) {
|
||||||
this.app.closeTab(tab, true)
|
this.app.closeTab(tab, true)
|
||||||
@@ -43,7 +45,7 @@ export class TabManagementContextMenu extends TabContextMenuItemProvider {
|
|||||||
items = [
|
items = [
|
||||||
...items,
|
...items,
|
||||||
{
|
{
|
||||||
label: 'Close other tabs',
|
label: this.translate.instant('Close other tabs'),
|
||||||
click: () => {
|
click: () => {
|
||||||
for (const 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)
|
||||||
@@ -51,7 +53,7 @@ export class TabManagementContextMenu extends TabContextMenuItemProvider {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Close tabs to the right',
|
label: this.translate.instant('Close tabs to the right'),
|
||||||
click: () => {
|
click: () => {
|
||||||
for (const 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)
|
||||||
@@ -59,7 +61,7 @@ export class TabManagementContextMenu extends TabContextMenuItemProvider {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Close tabs to the left',
|
label: this.translate.instant('Close tabs to the left'),
|
||||||
click: () => {
|
click: () => {
|
||||||
for (const 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)
|
||||||
@@ -71,13 +73,13 @@ export class TabManagementContextMenu extends TabContextMenuItemProvider {
|
|||||||
if (tab.parent instanceof SplitTabComponent) {
|
if (tab.parent instanceof SplitTabComponent) {
|
||||||
const directions: SplitDirection[] = ['r', 'b', 'l', 't']
|
const directions: SplitDirection[] = ['r', 'b', 'l', 't']
|
||||||
items.push({
|
items.push({
|
||||||
label: 'Split',
|
label: this.translate.instant('Split'),
|
||||||
submenu: directions.map(dir => ({
|
submenu: directions.map(dir => ({
|
||||||
label: {
|
label: {
|
||||||
r: 'Right',
|
r: this.translate.instant('Right'),
|
||||||
b: 'Down',
|
b: this.translate.instant('Down'),
|
||||||
l: 'Left',
|
l: this.translate.instant('Left'),
|
||||||
t: 'Up',
|
t: this.translate.instant('Up'),
|
||||||
}[dir],
|
}[dir],
|
||||||
click: () => {
|
click: () => {
|
||||||
(tab.parent as SplitTabComponent).splitTab(tab, dir)
|
(tab.parent as SplitTabComponent).splitTab(tab, dir)
|
||||||
@@ -99,6 +101,7 @@ export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
|
|||||||
private app: AppService,
|
private app: AppService,
|
||||||
private ngbModal: NgbModal,
|
private ngbModal: NgbModal,
|
||||||
private splitLayoutProfilesService: SplitLayoutProfilesService,
|
private splitLayoutProfilesService: SplitLayoutProfilesService,
|
||||||
|
private translate: TranslateService,
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
}
|
}
|
||||||
@@ -106,21 +109,22 @@ export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
|
|||||||
async getItems (tab: BaseTabComponent, tabHeader?: TabHeaderComponent): Promise<MenuItemOptions[]> {
|
async getItems (tab: BaseTabComponent, tabHeader?: TabHeaderComponent): Promise<MenuItemOptions[]> {
|
||||||
let items: MenuItemOptions[] = []
|
let items: MenuItemOptions[] = []
|
||||||
if (tabHeader) {
|
if (tabHeader) {
|
||||||
|
const currentColor = TAB_COLORS.find(x => x.value === tab.color)?.name
|
||||||
items = [
|
items = [
|
||||||
...items,
|
...items,
|
||||||
{
|
{
|
||||||
label: 'Rename',
|
label: this.translate.instant('Rename'),
|
||||||
click: () => tabHeader.showRenameTabModal(),
|
click: () => tabHeader.showRenameTabModal(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Duplicate',
|
label: this.translate.instant('Duplicate'),
|
||||||
click: () => this.app.duplicateTab(tab),
|
click: () => this.app.duplicateTab(tab),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Color',
|
label: this.translate.instant('Color'),
|
||||||
sublabel: TAB_COLORS.find(x => x.value === tab.color)?.name,
|
sublabel: currentColor ? this.translate.instant(currentColor) : undefined,
|
||||||
submenu: TAB_COLORS.map(color => ({
|
submenu: TAB_COLORS.map(color => ({
|
||||||
label: color.name,
|
label: this.translate.instant(color.name) ?? color.name,
|
||||||
type: 'radio',
|
type: 'radio',
|
||||||
checked: tab.color === color.value,
|
checked: tab.color === color.value,
|
||||||
click: () => {
|
click: () => {
|
||||||
@@ -132,10 +136,10 @@ export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
|
|||||||
|
|
||||||
if (tab instanceof SplitTabComponent && tab.getAllTabs().length > 1) {
|
if (tab instanceof SplitTabComponent && tab.getAllTabs().length > 1) {
|
||||||
items.push({
|
items.push({
|
||||||
label: 'Save layout as profile',
|
label: this.translate.instant('Save layout as profile'),
|
||||||
click: async () => {
|
click: async () => {
|
||||||
const modal = this.ngbModal.open(PromptModalComponent)
|
const modal = this.ngbModal.open(PromptModalComponent)
|
||||||
modal.componentInstance.prompt = 'Profile name'
|
modal.componentInstance.prompt = this.translate.instant('Profile name')
|
||||||
const name = (await modal.result)?.value
|
const name = (await modal.result)?.value
|
||||||
if (!name) {
|
if (!name) {
|
||||||
return
|
return
|
||||||
@@ -154,6 +158,7 @@ export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
|
|||||||
export class TaskCompletionContextMenu extends TabContextMenuItemProvider {
|
export class TaskCompletionContextMenu extends TabContextMenuItemProvider {
|
||||||
constructor (
|
constructor (
|
||||||
private app: AppService,
|
private app: AppService,
|
||||||
|
private translate: TranslateService,
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
}
|
}
|
||||||
@@ -167,10 +172,10 @@ export class TaskCompletionContextMenu extends TabContextMenuItemProvider {
|
|||||||
if (process) {
|
if (process) {
|
||||||
items.push({
|
items.push({
|
||||||
enabled: false,
|
enabled: false,
|
||||||
label: 'Current process: ' + process.name,
|
label: this.translate.instant('Current process: {name}', process),
|
||||||
})
|
})
|
||||||
items.push({
|
items.push({
|
||||||
label: 'Notify when done',
|
label: this.translate.instant('Notify when done'),
|
||||||
type: 'checkbox',
|
type: 'checkbox',
|
||||||
checked: extTab.__completionNotificationEnabled,
|
checked: extTab.__completionNotificationEnabled,
|
||||||
click: () => {
|
click: () => {
|
||||||
@@ -178,7 +183,7 @@ export class TaskCompletionContextMenu extends TabContextMenuItemProvider {
|
|||||||
|
|
||||||
if (extTab.__completionNotificationEnabled) {
|
if (extTab.__completionNotificationEnabled) {
|
||||||
this.app.observeTabCompletion(tab).subscribe(() => {
|
this.app.observeTabCompletion(tab).subscribe(() => {
|
||||||
new Notification('Process completed', {
|
new Notification(this.translate.instant('Process completed'), {
|
||||||
body: process.name,
|
body: process.name,
|
||||||
}).addEventListener('click', () => {
|
}).addEventListener('click', () => {
|
||||||
this.app.selectTab(tab)
|
this.app.selectTab(tab)
|
||||||
@@ -192,7 +197,7 @@ export class TaskCompletionContextMenu extends TabContextMenuItemProvider {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
items.push({
|
items.push({
|
||||||
label: 'Notify on activity',
|
label: this.translate.instant('Notify on activity'),
|
||||||
type: 'checkbox',
|
type: 'checkbox',
|
||||||
checked: !!extTab.__outputNotificationSubscription,
|
checked: !!extTab.__outputNotificationSubscription,
|
||||||
click: () => {
|
click: () => {
|
||||||
@@ -204,7 +209,7 @@ export class TaskCompletionContextMenu extends TabContextMenuItemProvider {
|
|||||||
if (extTab.__outputNotificationSubscription && active) {
|
if (extTab.__outputNotificationSubscription && active) {
|
||||||
extTab.__outputNotificationSubscription.unsubscribe()
|
extTab.__outputNotificationSubscription.unsubscribe()
|
||||||
extTab.__outputNotificationSubscription = null
|
extTab.__outputNotificationSubscription = null
|
||||||
new Notification('Tab activity', {
|
new Notification(this.translate.instant('Tab activity'), {
|
||||||
body: tab.title,
|
body: tab.title,
|
||||||
}).addEventListener('click', () => {
|
}).addEventListener('click', () => {
|
||||||
this.app.selectTab(tab)
|
this.app.selectTab(tab)
|
||||||
@@ -228,6 +233,7 @@ export class ProfilesContextMenu extends TabContextMenuItemProvider {
|
|||||||
private profilesService: ProfilesService,
|
private profilesService: ProfilesService,
|
||||||
private tabsService: TabsService,
|
private tabsService: TabsService,
|
||||||
private app: AppService,
|
private app: AppService,
|
||||||
|
private translate: TranslateService,
|
||||||
hotkeys: HotkeysService,
|
hotkeys: HotkeysService,
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
@@ -270,7 +276,7 @@ export class ProfilesContextMenu extends TabContextMenuItemProvider {
|
|||||||
if (!tabHeader && tab.parent instanceof SplitTabComponent && tab.parent.getAllTabs().length > 1) {
|
if (!tabHeader && tab.parent instanceof SplitTabComponent && tab.parent.getAllTabs().length > 1) {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
label: 'Switch profile',
|
label: this.translate.instant('Switch profile'),
|
||||||
click: () => this.switchTabProfile(tab),
|
click: () => this.switchTabProfile(tab),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
@@ -117,15 +117,13 @@ window-controls {
|
|||||||
|
|
||||||
$border-color: $base1;
|
$border-color: $base1;
|
||||||
|
|
||||||
body {
|
app-root {
|
||||||
background: $body-bg;
|
background: $body-bg;
|
||||||
|
|
||||||
&.vibrant {
|
&.vibrant {
|
||||||
background: rgba(255, 255, 255,.4) !important;
|
background: rgba(255, 255, 255,.4) !important;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
app-root {
|
|
||||||
&> .content {
|
&> .content {
|
||||||
.tab-bar {
|
.tab-bar {
|
||||||
.btn-tab-bar {
|
.btn-tab-bar {
|
||||||
@@ -382,7 +380,11 @@ start-page footer {
|
|||||||
background: $white !important;
|
background: $white !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.terminal-toolbar {
|
terminal-toolbar {
|
||||||
background: #ffffff4a !important;
|
background: #ffffff4a !important;
|
||||||
border-bottom: 1px solid #00000026 !important;
|
border-bottom: 1px solid #00000026 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bg-dark{
|
||||||
|
background-color: $base2 !important;
|
||||||
|
}
|
||||||
|
@@ -25,15 +25,13 @@ window-controls {
|
|||||||
|
|
||||||
$border-color: #111;
|
$border-color: #111;
|
||||||
|
|
||||||
body {
|
app-root {
|
||||||
background: $body-bg;
|
background: $body-bg;
|
||||||
|
|
||||||
&.vibrant {
|
&.vibrant {
|
||||||
background: rgba(0,0,0,.65);
|
background: rgba(0,0,0,.65);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
app-root {
|
|
||||||
&.no-tabs {
|
&.no-tabs {
|
||||||
background: rgba(0,0,0,.5);
|
background: rgba(0,0,0,.5);
|
||||||
}
|
}
|
||||||
@@ -124,8 +122,13 @@ app-root {
|
|||||||
|
|
||||||
&.platform-win32, &.platform-linux {
|
&.platform-win32, &.platform-linux {
|
||||||
border: 1px solid #111;
|
border: 1px solid #111;
|
||||||
&>.content .tab-bar .tabs tab-header:first-child {
|
|
||||||
border-left: none;
|
&>.content {
|
||||||
|
margin: -1px; // expand the content into the border
|
||||||
|
|
||||||
|
.tab-bar .tabs tab-header:first-child {
|
||||||
|
border-left: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,7 +136,7 @@ app-root {
|
|||||||
tab-body {
|
tab-body {
|
||||||
background: $content-bg;
|
background: $content-bg;
|
||||||
|
|
||||||
.terminal-toolbar .btn, .toolbar-pin-button {
|
terminal-toolbar .btn, .toolbar-pin-button {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,22 +1,31 @@
|
|||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
|
import { TranslateService } from '@ngx-translate/core'
|
||||||
import { Theme } from './api'
|
import { Theme } from './api'
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class StandardTheme extends Theme {
|
export class StandardTheme extends Theme {
|
||||||
name = 'Standard'
|
name = this.translate.instant('Standard')
|
||||||
css = require('./theme.scss')
|
css = require('./theme.scss')
|
||||||
terminalBackground = '#222a33'
|
terminalBackground = '#222a33'
|
||||||
|
|
||||||
|
constructor (private translate: TranslateService) {
|
||||||
|
super()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class StandardCompactTheme extends Theme {
|
export class StandardCompactTheme extends Theme {
|
||||||
name = 'Compact'
|
name = this.translate.instant('Compact')
|
||||||
css = require('./theme.compact.scss')
|
css = require('./theme.compact.scss')
|
||||||
terminalBackground = '#222a33'
|
terminalBackground = '#222a33'
|
||||||
macOSWindowButtonsInsetX = 8
|
macOSWindowButtonsInsetX = 8
|
||||||
macOSWindowButtonsInsetY = 6
|
macOSWindowButtonsInsetY = 6
|
||||||
|
|
||||||
|
constructor (private translate: TranslateService) {
|
||||||
|
super()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
import * as os from 'os'
|
import * as os from 'os'
|
||||||
import { NgZone } from '@angular/core'
|
import { NgZone } from '@angular/core'
|
||||||
|
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'
|
||||||
|
|
||||||
export const WIN_BUILD_CONPTY_SUPPORTED = 17692
|
export const WIN_BUILD_CONPTY_SUPPORTED = 17692
|
||||||
export const WIN_BUILD_CONPTY_STABLE = 18309
|
export const WIN_BUILD_CONPTY_STABLE = 18309
|
||||||
@@ -56,13 +57,13 @@ export class ResettableTimeout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const TAB_COLORS = [
|
export const TAB_COLORS = [
|
||||||
{ name: 'No color', value: null },
|
{ name: _('No color'), value: null },
|
||||||
{ name: 'Blue', value: '#0275d8' },
|
{ name: _('Blue'), value: '#0275d8' },
|
||||||
{ name: 'Green', value: '#5cb85c' },
|
{ name: _('Green'), value: '#5cb85c' },
|
||||||
{ name: 'Orange', value: '#f0ad4e' },
|
{ name: _('Orange'), value: '#f0ad4e' },
|
||||||
{ name: 'Purple', value: '#613d7c' },
|
{ name: _('Purple'), value: '#613d7c' },
|
||||||
{ name: 'Red', value: '#d9534f' },
|
{ name: _('Red'), value: '#d9534f' },
|
||||||
{ name: 'Yellow', value: '#ffd500' },
|
{ name: _('Yellow'), value: '#ffd500' },
|
||||||
]
|
]
|
||||||
|
|
||||||
export function serializeFunction <T extends () => Promise<any>> (fn: T): T {
|
export function serializeFunction <T extends () => Promise<any>> (fn: T): T {
|
||||||
|
@@ -2,6 +2,13 @@
|
|||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
"@ngx-translate/core@^14.0.0":
|
||||||
|
version "14.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@ngx-translate/core/-/core-14.0.0.tgz#af421d0e1a28376843f0fed375cd2fae7630a5ff"
|
||||||
|
integrity sha512-UevdwNCXMRCdJv//0kC8h2eSfmi02r29xeE8E9gJ1Al4D4jEJ7eiLPdjslTMc21oJNGguqqWeEVjf64SFtvw2w==
|
||||||
|
dependencies:
|
||||||
|
tslib "^2.3.0"
|
||||||
|
|
||||||
agent-base@6:
|
agent-base@6:
|
||||||
version "6.0.2"
|
version "6.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
|
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
|
||||||
@@ -56,6 +63,37 @@ js-yaml@^4.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
argparse "^2.0.1"
|
argparse "^2.0.1"
|
||||||
|
|
||||||
|
make-plural@^4.3.0:
|
||||||
|
version "4.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/make-plural/-/make-plural-4.3.0.tgz#f23de08efdb0cac2e0c9ba9f315b0dff6b4c2735"
|
||||||
|
integrity sha512-xTYd4JVHpSCW+aqDof6w/MebaMVNTVYBZhbB/vi513xXdiPT92JMVCo0Jq8W2UZnzYRFeVbQiQ+I25l13JuKvA==
|
||||||
|
optionalDependencies:
|
||||||
|
minimist "^1.2.0"
|
||||||
|
|
||||||
|
messageformat-formatters@^2.0.1:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/messageformat-formatters/-/messageformat-formatters-2.0.1.tgz#0492c1402a48775f751c9b17c0354e92be012b08"
|
||||||
|
integrity sha512-E/lQRXhtHwGuiQjI7qxkLp8AHbMD5r2217XNe/SREbBlSawe0lOqsFb7rflZJmlQFSULNLIqlcjjsCPlB3m3Mg==
|
||||||
|
|
||||||
|
messageformat-parser@^4.1.2:
|
||||||
|
version "4.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/messageformat-parser/-/messageformat-parser-4.1.3.tgz#b824787f57fcda7d50769f5b63e8d4fda68f5b9e"
|
||||||
|
integrity sha512-2fU3XDCanRqeOCkn7R5zW5VQHWf+T3hH65SzuqRvjatBK7r4uyFa5mEX+k6F9Bd04LVM5G4/BHBTUJsOdW7uyg==
|
||||||
|
|
||||||
|
messageformat@^2.3.0:
|
||||||
|
version "2.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/messageformat/-/messageformat-2.3.0.tgz#de263c49029d5eae65d7ee25e0754f57f425ad91"
|
||||||
|
integrity sha512-uTzvsv0lTeQxYI2y1NPa1lItL5VRI8Gb93Y2K2ue5gBPyrbJxfDi/EYWxh2PKv5yO42AJeeqblS9MJSh/IEk4w==
|
||||||
|
dependencies:
|
||||||
|
make-plural "^4.3.0"
|
||||||
|
messageformat-formatters "^2.0.1"
|
||||||
|
messageformat-parser "^4.1.2"
|
||||||
|
|
||||||
|
minimist@^1.2.0:
|
||||||
|
version "1.2.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||||
|
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
||||||
|
|
||||||
mixpanel@^0.13.0:
|
mixpanel@^0.13.0:
|
||||||
version "0.13.0"
|
version "0.13.0"
|
||||||
resolved "https://registry.yarnpkg.com/mixpanel/-/mixpanel-0.13.0.tgz#699bf510d9ba013c75edcf979ff1e24085fde9d2"
|
resolved "https://registry.yarnpkg.com/mixpanel/-/mixpanel-0.13.0.tgz#699bf510d9ba013c75edcf979ff1e24085fde9d2"
|
||||||
@@ -85,6 +123,13 @@ ngx-perfect-scrollbar@^10.1.0:
|
|||||||
resize-observer-polyfill "^1.5.0"
|
resize-observer-polyfill "^1.5.0"
|
||||||
tslib "^2.0.0"
|
tslib "^2.0.0"
|
||||||
|
|
||||||
|
ngx-translate-messageformat-compiler@^4.11.0:
|
||||||
|
version "4.11.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/ngx-translate-messageformat-compiler/-/ngx-translate-messageformat-compiler-4.11.0.tgz#c9b71dd139ba5fcdcd809001e22622de589fd707"
|
||||||
|
integrity sha512-OdGfWV4fF3DhZqGIHcLmOnQDufugmZ+E90NYr1UPGRZgT10lilr9oLmIrisy3lW4THnZFNo9JXsX7+fX84LbDw==
|
||||||
|
dependencies:
|
||||||
|
tslib "^1.10.0"
|
||||||
|
|
||||||
perfect-scrollbar@1.5.0:
|
perfect-scrollbar@1.5.0:
|
||||||
version "1.5.0"
|
version "1.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/perfect-scrollbar/-/perfect-scrollbar-1.5.0.tgz#821d224ed8ff61990c23f26db63048cdc75b6b83"
|
resolved "https://registry.yarnpkg.com/perfect-scrollbar/-/perfect-scrollbar-1.5.0.tgz#821d224ed8ff61990c23f26db63048cdc75b6b83"
|
||||||
@@ -116,11 +161,21 @@ string_decoder@^1.1.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer "~5.2.0"
|
safe-buffer "~5.2.0"
|
||||||
|
|
||||||
|
tslib@^1.10.0:
|
||||||
|
version "1.14.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||||
|
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
||||||
|
|
||||||
tslib@^2.0.0:
|
tslib@^2.0.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a"
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a"
|
||||||
integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==
|
integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==
|
||||||
|
|
||||||
|
tslib@^2.3.0:
|
||||||
|
version "2.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01"
|
||||||
|
integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
|
||||||
|
|
||||||
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"
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "tabby-electron",
|
"name": "tabby-electron",
|
||||||
"version": "1.0.165-nightly.0",
|
"version": "1.0.171-nightly.3",
|
||||||
"description": "Electron-specific bindings",
|
"description": "Electron-specific bindings",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"tabby-builtin-plugin"
|
"tabby-builtin-plugin"
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { HotkeyDescription, HotkeyProvider } from 'tabby-core'
|
import { HotkeyDescription, HotkeyProvider, TranslateService } from 'tabby-core'
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@@ -7,14 +7,16 @@ export class ElectronHotkeyProvider extends HotkeyProvider {
|
|||||||
hotkeys: HotkeyDescription[] = [
|
hotkeys: HotkeyDescription[] = [
|
||||||
{
|
{
|
||||||
id: 'new-window',
|
id: 'new-window',
|
||||||
name: 'New window',
|
name: this.translate.instant('New window'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'toggle-window',
|
id: 'toggle-window',
|
||||||
name: 'Toggle terminal window',
|
name: this.translate.instant('Toggle terminal window'),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
constructor (private translate: TranslateService) { super() }
|
||||||
|
|
||||||
async provide (): Promise<HotkeyDescription[]> {
|
async provide (): Promise<HotkeyDescription[]> {
|
||||||
return this.hotkeys
|
return this.hotkeys
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
import { NgModule } from '@angular/core'
|
import { NgModule } from '@angular/core'
|
||||||
import { PlatformService, LogService, UpdaterService, DockingService, HostAppService, ThemesService, Platform, AppService, ConfigService, WIN_BUILD_FLUENT_BG_SUPPORTED, isWindowsBuild, HostWindowService, HotkeyProvider, ConfigProvider, FileProvider } from 'tabby-core'
|
import { PlatformService, LogService, UpdaterService, DockingService, HostAppService, ThemesService, Platform, AppService, ConfigService, WIN_BUILD_FLUENT_BG_SUPPORTED, isWindowsBuild, HostWindowService, HotkeyProvider, ConfigProvider, FileProvider } from 'tabby-core'
|
||||||
import { TerminalColorSchemeProvider } from 'tabby-terminal'
|
import { TerminalColorSchemeProvider } from 'tabby-terminal'
|
||||||
import { SFTPContextMenuItemProvider } from 'tabby-ssh'
|
import { SFTPContextMenuItemProvider, SSHProfileImporter } from 'tabby-ssh'
|
||||||
|
import { auditTime } from 'rxjs'
|
||||||
|
|
||||||
import { HyperColorSchemes } from './colorSchemes'
|
import { HyperColorSchemes } from './colorSchemes'
|
||||||
import { ElectronPlatformService } from './services/platform.service'
|
import { ElectronPlatformService } from './services/platform.service'
|
||||||
@@ -16,6 +17,7 @@ import { ElectronService } from './services/electron.service'
|
|||||||
import { ElectronHotkeyProvider } from './hotkeys'
|
import { ElectronHotkeyProvider } from './hotkeys'
|
||||||
import { ElectronConfigProvider } from './config'
|
import { ElectronConfigProvider } from './config'
|
||||||
import { EditSFTPContextMenu } from './sftpContextMenu'
|
import { EditSFTPContextMenu } from './sftpContextMenu'
|
||||||
|
import { OpenSSHImporter, StaticFileImporter } from './sshImporters'
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
providers: [
|
providers: [
|
||||||
@@ -30,6 +32,8 @@ import { EditSFTPContextMenu } from './sftpContextMenu'
|
|||||||
{ provide: ConfigProvider, useClass: ElectronConfigProvider, multi: true },
|
{ provide: ConfigProvider, useClass: ElectronConfigProvider, multi: true },
|
||||||
{ provide: FileProvider, useClass: ElectronFileProvider, multi: true },
|
{ provide: FileProvider, useClass: ElectronFileProvider, multi: true },
|
||||||
{ provide: SFTPContextMenuItemProvider, useClass: EditSFTPContextMenu, multi: true },
|
{ provide: SFTPContextMenuItemProvider, useClass: EditSFTPContextMenu, multi: true },
|
||||||
|
{ provide: SSHProfileImporter, useExisting: OpenSSHImporter, multi: true },
|
||||||
|
{ provide: SSHProfileImporter, useExisting: StaticFileImporter, multi: true },
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export default class ElectronModule {
|
export default class ElectronModule {
|
||||||
@@ -68,7 +72,7 @@ export default class ElectronModule {
|
|||||||
|
|
||||||
let lastProgress: number|null = null
|
let lastProgress: number|null = null
|
||||||
app.tabOpened$.subscribe(tab => {
|
app.tabOpened$.subscribe(tab => {
|
||||||
tab.progress$.subscribe(progress => {
|
tab.progress$.pipe(auditTime(250)).subscribe(progress => {
|
||||||
if (lastProgress === progress) {
|
if (lastProgress === progress) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -113,7 +117,6 @@ export default class ElectronModule {
|
|||||||
if (this.hostApp.platform === Platform.Windows && !isWindowsBuild(WIN_BUILD_FLUENT_BG_SUPPORTED)) {
|
if (this.hostApp.platform === Platform.Windows && !isWindowsBuild(WIN_BUILD_FLUENT_BG_SUPPORTED)) {
|
||||||
vibrancyType = null
|
vibrancyType = null
|
||||||
}
|
}
|
||||||
document.body.classList.toggle('vibrant', this.config.store.appearance.vibrancy)
|
|
||||||
this.electron.ipcRenderer.send('window-set-vibrancy', this.config.store.appearance.vibrancy, vibrancyType)
|
this.electron.ipcRenderer.send('window-set-vibrancy', this.config.store.appearance.vibrancy, vibrancyType)
|
||||||
|
|
||||||
this.hostWindow.setOpacity(this.config.store.appearance.opacity)
|
this.hostWindow.setOpacity(this.config.store.appearance.opacity)
|
||||||
|
@@ -15,6 +15,7 @@ export class ElectronHostWindow extends HostWindowService {
|
|||||||
get isFullscreen (): boolean { return this._isFullscreen }
|
get isFullscreen (): boolean { return this._isFullscreen }
|
||||||
|
|
||||||
private _isFullscreen = false
|
private _isFullscreen = false
|
||||||
|
private _isMaximized = false
|
||||||
|
|
||||||
constructor (
|
constructor (
|
||||||
zone: NgZone,
|
zone: NgZone,
|
||||||
@@ -47,6 +48,16 @@ export class ElectronHostWindow extends HostWindowService {
|
|||||||
electron.ipcRenderer.on('host:became-main-window', () => zone.run(() => {
|
electron.ipcRenderer.on('host:became-main-window', () => zone.run(() => {
|
||||||
this.bootstrapData.isMainWindow = true
|
this.bootstrapData.isMainWindow = true
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
electron.ipcRenderer.on('host:window-maximized', () => zone.run(() => {
|
||||||
|
this._isMaximized = true
|
||||||
|
}))
|
||||||
|
|
||||||
|
electron.ipcRenderer.on('host:window-unmaximized', () => zone.run(() => {
|
||||||
|
this._isMaximized = false
|
||||||
|
}))
|
||||||
|
|
||||||
|
this._isMaximized = this.getWindow().isMaximized()
|
||||||
}
|
}
|
||||||
|
|
||||||
getWindow (): BrowserWindow {
|
getWindow (): BrowserWindow {
|
||||||
@@ -74,7 +85,7 @@ export class ElectronHostWindow extends HostWindowService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isMaximized (): boolean {
|
isMaximized (): boolean {
|
||||||
return this.getWindow().isMaximized()
|
return this._isMaximized
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleMaximize (): void {
|
toggleMaximize (): void {
|
||||||
|
@@ -7,7 +7,7 @@ import { promisify } from 'util'
|
|||||||
import promiseIpc, { RendererProcessType } from 'electron-promise-ipc'
|
import promiseIpc, { RendererProcessType } from 'electron-promise-ipc'
|
||||||
import { execFile } from 'mz/child_process'
|
import { execFile } from 'mz/child_process'
|
||||||
import { Injectable, NgZone } from '@angular/core'
|
import { Injectable, NgZone } from '@angular/core'
|
||||||
import { PlatformService, ClipboardContent, HostAppService, Platform, MenuItemOptions, MessageBoxOptions, MessageBoxResult, FileUpload, FileDownload, FileUploadOptions, wrapPromise } from 'tabby-core'
|
import { PlatformService, ClipboardContent, HostAppService, Platform, MenuItemOptions, MessageBoxOptions, MessageBoxResult, FileUpload, FileDownload, FileUploadOptions, wrapPromise, TranslateService } from 'tabby-core'
|
||||||
import { ElectronService } from '../services/electron.service'
|
import { ElectronService } from '../services/electron.service'
|
||||||
import { ElectronHostWindow } from './hostWindow.service'
|
import { ElectronHostWindow } from './hostWindow.service'
|
||||||
import { ShellIntegrationService } from './shellIntegration.service'
|
import { ShellIntegrationService } from './shellIntegration.service'
|
||||||
@@ -34,6 +34,7 @@ export class ElectronPlatformService extends PlatformService {
|
|||||||
private electron: ElectronService,
|
private electron: ElectronService,
|
||||||
private zone: NgZone,
|
private zone: NgZone,
|
||||||
private shellIntegration: ShellIntegrationService,
|
private shellIntegration: ShellIntegrationService,
|
||||||
|
private translate: TranslateService,
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
this.configPath = path.join(electron.app.getPath('userData'), 'config.yaml')
|
this.configPath = path.join(electron.app.getPath('userData'), 'config.yaml')
|
||||||
@@ -204,7 +205,7 @@ export class ElectronPlatformService extends PlatformService {
|
|||||||
const result = await this.electron.dialog.showOpenDialog(
|
const result = await this.electron.dialog.showOpenDialog(
|
||||||
this.hostWindow.getWindow(),
|
this.hostWindow.getWindow(),
|
||||||
{
|
{
|
||||||
buttonLabel: 'Select',
|
buttonLabel: this.translate.instant('Select'),
|
||||||
properties,
|
properties,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@@ -2,7 +2,7 @@ import type { AppUpdater } from 'electron-updater'
|
|||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
import { Logger, LogService, ConfigService, UpdaterService, PlatformService } from 'tabby-core'
|
import { Logger, LogService, ConfigService, UpdaterService, PlatformService, TranslateService } from 'tabby-core'
|
||||||
import { ElectronService } from '../services/electron.service'
|
import { ElectronService } from '../services/electron.service'
|
||||||
|
|
||||||
const UPDATES_URL = 'https://api.github.com/repos/eugeny/tabby/releases/latest'
|
const UPDATES_URL = 'https://api.github.com/repos/eugeny/tabby/releases/latest'
|
||||||
@@ -18,6 +18,7 @@ export class ElectronUpdaterService extends UpdaterService {
|
|||||||
constructor (
|
constructor (
|
||||||
log: LogService,
|
log: LogService,
|
||||||
config: ConfigService,
|
config: ConfigService,
|
||||||
|
private translate: TranslateService,
|
||||||
private platform: PlatformService,
|
private platform: PlatformService,
|
||||||
private electron: ElectronService,
|
private electron: ElectronService,
|
||||||
) {
|
) {
|
||||||
@@ -132,8 +133,11 @@ export class ElectronUpdaterService extends UpdaterService {
|
|||||||
if ((await this.platform.showMessageBox(
|
if ((await this.platform.showMessageBox(
|
||||||
{
|
{
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
message: 'Installing the update will close all tabs and restart Tabby.',
|
message: this.translate.instant('Installing the update will close all tabs and restart Tabby.'),
|
||||||
buttons: ['Update', 'Cancel'],
|
buttons: [
|
||||||
|
this.translate.instant('Update'),
|
||||||
|
this.translate.instant('Cancel'),
|
||||||
|
],
|
||||||
defaultId: 0,
|
defaultId: 0,
|
||||||
cancelId: 1,
|
cancelId: 1,
|
||||||
}
|
}
|
||||||
|
165
tabby-electron/src/sshImporters.ts
Normal file
165
tabby-electron/src/sshImporters.ts
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
import * as fs from 'fs/promises'
|
||||||
|
import * as fsSync from 'fs'
|
||||||
|
import * as path from 'path'
|
||||||
|
import slugify from 'slugify'
|
||||||
|
import * as yaml from 'js-yaml'
|
||||||
|
import { Injectable } from '@angular/core'
|
||||||
|
import { PartialProfile } from 'tabby-core'
|
||||||
|
import { SSHProfileImporter, PortForwardType, SSHProfile, SSHProfileOptions } from 'tabby-ssh'
|
||||||
|
|
||||||
|
import { ElectronService } from './services/electron.service'
|
||||||
|
|
||||||
|
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class OpenSSHImporter extends SSHProfileImporter {
|
||||||
|
async getProfiles (): Promise<PartialProfile<SSHProfile>[]> {
|
||||||
|
const deriveID = name => 'openssh-config:' + slugify(name)
|
||||||
|
|
||||||
|
const results: PartialProfile<SSHProfile>[] = []
|
||||||
|
const configPath = path.join(process.env.HOME ?? '~', '.ssh', 'config')
|
||||||
|
try {
|
||||||
|
const lines = (await fs.readFile(configPath, 'utf8')).split('\n')
|
||||||
|
const globalOptions: Partial<SSHProfileOptions> = {}
|
||||||
|
let currentProfile: PartialProfile<SSHProfile>|null = null
|
||||||
|
for (let line of lines) {
|
||||||
|
if (line.trim().startsWith('#') || !line.trim()) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (line.startsWith('Host ')) {
|
||||||
|
if (currentProfile) {
|
||||||
|
results.push(currentProfile)
|
||||||
|
}
|
||||||
|
const name = line.substr(5).trim()
|
||||||
|
currentProfile = {
|
||||||
|
id: deriveID(name),
|
||||||
|
name: `${name} (.ssh/config)`,
|
||||||
|
type: 'ssh',
|
||||||
|
group: 'Imported from .ssh/config',
|
||||||
|
options: {
|
||||||
|
...globalOptions,
|
||||||
|
host: name,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const target: Partial<SSHProfileOptions> = currentProfile?.options ?? globalOptions
|
||||||
|
line = line.trim()
|
||||||
|
const idx = /\s/.exec(line)?.index ?? -1
|
||||||
|
if (idx === -1) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const key = line.substr(0, idx).trim()
|
||||||
|
const value = line.substr(idx + 1).trim()
|
||||||
|
|
||||||
|
if (key === 'IdentityFile') {
|
||||||
|
target.privateKeys = value.split(',').map(s => s.trim()).map(s => {
|
||||||
|
if (s.startsWith('~')) {
|
||||||
|
s = path.join(process.env.HOME ?? '~', s.slice(2))
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
})
|
||||||
|
} else if (key === 'RemoteForward') {
|
||||||
|
const bind = value.split(/\s/)[0].trim()
|
||||||
|
const tgt = value.split(/\s/)[1].trim()
|
||||||
|
target.forwardedPorts ??= []
|
||||||
|
target.forwardedPorts.push({
|
||||||
|
type: PortForwardType.Remote,
|
||||||
|
description: value,
|
||||||
|
host: bind.split(':')[0] ?? '127.0.0.1',
|
||||||
|
port: parseInt(bind.split(':')[1] ?? bind),
|
||||||
|
targetAddress: tgt.split(':')[0],
|
||||||
|
targetPort: parseInt(tgt.split(':')[1]),
|
||||||
|
})
|
||||||
|
} else if (key === 'LocalForward') {
|
||||||
|
const bind = value.split(/\s/)[0].trim()
|
||||||
|
const tgt = value.split(/\s/)[1].trim()
|
||||||
|
target.forwardedPorts ??= []
|
||||||
|
target.forwardedPorts.push({
|
||||||
|
type: PortForwardType.Local,
|
||||||
|
description: value,
|
||||||
|
host: bind.split(':')[0] ?? '127.0.0.1',
|
||||||
|
port: parseInt(bind.split(':')[1] ?? bind),
|
||||||
|
targetAddress: tgt.split(':')[0],
|
||||||
|
targetPort: parseInt(tgt.split(':')[1]),
|
||||||
|
})
|
||||||
|
} else if (key === 'DynamicForward') {
|
||||||
|
const bind = value.trim()
|
||||||
|
target.forwardedPorts ??= []
|
||||||
|
target.forwardedPorts.push({
|
||||||
|
type: PortForwardType.Dynamic,
|
||||||
|
description: value,
|
||||||
|
host: bind.split(':')[0] ?? '127.0.0.1',
|
||||||
|
port: parseInt(bind.split(':')[1] ?? bind),
|
||||||
|
targetAddress: '',
|
||||||
|
targetPort: 22,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
const mappedKey = {
|
||||||
|
hostname: 'host',
|
||||||
|
host: 'host',
|
||||||
|
port: 'port',
|
||||||
|
user: 'user',
|
||||||
|
forwardx11: 'x11',
|
||||||
|
serveraliveinterval: 'keepaliveInterval',
|
||||||
|
serveralivecountmax: 'keepaliveCountMax',
|
||||||
|
proxycommand: 'proxyCommand',
|
||||||
|
proxyjump: 'jumpHost',
|
||||||
|
}[key.toLowerCase()]
|
||||||
|
if (mappedKey) {
|
||||||
|
target[mappedKey] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentProfile) {
|
||||||
|
results.push(currentProfile)
|
||||||
|
}
|
||||||
|
for (const p of results) {
|
||||||
|
if (p.options?.proxyCommand) {
|
||||||
|
p.options.proxyCommand = p.options.proxyCommand
|
||||||
|
.replace('%h', p.options.host ?? '')
|
||||||
|
.replace('%p', (p.options.port ?? 22).toString())
|
||||||
|
}
|
||||||
|
if (p.options?.jumpHost) {
|
||||||
|
p.options.jumpHost = deriveID(p.options.jumpHost)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results
|
||||||
|
} catch (e) {
|
||||||
|
if (e.code === 'ENOENT') {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class StaticFileImporter extends SSHProfileImporter {
|
||||||
|
private configPath: string
|
||||||
|
|
||||||
|
constructor (
|
||||||
|
electron: ElectronService,
|
||||||
|
) {
|
||||||
|
super()
|
||||||
|
this.configPath = path.join(electron.app.getPath('userData'), 'ssh-profiles.yaml')
|
||||||
|
}
|
||||||
|
|
||||||
|
async getProfiles (): Promise<PartialProfile<SSHProfile>[]> {
|
||||||
|
const deriveID = name => 'file-config:' + slugify(name)
|
||||||
|
|
||||||
|
if (!fsSync.existsSync(this.configPath)) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
const content = await fs.readFile(this.configPath, 'utf8')
|
||||||
|
if (!content) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
return (yaml.load(content) as PartialProfile<SSHProfile>[]).map(item => ({
|
||||||
|
...item,
|
||||||
|
id: deriveID(item.name),
|
||||||
|
type: 'ssh',
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
@@ -11,10 +11,10 @@
|
|||||||
enabled "2.0.x"
|
enabled "2.0.x"
|
||||||
kuler "^2.0.0"
|
kuler "^2.0.0"
|
||||||
|
|
||||||
async@^3.1.0:
|
async@^3.2.3:
|
||||||
version "3.2.0"
|
version "3.2.3"
|
||||||
resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720"
|
resolved "https://registry.yarnpkg.com/async/-/async-3.2.3.tgz#ac53dafd3f4720ee9e8a160628f18ea91df196c9"
|
||||||
integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==
|
integrity sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==
|
||||||
|
|
||||||
balanced-match@^1.0.0:
|
balanced-match@^1.0.0:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
@@ -70,7 +70,7 @@ color@3.0.x:
|
|||||||
color-convert "^1.9.1"
|
color-convert "^1.9.1"
|
||||||
color-string "^1.5.2"
|
color-string "^1.5.2"
|
||||||
|
|
||||||
colors@^1.2.1:
|
colors@1.4.0:
|
||||||
version "1.4.0"
|
version "1.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
|
resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
|
||||||
integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==
|
integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==
|
||||||
@@ -88,11 +88,6 @@ concat-map@0.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||||
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||||
|
|
||||||
core-util-is@~1.0.0:
|
|
||||||
version "1.0.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
|
||||||
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
|
|
||||||
|
|
||||||
define-properties@^1.1.3:
|
define-properties@^1.1.3:
|
||||||
version "1.1.3"
|
version "1.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
|
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
|
||||||
@@ -146,11 +141,6 @@ es-to-primitive@^1.2.1:
|
|||||||
is-date-object "^1.0.1"
|
is-date-object "^1.0.1"
|
||||||
is-symbol "^1.0.2"
|
is-symbol "^1.0.2"
|
||||||
|
|
||||||
fast-safe-stringify@^2.0.4:
|
|
||||||
version "2.0.7"
|
|
||||||
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743"
|
|
||||||
integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==
|
|
||||||
|
|
||||||
fecha@^4.2.0:
|
fecha@^4.2.0:
|
||||||
version "4.2.1"
|
version "4.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.1.tgz#0a83ad8f86ef62a091e22bb5a039cd03d23eecce"
|
resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.1.tgz#0a83ad8f86ef62a091e22bb5a039cd03d23eecce"
|
||||||
@@ -217,7 +207,7 @@ inflight@^1.0.4:
|
|||||||
once "^1.3.0"
|
once "^1.3.0"
|
||||||
wrappy "1"
|
wrappy "1"
|
||||||
|
|
||||||
inherits@2, inherits@^2.0.3, inherits@~2.0.3:
|
inherits@2, inherits@^2.0.3:
|
||||||
version "2.0.4"
|
version "2.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||||
@@ -289,25 +279,20 @@ is-symbol@^1.0.2, is-symbol@^1.0.3:
|
|||||||
dependencies:
|
dependencies:
|
||||||
has-symbols "^1.0.2"
|
has-symbols "^1.0.2"
|
||||||
|
|
||||||
isarray@~1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
|
||||||
integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
|
|
||||||
|
|
||||||
kuler@^2.0.0:
|
kuler@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3"
|
resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3"
|
||||||
integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==
|
integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==
|
||||||
|
|
||||||
logform@^2.2.0:
|
logform@^2.3.2:
|
||||||
version "2.2.0"
|
version "2.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/logform/-/logform-2.2.0.tgz#40f036d19161fc76b68ab50fdc7fe495544492f2"
|
resolved "https://registry.yarnpkg.com/logform/-/logform-2.3.2.tgz#68babe6a74ab09a1fd15a9b1e6cbc7713d41cb5b"
|
||||||
integrity sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg==
|
integrity sha512-V6JiPThZzTsbVRspNO6TmHkR99oqYTs8fivMBYQkjZj6rxW92KxtDCPE6IkAk1DNBnYKNkjm4jYBm6JDUcyhOA==
|
||||||
dependencies:
|
dependencies:
|
||||||
colors "^1.2.1"
|
colors "1.4.0"
|
||||||
fast-safe-stringify "^2.0.4"
|
|
||||||
fecha "^4.2.0"
|
fecha "^4.2.0"
|
||||||
ms "^2.1.1"
|
ms "^2.1.1"
|
||||||
|
safe-stable-stringify "^1.1.0"
|
||||||
triple-beam "^1.3.0"
|
triple-beam "^1.3.0"
|
||||||
|
|
||||||
minimatch@^3.0.4:
|
minimatch@^3.0.4:
|
||||||
@@ -371,24 +356,6 @@ path-is-absolute@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||||
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
|
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
|
||||||
|
|
||||||
process-nextick-args@~2.0.0:
|
|
||||||
version "2.0.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
|
|
||||||
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
|
|
||||||
|
|
||||||
readable-stream@^2.3.7:
|
|
||||||
version "2.3.7"
|
|
||||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
|
|
||||||
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
|
|
||||||
dependencies:
|
|
||||||
core-util-is "~1.0.0"
|
|
||||||
inherits "~2.0.3"
|
|
||||||
isarray "~1.0.0"
|
|
||||||
process-nextick-args "~2.0.0"
|
|
||||||
safe-buffer "~5.1.1"
|
|
||||||
string_decoder "~1.1.1"
|
|
||||||
util-deprecate "~1.0.1"
|
|
||||||
|
|
||||||
readable-stream@^3.4.0:
|
readable-stream@^3.4.0:
|
||||||
version "3.6.0"
|
version "3.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
|
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
|
||||||
@@ -405,16 +372,21 @@ rimraf@^3.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
glob "^7.1.3"
|
glob "^7.1.3"
|
||||||
|
|
||||||
safe-buffer@~5.1.0, safe-buffer@~5.1.1:
|
|
||||||
version "5.1.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
|
|
||||||
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
|
|
||||||
|
|
||||||
safe-buffer@~5.2.0:
|
safe-buffer@~5.2.0:
|
||||||
version "5.2.1"
|
version "5.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||||
|
|
||||||
|
safe-stable-stringify@^1.1.0:
|
||||||
|
version "1.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz#c8a220ab525cd94e60ebf47ddc404d610dc5d84a"
|
||||||
|
integrity sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw==
|
||||||
|
|
||||||
|
safe-stable-stringify@^2.3.1:
|
||||||
|
version "2.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.3.1.tgz#ab67cbe1fe7d40603ca641c5e765cb942d04fc73"
|
||||||
|
integrity sha512-kYBSfT+troD9cDA85VDnHZ1rpHC50O0g1e6WlGHVCz/g+JS+9WKLj+XwFYyR8UbrZN8ll9HUpDAAddY58MGisg==
|
||||||
|
|
||||||
serialize-error@^5.0.0:
|
serialize-error@^5.0.0:
|
||||||
version "5.0.0"
|
version "5.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-5.0.0.tgz#a7ebbcdb03a5d71a6ed8461ffe0fc1a1afed62ac"
|
resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-5.0.0.tgz#a7ebbcdb03a5d71a6ed8461ffe0fc1a1afed62ac"
|
||||||
@@ -457,13 +429,6 @@ string_decoder@^1.1.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
safe-buffer "~5.2.0"
|
safe-buffer "~5.2.0"
|
||||||
|
|
||||||
string_decoder@~1.1.1:
|
|
||||||
version "1.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
|
|
||||||
integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
|
|
||||||
dependencies:
|
|
||||||
safe-buffer "~5.1.0"
|
|
||||||
|
|
||||||
text-hex@1.0.x:
|
text-hex@1.0.x:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
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"
|
||||||
@@ -503,7 +468,7 @@ unbox-primitive@^1.0.0:
|
|||||||
has-symbols "^1.0.2"
|
has-symbols "^1.0.2"
|
||||||
which-boxed-primitive "^1.0.2"
|
which-boxed-primitive "^1.0.2"
|
||||||
|
|
||||||
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=
|
||||||
@@ -524,28 +489,30 @@ which-boxed-primitive@^1.0.2:
|
|||||||
is-string "^1.0.5"
|
is-string "^1.0.5"
|
||||||
is-symbol "^1.0.3"
|
is-symbol "^1.0.3"
|
||||||
|
|
||||||
winston-transport@^4.4.0:
|
winston-transport@^4.4.2:
|
||||||
version "4.4.0"
|
version "4.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.4.0.tgz#17af518daa690d5b2ecccaa7acf7b20ca7925e59"
|
resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.4.2.tgz#554efe3fce229d046df006e0e3c411d240652e51"
|
||||||
integrity sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw==
|
integrity sha512-9jmhltAr5ygt5usgUTQbEiw/7RYXpyUbEAFRCSicIacpUzPkrnQsQZSPGEI12aLK9Jth4zNcYJx3Cvznwrl8pw==
|
||||||
dependencies:
|
dependencies:
|
||||||
readable-stream "^2.3.7"
|
logform "^2.3.2"
|
||||||
|
readable-stream "^3.4.0"
|
||||||
triple-beam "^1.2.0"
|
triple-beam "^1.2.0"
|
||||||
|
|
||||||
winston@^3.3.3:
|
winston@^3.3.3:
|
||||||
version "3.3.3"
|
version "3.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/winston/-/winston-3.3.3.tgz#ae6172042cafb29786afa3d09c8ff833ab7c9170"
|
resolved "https://registry.yarnpkg.com/winston/-/winston-3.5.0.tgz#b1ef4dbc6d1a7c1b462650070f171abc7ce9eac0"
|
||||||
integrity sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==
|
integrity sha512-OQMbmLsIdVHvm2hSurrYZs+iZNIImXneYJ6pX7LseSMEq20HdTETXiNnNX3FDwN4LB/xDRZLF6JYOY+AI112Kw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@dabh/diagnostics" "^2.0.2"
|
"@dabh/diagnostics" "^2.0.2"
|
||||||
async "^3.1.0"
|
async "^3.2.3"
|
||||||
is-stream "^2.0.0"
|
is-stream "^2.0.0"
|
||||||
logform "^2.2.0"
|
logform "^2.3.2"
|
||||||
one-time "^1.0.0"
|
one-time "^1.0.0"
|
||||||
readable-stream "^3.4.0"
|
readable-stream "^3.4.0"
|
||||||
|
safe-stable-stringify "^2.3.1"
|
||||||
stack-trace "0.0.x"
|
stack-trace "0.0.x"
|
||||||
triple-beam "^1.3.0"
|
triple-beam "^1.3.0"
|
||||||
winston-transport "^4.4.0"
|
winston-transport "^4.4.2"
|
||||||
|
|
||||||
wrappy@1:
|
wrappy@1:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "tabby-linkifier",
|
"name": "tabby-linkifier",
|
||||||
"version": "1.0.165-nightly.0",
|
"version": "1.0.171-nightly.3",
|
||||||
"description": "Makes URLs, IPs and file paths clickable in Tabby",
|
"description": "Makes URLs, IPs and file paths clickable in Tabby",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"tabby-builtin-plugin"
|
"tabby-builtin-plugin"
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { Inject, Injectable } from '@angular/core'
|
import { Inject, Injectable } from '@angular/core'
|
||||||
import { ConfigService, PlatformService } from 'tabby-core'
|
import { ConfigService, PlatformService, TranslateService } from 'tabby-core'
|
||||||
import { TerminalDecorator, BaseTerminalTabComponent } from 'tabby-terminal'
|
import { TerminalDecorator, BaseTerminalTabComponent } from 'tabby-terminal'
|
||||||
|
|
||||||
import { LinkHandler } from './api'
|
import { LinkHandler } from './api'
|
||||||
@@ -9,6 +9,7 @@ export class LinkHighlighterDecorator extends TerminalDecorator {
|
|||||||
constructor (
|
constructor (
|
||||||
private config: ConfigService,
|
private config: ConfigService,
|
||||||
private platform: PlatformService,
|
private platform: PlatformService,
|
||||||
|
private translate: TranslateService,
|
||||||
@Inject(LinkHandler) private handlers: LinkHandler[],
|
@Inject(LinkHandler) private handlers: LinkHandler[],
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
@@ -42,13 +43,13 @@ export class LinkHighlighterDecorator extends TerminalDecorator {
|
|||||||
this.platform.popupContextMenu([
|
this.platform.popupContextMenu([
|
||||||
{
|
{
|
||||||
click: () => openLink(uri),
|
click: () => openLink(uri),
|
||||||
label: 'Open',
|
label: this.translate.instant('Open'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
click: async () => {
|
click: async () => {
|
||||||
this.platform.setClipboard({ text: await getLink(uri) })
|
this.platform.setClipboard({ text: await getLink(uri) })
|
||||||
},
|
},
|
||||||
label: 'Copy',
|
label: this.translate.instant('Copy'),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
return false
|
return false
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user