Translation infrastructure

This commit is contained in:
Eugene Pankov 2022-01-08 16:02:56 +01:00
parent 04010b58bb
commit 0814d44207
No known key found for this signature in database
GPG key ID: 5896FCBBDD1CF4F4
134 changed files with 8137 additions and 889 deletions

2
.gitignore vendored
View file

@ -34,3 +34,5 @@ sentry-symbols.js
tabby-ssh/util/pagent.exe
*.psd
crowdin.yml

3
locale/STOP.txt Normal file
View file

@ -0,0 +1,3 @@
Do not submit pull requests for translations.
Translations are managed at https://crowdin.com/project/tabby

196
locale/af.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: af\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: Afrikaans\n"
"Language: af_ZA\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

1303
locale/app.pot Normal file

File diff suppressed because it is too large Load diff

196
locale/ar.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5);\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: ar\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: Arabic\n"
"Language: ar_SA\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

196
locale/ca.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: ca\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: Catalan\n"
"Language: ca_ES\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

196
locale/cs.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 3;\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: cs\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: Czech\n"
"Language: cs_CZ\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

196
locale/da.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: da\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: Danish\n"
"Language: da_DK\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

196
locale/de.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: de\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: German\n"
"Language: de_DE\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

196
locale/el.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: el\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: Greek\n"
"Language: el_GR\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

196
locale/en.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: en\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: English\n"
"Language: en_US\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

196
locale/es.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: es-ES\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: Spanish\n"
"Language: es_ES\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

196
locale/fi.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: fi\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: Finnish\n"
"Language: fi_FI\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

196
locale/fr.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: fr\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: French\n"
"Language: fr_FR\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

196
locale/he.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: he\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: Hebrew\n"
"Language: he_IL\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

196
locale/hu.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: hu\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: Hungarian\n"
"Language: hu_HU\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

196
locale/it.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: it\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: Italian\n"
"Language: it_IT\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

196
locale/ja.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: ja\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: Japanese\n"
"Language: ja_JP\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

196
locale/ko.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: ko\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: Korean\n"
"Language: ko_KR\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

196
locale/nl.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: nl\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: Dutch\n"
"Language: nl_NL\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

196
locale/no.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: no\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: Norwegian\n"
"Language: no_NO\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

196
locale/pl.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: pl\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: Polish\n"
"Language: pl_PL\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

196
locale/pt.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: pt-BR\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: Portuguese, Brazilian\n"
"Language: pt_BR\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

196
locale/ro.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : (n==0 || (n%100>0 && n%100<20)) ? 1 : 2);\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: ro\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: Romanian\n"
"Language: ro_RO\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

196
locale/ru.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: ru\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: Russian\n"
"Language: ru_RU\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr "Приложение"
msgid "Application settings"
msgstr "Настройки приложения"
msgid "Ask a question"
msgstr "Задать вопрос"
msgid "Automatic Updates"
msgstr "Автоматическое обновление"
msgid "Blue"
msgstr "Синий"
msgid "Check for updates"
msgstr "Проверить обновления"
msgid "Close"
msgstr "Закрыть"
msgid "Close other tabs"
msgstr "Закрыть другие вкладки"
msgid "Close tabs to the left"
msgstr "Закрыть вкладки слева"
msgid "Close tabs to the right"
msgstr "Закрыть вкладки справа"
msgid "Color"
msgstr "Цвет"
msgid "Config file"
msgstr "Файл настроек"
msgid "Current process: {name}"
msgstr "Текущий процесс: {name}"
msgid "Debugging"
msgstr "Отладка"
msgid "Defaults"
msgstr "Значения по умолчанию"
msgid "Down"
msgstr "Вниз"
msgid "Duplicate"
msgstr "Дублировать"
msgid "Enable analytics"
msgstr "Аналитика"
msgid "Enable automatic installation of updates when they become available."
msgstr "Включить автоматическую установку обновлений, когда они доступны."
msgid "English"
msgstr "Английский"
msgid "French"
msgstr "Французский"
msgid "Generate a pre-filled GitHub issue"
msgstr "Открыть пред-заполненный отчет на GitHub"
msgid "German"
msgstr "Немецкий"
msgid "Green"
msgstr "Зеленый"
msgid "Invalid syntax"
msgstr "Неверный синтаксис"
msgid "Language"
msgstr "Язык"
msgid "Left"
msgstr "Налево"
msgid "No color"
msgstr "Без цвета"
msgid "Notify on activity"
msgstr "Уведомить об активности"
msgid "Notify when done"
msgstr "Уведомить о завершении"
msgid "On GitHub Discussions"
msgstr "На GitHub Discussions"
msgid "Open DevTools"
msgstr "Открыть DevTools"
msgid "Orange"
msgstr "Оранжевый"
msgid "Process completed"
msgstr "Процесс завершен"
msgid "Profile name"
msgstr "Название профиля"
msgid "Purple"
msgstr "Фиолетовый"
msgid "Red"
msgstr "Красный"
msgid "Rename"
msgstr "Переименовать"
msgid "Report a problem"
msgstr "Сообщить о проблеме"
msgid "Restart the app to apply changes"
msgstr "Перезапустите приложение, чтобы применить изменения"
msgid "Right"
msgstr "Направо"
msgid "Russian"
msgstr "Русский"
msgid "Save and apply"
msgstr "Сохранить и применить"
msgid "Save layout as profile"
msgstr "Сохранить как профиль"
msgid "Shell integration"
msgstr "Интеграция в систему"
msgid "Show config file"
msgstr "Показать файл настроек"
msgid "Show defaults"
msgstr "Показать значения по умолчанию"
msgid "Show release notes"
msgstr "Посмотреть изменения в релизе"
msgid "Source code"
msgstr "Исходный код"
msgid "Split"
msgstr "Разделить"
msgid "Subscribe to updates"
msgstr "Подпишитесь на обновления"
msgid "Tab activity"
msgstr "Активность в вкладке"
msgid "Tabby news and updates on Twitter"
msgstr "Новости и обновления про Tabby в Twitter"
msgid "Up"
msgstr "Вверх"
msgid "Update"
msgstr "Обновить"
msgid "We're only tracking your Tabby and OS versions."
msgstr "Отслеживаем только версию ОС и приложения."
msgid "What's new"
msgstr "Что нового"
msgid "Yellow"
msgstr "Желтый"
msgid "click"
msgstr ""

196
locale/sr.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: sr\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: Serbian (Cyrillic)\n"
"Language: sr_SP\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

196
locale/sv.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: sv-SE\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: Swedish\n"
"Language: sv_SE\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

196
locale/tr.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: tr\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: Turkish\n"
"Language: tr_TR\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

196
locale/uk.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: uk\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: Ukrainian\n"
"Language: uk_UA\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

196
locale/vi.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: vi\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: Vietnamese\n"
"Language: vi_VN\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

196
locale/zh.po Normal file
View file

@ -0,0 +1,196 @@
msgid ""
msgstr ""
"mime-version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Crowdin-Project: tabby\n"
"X-Crowdin-Project-ID: 493349\n"
"X-Crowdin-Language: zh-TW\n"
"X-Crowdin-File: /locale/app.pot\n"
"X-Crowdin-File-ID: 75\n"
"Project-Id-Version: tabby\n"
"Language-Team: Chinese Traditional\n"
"Language: zh_TW\n"
"PO-Revision-Date: 2022-01-08 12:42\n"
msgid "Allows quickly opening a terminal in the selected folder"
msgstr ""
msgid "Application"
msgstr ""
msgid "Application settings"
msgstr ""
msgid "Ask a question"
msgstr ""
msgid "Automatic Updates"
msgstr ""
msgid "Blue"
msgstr ""
msgid "Check for updates"
msgstr ""
msgid "Close"
msgstr ""
msgid "Close other tabs"
msgstr ""
msgid "Close tabs to the left"
msgstr ""
msgid "Close tabs to the right"
msgstr ""
msgid "Color"
msgstr ""
msgid "Config file"
msgstr ""
msgid "Current process: {name}"
msgstr ""
msgid "Debugging"
msgstr ""
msgid "Defaults"
msgstr ""
msgid "Down"
msgstr ""
msgid "Duplicate"
msgstr ""
msgid "Enable analytics"
msgstr ""
msgid "Enable automatic installation of updates when they become available."
msgstr ""
msgid "English"
msgstr ""
msgid "French"
msgstr ""
msgid "Generate a pre-filled GitHub issue"
msgstr ""
msgid "German"
msgstr ""
msgid "Green"
msgstr ""
msgid "Invalid syntax"
msgstr ""
msgid "Language"
msgstr ""
msgid "Left"
msgstr ""
msgid "No color"
msgstr ""
msgid "Notify on activity"
msgstr ""
msgid "Notify when done"
msgstr ""
msgid "On GitHub Discussions"
msgstr ""
msgid "Open DevTools"
msgstr ""
msgid "Orange"
msgstr ""
msgid "Process completed"
msgstr ""
msgid "Profile name"
msgstr ""
msgid "Purple"
msgstr ""
msgid "Red"
msgstr ""
msgid "Rename"
msgstr ""
msgid "Report a problem"
msgstr ""
msgid "Restart the app to apply changes"
msgstr ""
msgid "Right"
msgstr ""
msgid "Russian"
msgstr ""
msgid "Save and apply"
msgstr ""
msgid "Save layout as profile"
msgstr ""
msgid "Shell integration"
msgstr ""
msgid "Show config file"
msgstr ""
msgid "Show defaults"
msgstr ""
msgid "Show release notes"
msgstr ""
msgid "Source code"
msgstr ""
msgid "Split"
msgstr ""
msgid "Subscribe to updates"
msgstr ""
msgid "Tab activity"
msgstr ""
msgid "Tabby news and updates on Twitter"
msgstr ""
msgid "Up"
msgstr ""
msgid "Update"
msgstr ""
msgid "We're only tracking your Tabby and OS versions."
msgstr ""
msgid "What's new"
msgstr ""
msgid "Yellow"
msgstr ""
msgid "click"
msgstr ""

View file

@ -7,6 +7,8 @@
"@angular/forms": "^12.0.0",
"@angular/platform-browser": "^12.0.0",
"@angular/platform-browser-dynamic": "^12.0.0",
"@biesbjerg/ngx-translate-extract": "^7.0.4",
"@biesbjerg/ngx-translate-extract-marker": "^1.0.0",
"@fortawesome/fontawesome-free": "^6.0.0-beta3",
"@ng-bootstrap/ng-bootstrap": "^10.0.0",
"@sentry/cli": "^1.71.0",
@ -40,7 +42,7 @@
"file-loader": "^6.2.0",
"graceful-fs": "^4.2.8",
"html-loader": "2.1.2",
"json-loader": "0.5.7",
"json-loader": "^0.5.7",
"lru-cache": "^6.0.0",
"macos-release": "^3.0.1",
"ngx-sortablejs": "^11.1.0",
@ -50,7 +52,9 @@
"npmlog": "6.0.0",
"npx": "^10.2.2",
"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-lint": "^2.6.0",
"pug-loader": "^2.4.0",
@ -80,6 +84,7 @@
"zone.js": "^0.11.4"
},
"resolutions": {
"*/pug": "^3",
"lzma-native": "^8.0.0",
"*/node-abi": "^3.5.0",
"**/graceful-fs": "^4.2.4"

28
scripts/i18n-extract.js Executable file
View file

@ -0,0 +1,28 @@
#!/usr/bin/env node
const sh = require('shelljs')
const fs = require('fs/promises')
const vars = require('./vars')
const log = require('npmlog')
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('extract-pug', plugin)
sh.exec(`yarn pug --doctype html -s --pretty -O '{require: function(){}}' -o ${tempHtml}/${plugin} ${plugin}`)
log.info('extract-ts', plugin)
sh.exec(`node node_modules/.bin/ngx-translate-extract -i ${plugin}/src -m -s -f pot -o ${tempOutput}`)
}
log.info('extract-pug')
sh.exec(`node node_modules/.bin/ngx-translate-extract -i ${tempHtml} -f pot -s -o ${tempOutput}`)
sh.rm('-r', tempHtml)
await fs.rename(tempOutput, pot)
})()

View file

@ -17,12 +17,15 @@
"author": "Eugene Pankov",
"license": "MIT",
"devDependencies": {
"@ngx-translate/core": "^14.0.0",
"bootstrap": "^4.1.3",
"deepmerge": "^4.1.1",
"js-yaml": "^4.0.0",
"messageformat": "^2.3.0",
"mixpanel": "^0.13.0",
"ngx-filesize": "^2.0.16",
"ngx-perfect-scrollbar": "^10.1.0",
"ngx-translate-messageformat-compiler": "^4.11.0",
"readable-stream": "3.6.0",
"uuid": "^8.0.0"
},

View file

@ -35,4 +35,5 @@ export { TabsService, NewTabParameters, TabComponentType } from '../services/tab
export { UpdaterService } from '../services/updater.service'
export { VaultService, Vault, VaultSecret, VaultFileSecret, VAULT_SECRET_TYPE_FILE, StoredVault, VaultSecretKey } from '../services/vault.service'
export { FileProvidersService } from '../services/fileProviders.service'
export { LocaleService, TranslateServiceWrapper as TranslateService } from '../services/locale.service'
export * from '../utils'

View file

@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { Injectable } from '@angular/core'
import { TranslateService } from '@ngx-translate/core'
import { ToolbarButton, ToolbarButtonProvider } from './api/toolbarButtonProvider'
import { HostAppService, Platform } from './api/hostApp'
@ -12,6 +13,7 @@ export class ButtonProvider extends ToolbarButtonProvider {
constructor (
private hostApp: HostAppService,
private profilesService: ProfilesService,
private translate: TranslateService,
hotkeys: HotkeysService,
) {
super()
@ -35,7 +37,7 @@ export class ButtonProvider extends ToolbarButtonProvider {
icon: this.hostApp.platform === Platform.Web
? require('./icons/plus.svg')
: require('./icons/profiles.svg'),
title: 'Profiles and connections',
title: this.translate.instant('Profiles and connections'),
click: () => this.activate(),
},
...this.profilesService.getRecentProfiles().map(profile => ({

View file

@ -2,5 +2,5 @@
input.form-control(type='text', #input, [(ngModel)]='value', (keyup.enter)='save()', autofocus)
.modal-footer
button.btn.btn-primary((click)='save()') Save
button.btn.btn-secondary((click)='close()') Cancel
button.btn.btn-primary((click)='save()', translate) Save
button.btn.btn-secondary((click)='close()', translate) Cancel

View file

@ -1,7 +1,7 @@
.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}}
.modal-footer
button.btn.btn-primary((click)='close()') Close
button.btn.btn-primary((click)='close()', translate) Close

View file

@ -15,9 +15,9 @@ footer.d-flex.align-items-center
.btn-group.mr-auto
button.btn.btn-dark((click)='homeBase.openGitHub()')
i.fab.fa-github
span GitHub
span(translate) GitHub
button.btn.btn-dark((click)='homeBase.reportBug()')
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, [translateParams]='{version: homeBase.appVersion}') Version: {version}

View file

@ -1,5 +1,5 @@
.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')}
.transfer(*ngFor='let transfer of transfers', (click)='showTransfer(transfer)')
.icon(*ngIf='isDownload(transfer)') !{require('../icons/download.svg')}

View file

@ -1,4 +1,5 @@
import { Component, Input, Output, EventEmitter } from '@angular/core'
import { TranslateService } from '@ngx-translate/core'
import { FileDownload, FileTransfer, PlatformService } from '../api/platform'
/** @hidden */
@ -11,7 +12,10 @@ export class TransfersMenuComponent {
@Input() transfers: FileTransfer[]
@Output() transfersChange = new EventEmitter<FileTransfer[]>()
constructor (private platform: PlatformService) { }
constructor (
private platform: PlatformService,
private translate: TranslateService,
) { }
isDownload (transfer: FileTransfer): boolean {
return transfer instanceof FileDownload
@ -40,8 +44,11 @@ export class TransfersMenuComponent {
if (this.transfers.some(x => !x.isComplete())) {
if ((await this.platform.showMessageBox({
type: 'warning',
message: 'There are active file transfers',
buttons: ['Abort all', 'Do not abort'],
message: this.translate.instant('There are active file transfers'),
buttons: [
this.translate.instant('Abort all'),
this.translate.instant('Do not abort'),
],
defaultId: 1,
cancelId: 1,
})).response === 1) {

View file

@ -1,13 +1,18 @@
.modal-body
.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')
button.btn.btn-link(ngbDropdownToggle, (click)='$event.stopPropagation()')
span(*ngIf='rememberFor') Remember for {{getRememberForDisplay(rememberFor)}}
span(*ngIf='!rememberFor') Do not remember
span(
*ngIf='rememberFor',
translate,
[translateParams]='{time: getRememberForDisplay(rememberFor)}'
) Remember for {time}
span(*ngIf='!rememberFor', translate) Do not remember
div(ngbDropdownMenu)
button.dropdown-item(
(click)='rememberFor = 0',
translate
) Do not remember
button.dropdown-item(
*ngFor='let x of rememberOptions',

View file

@ -4,21 +4,21 @@
h1.tabby-title Tabby
sup α
.text-center.mb-5 Thank you for downloading Tabby!
.text-center.mb-5(translate) Thank you for downloading Tabby!
.form-line
.header
.title Enable analytics
.description Help track the number of Tabby installs across the world!
.title(translate) Enable analytics
.description(translate) Help track the number of Tabby installs across the world!
toggle([(ngModel)]='config.store.enableAnalytics')
.form-line
.header
.title Enable global hotkey (#[strong Ctrl-Space])
.description Toggles the Tabby window visibility
.title(translate) Enable global hotkey (Ctrl-Space)
.description(translate) Toggles the Tabby window visibility
toggle([(ngModel)]='enableGlobalHotkey')
.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

View file

@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { Component } from '@angular/core'
import { TranslateService } from '@ngx-translate/core'
import { BaseTabComponent } from './baseTab.component'
import { ConfigService } from '../services/config.service'
import { HostWindowService } from '../api/hostWindow'
@ -16,9 +17,10 @@ export class WelcomeTabComponent extends BaseTabComponent {
constructor (
private hostWindow: HostWindowService,
public config: ConfigService,
translate: TranslateService,
) {
super()
this.setTitle('Welcome')
this.setTitle(translate.instant('Welcome'))
}
async closeAndDisable () {

View file

@ -38,3 +38,4 @@ enableExperimentalFeatures: false
pluginBlacklist: []
hacks:
disableGPU: false
language: null

View file

@ -1,4 +1,5 @@
import { Injectable } from '@angular/core'
import { TranslateService } from '@ngx-translate/core'
import { ProfilesService } from './services/profiles.service'
import { HotkeyDescription, HotkeyProvider } from './api/hotkeyProvider'
import { PartialProfile, Profile } from './api'
@ -9,188 +10,189 @@ export class AppHotkeyProvider extends HotkeyProvider {
hotkeys: HotkeyDescription[] = [
{
id: 'profile-selector',
name: 'Show profile selector',
name: this.translate.instant('Show profile selector'),
},
{
id: 'toggle-fullscreen',
name: 'Toggle fullscreen mode',
name: this.translate.instant('Toggle fullscreen mode'),
},
{
id: 'rename-tab',
name: 'Rename Tab',
name: this.translate.instant('Rename Tab'),
},
{
id: 'close-tab',
name: 'Close tab',
name: this.translate.instant('Close tab'),
},
{
id: 'reopen-tab',
name: 'Reopen last tab',
name: this.translate.instant('Reopen last tab'),
},
{
id: 'toggle-last-tab',
name: 'Toggle last tab',
name: this.translate.instant('Toggle last tab'),
},
{
id: 'next-tab',
name: 'Next tab',
name: this.translate.instant('Next tab'),
},
{
id: 'previous-tab',
name: 'Previous tab',
name: this.translate.instant('Previous tab'),
},
{
id: 'move-tab-left',
name: 'Move tab to the left',
name: this.translate.instant('Move tab to the left'),
},
{
id: 'move-tab-right',
name: 'Move tab to the right',
name: this.translate.instant('Move tab to the right'),
},
{
id: 'rearrange-panes',
name: 'Show pane labels (for rearranging)',
name: this.translate.instant('Show pane labels (for rearranging)'),
},
{
id: 'duplicate-tab',
name: 'Duplicate tab',
name: this.translate.instant('Duplicate tab'),
},
{
id: 'tab-1',
name: 'Tab 1',
name: this.translate.instant('Tab 1'),
},
{
id: 'tab-2',
name: 'Tab 2',
name: this.translate.instant('Tab 2'),
},
{
id: 'tab-3',
name: 'Tab 3',
name: this.translate.instant('Tab 3'),
},
{
id: 'tab-4',
name: 'Tab 4',
name: this.translate.instant('Tab 4'),
},
{
id: 'tab-5',
name: 'Tab 5',
name: this.translate.instant('Tab 5'),
},
{
id: 'tab-6',
name: 'Tab 6',
name: this.translate.instant('Tab 6'),
},
{
id: 'tab-7',
name: 'Tab 7',
name: this.translate.instant('Tab 7'),
},
{
id: 'tab-8',
name: 'Tab 8',
name: this.translate.instant('Tab 8'),
},
{
id: 'tab-9',
name: 'Tab 9',
name: this.translate.instant('Tab 9'),
},
{
id: 'tab-10',
name: 'Tab 10',
name: this.translate.instant('Tab 10'),
},
{
id: 'tab-11',
name: 'Tab 11',
name: this.translate.instant('Tab 11'),
},
{
id: 'tab-12',
name: 'Tab 12',
name: this.translate.instant('Tab 12'),
},
{
id: 'tab-13',
name: 'Tab 13',
name: this.translate.instant('Tab 13'),
},
{
id: 'tab-14',
name: 'Tab 14',
name: this.translate.instant('Tab 14'),
},
{
id: 'tab-15',
name: 'Tab 15',
name: this.translate.instant('Tab 15'),
},
{
id: 'tab-16',
name: 'Tab 16',
name: this.translate.instant('Tab 16'),
},
{
id: 'tab-17',
name: 'Tab 17',
name: this.translate.instant('Tab 17'),
},
{
id: 'tab-18',
name: 'Tab 18',
name: this.translate.instant('Tab 18'),
},
{
id: 'tab-19',
name: 'Tab 19',
name: this.translate.instant('Tab 19'),
},
{
id: 'tab-20',
name: 'Tab 20',
name: this.translate.instant('Tab 20'),
},
{
id: 'split-right',
name: 'Split to the right',
name: this.translate.instant('Split to the right'),
},
{
id: 'split-bottom',
name: 'Split to the bottom',
name: this.translate.instant('Split to the bottom'),
},
{
id: 'split-left',
name: 'Split to the left',
name: this.translate.instant('Split to the left'),
},
{
id: 'split-top',
name: 'Split to the top',
name: this.translate.instant('Split to the top'),
},
{
id: 'pane-maximize',
name: 'Maximize the active pane',
name: this.translate.instant('Maximize the active pane'),
},
{
id: 'pane-nav-up',
name: 'Focus the pane above',
name: this.translate.instant('Focus the pane above'),
},
{
id: 'pane-nav-down',
name: 'Focus the pane below',
name: this.translate.instant('Focus the pane below'),
},
{
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',
name: 'Focus the pane on the right',
name: this.translate.instant('Focus the pane on the right'),
},
{
id: 'pane-nav-previous',
name: 'Focus previous pane',
name: this.translate.instant('Focus previous pane'),
},
{
id: 'pane-nav-next',
name: 'Focus next pane',
name: this.translate.instant('Focus next pane'),
},
{
id: 'switch-profile',
name: 'Switch profile in the active pane',
name: this.translate.instant('Switch profile in the active pane'),
},
{
id: 'close-pane',
name: 'Close focused pane',
name: this.translate.instant('Close focused pane'),
},
]
constructor (
private profilesService: ProfilesService,
private translate: TranslateService,
) { super() }
async provide (): Promise<HotkeyDescription[]> {

View file

@ -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 { BrowserAnimationsModule } from '@angular/platform-browser/animations'
import { FormsModule } from '@angular/forms'
@ -7,6 +7,8 @@ import { PerfectScrollbarModule, PERFECT_SCROLLBAR_CONFIG } from 'ngx-perfect-sc
import { NgxFilesizeModule } from 'ngx-filesize'
import { SortablejsModule } from 'ngx-sortablejs'
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 { CheckboxComponent } from './components/checkbox.component'
@ -40,6 +42,7 @@ import { AppService } from './services/app.service'
import { ConfigService } from './services/config.service'
import { VaultFileProvider } from './services/vault.service'
import { HotkeysService } from './services/hotkeys.service'
import { LocaleService, TranslateServiceWrapper } from './services/locale.service'
import { StandardTheme, StandardCompactTheme, PaperTheme } from './theme'
import { CoreConfigProvider } from './config'
@ -51,6 +54,10 @@ import { SplitLayoutProfilesService } from './profiles'
import 'perfect-scrollbar/css/perfect-scrollbar.css'
export function TranslateMessageFormatCompilerFactory (): TranslateMessageFormatCompiler {
return new TranslateMessageFormatCompiler()
}
const PROVIDERS = [
{ provide: HotkeyProvider, useClass: AppHotkeyProvider, multi: true },
{ provide: Theme, useClass: StandardTheme, multi: true },
@ -68,6 +75,19 @@ const PROVIDERS = [
{ provide: FileProvider, useClass: VaultFileProvider, multi: true },
{ provide: ToolbarButtonProvider, useClass: ButtonProvider, multi: true },
{ provide: ProfileProvider, useExisting: SplitLayoutProfilesService, multi: true },
{
provide: LOCALE_ID,
deps: [LocaleService],
useFactory: locale => locale.getLocale(),
},
{
provide: MESSAGE_FORMAT_CONFIG,
useValue: LocaleService.allLocales,
},
{
provide: TranslateService,
useClass: TranslateServiceWrapper,
},
]
/** @hidden */
@ -81,6 +101,7 @@ const PROVIDERS = [
PerfectScrollbarModule,
DragDropModule,
SortablejsModule.forRoot({ animation: 150 }),
TranslateModule,
],
declarations: [
AppRootComponent,
@ -127,6 +148,7 @@ const PROVIDERS = [
AlwaysVisibleTypeaheadDirective,
SortablejsModule,
DragDropModule,
TranslateModule,
],
})
export default class AppModule { // eslint-disable-line @typescript-eslint/no-extraneous-class
@ -135,6 +157,8 @@ export default class AppModule { // eslint-disable-line @typescript-eslint/no-ex
config: ConfigService,
platform: PlatformService,
hotkeys: HotkeysService,
public locale: LocaleService,
private translate: TranslateService,
private profilesService: ProfilesService,
private selector: SelectorService,
) {
@ -182,8 +206,8 @@ export default class AppModule { // eslint-disable-line @typescript-eslint/no-ex
if (provider.supportsQuickConnect) {
options.push({
name: 'Quick connect',
freeInputPattern: 'Connect to "%s"...',
name: this.translate.instant('Quick connect'),
freeInputPattern: this.translate.instant('Connect to "%s"...'),
icon: 'fas fa-arrow-right',
callback: query => {
const p = provider.quickConnect(query)
@ -194,13 +218,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> {
const translateModule = TranslateModule.forRoot({
defaultLanguage: 'en',
compiler: {
provide: TranslateCompiler,
useFactory: TranslateMessageFormatCompilerFactory,
},
})
return {
ngModule: AppModule,
providers: PROVIDERS,
providers: [
...PROVIDERS,
...translateModule.providers!.filter(x => x !== TranslateService),
],
}
}
}

View file

@ -1,6 +1,7 @@
import slugify from 'slugify'
import { v4 as uuidv4 } from 'uuid'
import { Injectable } from '@angular/core'
import { TranslateService } from '@ngx-translate/core'
import { ConfigService, NewTabParameters, PartialProfile, Profile, ProfileProvider } from './api'
import { SplitTabComponent, SplitTabRecoveryProvider } from './components/splitTab.component'
@ -15,7 +16,7 @@ export interface SplitLayoutProfile extends Profile {
@Injectable({ providedIn: 'root' })
export class SplitLayoutProfilesService extends ProfileProvider<SplitLayoutProfile> {
id = 'split-layout'
name = 'Saved layout'
name = this.translate.instant('Saved layout')
configDefaults = {
options: {
recoveryToken: null,
@ -25,6 +26,7 @@ export class SplitLayoutProfilesService extends ProfileProvider<SplitLayoutProfi
constructor (
private splitTabRecoveryProvider: SplitTabRecoveryProvider,
private config: ConfigService,
private translate: TranslateService,
) {
super()
}

View file

@ -4,6 +4,7 @@ import { v4 as uuidv4 } from 'uuid'
import * as yaml from 'js-yaml'
import { Observable, Subject, AsyncSubject } from 'rxjs'
import { Injectable, Inject } from '@angular/core'
import { TranslateService } from '@ngx-translate/core'
import { ConfigProvider } from '../api/configProvider'
import { PlatformService } from '../api/platform'
import { HostAppService } from '../api/hostApp'
@ -136,6 +137,7 @@ export class ConfigService {
private hostApp: HostAppService,
private platform: PlatformService,
private vault: VaultService,
private translate: TranslateService,
@Inject(ConfigProvider) private configProviders: ConfigProvider[],
) {
this.defaults = this.mergeDefaults()
@ -360,9 +362,13 @@ export class ConfigService {
} catch (e) {
let result = await this.platform.showMessageBox({
type: 'error',
message: 'Could not decrypt config',
message: this.translate.instant('Could not decrypt config'),
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,
})
if (result.response === 2) {
@ -371,9 +377,12 @@ export class ConfigService {
if (result.response === 1) {
result = await this.platform.showMessageBox({
type: 'warning',
message: 'Are you sure?',
message: this.translate.instant('Are you sure?'),
detail: e.toString(),
buttons: ['Erase config', 'Quit'],
buttons: [
this.translate.instant('Erase config'),
this.translate.instant('Quit'),
],
defaultId: 1,
cancelId: 1,
})

View file

@ -1,4 +1,5 @@
import { Inject, Injectable } from '@angular/core'
import { TranslateService } from '@ngx-translate/core'
import { FileProvider, NotificationsService, SelectorService } from '../api'
@Injectable({ providedIn: 'root' })
@ -7,6 +8,7 @@ export class FileProvidersService {
private constructor (
private selector: SelectorService,
private notifications: NotificationsService,
private translate: TranslateService,
@Inject(FileProvider) private fileProviders: FileProvider[],
) { }
@ -34,15 +36,18 @@ export class FileProvidersService {
}
}))
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')
}
if (providers.length === 1) {
return providers[0]
}
return this.selector.show('Select file storage', providers.map(p => ({
return this.selector.show(
this.translate.instant('Select file storage'),
providers.map(p => ({
name: p.name,
result: p,
})))
}))
)
}
}

View file

@ -0,0 +1,134 @@
import { Injectable } from '@angular/core'
import { registerLocaleData } from '@angular/common'
import { TranslateService } from '@ngx-translate/core'
import localeEN from '@angular/common/locales/en-GB'
import localeRU from '@angular/common/locales/ru'
import { Observable, Subject } from 'rxjs'
import { distinctUntilChanged } from 'rxjs/operators'
import { ConfigService } from './config.service'
import { LogService, Logger } from './log.service'
registerLocaleData(localeEN)
registerLocaleData(localeRU)
@Injectable({ providedIn: 'root' })
export class TranslateServiceWrapper extends TranslateService {
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
getParsedResult (translations: any, key: any, interpolateParams?: any): any {
this.translations[this.defaultLang][key] ??= this.compiler.compile(key, this.defaultLang)
return super.getParsedResult(translations, key, interpolateParams)
}
}
@Injectable({ providedIn: 'root' })
export class LocaleService {
private logger: Logger
static readonly allLocales = ['en', 'de', 'fr', 'ru']
get localeChanged$ (): Observable<string> {
return this.localeChanged.pipe(distinctUntilChanged())
}
get catalogChanged$ (): Observable<Record<string, string | undefined>> {
return this.catalogChanged.pipe(distinctUntilChanged())
}
readonly allLanguages: { code: string, name: string }[]
private translations = {
en: {
Close: 'Close',
},
ru: {
Close: 'Закрыть',
},
}
private locale = 'en'
private localeChanged = new Subject<string>()
private catalogChanged = new Subject<Record<string, string | undefined>>()
constructor (
private config: ConfigService,
private translate: TranslateService,
log: LogService,
) {
this.logger = log.create('translate')
config.changed$.subscribe(() => {
this.refresh()
})
config.ready$.subscribe(() => {
this.refresh()
})
this.allLanguages = [
{
code: 'en',
name: translate.instant('English'),
},
{
code: 'de',
name: translate.instant('German'),
},
{
code: 'fr',
name: translate.instant('French'),
},
/* {
code: 'it',
name: translate.instant('Italian'),
},
{
code: 'es',
name: translate.instant('Spanish'),
}, */
{
code: 'ru',
name: translate.instant('Russian'),
},
/* {
code: 'ar',
name: translate.instant('Arabic'),
}, */
]
}
refresh (): void {
let lang = this.config.store.language
if (!lang) {
const systemLanguage = navigator.language.toLowerCase().split('-')[0]
if (this.allLanguages.some(x => x.code === systemLanguage)) {
lang = systemLanguage
}
}
lang ??= 'en'
this.setLocale(lang)
}
async setLocale (lang: string): Promise<void> {
const strings = this.translations[lang]
if (!this.translate.langs.includes(lang)) {
this.translate.addLangs([lang])
const po = require(`../../../locale/${lang}.po`).translations['']
const translation = {}
for (const k of Object.keys(po)) {
translation[k] = po[k].msgstr[0] || k
}
this.translate.setTranslation(lang, translation)
}
this.translate.setDefaultLang(lang)
this.locale = lang
this.localeChanged.next(lang)
this.logger.debug('Setting language to', lang)
this.catalogChanged.next(strings)
}
getLocale (): string {
return this.locale
}
}

View file

@ -1,4 +1,5 @@
import { Injectable, Inject } from '@angular/core'
import { TranslateService } from '@ngx-translate/core'
import { NewTabParameters } from './tabs.service'
import { BaseTabComponent } from '../components/baseTab.component'
import { PartialProfile, Profile, ProfileProvider } from '../api/profileProvider'
@ -29,6 +30,7 @@ export class ProfilesService {
private config: ConfigService,
private notifications: NotificationsService,
private selector: SelectorService,
private translate: TranslateService,
@Inject(ProfileProvider) private profileProviders: ProfileProvider<Profile>[],
) { }
@ -103,7 +105,7 @@ export class ProfilesService {
let options: SelectorOption<void>[] = recentProfiles.map(p => ({
...this.selectorOptionForProfile(p),
group: 'Recent',
group: this.translate.instant('Recent'),
icon: 'fas fa-history',
color: p.color,
callback: async () => {
@ -115,8 +117,8 @@ export class ProfilesService {
}))
if (recentProfiles.length) {
options.push({
name: 'Clear recent profiles',
group: 'Recent',
name: this.translate.instant('Clear recent profiles'),
group: this.translate.instant('Recent'),
icon: 'fas fa-eraser',
callback: async () => {
window.localStorage.removeItem('recentProfiles')
@ -142,7 +144,7 @@ export class ProfilesService {
try {
const { SettingsTabComponent } = window['nodeRequire']('tabby-settings')
options.push({
name: 'Manage profiles',
name: this.translate.instant('Manage profiles'),
icon: 'fas fa-window-restore',
callback: () => {
this.app.openNewTabRaw({
@ -156,8 +158,8 @@ export class ProfilesService {
if (this.getProviders().some(x => x.supportsQuickConnect)) {
options.push({
name: 'Quick connect',
freeInputPattern: 'Connect to "%s"...',
name: this.translate.instant('Quick connect'),
freeInputPattern: this.translate.instant('Connect to "%s"...'),
icon: 'fas fa-arrow-right',
callback: query => {
const profile = this.quickConnect(query)
@ -165,7 +167,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) {
reject(err)
}

View file

@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { Injectable } from '@angular/core'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { TranslateService } from '@ngx-translate/core'
import { Subscription } from 'rxjs'
import { AppService } from './services/app.service'
import { BaseTabComponent } from './components/baseTab.component'
@ -22,6 +23,7 @@ export class TabManagementContextMenu extends TabContextMenuItemProvider {
constructor (
private app: AppService,
private translate: TranslateService,
) {
super()
}
@ -29,7 +31,7 @@ export class TabManagementContextMenu extends TabContextMenuItemProvider {
async getItems (tab: BaseTabComponent, tabHeader?: TabHeaderComponent): Promise<MenuItemOptions[]> {
let items: MenuItemOptions[] = [
{
label: 'Close',
label: this.translate.instant('Close'),
click: () => {
if (this.app.tabs.includes(tab)) {
this.app.closeTab(tab, true)
@ -43,7 +45,7 @@ export class TabManagementContextMenu extends TabContextMenuItemProvider {
items = [
...items,
{
label: 'Close other tabs',
label: this.translate.instant('Close other tabs'),
click: () => {
for (const t of this.app.tabs.filter(x => x !== tab)) {
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: () => {
for (const t of this.app.tabs.slice(this.app.tabs.indexOf(tab) + 1)) {
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: () => {
for (const t of this.app.tabs.slice(0, this.app.tabs.indexOf(tab))) {
this.app.closeTab(t, true)
@ -71,13 +73,13 @@ export class TabManagementContextMenu extends TabContextMenuItemProvider {
if (tab.parent instanceof SplitTabComponent) {
const directions: SplitDirection[] = ['r', 'b', 'l', 't']
items.push({
label: 'Split',
label: this.translate.instant('Split'),
submenu: directions.map(dir => ({
label: {
r: 'Right',
b: 'Down',
l: 'Left',
t: 'Up',
r: this.translate.instant('Right'),
b: this.translate.instant('Down'),
l: this.translate.instant('Left'),
t: this.translate.instant('Up'),
}[dir],
click: () => {
(tab.parent as SplitTabComponent).splitTab(tab, dir)
@ -99,6 +101,7 @@ export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
private app: AppService,
private ngbModal: NgbModal,
private splitLayoutProfilesService: SplitLayoutProfilesService,
private translate: TranslateService,
) {
super()
}
@ -109,18 +112,18 @@ export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
items = [
...items,
{
label: 'Rename',
label: this.translate.instant('Rename'),
click: () => tabHeader.showRenameTabModal(),
},
{
label: 'Duplicate',
label: this.translate.instant('Duplicate'),
click: () => this.app.duplicateTab(tab),
},
{
label: 'Color',
label: this.translate.instant('Color'),
sublabel: TAB_COLORS.find(x => x.value === tab.color)?.name,
submenu: TAB_COLORS.map(color => ({
label: color.name,
label: this.translate.instant(color.name),
type: 'radio',
checked: tab.color === color.value,
click: () => {
@ -132,10 +135,10 @@ export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
if (tab instanceof SplitTabComponent && tab.getAllTabs().length > 1) {
items.push({
label: 'Save layout as profile',
label: this.translate.instant('Save layout as profile'),
click: async () => {
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
if (!name) {
return
@ -154,6 +157,7 @@ export class CommonOptionsContextMenu extends TabContextMenuItemProvider {
export class TaskCompletionContextMenu extends TabContextMenuItemProvider {
constructor (
private app: AppService,
private translate: TranslateService,
) {
super()
}
@ -167,10 +171,10 @@ export class TaskCompletionContextMenu extends TabContextMenuItemProvider {
if (process) {
items.push({
enabled: false,
label: 'Current process: ' + process.name,
label: this.translate.instant('Current process: {name}', process),
})
items.push({
label: 'Notify when done',
label: this.translate.instant('Notify when done'),
type: 'checkbox',
checked: extTab.__completionNotificationEnabled,
click: () => {
@ -178,7 +182,7 @@ export class TaskCompletionContextMenu extends TabContextMenuItemProvider {
if (extTab.__completionNotificationEnabled) {
this.app.observeTabCompletion(tab).subscribe(() => {
new Notification('Process completed', {
new Notification(this.translate.instant('Process completed'), {
body: process.name,
}).addEventListener('click', () => {
this.app.selectTab(tab)
@ -192,7 +196,7 @@ export class TaskCompletionContextMenu extends TabContextMenuItemProvider {
})
}
items.push({
label: 'Notify on activity',
label: this.translate.instant('Notify on activity'),
type: 'checkbox',
checked: !!extTab.__outputNotificationSubscription,
click: () => {
@ -204,7 +208,7 @@ export class TaskCompletionContextMenu extends TabContextMenuItemProvider {
if (extTab.__outputNotificationSubscription && active) {
extTab.__outputNotificationSubscription.unsubscribe()
extTab.__outputNotificationSubscription = null
new Notification('Tab activity', {
new Notification(this.translate.instant('Tab activity'), {
body: tab.title,
}).addEventListener('click', () => {
this.app.selectTab(tab)
@ -228,6 +232,7 @@ export class ProfilesContextMenu extends TabContextMenuItemProvider {
private profilesService: ProfilesService,
private tabsService: TabsService,
private app: AppService,
private translate: TranslateService,
hotkeys: HotkeysService,
) {
super()
@ -270,7 +275,7 @@ export class ProfilesContextMenu extends TabContextMenuItemProvider {
if (!tabHeader && tab.parent instanceof SplitTabComponent && tab.parent.getAllTabs().length > 1) {
return [
{
label: 'Switch profile',
label: this.translate.instant('Switch profile'),
click: () => this.switchTabProfile(tab),
},
]

View file

@ -1,28 +1,41 @@
import { Injectable } from '@angular/core'
import { TranslateService } from '@ngx-translate/core'
import { Theme } from './api'
/** @hidden */
@Injectable()
export class StandardTheme extends Theme {
name = 'Standard'
name = this.translate.instant('Standard')
css = require('./theme.scss')
terminalBackground = '#222a33'
constructor (private translate: TranslateService) {
super()
}
}
/** @hidden */
@Injectable()
export class StandardCompactTheme extends Theme {
name = 'Compact'
name = this.translate.instant('Compact')
css = require('./theme.compact.scss')
terminalBackground = '#222a33'
macOSWindowButtonsInsetX = 8
macOSWindowButtonsInsetY = 6
constructor (private translate: TranslateService) {
super()
}
}
/** @hidden */
@Injectable()
export class PaperTheme extends Theme {
name = 'Paper'
name = this.translate.instant('Paper')
css = require('./theme.paper.scss')
terminalBackground = '#f7f1e0'
constructor (private translate: TranslateService) {
super()
}
}

View file

@ -1,5 +1,6 @@
import * as os from 'os'
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_STABLE = 18309
@ -56,13 +57,13 @@ export class ResettableTimeout {
}
export const TAB_COLORS = [
{ name: 'No color', value: null },
{ name: 'Blue', value: '#0275d8' },
{ name: 'Green', value: '#5cb85c' },
{ name: 'Orange', value: '#f0ad4e' },
{ name: 'Purple', value: '#613d7c' },
{ name: 'Red', value: '#d9534f' },
{ name: 'Yellow', value: '#ffd500' },
{ name: _('No color'), value: null },
{ name: _('Blue'), value: '#0275d8' },
{ name: _('Green'), value: '#5cb85c' },
{ name: _('Orange'), value: '#f0ad4e' },
{ name: _('Purple'), value: '#613d7c' },
{ name: _('Red'), value: '#d9534f' },
{ name: _('Yellow'), value: '#ffd500' },
]
export function serializeFunction <T extends () => Promise<any>> (fn: T): T {

View file

@ -2,6 +2,13 @@
# 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:
version "6.0.2"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
@ -56,6 +63,37 @@ js-yaml@^4.0.0:
dependencies:
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:
version "0.13.0"
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"
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:
version "1.5.0"
resolved "https://registry.yarnpkg.com/perfect-scrollbar/-/perfect-scrollbar-1.5.0.tgz#821d224ed8ff61990c23f26db63048cdc75b6b83"
@ -116,11 +161,21 @@ string_decoder@^1.1.1:
dependencies:
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:
version "2.1.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a"
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:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"

View file

@ -1,5 +1,5 @@
import { Injectable } from '@angular/core'
import { HotkeyDescription, HotkeyProvider } from 'tabby-core'
import { HotkeyDescription, HotkeyProvider, TranslateService } from 'tabby-core'
/** @hidden */
@Injectable()
@ -7,14 +7,16 @@ export class ElectronHotkeyProvider extends HotkeyProvider {
hotkeys: HotkeyDescription[] = [
{
id: 'new-window',
name: 'New window',
name: this.translate.instant('New window'),
},
{
id: 'toggle-window',
name: 'Toggle terminal window',
name: this.translate.instant('Toggle terminal window'),
},
]
constructor (private translate: TranslateService) { super() }
async provide (): Promise<HotkeyDescription[]> {
return this.hotkeys
}

View file

@ -7,7 +7,7 @@ import { promisify } from 'util'
import promiseIpc, { RendererProcessType } from 'electron-promise-ipc'
import { execFile } from 'mz/child_process'
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 { ElectronHostWindow } from './hostWindow.service'
import { ShellIntegrationService } from './shellIntegration.service'
@ -34,6 +34,7 @@ export class ElectronPlatformService extends PlatformService {
private electron: ElectronService,
private zone: NgZone,
private shellIntegration: ShellIntegrationService,
private translate: TranslateService,
) {
super()
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(
this.hostWindow.getWindow(),
{
buttonLabel: 'Select',
buttonLabel: this.translate.instant('Select'),
properties,
},
)

View file

@ -2,7 +2,7 @@ import type { AppUpdater } from 'electron-updater'
import { Injectable } from '@angular/core'
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'
const UPDATES_URL = 'https://api.github.com/repos/eugeny/tabby/releases/latest'
@ -18,6 +18,7 @@ export class ElectronUpdaterService extends UpdaterService {
constructor (
log: LogService,
config: ConfigService,
private translate: TranslateService,
private platform: PlatformService,
private electron: ElectronService,
) {
@ -132,8 +133,11 @@ export class ElectronUpdaterService extends UpdaterService {
if ((await this.platform.showMessageBox(
{
type: 'warning',
message: 'Installing the update will close all tabs and restart Tabby.',
buttons: ['Update', 'Cancel'],
message: this.translate.instant('Installing the update will close all tabs and restart Tabby.'),
buttons: [
this.translate.instant('Update'),
this.translate.instant('Cancel'),
],
defaultId: 0,
cancelId: 1,
}

View file

@ -1,5 +1,5 @@
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 { LinkHandler } from './api'
@ -9,6 +9,7 @@ export class LinkHighlighterDecorator extends TerminalDecorator {
constructor (
private config: ConfigService,
private platform: PlatformService,
private translate: TranslateService,
@Inject(LinkHandler) private handlers: LinkHandler[],
) {
super()
@ -42,13 +43,13 @@ export class LinkHighlighterDecorator extends TerminalDecorator {
this.platform.popupContextMenu([
{
click: () => openLink(uri),
label: 'Open',
label: this.translate.instant('Open'),
},
{
click: async () => {
this.platform.setClipboard({ text: await getLink(uri) })
},
label: 'Copy',
label: this.translate.instant('Copy'),
},
])
return false

View file

@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { Injectable } from '@angular/core'
import { ToolbarButtonProvider, ToolbarButton } from 'tabby-core'
import { ToolbarButtonProvider, ToolbarButton, TranslateService } from 'tabby-core'
import { TerminalService } from './services/terminal.service'
/** @hidden */
@ -8,6 +8,7 @@ import { TerminalService } from './services/terminal.service'
export class ButtonProvider extends ToolbarButtonProvider {
constructor (
private terminal: TerminalService,
private translate: TranslateService,
) {
super()
}
@ -16,7 +17,7 @@ export class ButtonProvider extends ToolbarButtonProvider {
return [
{
icon: require('./icons/plus.svg'),
title: 'New terminal',
title: this.translate.instant('New terminal'),
touchBarNSImage: 'NSTouchBarAddDetailTemplate',
click: () => {
this.terminal.openTab()

View file

@ -1,6 +1,6 @@
ng-container(*ngIf='!argvMode')
.form-group
label Command line
label(translate) Command line
.input-group
.input-group-prepend
a.input-group-text(
@ -16,7 +16,7 @@ ng-container(*ngIf='!argvMode')
ng-container(*ngIf='argvMode')
.form-group
label Program
label(translate) Program
.input-group
.input-group-prepend
a.input-group-text(
@ -31,7 +31,7 @@ ng-container(*ngIf='argvMode')
)
.form-group
label Arguments
label(translate) Arguments
.input-group(
*ngFor='let arg of _model.args; index as i; trackBy: trackByIndex',
)
@ -46,4 +46,4 @@ ng-container(*ngIf='argvMode')
.mt-2
button.btn.btn-secondary((click)='_model.args.push("")')
i.fas.fa-plus.mr-2
| Add
span(translate) Add

View file

@ -11,10 +11,10 @@
.d-flex
button.btn.btn-secondary((click)='addEnvironmentVar()')
i.fas.fa-plus.mr-2
span Add
span(translate) Add
.ml-auto
.text-muted Substitutions allowed.
.text-muted(translate) Substitutions allowed.
.d-flex.ml-1(*ngIf='shouldShowExample()')
.text-muted Example:
.text-muted(translate) Example:
a.ml-1((click)='addExample()', href='#') extend PATH

View file

@ -2,13 +2,13 @@ command-line-editor([model]='profile.options')
.form-line(*ngIf='uac.isAvailable')
.header
.title Run as administrator
.title(translate) Run as administrator
toggle(
[(ngModel)]='profile.options.runAsAdministrator',
)
.form-group
label Working directory
label(translate) Working directory
.input-group
input.form-control(
@ -21,7 +21,7 @@ command-line-editor([model]='profile.options')
i.fas.fa-folder-open
.form-group
label Environment
label(translate) Environment
environment-editor(
type='text',
[(model)]='profile.options.env',

View file

@ -1,9 +1,9 @@
h3.mb-3 Shell
h3.mb-3(translate) Shell
.form-line(*ngIf='isConPTYAvailable')
.header
.title Use ConPTY
.description Enables the experimental Windows ConPTY API
.title(translate) Use ConPTY
.description(translate) Enables the experimental Windows ConPTY API
toggle(
[(ngModel)]='config.store.terminal.useConPTY',
@ -11,7 +11,7 @@ h3.mb-3 Shell
)
.alert.alert-info.d-flex.align-items-center(*ngIf='config.store.terminal.useConPTY && isConPTYAvailable && !isConPTYStable')
.mr-auto Windows 10 build 18309 or above is recommended for ConPTY
.mr-auto(translate) Windows 10 build 18309 or above is recommended for ConPTY
.alert.alert-info.d-flex.align-items-center(*ngIf='config.store.terminal.profile.startsWith("WSL") && (!config.store.terminal.useConPTY)')
.mr-auto WSL terminal only supports TrueColor with ConPTY
.mr-auto(translate) WSL terminal only supports TrueColor with ConPTY

View file

@ -1,5 +1,5 @@
import { Component, Input, Injector } from '@angular/core'
import { BaseTabProcess, WIN_BUILD_CONPTY_SUPPORTED, isWindowsBuild } from 'tabby-core'
import { BaseTabProcess, WIN_BUILD_CONPTY_SUPPORTED, isWindowsBuild, TranslateService } from 'tabby-core'
import { BaseTerminalTabComponent } from 'tabby-terminal'
import { LocalProfile, SessionOptions } from '../api'
import { Session } from '../session'
@ -20,6 +20,7 @@ export class TerminalTabComponent extends BaseTerminalTabComponent {
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
constructor (
injector: Injector,
private translate: TranslateService,
private uac: UACService,
) {
super(injector)
@ -108,8 +109,14 @@ export class TerminalTabComponent extends BaseTerminalTabComponent {
return (await this.platform.showMessageBox(
{
type: 'warning',
message: `"${children[0].command}" is still running. Close?`,
buttons: ['Kill', 'Cancel'],
message: this.translate.instant(
'"{command}" is still running. Close?',
children[0],
),
buttons: [
this.translate.instant('Kill'),
this.translate.instant('Cancel'),
],
defaultId: 0,
cancelId: 1,
}

View file

@ -1,5 +1,5 @@
import { Injectable } from '@angular/core'
import { HotkeyDescription, HotkeyProvider } from 'tabby-core'
import { HotkeyDescription, HotkeyProvider, TranslateService } from 'tabby-core'
/** @hidden */
@Injectable()
@ -7,10 +7,12 @@ export class LocalTerminalHotkeyProvider extends HotkeyProvider {
hotkeys: HotkeyDescription[] = [
{
id: 'new-tab',
name: 'New tab',
name: this.translate.instant('New tab'),
},
]
constructor (private translate: TranslateService) { super() }
async provide (): Promise<HotkeyDescription[]> {
return this.hotkeys
}

View file

@ -1,6 +1,6 @@
import deepClone from 'clone-deep'
import { Injectable, Inject } from '@angular/core'
import { ProfileProvider, NewTabParameters, ConfigService, SplitTabComponent, AppService, PartialProfile } from 'tabby-core'
import { ProfileProvider, NewTabParameters, ConfigService, SplitTabComponent, AppService, PartialProfile, TranslateService } from 'tabby-core'
import { TerminalTabComponent } from './components/terminalTab.component'
import { LocalProfileSettingsComponent } from './components/localProfileSettings.component'
import { ShellProvider, Shell, SessionOptions, LocalProfile } from './api'
@ -8,7 +8,7 @@ import { ShellProvider, Shell, SessionOptions, LocalProfile } from './api'
@Injectable({ providedIn: 'root' })
export class LocalProfilesService extends ProfileProvider<LocalProfile> {
id = 'local'
name = 'Local'
name = this.translate.instant('Local terminal')
settingsComponent = LocalProfileSettingsComponent
configDefaults = {
options: {
@ -29,6 +29,7 @@ export class LocalProfilesService extends ProfileProvider<LocalProfile> {
constructor (
private app: AppService,
private config: ConfigService,
private translate: TranslateService,
@Inject(ShellProvider) private shellProviders: ShellProvider[],
) {
super()

View file

@ -1,5 +1,5 @@
import { NgZone, Injectable } from '@angular/core'
import { ConfigService, HostAppService, Platform, ProfilesService } from 'tabby-core'
import { ConfigService, HostAppService, Platform, ProfilesService, TranslateService } from 'tabby-core'
import { ElectronService } from 'tabby-electron'
/** @hidden */
@ -13,6 +13,7 @@ export class DockMenuService {
private hostApp: HostAppService,
private zone: NgZone,
private profilesService: ProfilesService,
private translate: TranslateService,
) {
config.changed$.subscribe(() => this.update())
}
@ -21,7 +22,7 @@ export class DockMenuService {
if (this.hostApp.platform === Platform.Windows) {
this.electron.app.setJumpList(this.config.store.profiles.length ? [{
type: 'custom',
name: 'Profiles',
name: this.translate.instant('Profiles'),
items: this.config.store.profiles.map(profile => ({
type: 'task',
program: process.execPath,

View file

@ -1,6 +1,6 @@
import * as fs from 'mz/fs'
import { Injectable } from '@angular/core'
import { HostAppService, Platform, LogService, Logger } from 'tabby-core'
import { HostAppService, Platform, LogService, Logger, TranslateService } from 'tabby-core'
import { ShellProvider, Shell } from '../api'
@ -11,6 +11,7 @@ export class LinuxDefaultShellProvider extends ShellProvider {
constructor (
private hostApp: HostAppService,
private translate: TranslateService,
log: LogService,
) {
super()
@ -27,14 +28,14 @@ export class LinuxDefaultShellProvider extends ShellProvider {
this.logger.warn('Could not detect user shell')
return [{
id: 'default',
name: 'User default',
name: this.translate.instant('User default'),
command: '/bin/sh',
env: {},
}]
} else {
return [{
id: 'default',
name: 'User default',
name: this.translate.instant('User default'),
command: line.split(':')[6],
args: ['--login'],
hidden: true,

View file

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core'
import promiseIpc, { RendererProcessType } from 'electron-promise-ipc'
import { HostAppService, Platform } from 'tabby-core'
import { HostAppService, Platform, TranslateService } from 'tabby-core'
import { ShellProvider, Shell } from '../api'
@ -11,6 +11,7 @@ export class MacOSDefaultShellProvider extends ShellProvider {
constructor (
private hostApp: HostAppService,
private translate: TranslateService,
) {
super()
}
@ -21,7 +22,7 @@ export class MacOSDefaultShellProvider extends ShellProvider {
}
return [{
id: 'default',
name: 'OS default',
name: this.translate.instant('OS default'),
command: await this.getDefaultShellCached(),
args: ['--login'],
hidden: true,

View file

@ -1,5 +1,5 @@
import { Injectable } from '@angular/core'
import { HostAppService, Platform } from 'tabby-core'
import { HostAppService, Platform, TranslateService } from 'tabby-core'
import { ShellProvider, Shell } from '../api'
@ -17,6 +17,7 @@ export class WindowsDefaultShellProvider extends ShellProvider {
wsl: WSLShellProvider,
stock: WindowsStockShellsProvider,
private hostApp: HostAppService,
private translate: TranslateService,
) {
super()
this.providers = [
@ -39,7 +40,7 @@ export class WindowsDefaultShellProvider extends ShellProvider {
return [{
...shell,
id: 'default',
name: `OS default (${shell.name})`,
name: this.translate.instant('OS default ({name})', shell),
hidden: true,
env: {},
}]

View file

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { ConfigService, BaseTabComponent, TabContextMenuItemProvider, TabHeaderComponent, SplitTabComponent, NotificationsService, MenuItemOptions, ProfilesService, PromptModalComponent } from 'tabby-core'
import { ConfigService, BaseTabComponent, TabContextMenuItemProvider, TabHeaderComponent, SplitTabComponent, NotificationsService, MenuItemOptions, ProfilesService, PromptModalComponent, TranslateService } from 'tabby-core'
import { TerminalTabComponent } from './components/terminalTab.component'
import { UACService } from './services/uac.service'
import { TerminalService } from './services/terminal.service'
@ -13,6 +13,7 @@ export class SaveAsProfileContextMenu extends TabContextMenuItemProvider {
private config: ConfigService,
private ngbModal: NgbModal,
private notifications: NotificationsService,
private translate: TranslateService,
) {
super()
}
@ -23,10 +24,10 @@ export class SaveAsProfileContextMenu extends TabContextMenuItemProvider {
}
const items: MenuItemOptions[] = [
{
label: 'Save as profile',
label: this.translate.instant('Save as profile'),
click: async () => {
const modal = this.ngbModal.open(PromptModalComponent)
modal.componentInstance.prompt = 'New profile name'
modal.componentInstance.prompt = this.translate.instant('New profile name')
const name = (await modal.result)?.value
if (!name) {
return
@ -44,7 +45,7 @@ export class SaveAsProfileContextMenu extends TabContextMenuItemProvider {
profile,
]
this.config.save()
this.notifications.info('Saved')
this.notifications.info(this.translate.instant('Saved'))
},
},
]
@ -63,6 +64,7 @@ export class NewTabContextMenu extends TabContextMenuItemProvider {
private profilesService: ProfilesService,
private terminalService: TerminalService,
private uac: UACService,
private translate: TranslateService,
) {
super()
}
@ -72,7 +74,7 @@ export class NewTabContextMenu extends TabContextMenuItemProvider {
const items: MenuItemOptions[] = [
{
label: 'New terminal',
label: this.translate.instant('New terminal'),
click: () => {
if (tab instanceof TerminalTabComponent) {
this.profilesService.openNewTabForProfile(tab.profile)
@ -82,7 +84,7 @@ export class NewTabContextMenu extends TabContextMenuItemProvider {
},
},
{
label: 'New with profile',
label: this.translate.instant('New with profile'),
submenu: profiles.map(profile => ({
label: profile.name,
click: async () => {
@ -98,7 +100,7 @@ export class NewTabContextMenu extends TabContextMenuItemProvider {
if (this.uac.isAvailable) {
items.push({
label: 'New admin tab',
label: this.translate.instant('New admin tab'),
submenu: profiles.map(profile => ({
label: profile.name,
click: () => {
@ -116,7 +118,7 @@ export class NewTabContextMenu extends TabContextMenuItemProvider {
if (tab instanceof TerminalTabComponent && tabHeader && this.uac.isAvailable) {
items.push({
label: 'Duplicate as administrator',
label: this.translate.instant('Duplicate as administrator'),
click: () => {
this.profilesService.openNewTabForProfile({
...tab.profile,
@ -131,7 +133,7 @@ export class NewTabContextMenu extends TabContextMenuItemProvider {
if (tab instanceof TerminalTabComponent && tab.parent instanceof SplitTabComponent && tab.parent.getAllTabs().length > 1) {
items.push({
label: 'Focus all panes',
label: this.translate.instant('Focus all panes'),
click: () => {
tab.focusAllPanes()
},

View file

@ -1,16 +1,16 @@
.d-flex.mb-3
h3 Plugins
h3(translate) Plugins
button.btn.btn-secondary.btn-sm.ml-auto((click)='openPluginsFolder()')
i.fas.fa-folder
span Plugins folder
span(translate) Plugins folder
.alert.alert-danger(*ngIf='errorMessage')
strong Error in {{erroredPlugin}}:
strong(translate, [translateParams]='{plugin: erroredPlugin}') Error in {plugin}:
pre {{errorMessage}}
ul.nav-tabs.mb-2(ngbNav, #nav='ngbNav')
li(ngbNavItem)
a(ngbNavLink) Available
a(ngbNavLink, translate) Available
ng-template(ngbNavContent)
.input-group.mb-3.mt-3
.input-group-prepend
@ -40,14 +40,14 @@ ul.nav-tabs.mb-2(ngbNav, #nav='ngbNav')
)
i.fas.fa-fw.fa-cloud-download(*ngIf='busy.get(plugin.name) != BusyState.Installing')
i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='busy.get(plugin.name) == BusyState.Installing')
span.ml-2 Get
span.ml-2(translate) Get
button.btn.btn-secondary.btn-block.justify-content-center(
*ngIf='plugin.homepage',
(click)='showPluginHomepage(plugin)'
)
i.fas.fa-fw.fa-external-link-alt
span.ml-2 Homepage
span.ml-2(translate) Homepage
.col-8
ng-container(*ngTemplateOutlet='pluginInfo; context: { plugin }')
@ -55,7 +55,7 @@ ul.nav-tabs.mb-2(ngbNav, #nav='ngbNav')
.mt-2 {{plugin.description}}
li(ngbNavItem)
a(ngbNavLink) Installed
a(ngbNavLink, translate) Installed
ng-template(ngbNavContent)
ngb-accordion.mb-4([closeOthers]='true')
ng-container(*ngFor='let plugin of pluginManager.installedPlugins')
@ -64,8 +64,8 @@ ul.nav-tabs.mb-2(ngbNav, #nav='ngbNav')
.text-left.mr-auto
div
strong {{plugin.name}}
small.text-muted.ml-2(*ngIf='plugin.isBuiltin') Built-in
small.text-warning.ml-2(*ngIf='!isPluginEnabled(plugin)') Disabled
small.text-muted.ml-2(*ngIf='plugin.isBuiltin', translate) Built-in
small.text-warning.ml-2(*ngIf='!isPluginEnabled(plugin)', translate) Disabled
small.d-block.text-muted {{plugin.description}}
button.btn.btn-primary.ml-2(
@ -75,7 +75,7 @@ ul.nav-tabs.mb-2(ngbNav, #nav='ngbNav')
)
i.fas.fa-fw.fa-arrow-up(*ngIf='busy.get(plugin.name) != BusyState.Installing')
i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='busy.get(plugin.name) == BusyState.Installing')
span Upgrade to {{knownUpgrades[plugin.name].version}}
span(translate, [translateParams]='{version: knownUpgrades[plugin.name].version}') Upgrade to {version}
ng-template(ngbPanelContent)
.row
@ -83,12 +83,14 @@ ul.nav-tabs.mb-2(ngbNav, #nav='ngbNav')
button.btn.btn-warning.btn-block.justify-content-center(
(click)='togglePlugin(plugin)',
*ngIf='isPluginEnabled(plugin)',
[disabled]='!canDisablePlugin(plugin)'
[disabled]='!canDisablePlugin(plugin)',
translate
) Disable
button.btn.btn-success.btn-block.justify-content-center(
(click)='togglePlugin(plugin)',
*ngIf='canDisablePlugin(plugin) && !isPluginEnabled(plugin)'
*ngIf='canDisablePlugin(plugin) && !isPluginEnabled(plugin)',
translate
) Enable
button.btn.btn-danger.btn-block.justify-content-center(
@ -98,26 +100,25 @@ ul.nav-tabs.mb-2(ngbNav, #nav='ngbNav')
)
i.fas.fa-fw.fa-trash(*ngIf='busy.get(plugin.name) != BusyState.Uninstalling')
i.fas.fa-fw.fa-circle-notch.fa-spin(*ngIf='busy.get(plugin.name) == BusyState.Uninstalling')
span Uninstall
span(translate) Uninstall
.col-8
ng-container(*ngTemplateOutlet='pluginInfo; context: { plugin }')
.mt-2 {{plugin.description}}
ng-template(#pluginInfo, let-plugin='plugin')
.row.align-items-center
.col-4
strong Version
strong(translate) Version
.col-8
span {{plugin.version}}
.row.align-items-center
.col-4
strong Author
strong(translate) Author
.col-8
.badge.badge-success(*ngIf='plugin.isOfficial')
i.fas.fa-check
span.ml-1 Official
span.ml-1(translate) Official
a.btn.btn-link.px-0.w-auto((click)='showPluginInfo(plugin)', *ngIf='!plugin.isOfficial')
span {{plugin.author}}
i.fas.fa-fw.fa-external-link-alt.ml-2

View file

@ -1,11 +1,11 @@
ul.nav-tabs(ngbNav, #nav='ngbNav')
li(ngbNavItem)
a(ngbNavLink) General
a(ngbNavLink, translate) General
ng-template(ngbNavContent)
.row
.col-6(ng:if='hostApp.platform !== Platform.Web')
.form-group
label Device
label(translate) Device
input.form-control(
type='text',
alwaysVisibleTypeahead,
@ -16,7 +16,7 @@ ul.nav-tabs(ngbNav, #nav='ngbNav')
.col-6
.form-group
label Baud Rate
label(translate) Baud rate
input.form-control(
type='number',
alwaysVisibleTypeahead,
@ -28,11 +28,11 @@ ul.nav-tabs(ngbNav, #nav='ngbNav')
stream-processing-settings([options]='profile.options')
li(ngbNavItem)
a(ngbNavLink) Advanced
a(ngbNavLink, translate) Advanced
ng-template(ngbNavContent)
.form-line
.header
.title Data bits
.title(translate) Data bits
input.form-control(
type='number',
placeholder='8',
@ -41,7 +41,7 @@ ul.nav-tabs(ngbNav, #nav='ngbNav')
.form-line
.header
.title Stop bits
.title(translate) Stop bits
input.form-control(
type='number',
placeholder='1',
@ -50,12 +50,12 @@ ul.nav-tabs(ngbNav, #nav='ngbNav')
.form-line
.header
.title Parity
.title(translate) Parity
select.form-control(
type='text',
[(ngModel)]='profile.options.parity'
)
option(value='none') None
option(value='none', translate) None
option(value='even') Even
option(value='odd') Odd
option(value='mark', ng:if='hostApp.platform === Platform.Windows') Mark
@ -83,12 +83,12 @@ ul.nav-tabs(ngbNav, #nav='ngbNav')
.form-line
.header
.title Slow feed
.description Sends data one byte at a time
.title(translate) Slow feed
.description(translate) Sends data one byte at a time
toggle([(ngModel)]='profile.options.slowFeed')
li(ngbNavItem)
a(ngbNavLink) Login scripts
a(ngbNavLink, translate) Login scripts
ng-template(ngbNavContent)
login-scripts-settings([options]='profile.options')

View file

@ -9,8 +9,8 @@
.mr-auto
button.btn.btn-sm.btn-link.mr-3((click)='changeBaudRate()', *ngIf='session && session.open && hostApp.platform !== Platform.Web')
span Change baud rate
span(translate) Change baud rate
button.btn.btn-sm.btn-link((click)='reconnect()', *ngIf='!session || !session.open')
i.fas.fa-redo
span Reconnect
span(translate) Reconnect

View file

@ -2,7 +2,7 @@
import colors from 'ansi-colors'
import { Component, Injector } from '@angular/core'
import { first } from 'rxjs'
import { Platform, SelectorService } from 'tabby-core'
import { Platform, SelectorService, TranslateService } from 'tabby-core'
import { BaseTerminalTabComponent } from 'tabby-terminal'
import { SerialSession, BAUD_RATES, SerialProfile } from '../api'
@ -23,6 +23,7 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
constructor (
injector: Injector,
private selector: SelectorService,
private translate: TranslateService,
) {
super(injector)
this.enableToolbar = true
@ -67,14 +68,13 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
const session = new SerialSession(this.injector, this.profile)
this.setSession(session)
this.write(`Connecting to `)
this.startSpinner('Connecting')
this.startSpinner(this.translate.instant('Connecting'))
try {
await this.session!.start()
this.stopSpinner()
session.emitServiceMessage('Port opened')
session.emitServiceMessage(this.translate.instant('Port opened'))
} catch (e) {
this.stopSpinner()
this.write(colors.black.bgRed(' X ') + ' ' + colors.red(e.message) + '\r\n')
@ -89,7 +89,7 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
this.session?.resize(this.size.columns, this.size.rows)
})
this.attachSessionHandler(this.session!.destroyed$, () => {
this.write('Press any key to reconnect\r\n')
this.write(this.translate.instant('Press any key to reconnect') + '\r\n')
this.input$.pipe(first()).subscribe(() => {
if (!this.session?.open) {
this.reconnect()
@ -114,9 +114,12 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
}
async changeBaudRate () {
const rate = await this.selector.show('Baud rate', BAUD_RATES.map(x => ({
const rate = await this.selector.show(
this.translate.instant('Baud rate'),
BAUD_RATES.map(x => ({
name: x.toString(), result: x,
})))
})),
)
this.serialPort.update({ baudRate: rate })
this.profile!.options.baudrate = rate
}

View file

@ -1,5 +1,5 @@
import { Injectable } from '@angular/core'
import { HotkeyDescription, HotkeyProvider } from 'tabby-core'
import { HotkeyDescription, HotkeyProvider, TranslateService } from 'tabby-core'
/** @hidden */
@Injectable()
@ -7,14 +7,16 @@ export class SerialHotkeyProvider extends HotkeyProvider {
hotkeys: HotkeyDescription[] = [
{
id: 'serial',
name: 'Show Serial connections',
name: this.translate.instant('Show Serial connections'),
},
{
id: 'restart-serial-session',
name: 'Restart current serial session',
name: this.translate.instant('Restart current serial session'),
},
]
constructor (private translate: TranslateService) { super() }
async provide (): Promise<HotkeyDescription[]> {
return this.hotkeys
}

View file

@ -3,7 +3,7 @@ import SerialPort from 'serialport'
import WSABinding from 'serialport-binding-webserialapi'
import deepClone from 'clone-deep'
import { Injectable } from '@angular/core'
import { ProfileProvider, NewTabParameters, SelectorService, HostAppService, Platform } from 'tabby-core'
import { ProfileProvider, NewTabParameters, SelectorService, HostAppService, Platform, TranslateService } from 'tabby-core'
import { SerialProfileSettingsComponent } from './components/serialProfileSettings.component'
import { SerialTabComponent } from './components/serialTab.component'
import { SerialService } from './services/serial.service'
@ -12,7 +12,7 @@ import { BAUD_RATES, SerialProfile } from './api'
@Injectable({ providedIn: 'root' })
export class SerialProfilesService extends ProfileProvider<SerialProfile> {
id = 'serial'
name = 'Serial'
name = this.translate.instant('Serial')
settingsComponent = SerialProfileSettingsComponent
configDefaults = {
options: {
@ -38,6 +38,7 @@ export class SerialProfilesService extends ProfileProvider<SerialProfile> {
private selector: SelectorService,
private serial: SerialService,
private hostApp: HostAppService,
private translate: TranslateService,
) {
super()
if (hostApp.platform === Platform.Web) {
@ -51,7 +52,7 @@ export class SerialProfilesService extends ProfileProvider<SerialProfile> {
{
id: `serial:web`,
type: 'serial',
name: 'Serial connection',
name: this.translate.instant('Serial connection'),
icon: 'fas fa-microchip',
isBuiltin: true,
} as SerialProfile,
@ -62,7 +63,7 @@ export class SerialProfilesService extends ProfileProvider<SerialProfile> {
{
id: `serial:template`,
type: 'serial',
name: 'Serial connection',
name: this.translate.instant('Serial connection'),
icon: 'fas fa-microchip',
isBuiltin: true,
isTemplate: true,
@ -70,7 +71,9 @@ export class SerialProfilesService extends ProfileProvider<SerialProfile> {
...(await this.serial.listPorts()).map(p => ({
id: `serial:port-${slugify(p.name).replace('.', '-')}`,
type: 'serial',
name: p.description ? `Serial: ${p.description}` : 'Serial',
name: p.description ?
this.translate.instant('Serial: {description}', p) :
this.translate.instant('Serial'),
icon: 'fas fa-microchip',
isBuiltin: true,
options: {
@ -83,9 +86,12 @@ export class SerialProfilesService extends ProfileProvider<SerialProfile> {
async getNewTabParameters (profile: SerialProfile): Promise<NewTabParameters<SerialTabComponent>> {
if (!profile.options.baudrate) {
profile = deepClone(profile)
profile.options.baudrate = await this.selector.show('Baud rate', BAUD_RATES.map(x => ({
profile.options.baudrate = await this.selector.show(
this.translate.instant('Baud rate'),
BAUD_RATES.map(x => ({
name: x.toString(), result: x,
})))
})),
)
}
return {
type: SerialTabComponent,

View file

@ -1,5 +1,5 @@
import { Injectable } from '@angular/core'
import { ToolbarButtonProvider, ToolbarButton, AppService, HostAppService, HotkeysService } from 'tabby-core'
import { ToolbarButtonProvider, ToolbarButton, AppService, HostAppService, HotkeysService, TranslateService } from 'tabby-core'
import { SettingsTabComponent } from './components/settingsTab.component'
@ -10,6 +10,7 @@ export class ButtonProvider extends ToolbarButtonProvider {
hostApp: HostAppService,
hotkeys: HotkeysService,
private app: AppService,
private translate: TranslateService,
) {
super()
hostApp.settingsUIRequest$.subscribe(() => this.open())
@ -24,7 +25,7 @@ export class ButtonProvider extends ToolbarButtonProvider {
provide (): ToolbarButton[] {
return [{
icon: require('./icons/cog.svg'),
title: 'Settings',
title: this.translate.instant('Settings'),
touchBarNSImage: 'NSTouchBarComposeTemplate',
weight: 10,
click: (): void => this.open(),

View file

@ -1,12 +1,12 @@
h3.mb-3 Config sync
h3.mb-3(translate) Config sync
ul.nav-tabs(ngbNav, #nav='ngbNav')
li(ngbNavItem)
a(ngbNavLink) Sync
a(ngbNavLink, translate) Sync
ng-template(ngbNavContent)
.form-line
.header
.title Sync host
.title(translate) Sync host
.input-group.w-50
input.form-control(
@ -20,8 +20,8 @@ ul.nav-tabs(ngbNav, #nav='ngbNav')
.form-line
.header
.title Secret sync token
.description Get it from the Tabby Web settings window
.title(translate) Secret sync token
.description(translate) Get it from the Tabby Web settings window
.input-group
input.form-control(
@ -38,16 +38,16 @@ ul.nav-tabs(ngbNav, #nav='ngbNav')
ng-container(*ngIf='config.store.configSync.token')
.alert.alert-danger(*ngIf='connectionSuccessful === false')
i.fas.fa-exclamation-triangle
span.ml-2 Connection failed: {{connectionError}}
span.ml-2(translate, [translateParams]='{error: connectionError}') Connection failed: {error}
ng-container(*ngIf='connectionSuccessful')
.form-line
.header
.title Configs
.title(translate) Configs
div(*ngIf='configs === null')
i.fas.fa-fw.fa-circle-notch.fa-spin
span.ml-2 Loading configs...
span.ml-2(translate) Loading configs...
ng-container(*ngIf='configs !== null')
.list-group-light
@ -59,34 +59,34 @@ ul.nav-tabs(ngbNav, #nav='ngbNav')
i.fas.fa-fw.fa-file
.ml-2.d-flex.flex-column.align-items-start
div {{cfg.name}}
small.text-muted Modified on {{cfg.modified_at|date:'medium'}}
small.text-muted(translate, [translateParams]='{date: cfg.modified_at|date:"medium"}') Modified on {date}
.mr-auto
button.btn.btn-link.ml-1(
(click)='uploadAndSync(cfg)',
[class.hover-reveal]='!isActiveConfig(cfg)'
)
i.fas.fa-arrow-up
span.ml-2(*ngIf='isActiveConfig(cfg)') Upload
span.ml-2(*ngIf='!isActiveConfig(cfg)') Replace
span.ml-2(*ngIf='isActiveConfig(cfg)', translate) Upload
span.ml-2(*ngIf='!isActiveConfig(cfg)', translate) Replace
button.btn.btn-link.ml-1(
(click)='downloadAndSync(cfg)',
[class.hover-reveal]='!isActiveConfig(cfg)'
)
i.fas.fa-arrow-down
span.ml-2 Download
span.ml-2(translate) Download
a.list-group-item.list-group-item-action.d-flex.align-items-center(
href='#',
(click)='uploadAsNew()'
)
i.fas.fa-fw
i.fas.fa-fw.fa-cloud-upload-alt
.ml-2 Upload as a new config
.ml-2(translate) Upload as a new config
ng-container(*ngIf='hasMatchingRemoteConfig()')
.form-line
.header
.title Sync automatically
.description Automatically upload changes and check for updates every minute
.title(translate) Sync automatically
.description(translate) Automatically upload changes and check for updates every minute
toggle(
[(ngModel)]='config.store.configSync.auto',
@ -94,11 +94,11 @@ ul.nav-tabs(ngbNav, #nav='ngbNav')
)
li(ngbNavItem)
a(ngbNavLink) Advanced
a(ngbNavLink, translate) Advanced
ng-template(ngbNavContent)
.form-line
.header
.title Sync hotkeys
.title(translate) Sync hotkeys
toggle(
[(ngModel)]='config.store.configSync.parts.hotkeys',
(ngModelChange)='config.save()',
@ -106,7 +106,7 @@ ul.nav-tabs(ngbNav, #nav='ngbNav')
.form-line
.header
.title Sync window settings
.title(translate) Sync window settings
toggle(
[(ngModel)]='config.store.configSync.parts.appearance',
(ngModelChange)='config.save()',
@ -114,7 +114,7 @@ ul.nav-tabs(ngbNav, #nav='ngbNav')
.form-line
.header
.title Sync Vault
.title(translate) Sync Vault
toggle(
[(ngModel)]='config.store.configSync.parts.vault',
(ngModelChange)='config.save()',

View file

@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { Component, HostBinding } from '@angular/core'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { BaseComponent, ConfigService, PromptModalComponent, HostAppService, PlatformService, NotificationsService } from 'tabby-core'
import { BaseComponent, ConfigService, PromptModalComponent, HostAppService, PlatformService, NotificationsService, TranslateService } from 'tabby-core'
import { Config, ConfigSyncService } from '../services/configSync.service'
@ -24,6 +24,7 @@ export class ConfigSyncSettingsTabComponent extends BaseComponent {
private hostApp: HostAppService,
private ngbModal: NgbModal,
private notifications: NotificationsService,
private translate: TranslateService,
) {
super()
}
@ -54,9 +55,9 @@ export class ConfigSyncSettingsTabComponent extends BaseComponent {
}
async uploadAsNew () {
let name = `New config on ${this.hostApp.platform}`
let name = this.translate.instant('New config on {platform}', this.hostApp)
const modal = this.ngbModal.open(PromptModalComponent)
modal.componentInstance.prompt = 'Name for the new config'
modal.componentInstance.prompt = this.translate.instant('Name for the new config')
modal.componentInstance.value = name
name = (await modal.result)?.value
if (!name) {
@ -72,8 +73,11 @@ export class ConfigSyncSettingsTabComponent extends BaseComponent {
if (this.config.store.configSync.configID !== cfg.id) {
if ((await this.platform.showMessageBox({
type: 'warning',
message: 'Overwrite the config on the remote side and start syncing?',
buttons: ['Overwrite remote and sync', 'Cancel'],
message: this.translate.instant('Overwrite the config on the remote side and start syncing?'),
buttons: [
this.translate.instant('Overwrite remote and sync'),
this.translate.instant('Cancel'),
],
defaultId: 1,
cancelId: 1,
})).response === 1) {
@ -83,14 +87,17 @@ export class ConfigSyncSettingsTabComponent extends BaseComponent {
this.configSync.setConfig(cfg)
await this.configSync.upload()
this.loadConfigs()
this.notifications.info('Config uploaded')
this.notifications.info(this.translate.instant('Config uploaded'))
}
async downloadAndSync (cfg: Config) {
if ((await this.platform.showMessageBox({
type: 'warning',
message: 'Overwrite the local config and start syncing?',
buttons: ['Overwrite local and sync', 'Cancel'],
message: this.translate.instant('Overwrite the local config and start syncing?'),
buttons: [
this.translate.instant('Overwrite local and sync'),
this.translate.instant('Cancel'),
],
defaultId: 1,
cancelId: 1,
})).response === 1) {
@ -98,7 +105,7 @@ export class ConfigSyncSettingsTabComponent extends BaseComponent {
}
this.configSync.setConfig(cfg)
await this.configSync.download()
this.notifications.info('Config downloaded')
this.notifications.info(this.translate.instant('Config downloaded'))
}
hasMatchingRemoteConfig () {

View file

@ -2,13 +2,13 @@
h3.m-0 {{profile.name}}
.modal-header(*ngIf='defaultsMode')
h3.m-0 Defaults for {{profileProvider.name}}
h3.m-0(translate, [translateParams]='{type: profileProvider.name}') Defaults for {type}
.modal-body
.row
.col-12.col-lg-4
.form-group(*ngIf='!defaultsMode')
label Name
label(translate) Name
input.form-control(
type='text',
autofocus,
@ -16,7 +16,7 @@
)
.form-group(*ngIf='!defaultsMode')
label Group
label(translate) Group
input.form-control(
type='text',
alwaysVisibleTypeahead,
@ -26,7 +26,7 @@
)
.form-group(*ngIf='!defaultsMode')
label Icon
label(translate) Icon
.input-group
input.form-control(
type='text',
@ -45,7 +45,7 @@
.form-line
.header
.title Color
.title(translate) Color
input.form-control.w-50(
type='text',
[(ngModel)]='profile.color',
@ -56,8 +56,8 @@
.form-line
.header
.title Disable dynamic tab title
.description Connection name will be used instead
.title(translate) Disable dynamic tab title
.description(translate) Connection name will be used instead
toggle([(ngModel)]='profile.disableDynamicTitle')
.mb-4
@ -66,5 +66,5 @@
ng-template(#placeholder)
.modal-footer
button.btn.btn-primary((click)='save()') Save
button.btn.btn-danger((click)='cancel()') Cancel
button.btn.btn-primary((click)='save()', translate) Save
button.btn.btn-danger((click)='cancel()', translate) Cancel

View file

@ -1,5 +1,5 @@
.modal-header
h5 Press the key now
h5(translate) Press the key now
.modal-body
.input
@ -9,4 +9,4 @@
div([style.width]='timeoutProgress + "%"')
.modal-footer
button.btn.btn-primary((click)='close()') Cancel
button.btn.btn-primary((click)='close()', translate) Cancel

View file

@ -1,4 +1,4 @@
h3.mb-3 Hotkeys
h3.mb-3(translate) Hotkeys
.input-group.mb-4
.input-group-prepend

View file

@ -3,4 +3,4 @@
.stroke(*ngFor='let stroke of item') {{stroke}}
.remove((click)='removeItem(item)') &times;
.add((click)='addItem()') Add...
.add((click)='addItem()', translate) Add...

View file

@ -1,12 +1,12 @@
h3.mb-3 Profiles
h3.mb-3(translate) Profiles
ul.nav-tabs(ngbNav, #nav='ngbNav')
li(ngbNavItem)
a(ngbNavLink) Profiles
a(ngbNavLink, translate) Profiles
ng-template(ngbNavContent)
.form-line
.header
.title Default profile for new tabs
.title(translate) Default profile for new tabs
select.form-control(
[(ngModel)]='config.store.terminal.profile',
@ -30,7 +30,7 @@ ul.nav-tabs(ngbNav, #nav='ngbNav')
button.btn.btn-primary.flex-shrink-0.ml-3((click)='newProfile()')
i.fas.fa-fw.fa-plus
| New profile
span(translate) New profile
.list-group.mt-3.mb-3
ng-container(*ngFor='let group of profileGroups')
@ -40,7 +40,7 @@ ul.nav-tabs(ngbNav, #nav='ngbNav')
)
.fa.fa-fw.fa-chevron-right(*ngIf='group.collapsed')
.fa.fa-fw.fa-chevron-down(*ngIf='!group.collapsed')
span.ml-3.mr-auto {{group.name || "Ungrouped"}}
span.ml-3.mr-auto {{group.name || ("Ungrouped"|translate)}}
button.btn.btn-sm.btn-link.hover-reveal.ml-2(
*ngIf='group.editable && group.name',
(click)='$event.stopPropagation(); editGroup(group)'
@ -88,12 +88,12 @@ ul.nav-tabs(ngbNav, #nav='ngbNav')
.ml-1(class='badge badge-{{getTypeColorClass(profile)}}') {{getTypeLabel(profile)}}
li(ngbNavItem)
a(ngbNavLink) Advanced
a(ngbNavLink, translate) Advanced
ng-template(ngbNavContent)
.form-line(*ngIf='config.store.profiles.length > 0')
.header
.title Show recent profiles in selector
.description Set to 0 to disable recent profiles
.title(translate) Show recent profiles in selector
.description(translate) Set to 0 to disable recent profiles
input.form-control(
type='number',
@ -105,8 +105,8 @@ ul.nav-tabs(ngbNav, #nav='ngbNav')
.form-line(*ngIf='config.store.profiles.length > 0')
.header
.title Show built-in profiles in selector
.description If disabled, only custom profiles will show up in the profile selector
.title(translate) Show built-in profiles in selector
.description(translate) If disabled, only custom profiles will show up in the profile selector
toggle(
[(ngModel)]='config.store.terminal.showBuiltinProfiles',
@ -115,8 +115,8 @@ ul.nav-tabs(ngbNav, #nav='ngbNav')
.form-line
.header
.title Default profile settings
.description These apply to all profiles of a given type
.title(translate) Default profile settings
.description(translate) These apply to all profiles of a given type
.list-group.mt-3.mb-3
a.list-group-item.list-group-item-action(

View file

@ -3,7 +3,7 @@ import slugify from 'slugify'
import deepClone from 'clone-deep'
import { Component, HostBinding, Inject } from '@angular/core'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { ConfigService, HostAppService, Profile, SelectorService, ProfilesService, PromptModalComponent, PlatformService, BaseComponent, PartialProfile, ProfileProvider } from 'tabby-core'
import { ConfigService, HostAppService, Profile, SelectorService, ProfilesService, PromptModalComponent, PlatformService, BaseComponent, PartialProfile, ProfileProvider, TranslateService } from 'tabby-core'
import { EditProfileModalComponent } from './editProfileModal.component'
interface ProfileGroup {
@ -35,6 +35,7 @@ export class ProfilesSettingsTabComponent extends BaseComponent {
private selector: SelectorService,
private ngbModal: NgbModal,
private platform: PlatformService,
private translate: TranslateService,
) {
super()
this.profileProviders.sort((a, b) => a.name.localeCompare(b.name))
@ -58,7 +59,7 @@ export class ProfilesSettingsTabComponent extends BaseComponent {
const profiles = [...this.templateProfiles, ...this.builtinProfiles, ...this.profiles]
profiles.sort((a, b) => (a.weight ?? 0) - (b.weight ?? 0))
base = await this.selector.show(
'Select a base profile to use as a template',
this.translate.instant('Select a base profile to use as a template'),
profiles.map(p => ({
icon: p.icon,
description: this.profilesService.getDescription(p) ?? undefined,
@ -72,14 +73,14 @@ export class ProfilesSettingsTabComponent extends BaseComponent {
if (base.isTemplate) {
profile.name = ''
} else if (!base.isBuiltin) {
profile.name = `${base.name} copy`
profile.name = this.translate.instant('{name} copy', base)
}
profile.isBuiltin = false
profile.isTemplate = false
await this.showProfileEditModal(profile)
if (!profile.name) {
const cfgProxy = this.profilesService.getConfigProxyForProfile(profile)
profile.name = this.profilesService.providerForProfile(profile)?.getSuggestedName(cfgProxy) ?? `${base.name} copy`
profile.name = this.profilesService.providerForProfile(profile)?.getSuggestedName(cfgProxy) ?? this.translate.instant('{name} copy', base)
}
profile.id = `${profile.type}:custom:${slugify(profile.name)}:${uuidv4()}`
this.config.store.profiles = [profile, ...this.config.store.profiles]
@ -122,8 +123,11 @@ export class ProfilesSettingsTabComponent extends BaseComponent {
if ((await this.platform.showMessageBox(
{
type: 'warning',
message: `Delete "${profile.name}"?`,
buttons: ['Delete', 'Keep'],
message: this.translate.instant('Delete "{name}"?', profile),
buttons: [
this.translate.instant('Delete'),
this.translate.instant('Keep'),
],
defaultId: 1,
cancelId: 1,
}
@ -156,7 +160,7 @@ export class ProfilesSettingsTabComponent extends BaseComponent {
this.profileGroups.sort((a, b) => a.name?.localeCompare(b.name ?? '') ?? -1)
this.profileGroups.push({
name: 'Built-in',
name: this.translate.instant('Built-in'),
profiles: this.builtinProfiles,
editable: false,
collapsed: false,
@ -165,7 +169,7 @@ export class ProfilesSettingsTabComponent extends BaseComponent {
async editGroup (group: ProfileGroup): Promise<void> {
const modal = this.ngbModal.open(PromptModalComponent)
modal.componentInstance.prompt = 'New name'
modal.componentInstance.prompt = this.translate.instant('New name')
modal.componentInstance.value = group.name
const result = await modal.result
if (result) {
@ -181,8 +185,11 @@ export class ProfilesSettingsTabComponent extends BaseComponent {
if ((await this.platform.showMessageBox(
{
type: 'warning',
message: `Delete "${group.name}"?`,
buttons: ['Delete', 'Keep'],
message: this.translate.instant('Delete "{name}"?', group),
buttons: [
this.translate.instant('Delete'),
this.translate.instant('Keep'),
],
defaultId: 1,
cancelId: 1,
}
@ -190,8 +197,11 @@ export class ProfilesSettingsTabComponent extends BaseComponent {
if ((await this.platform.showMessageBox(
{
type: 'warning',
message: `Delete the group's profiles?`,
buttons: ['Move to "Ungrouped"', 'Delete'],
message: this.translate.instant(`Delete the group's profiles?`),
buttons: [
this.translate.instant('Move to "Ungrouped"'),
this.translate.instant('Delete'),
],
defaultId: 0,
cancelId: 0,
}
@ -224,10 +234,10 @@ export class ProfilesSettingsTabComponent extends BaseComponent {
getTypeLabel (profile: PartialProfile<Profile>): string {
const name = this.profilesService.providerForProfile(profile)?.name
if (name === 'Local') {
if (name === this.translate.instant('Local terminal')) {
return ''
}
return name ?? 'Unknown'
return name ?? this.translate.instant('Unknown')
}
getTypeColorClass (profile: PartialProfile<Profile>): string {

View file

@ -2,7 +2,7 @@
import axios from 'axios'
import { marked } from 'marked'
import { Component } from '@angular/core'
import { BaseTabComponent } from 'tabby-core'
import { BaseTabComponent, TranslateService } from 'tabby-core'
export interface Release {
name: string
@ -21,9 +21,9 @@ export class ReleaseNotesComponent extends BaseTabComponent {
releases: Release[] = []
lastPage = 1
constructor () {
constructor (translate: TranslateService) {
super()
this.setTitle('Release notes')
this.setTitle(translate.instant('Release notes'))
this.loadReleases(1)
}

View file

@ -1,6 +1,6 @@
h3.modal-header.m-0.pb-0 Set master passphrase
h3.modal-header.m-0.pb-0(translate) Set master passphrase
.modal-body
.mb-2 You can change it later, but it's unrecoverable if forgotten.
.mb-2(translate) You can change it later, but it's unrecoverable if forgotten.
.input-group
input.form-control.form-control-lg(
[type]='showPassphrase ? "text" : "password"',
@ -16,5 +16,5 @@ h3.modal-header.m-0.pb-0 Set master passphrase
i.fas.fa-eye
.modal-footer
button.btn.btn-primary((click)='ok()') Set passphrase
button.btn.btn-danger((click)='cancel()') Cancel
button.btn.btn-primary((click)='ok()', translate) Set passphrase
button.btn.btn-danger((click)='cancel()', translate) Cancel

View file

@ -3,7 +3,7 @@
li(ngbNavItem='application')
a(ngbNavLink)
i.fas.fa-fw.fa-window-maximize.mr-2
| Application
span(translate) Application
ng-template(ngbNavContent)
.content-box
.row
@ -23,59 +23,69 @@
i.fas.fa-sync(
[class.fa-spin]='checkingForUpdate'
)
span Check for updates
span(translate) Check for updates
button.btn.btn-info.mt-3.mb-2(
*ngIf='updateAvailable',
(click)='updater.update()',
)
i.fas.fa-sync
span Update
span(translate) Update
.col-12.col-md-6
.list-group.list-group-light.mb-5
button.list-group-item.list-group-item-action.link-card((click)='homeBase.reportBug()')
i.fas.fa-fw.fa-bug
div
div Report a problem
small.text-muted Generate a pre-filled GitHub issue
div(translate) Report a problem
small.text-muted(translate) Generate a pre-filled GitHub issue
button.list-group-item.list-group-item-action.link-card((click)='homeBase.openDiscussions()')
i.fas.fa-fw.fa-comments
div
div Ask a question
small.text-muted On GitHub Discussions
div(translate) Ask a question
small.text-muted(translate) On GitHub Discussions
button.list-group-item.list-group-item-action.link-card((click)='homeBase.openGitHub()')
i.fab.fa-fw.fa-github
div
div GitHub
small.text-muted Source code
small.text-muted(translate) Source code
button.list-group-item.list-group-item-action.link-card((click)='showReleaseNotes()')
i.fas.fa-fw.fa-book
div
div What's new
small.text-muted Show release notes
div(translate) What's new
small.text-muted(translate) Show release notes
button.list-group-item.list-group-item-action.link-card((click)='homeBase.openTwitter()')
i.fab.fa-fw.fa-twitter
div
div Subscribe to updates
small.text-muted Tabby news and updates on Twitter
div(translate) Subscribe to updates
small.text-muted(translate) Tabby news and updates on Twitter
h3 Application settings
h3(translate) Application settings
.form-line
.header
.title(translate) Language
select.form-control([(ngModel)]='config.store.language', (ngModelChange)='saveConfiguration()')
option([value]='null', translate) Automatic
option(
[value]='lang.code',
*ngFor='let lang of locale.allLanguages'
) {{lang.name|translate}}
.form-line(*ngIf='platform.isShellIntegrationSupported()')
.header
.title Shell integration
.description Allows quickly opening a terminal in the selected folder
.title(translate) Shell integration
.description(translate) Allows quickly opening a terminal in the selected folder
toggle([ngModel]='isShellIntegrationInstalled', (ngModelChange)='toggleShellIntegration()')
.form-line(*ngIf='hostApp.platform !== Platform.Web')
.header
.title Enable analytics
.description We're only tracking your Tabby and OS versions.
.title(translate) Enable analytics
.description(translate) We're only tracking your Tabby and OS versions.
toggle(
[(ngModel)]='config.store.enableAnalytics',
(ngModelChange)='saveConfiguration(true)',
@ -83,23 +93,23 @@
.form-line(*ngIf='hostApp.platform !== Platform.Web')
.header
.title Automatic Updates
.description Enable automatic installation of updates when they become available.
.title(translate) Automatic Updates
.description(translate) Enable automatic installation of updates when they become available.
toggle([(ngModel)]='config.store.enableAutomaticUpdates', (ngModelChange)='saveConfiguration()')
.form-line(*ngIf='hostApp.platform !== Platform.Web')
.header
.title Debugging
.title(translate) Debugging
button.btn.btn-secondary((click)='hostWindow.openDevTools()')
i.fas.fa-bug
span Open DevTools
span(translate) Open DevTools
ng-container(*ngFor='let provider of settingsProviders')
li(*ngIf='provider.prioritized', [ngbNavItem]='provider.id')
a(ngbNavLink)
i(class='fas fa-fw mr-2 fa-{{provider.icon}}')
| {{provider.title}}
span(translate) {{provider.title}}
ng-template(ngbNavContent)
settings-tab-body([provider]='provider')
@ -109,24 +119,24 @@
li(*ngIf='!provider.prioritized', [ngbNavItem]='provider.id')
a(ngbNavLink)
i(class='fas fa-fw mr-2 fa-{{provider.icon || "puzzle-piece"}}')
| {{provider.title}}
span(translate) {{provider.title}}
ng-template(ngbNavContent)
settings-tab-body([provider]='provider')
li(ngbNavItem='config-file')
a(ngbNavLink)
i.fas.fa-fw.fa-code.mr-2
| Config file
span(translate) Config file
ng-template.test(ngbNavContent)
.d-flex.flex-column.w-100.h-100
.h-100.d-flex
.w-100.d-flex.flex-column
h3 Config file
h3(translate) Config file
textarea.form-control.h-100(
[(ngModel)]='configFile'
)
.w-100.d-flex.flex-column(*ngIf='showConfigDefaults')
h3 Defaults
h3(translate) Defaults
textarea.form-control.h-100(
[(ngModel)]='configDefaults',
readonly
@ -134,20 +144,25 @@
.mt-3.d-flex
button.btn.btn-primary((click)='saveConfigFile()', *ngIf='isConfigFileValid()')
i.fas.fa-check.mr-2
| Save and apply
span(translate) Save and apply
button.btn.btn-primary(disabled, *ngIf='!isConfigFileValid()')
i.fas.fa-exclamation-triangle.mr-2
| Invalid syntax
span(translate) Invalid syntax
button.btn.btn-secondary.ml-auto(
(click)='showConfigDefaults = !showConfigDefaults'
(click)='showConfigDefaults = !showConfigDefaults',
translate
) Show defaults
button.btn.btn-secondary.ml-3(
*ngIf='platform.getConfigPath()',
(click)='showConfigFile()'
)
i.fas.fa-external-link-square-alt.mr-2
| Show config file
span(translate) Show config file
div([ngbNavOutlet]='nav')
button.btn.btn-warning.btn-block(*ngIf='config.restartRequested', '(click)'='restartApp()') Restart the app to apply changes
button.btn.btn-warning.btn-block(
*ngIf='config.restartRequested',
(click)='restartApp()',
translate
) Restart the app to apply changes

View file

@ -12,6 +12,8 @@ import {
PlatformService,
HostWindowService,
AppService,
LocaleService,
TranslateService,
} from 'tabby-core'
import { SettingsTabProvider } from '../api'
@ -43,12 +45,14 @@ export class SettingsTabComponent extends BaseTabComponent {
public homeBase: HomeBaseService,
public platform: PlatformService,
public zone: NgZone,
public locale: LocaleService,
private updater: UpdaterService,
private app: AppService,
@Inject(SettingsTabProvider) public settingsProviders: SettingsTabProvider[],
translate: TranslateService,
) {
super()
this.setTitle('Settings')
this.setTitle(translate.instant('Settings'))
this.settingsProviders = config.enabledServices(this.settingsProviders)
this.settingsProviders = this.settingsProviders.filter(x => !!x.getComponentType())
this.settingsProviders.sort((a, b) => a.weight - b.weight + a.title.localeCompare(b.title))

View file

@ -1,27 +1,27 @@
.text-center(*ngIf='!vault.isEnabled()')
i.fas.fa-key.fa-3x.m-3
h3.m-3 Vault is not configured
.m-3 Vault is an always-encrypted container for secrets such as SSH passwords and private key passphrases.
button.btn.btn-primary.m-2((click)='enableVault()') Set master passphrase
h3.m-3(translate) Vault is not configured
.m-3(translate) Vault is an always-encrypted container for secrets such as SSH passwords and private key passphrases.
button.btn.btn-primary.m-2((click)='enableVault()', translate) Set master passphrase
div(*ngIf='vault.isEnabled()')
.d-flex.align-items-center.mb-3
h3.m-0 Vault
h3.m-0(translate) Vault
.d-flex.ml-auto(ngbDropdown, *ngIf='vault.isEnabled()')
button.btn.btn-secondary(ngbDropdownToggle) Options
button.btn.btn-secondary(ngbDropdownToggle, translate) Options
div(ngbDropdownMenu)
a(ngbDropdownItem, (click)='changePassphrase()')
i.fas.fa-fw.fa-key
span Change the master passphrase
span(translate) Change the master passphrase
a(ngbDropdownItem, (click)='disableVault()')
i.fas.fa-fw.fa-radiation-alt
span Erase the vault
span(translate) Erase the Vault
div(*ngIf='vaultContents')
.text-center(*ngIf='!vaultContents.secrets.length')
i.fas.fa-empty-set.fa-3x
h3.m-3 Vault is empty
h3.m-3(translate) Vault is empty
.list-group
.list-group-item.d-flex.align-items-center.p-1.pl-3(*ngFor='let secret of vaultContents.secrets')
@ -38,30 +38,30 @@ div(*ngIf='vault.isEnabled()')
(click)='renameFile(secret)'
)
i.fas.fa-fw.fa-pencil-alt
span Rename
span(translate) Rename
button(
ngbDropdownItem,
*ngIf='secret.type === VAULT_SECRET_TYPE_FILE',
(click)='replaceFileContent(secret)'
)
i.fas.fa-fw.fa-file-import
span Replace
span(translate) Replace
button(
ngbDropdownItem,
*ngIf='secret.type === VAULT_SECRET_TYPE_FILE',
(click)='exportFile(secret)'
)
i.fas.fa-fw.fa-file-export
span Export
span(translate) Export
button(ngbDropdownItem, (click)='removeSecret(secret)')
i.fas.fa-fw.fa-trash
span Delete
span(translate) Delete
h3.mt-5 Options
h3.mt-5(translate) Options
.form-line
.header
.title Encrypt config file
.description Puts all of Tabby's configuration into the vault
.title(translate) Encrypt config file
.description(translate) Puts all of Tabby's configuration into the vault
toggle(
[ngModel]='config.store.encrypted',
(click)='toggleConfigEncrypted()',
@ -69,5 +69,5 @@ div(*ngIf='vault.isEnabled()')
.text-center(*ngIf='!vaultContents')
i.fas.fa-key.fa-3x
h3.m-3 Vault is locked
button.btn.btn-primary.m-2((click)='loadVault()') Show vault contents
h3.m-3(translate) Vault is locked
button.btn.btn-primary.m-2((click)='loadVault()', translate) Show vault contents

View file

@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { Component, HostBinding } from '@angular/core'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import { BaseComponent, VaultService, VaultSecret, Vault, PlatformService, ConfigService, VAULT_SECRET_TYPE_FILE, PromptModalComponent, VaultFileSecret } from 'tabby-core'
import { BaseComponent, VaultService, VaultSecret, Vault, PlatformService, ConfigService, VAULT_SECRET_TYPE_FILE, PromptModalComponent, VaultFileSecret, TranslateService } from 'tabby-core'
import { SetVaultPassphraseModalComponent } from './setVaultPassphraseModal.component'
@ -21,6 +21,7 @@ export class VaultSettingsTabComponent extends BaseComponent {
public config: ConfigService,
private platform: PlatformService,
private ngbModal: NgbModal,
private translate: TranslateService,
) {
super()
if (vault.isOpen()) {
@ -43,8 +44,11 @@ export class VaultSettingsTabComponent extends BaseComponent {
if ((await this.platform.showMessageBox(
{
type: 'warning',
message: 'Delete vault contents?',
buttons: ['Delete', 'Keep'],
message: this.translate.instant('Delete vault contents?'),
buttons: [
this.translate.instant('Delete'),
this.translate.instant('Keep'),
],
defaultId: 1,
cancelId: 1,
}
@ -77,16 +81,16 @@ export class VaultSettingsTabComponent extends BaseComponent {
getSecretLabel (secret: VaultSecret) {
if (secret.type === 'ssh:password') {
return `SSH password for ${(secret as any).key.user}@${(secret as any).key.host}:${(secret as any).key.port}`
return this.translate.instant('SSH password for {user}@{host}:{port}', (secret as any).key)
}
if (secret.type === 'ssh:key-passphrase') {
return `Passphrase for a private key with hash ${(secret as any).key.hash.substring(0, 8)}...`
return this.translate.instant('Passphrase for a private key with hash {hash}...', { hash: (secret as any).key.hash.substring(0, 8) })
}
if (secret.type === VAULT_SECRET_TYPE_FILE) {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
return `File: ${(secret as VaultFileSecret).key.description}`
return this.translate.instant('File: {description}', (secret as VaultFileSecret).key)
}
return `Unknown secret of type ${secret.type} for ${JSON.stringify(secret.key)}`
return this.translate.instant('Unknown secret of type {type} for {key}', { type: secret.type, key: JSON.stringify(secret.key) })
}
removeSecret (secret: VaultSecret) {
@ -111,7 +115,7 @@ export class VaultSettingsTabComponent extends BaseComponent {
async renameFile (secret: VaultFileSecret) {
const modal = this.ngbModal.open(PromptModalComponent)
modal.componentInstance.prompt = 'New name'
modal.componentInstance.prompt = this.translate.instant('New name')
modal.componentInstance.value = secret.key.description
const description = (await modal.result)?.value

View file

@ -1,8 +1,8 @@
h3.mb-3 Window
h3.mb-3(translate) Window
.form-line
.header
.title Theme
.title(translate) Theme
select.form-control(
[(ngModel)]='config.store.appearance.theme',
(ngModelChange)='saveConfiguration()',
@ -12,8 +12,8 @@ h3.mb-3 Window
.form-line(*ngIf='hostApp.platform === Platform.Web')
.header
.title Ask before closing the browser tab
.description Prevents accidental closing
.title(translate) Ask before closing the browser tab
.description(translate) Prevents accidental closing
toggle(
[(ngModel)]='config.store.web.preventAccidentalTabClosure',
(ngModelChange)='saveConfiguration()',
@ -22,9 +22,9 @@ h3.mb-3 Window
.form-line(*ngIf='platform.supportsWindowControls')
.header
.title(*ngIf='hostApp.platform !== Platform.macOS') Acrylic background
.title(*ngIf='hostApp.platform === Platform.macOS') Vibrancy
.description Gives the window a blurred transparent background
.title(*ngIf='hostApp.platform !== Platform.macOS', translate) Acrylic background
.title(*ngIf='hostApp.platform === Platform.macOS', translate) Vibrancy
.description(translate) Gives the window a blurred transparent background
toggle(
[(ngModel)]='config.store.appearance.vibrancy',
@ -33,7 +33,7 @@ h3.mb-3 Window
.form-line(*ngIf='config.store.appearance.vibrancy && isFluentVibrancySupported')
.header
.title Background type
.title(translate) Background type
.btn-group(
[(ngModel)]='config.store.appearance.vibrancyType',
(ngModelChange)='saveConfiguration()',
@ -45,18 +45,18 @@ h3.mb-3 Window
ngbButton,
[value]='"blur"'
)
| Blur
span(translate) Blur
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='"fluent"'
)
| Fluent
span Fluent
.form-line(*ngIf='platform.supportsWindowControls')
.header
.title Opacity
.title(translate) Opacity
input(
type='range',
[(ngModel)]='config.store.appearance.opacity',
@ -68,8 +68,8 @@ h3.mb-3 Window
.form-line(*ngIf='platform.supportsWindowControls')
.header
.title Window frame
.description Whether a custom window or an OS native window should be used
.title(translate) Window frame
.description(translate) Whether a custom window or an OS native window should be used
.btn-group(
[(ngModel)]='config.store.appearance.frame',
@ -82,28 +82,28 @@ h3.mb-3 Window
ngbButton,
[value]='"native"'
)
| Native
span(translate) Native
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='"thin"'
)
| Thin
span(translate) Thin
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='"full"'
)
| Full
span(translate) Full
h3.mt-4 Docking
h3.mt-4(translate) Docking
.form-line(*ngIf='docking')
.header
.title Dock the terminal
.description Snaps the window to a side of the screen
.title(translate) Dock the terminal
.description(translate) Snaps the window to a side of the screen
.btn-group(
[(ngModel)]='config.store.appearance.dock',
@ -116,40 +116,40 @@ h3.mt-4 Docking
ngbButton,
[value]='"off"'
)
| Off
span(translate) Off
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='"top"'
)
| Top
span(translate) Top
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='"left"'
)
| Left
span(translate) Left
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='"right"'
)
| Right
span(translate) Right
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='"bottom"'
)
| Bottom
span(translate) Bottom
.ml-5.form-line(*ngIf='docking && config.store.appearance.dock != "off"')
.header
.title Display on
.description Snaps the window to a side of the screen
.title(translate) Display on
.description(translate) Snaps the window to a side of the screen
div(
[(ngModel)]='config.store.appearance.dockScreen',
@ -162,7 +162,7 @@ h3.mt-4 Docking
ngbButton,
value='current'
)
| Current
span(translate) Current
label.btn.btn-secondary(*ngFor='let screen of screens', ngbButtonLabel)
input(
type='radio',
@ -173,8 +173,8 @@ h3.mt-4 Docking
.ml-5.form-line(*ngIf='docking && config.store.appearance.dock != "off"')
.header
.title Dock always on top
.description Keep docked terminal always on top
.title(translate) Dock always on top
.description(translate) Keep docked terminal always on top
toggle(
[(ngModel)]='config.store.appearance.dockAlwaysOnTop',
(ngModelChange)='saveConfiguration(); docking.dock()',
@ -182,7 +182,7 @@ h3.mt-4 Docking
.ml-5.form-line(*ngIf='docking && config.store.appearance.dock != "off"')
.header
.title Docked terminal size
.title(translate) Docked terminal size
input(
type='range',
[(ngModel)]='config.store.appearance.dockFill',
@ -194,7 +194,7 @@ h3.mt-4 Docking
.ml-5.form-line(*ngIf='docking && config.store.appearance.dock != "off"')
.header
.title Docked terminal space
.title(translate) Docked terminal space
input(
type='range',
[(ngModel)]='config.store.appearance.dockSpace',
@ -206,18 +206,18 @@ h3.mt-4 Docking
.ml-5.form-line(*ngIf='docking && config.store.appearance.dock != "off"')
.header
.title Hide dock on blur
.description Hides the docked terminal when you click away.
.title(translate) Hide dock on blur
.description(translate) Hides the docked terminal when you click away.
toggle(
[(ngModel)]='config.store.appearance.dockHideOnBlur',
(ngModelChange)='saveConfiguration(); ',
)
h3.mt-4 Tabs
h3.mt-4(translate) Tabs
.form-line
.header
.title Tabs location
.title(translate) Tabs location
.btn-group(
[(ngModel)]='config.store.appearance.tabsLocation',
(ngModelChange)='saveConfiguration()',
@ -229,32 +229,32 @@ h3.mt-4 Tabs
ngbButton,
[value]='"top"'
)
| Top
span(translate) Top
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='"bottom"'
)
| Bottom
span(translate) Bottom
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='"left"'
)
| Left
span(translate) Left
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='"right"'
)
| Right
span(translate) Right
.form-line
.header
.title Tabs width
.title(translate) Tabs width
.btn-group(
[(ngModel)]='config.store.appearance.flexTabs',
(ngModelChange)='saveConfiguration()',
@ -266,18 +266,18 @@ h3.mt-4 Tabs
ngbButton,
[value]='true'
)
| Dynamic
span(translate) Dynamic
label.btn.btn-secondary(ngbButtonLabel)
input(
type='radio',
ngbButton,
[value]='false'
)
| Fixed
span(translate) Fixed
.form-line
.header
.title Hide tab index
.title(translate) Hide tab index
toggle(
[(ngModel)]='config.store.terminal.hideTabIndex',
@ -286,7 +286,7 @@ h3.mt-4 Tabs
.form-line
.header
.title Hide tab close button
.title(translate) Hide tab close button
toggle(
[(ngModel)]='config.store.terminal.hideCloseButton',
@ -297,8 +297,8 @@ h3.mt-4 Hacks
.form-line
.header
.title Disable GPU acceleration
.description Tick this if you're experiencing aliasing, ghosting or other visual issues
.title(translate) Disable GPU acceleration
.description(translate) Tick this if you're experiencing aliasing, ghosting or other visual issues
toggle(
[(ngModel)]='config.store.hacks.disableGPU',

View file

@ -1,5 +1,5 @@
import { Injectable } from '@angular/core'
import { HotkeyDescription, HotkeyProvider } from 'tabby-core'
import { HotkeyDescription, HotkeyProvider, TranslateService } from 'tabby-core'
/** @hidden */
@Injectable()
@ -7,10 +7,12 @@ export class SettingsHotkeyProvider extends HotkeyProvider {
hotkeys: HotkeyDescription[] = [
{
id: 'settings',
name: 'Open Settings',
name: this.translate.instant('Open Settings'),
},
]
constructor (private translate: TranslateService) { super() }
async provide (): Promise<HotkeyDescription[]> {
return this.hotkeys
}

View file

@ -5,13 +5,16 @@ import { WindowSettingsTabComponent } from './components/windowSettingsTab.compo
import { VaultSettingsTabComponent } from './components/vaultSettingsTab.component'
import { ConfigSyncSettingsTabComponent } from './components/configSyncSettingsTab.component'
import { ProfilesSettingsTabComponent } from './components/profilesSettingsTab.component'
import { TranslateService } from 'tabby-core'
/** @hidden */
@Injectable()
export class HotkeySettingsTabProvider extends SettingsTabProvider {
id = 'hotkeys'
icon = 'keyboard'
title = 'Hotkeys'
title = this.translate.instant('Hotkeys')
constructor (private translate: TranslateService) { super() }
getComponentType (): any {
return HotkeySettingsTabComponent
@ -24,7 +27,9 @@ export class HotkeySettingsTabProvider extends SettingsTabProvider {
export class WindowSettingsTabProvider extends SettingsTabProvider {
id = 'window'
icon = 'window-maximize'
title = 'Window'
title = this.translate.instant('Window')
constructor (private translate: TranslateService) { super() }
getComponentType (): any {
return WindowSettingsTabComponent
@ -50,9 +55,11 @@ export class VaultSettingsTabProvider extends SettingsTabProvider {
export class ProfilesSettingsTabProvider extends SettingsTabProvider {
id = 'profiles'
icon = 'window-restore'
title = 'Profiles & connections'
title = this.translate.instant('Profiles & connections')
prioritized = true
constructor (private translate: TranslateService) { super() }
getComponentType (): any {
return ProfilesSettingsTabComponent
}
@ -63,7 +70,9 @@ export class ProfilesSettingsTabProvider extends SettingsTabProvider {
export class ConfigSyncSettingsTabProvider extends SettingsTabProvider {
id = 'config-sync'
icon = 'cloud'
title = 'Config sync'
title = this.translate.instant('Config sync')
constructor (private translate: TranslateService) { super() }
getComponentType (): any {
return ConfigSyncSettingsTabComponent

View file

@ -1,5 +1,5 @@
.d-flex
strong Keyboard-interactive auth
strong(translate) Keyboard-interactive auth
.ml-2 {{prompt.name}}
.prompt-text {{prompt.prompts[step].prompt}}

View file

@ -1,6 +1,6 @@
.modal-body
label Deleting
label(translate) Deleting
.no-wrap {{progressMessage}}
.modal-footer
button.btn.btn-danger((click)='cancel()') Cancel
button.btn.btn-danger((click)='cancel()', translate) Cancel

View file

@ -8,21 +8,21 @@
button.btn.btn-link.btn-sm.d-flex((click)='upload()')
i.fas.fa-upload.mr-1
div Upload
div(translate) Upload
button.btn.btn-link.btn-close((click)='close()') !{require('../../../tabby-core/src/icons/times.svg')}
.body(dropZone, (transfer)='uploadOne($event)')
div(*ngIf='!sftp') Connecting
div(*ngIf='!sftp', translate) Connecting
div(*ngIf='sftp')
div(*ngIf='fileList === null') Loading
div(*ngIf='fileList === null', translate) Loading
.list-group.list-group-light(*ngIf='fileList !== null')
.list-group-item.list-group-item-action.d-flex.align-items-center(
*ngIf='path !== "/"',
(click)='goUp()'
)
i.fas.fa-fw.fa-level-up-alt
div Go up
div(translate) Go up
.list-group-item.list-group-item-action.d-flex.align-items-center(
*ngFor='let item of fileList',
(contextmenu)='showContextMenu(item, $event)',

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