Merge signal-1.24.0

# Conflicts:
#	.github/PULL_REQUEST_TEMPLATE.md
#	background.html
#	config/default.json
#	config/production.json
#	js/models/conversations.js
#	js/models/messages.js
#	js/views/conversation_view.js
#	js/views/inbox_view.js
#	js/views/settings_view.js
#	main.js
#	package.json
#	test/index.html
#	ts/components/conversation/ContactName.tsx
#	yarn.lock
This commit is contained in:
Mikunj 2019-04-18 12:45:19 +10:00
commit 8808100796
107 changed files with 79901 additions and 1147 deletions

View File

@ -5,6 +5,7 @@ dist/**
mnemonic_languages/**
# Generated files
js/curve/*
js/components.js
js/libtextsecure.js
js/libloki.js

38
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,38 @@
<!--
Thanks for contributing to the project!
Please help us keep this project in good shape by going through this checklist.
Replace the empty checkboxes [ ] below with checked ones [X] as they are completed
Remember, you can preview this before saving it.
-->
<!-- You can remove this first section if you have contributed before -->
### First time contributor checklist:
* [ ] I have read the [README](https://github.com/signalapp/Signal-Desktop/blob/master/README.md) and [Contributor Guidelines](https://github.com/signalapp/Signal-Desktop/blob/master/CONTRIBUTING.md)
* [ ] I have signed the [Contributor Licence Agreement](https://signal.org/cla/)
### Contributor checklist:
* [ ] My contribution is **not** related to translations. _Please submit translation changes via our [Signal Desktop Transifex project](https://www.transifex.com/signalapp/signal-desktop/)._
* [ ] My commits are in nice logical chunks with [good commit messages](http://chris.beams.io/posts/git-commit/)
* [ ] My changes are [rebased](https://medium.freecodecamp.org/git-rebase-and-the-golden-rule-explained-70715eccc372) on the latest [`development`](https://github.com/signalapp/Signal-Desktop/tree/development) branch
* [ ] A `yarn ready` run passes successfully ([more about tests here](https://github.com/signalapp/Signal-Desktop/blob/master/CONTRIBUTING.md#tests))
* [ ] My changes are ready to be shipped to users
### Description
<!--
Describe briefly what your pull request changes. Focus on the value provided to users.
Does it address any outstanding issues in this project?
https://github.com/signalapp/Signal-Desktop/issues?utf8=%E2%9C%93&q=is%3Aissue
Reference an issue with the hash symbol: "#222"
If you're fixing it, use something like "Fixes #222"
Please write a summary of your test approach:
- What kind of manual testing did you do?
- Did you write any new tests?
- What operating systems did you test with? (please use specific versions: http://whatsmyos.com/)
- What other devices did you test with? (other Desktop devices, Android, Android Simulator, iOS, iOS Simulator)
-->

View File

@ -26,6 +26,7 @@ libloki/test/components.js
# Third-party files
node_modules/**
components/**
js/curve/**
js/Mp3LameEncoder.min.js
js/WebAudioRecorderMp3.js
js/libsignal-protocol-worker.js

View File

@ -10,11 +10,6 @@ It's a good idea to gauge interest in your intended work by finding the current
for it or creating a new one yourself. You can use also that issue as a place to signal
your intentions and get feedback from the users most likely to appreciate your changes.
You're most likely to have your pull request accepted easily if it addresses bugs already
in the [Next Steps project](https://github.com/signalapp/Signal-Desktop/projects/1),
especially if they are near the top of the Backlog column. Those are what we'll be looking
at next, so it would be great if you helped us out!
Once you've spent a little bit of time planning your solution, it's a good idea to go
back to the issue and talk about your approach. We'd be happy to provide feedback. [An
ounce of prevention, as they say!](https://www.goodreads.com/quotes/247269-an-ounce-of-prevention-is-worth-a-pound-of-cure)
@ -87,9 +82,12 @@ yarn grunt dev # runs until you stop it, re-generating built assets on file chan
By default the application will connect to the **staging** servers, which means that you
**will not** be able to link it with your primary mobile device.
Fear not! You don't have to link the app with your phone. During setup in development
mode, you'll be presented with a 'Standalone' button which goes through the registration
process like you would on a phone. But you won't be linked to any other devices.
Fear not! You don't have to link the app with your phone. On the QR code screen, you can
select 'Set Up as Standalone Device' from the File menu, which goes through the
registration process like you would on a phone.
Note: you won't be linked to a primary phone, which will make testing certain things very
difficult (contacts, profiles, and groups are all solely managed on your phone).
## The staging environment
@ -173,6 +171,8 @@ the report with `yarn open-coverage`.
So you wanna make a pull request? Please observe the following guidelines.
* First, make sure that your `yarn ready` run passes - it's very similar to what our
Continuous Integration servers do to test the app.
* Please do not submit pull requests for translation fixes. Anyone can update
the translations in
[Transifex](https://www.transifex.com/projects/p/signal-desktop).

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Copy error and quit",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Unknown group",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Database Error",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Delete all data and restart",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&File",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Archived Conversations",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "These conversations are archived and will only appear in the Inbox if new messages are received.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Archive Conversation",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Move Conversation to Inbox",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Choose folder",
"description": "Button to allow the user to find a folder on disk"
@ -611,14 +643,36 @@
"message": "Quit",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Enter name or number",
"search": {
"message": "بحث",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "No results for \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "المحادثات",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "جهات الإتصال",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "الرسائل",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "مرحبا الى سيجنال Signal",
"description": ""
@ -673,6 +727,10 @@
"message": "PO Box",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "التنزيل جارٍ...",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Download Attachment",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "Photo",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "حسنا",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "إلى",
"message": "to",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1055,10 +1125,6 @@
"message": "انتهت صلاحية هذا الإصدار من سيغنال للحاسوب. الرجاء الارتقاء الى أحدث إصدار لمواصلة الرسائل.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "مستخدم أندرويد سيستقبل فقط أول 2000 حرف من هذه الرسالة",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "تحديث",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "Dark",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Note to Self",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "Hide menu bar",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Start conversation…",
"message": "Start new conversation…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Copy error and quit",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Unknown group",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Database Error",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Delete all data and restart",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&Файл",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Архивирани разговори",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "These conversations are archived and will only appear in the Inbox if new messages are received.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Archive Conversation",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Move Conversation to Inbox",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Изберете папка",
"description": "Button to allow the user to find a folder on disk"
@ -611,14 +643,36 @@
"message": "Изход",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Сигнал Десктоп",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Въведете име или номер",
"search": {
"message": "Търсене",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "No results for \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Чатове",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Контакти",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Съобщения",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Добре дошли в Сигнал",
"description": ""
@ -673,6 +727,10 @@
"message": "PO Box",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Downloading",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Download Attachment",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "Изображение",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "Добре",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "До",
"message": "to",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1055,10 +1125,6 @@
"message": "Тази версия на Сигнал за компютър вече е остаряла. Моля, обновете до последната версия за да можете да изпращате съобщения.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Клиентите на Android получават само първите 2000 знака от това съобщение.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Обновяване",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "Dark",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Note to Self",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "Скрий лентата с менютата",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Започнете разговор...",
"message": "Start new conversation…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Copia l'error i surt",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Grup desconegut",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Error de la base de dades",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Suprimeix totes les dades i reinicia",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&Fitxer",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Converses arxivades",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "Aquestes converses estan arxivades i només apareixeran a la bústia d'entrada si es reben missatges nous.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Arxiva la conversa",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Mou la conversa a la safata d'entrada",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Trieu una carpeta",
"description": "Button to allow the user to find a folder on disk"
@ -611,14 +643,36 @@
"message": "Surt",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Introduïu un nom o número",
"search": {
"message": "Cerca",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "No hi ha cap resultat per a \"$searchTerm$\".",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Converses",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Contactes",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Missatges",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Benvingut al Signal",
"description": ""
@ -673,6 +727,10 @@
"message": "Apartat de correus",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "S'està baixant",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Baixa l'adjunt",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "Foto",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "D'acord",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "A",
"message": "a",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1055,10 +1125,6 @@
"message": "Aquesta versió del Signal Desktop ha expirat. Actualitzeu a l'última versió per a poder seguir enviant i rebent missatges.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Els clients d'Android només rebran els primers 2000 caràcters d'aquest missatge.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Actualitza",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "Fosc",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Notifica-m'ho",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "Amaga la barra de menú",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Comenceu la conversa...",
"message": "Comença una conversa nova...",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Zkopírovat chybu a ukončit",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Unknown group",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Chyba databáze",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Smazat všechna data a restartovat",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&Soubor",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Archivované konverzace",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "Tyto konverzace jsou archivované a zobrazí se mezi doručenými zprávami, pokud budou přijaty nové zprávy.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Archive Conversation",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Move Conversation to Inbox",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Vybrat složku",
"description": "Button to allow the user to find a folder on disk"
@ -611,14 +643,36 @@
"message": "Opustit",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Zadejte jméno nebo číslo",
"search": {
"message": "Hledat",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "No results for \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Konverzace",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Kontakty",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Zprávy",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Vítejte v Signalu",
"description": ""
@ -673,6 +727,10 @@
"message": "P. O. BOX",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Downloading",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Stáhnout přílohu",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "Fotografie",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "OK",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "Komu",
"message": "to",
"description": "Label for the receiver of a message"
},
"sent": {
@ -908,7 +978,7 @@
"description": "Used in the guidance to help people find the 'link new device' area of their Signal mobile app"
},
"plusButton": {
"message": "'+' Button",
"message": "Tlačítko '+'",
"description": "The button used in Signal Android to add a new linked device"
},
"linkNewDevice": {
@ -1055,10 +1125,6 @@
"message": "Tato verze aplikace Signal Desktop je zastaralá. Abyste mohli dále komunikovat, aktualizujte ji prosím na nejnovější verzi.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Uživatelé Androidu dostanou pouze prvních 2000 znaků této zprávy.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Aktualizovat",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "Tmavý",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Poznámka sobě",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "Schovat lištu menu",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Zahájit konverzaci...",
"message": "Start new conversation…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -3,6 +3,10 @@
"message": "Kopier fejl og afslut",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Ukendt gruppe",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Databasefejl",
"description": "Shown in a popup if the database cannot start up properly"
@ -157,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Arkiveret samtaler",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "Disse samtaler arkiveres og vises kun i indbakken, hvis der modtages nye meddelelser.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Arkiver samtalen",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Flyt samtalen til indbakken",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Vælg mappe",
"description": "Button to allow the user to find a folder on disk"
@ -623,14 +643,36 @@
"message": "Afslut",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Indtast navn eller nummer",
"search": {
"message": "Søg",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "Ingen resultater for \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Samtaler",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Kontakter",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Beskeder",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Velkommen til Signal",
"description": ""
@ -685,6 +727,10 @@
"message": "Postboks",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Henter",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Hent vedhæftet fil",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -747,6 +793,18 @@
"message": "Billede",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "Ok",
"description": ""
@ -784,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "Til",
"message": "til",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1067,10 +1125,6 @@
"message": "Denne version af Signal er forældet. Venligst opgrader til den seneste version.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Android-enheder vil kun modtage de første 2000 tegn af denne besked.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Opgrader",
"description": "Label text for button to upgrade the app to the latest version"
@ -1386,7 +1440,7 @@
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Start samtale...",
"message": "Start ny samtale...",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -3,6 +3,10 @@
"message": "Fehler kopieren und beenden",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Unbekannte Gruppe",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Datenbankfehler",
"description": "Shown in a popup if the database cannot start up properly"
@ -157,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Archivierte Unterhaltungen",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "Diese Unterhaltungen sind archiviert und werden nur dann im Eingang erscheinen, falls neue Nachrichten empfangen werden.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Unterhaltung archivieren",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Unterhaltung in Eingang verschieben",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Ordner wählen",
"description": "Button to allow the user to find a folder on disk"
@ -623,14 +643,36 @@
"message": "Beenden",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Name oder Rufnummer eingeben",
"search": {
"message": "Suchen",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "Keine Ergebnisse für »$searchTerm$«",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Unterhaltungen",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Kontakte",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Nachrichten",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Willkommen bei Signal",
"description": ""
@ -685,6 +727,10 @@
"message": "Postfach",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Wird heruntergeladen",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Anhang herunterladen",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -747,6 +793,18 @@
"message": "Foto",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "Okay",
"description": ""
@ -784,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "An",
"message": "an",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1067,10 +1125,6 @@
"message": "Diese Version von Signal Desktop ist veraltet. Bitte führe eine Aktualisierung auf die aktuellste Version durch, um weiterhin Nachrichten austauschen zu können.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Signal für Android kann nur die ersten 2.000 Zeichen dieser Nachricht empfangen.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Aktualisieren",
"description": "Label text for button to upgrade the app to the latest version"
@ -1386,7 +1440,7 @@
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Unterhaltung beginnen …",
"message": "Neue Unterhaltung beginnen …",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Αντιγραφή λάθους και έξοδος",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Unknown group",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Λάθος της βάσης δεδομένων",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Διαγραφή όλων των δεδομένων και επανεκκίνηση",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&Φάκελος",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,12 +161,28 @@
}
}
},
"archivedConversations": {
"message": "Αρχειοθετημένες Συνομιλίες",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "Αυτές οι συνομιλίες είναι αρχειοθετημένες και θα εμφανιστούν στα εισερχόμενα μόνο αν ληφθούν νέα μηνύματα.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Archive Conversation",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Move Conversation to Inbox",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Επιλογή φακέλου",
"description": "Button to allow the user to find a folder on disk"
},
"chooseFile": {
"message": "Choose file",
"message": "Επιλογή αρχείου",
"description": "Button to allow the user to find a file on disk"
},
"loadDataHeader": {
@ -484,11 +516,11 @@
"description": "Shown in toast when user attempts to send .exe file, for example"
},
"loadingPreview": {
"message": "Loading Preview...",
"message": "Φόρτωση προεσκόπισης...",
"description": "Shown while Signal Desktop is fetching metadata for a url in composition area"
},
"stagedPreviewThumbnail": {
"message": "Draft thumbnail link preview for $domain$",
"message": "Πρόχειρη μικρή προεσκόπιση συνδέσμου για $domain$",
"description": "Shown while Signal Desktop is fetching metadata for a url in composition area",
"placeholders": {
"path": {
@ -498,7 +530,7 @@
}
},
"previewThumbnail": {
"message": "Thumbnail link preview for $domain$",
"message": "Μικρή προεσκόπιση συνδέσμου για $domain$",
"description": "Shown while Signal Desktop is fetching metadata for a url in composition area",
"placeholders": {
"path": {
@ -508,7 +540,7 @@
}
},
"stagedImageAttachment": {
"message": "Draft image attachment: $path$",
"message": "Πρόχειρη συνημμένη εικόνα: $path$",
"description": "Alt text for staged attachments",
"placeholders": {
"path": {
@ -518,15 +550,15 @@
}
},
"oneNonImageAtATimeToast": {
"message": "When including a non-image attachment, the limit is one attachment per message.",
"message": "Για συνημμένα αρχεία που δεν είναι εικόνες, το όριο είναι ένα αρχείο ανά μήνυμα.",
"description": "An error popup when the user has attempted to add an attachment"
},
"cannotMixImageAdnNonImageAttachments": {
"message": "You cannot mix non-image and image attachments in one message.",
"message": "Δεν είναι δυνατό να συνάψετε εικόνες μαζί με αρχεία άλλου τύπου στο ίδιο μήνυμα.",
"description": "An error popup when the user has attempted to add an attachment"
},
"maximumAttachments": {
"message": "You cannot add any more attachments to this message.",
"message": "Δεν είναι δυνατή η προσθήκη άλλων συνημμένων αρχείων σε αυτό το μήνυμα.",
"description": "An error popup when the user has attempted to add an attachment"
},
"fileSizeWarning": {
@ -611,14 +643,36 @@
"message": "Έξοδος",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Εισάγετε όνομα ή αριθμό",
"search": {
"message": "Αναζήτηση",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "No results for \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Συνομιλίες",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Επαφές",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Μηνύματα",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Καλώς ορίσατε στο Signal",
"description": ""
@ -628,7 +682,7 @@
"description": ""
},
"typingAlt": {
"message": "Typing animation for this conversation",
"message": "Κινούμενη εικόνα που δείχνει πληκτρολόγηση για αυτή τη συζήτηση",
"description": "Used as the 'title' attibute for the typing animation"
},
"contactAvatarAlt": {
@ -673,6 +727,10 @@
"message": "Τ.Θ.",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Downloading",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Λήψη Συνημμένου",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -694,7 +752,7 @@
"description": "Shown in toast if user clicks on quote references messages not loaded in view, but in database"
},
"voiceNoteMustBeOnlyAttachment": {
"message": "A voice note must be the only attachment included in a message.",
"message": "Ένα μήνυμα φωνής πρέπει να είναι το μοναδικό συνημμένο αρχείο σε ένα μήνυμα.",
"description": "Shown in toast if tries to record a voice note with any staged attachments"
},
"you": {
@ -735,6 +793,18 @@
"message": "Φωτογραφία ",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "OK",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "Προς",
"message": "to",
"description": "Label for the receiver of a message"
},
"sent": {
@ -862,7 +932,7 @@
"description": "Used in the alt tag for the image shown in a full-screen lightbox view"
},
"imageCaptionIconAlt": {
"message": "Icon showing that this image has a caption",
"message": "Εικονίδιο που ενδεικνύει ότι αυτή η εικόνα έχει υπότιτλο",
"description": "Used for the icon layered on top of an image in message bubbles"
},
"addACaption": {
@ -956,7 +1026,7 @@
"description": "Description of the media permission description"
},
"general": {
"message": "General",
"message": "Γενικά",
"description": "Header for general options on the settings screen"
},
"spellCheckDescription": {
@ -1055,10 +1125,6 @@
"message": "Αυτή η έκδοση του Signal Desktop έχει λήξει. Κάντε αναβάθμιση στην πιο πρόσφατη έκδοση για να συνεχίσετε την ανταλλαγή μηνυμάτων.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Οι παραλήπτες σε Android θα λάβουν μόνο τους πρώτους 2000 χαρακτήρες αυτού του μηνύματος.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Αναβάθμιση",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "Σκοτεινό",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Να μην ξεχάσω ",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "Απόκρυψη γραμμής μενού",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Έναρξη συνομιλίας...",
"message": "Start new conversation…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -900,6 +900,22 @@
"description":
"Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message":
"Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description":
"Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message":
"Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description":
"Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "OK"
},
@ -1430,6 +1446,10 @@
"description":
"Timestamp format string for displaying month and day (but not the year) of a date within the current year, ex: use 'MMM D' for 'Aug 8', or 'D MMM' for '8 Aug'."
},
"messageBodyTooLong": {
"message": "Message body is too long.",
"description": "Shown if the user tries to send more than 64kb of text"
},
"unblockToSend": {
"message": "Unblock this contact to send a message.",
"description": "Brief message shown when trying to message a blocked number"

View File

@ -3,6 +3,10 @@
"message": "Kopii la eraron kaj eliri",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Nekonata grupo",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Datumbaza eraro",
"description": "Shown in a popup if the database cannot start up properly"
@ -157,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Enarĥivigitaj interparoloj",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "Tiuj interparoloj estas enarĥivigitaj kaj aperos en la ricevujo, nur se novaj mesaĝoj riceviĝas.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Enarĥivigi interparolon",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Movi interparolon al la ricevujo",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Elekti dosierujon",
"description": "Button to allow the user to find a folder on disk"
@ -623,14 +643,36 @@
"message": "Fini",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Entajpi nomon aŭ numeron",
"search": {
"message": "Serĉi",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "Neniu rezulto pri „$searchTerm$“",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Interparoloj",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Kontaktaro",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Mesaĝoj",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Bonvenon al Signal",
"description": ""
@ -685,6 +727,10 @@
"message": "abonkesto",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Elŝutado",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Elŝuti kunsendaĵon",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -747,6 +793,18 @@
"message": "Foto",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "Bone",
"description": ""
@ -784,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "Al",
"message": "al",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1067,10 +1125,6 @@
"message": "Tiu ĉi versio de Signal Desktop jam nevalidas. Bonvolu ĝisdatigi al la nuna versio por daŭrigi sendi mesaĝojn.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Androidaj klientoj ricevos nur la unuajn 2 000 signojn de tiu mesaĝo.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Ĝisdatigi",
"description": "Label text for button to upgrade the app to the latest version"
@ -1386,7 +1440,7 @@
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Komenci interparolon…",
"message": "Krei novan interparolon...",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -3,6 +3,10 @@
"message": "Copiar fallo y cerrar Signal",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Grupo sin nombre",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Fallo en la base de datos",
"description": "Shown in a popup if the database cannot start up properly"
@ -157,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Chats archivados",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "Estos chats están archivados y sólo aparecerán en el buzón de entrada si recibes nuevos mensajes.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Archivar chat",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Devolver chat al buzón de entrada",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Seleccionar carpeta",
"description": "Button to allow the user to find a folder on disk"
@ -623,14 +643,36 @@
"message": "Cerrar",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Introducir nombre o número",
"search": {
"message": "Buscar",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "Sin resultados para «$searchTerm$»",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Chats",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Contactos",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Mensajes",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Bienvenida a Signal",
"description": ""
@ -685,6 +727,10 @@
"message": "apdo. de correos",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Descargando",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Descargar adjunto",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -747,6 +793,18 @@
"message": "Foto",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "Aceptar",
"description": ""
@ -784,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "A",
"message": "para",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1067,10 +1125,6 @@
"message": "Esta versión de Signal Desktop ha caducado. Por favor, actualiza a la última versión para seguir enviando mensajes.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Contactos con un teléfono Android solo recibirán los primeros 2000 caracteres de este mensaje.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Actualizar",
"description": "Label text for button to upgrade the app to the latest version"
@ -1386,7 +1440,7 @@
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Iniciar chat ...",
"message": "Comienza con un chat ...",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Copy error and quit",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Unknown group",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Database Error",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Delete all data and restart",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&Fail",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Arhiveeritud vestlused",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "Need vestlused on arhiveeritud ja ilmuvad sisendkausta, kui saabub uusi sõnumeid.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Archive Conversation",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Move Conversation to Inbox",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Vali kaust",
"description": "Button to allow the user to find a folder on disk"
@ -484,11 +516,11 @@
"description": "Shown in toast when user attempts to send .exe file, for example"
},
"loadingPreview": {
"message": "Loading Preview...",
"message": "Eelvaate laadimine...",
"description": "Shown while Signal Desktop is fetching metadata for a url in composition area"
},
"stagedPreviewThumbnail": {
"message": "Draft thumbnail link preview for $domain$",
"message": "Lingi eelvaate pisipildi mustand: $domain$",
"description": "Shown while Signal Desktop is fetching metadata for a url in composition area",
"placeholders": {
"path": {
@ -498,7 +530,7 @@
}
},
"previewThumbnail": {
"message": "Thumbnail link preview for $domain$",
"message": "Lingi eelvaate pisipilt: $domain$",
"description": "Shown while Signal Desktop is fetching metadata for a url in composition area",
"placeholders": {
"path": {
@ -508,7 +540,7 @@
}
},
"stagedImageAttachment": {
"message": "Draft image attachment: $path$",
"message": "Piltmanuse mustand: $path$",
"description": "Alt text for staged attachments",
"placeholders": {
"path": {
@ -518,15 +550,15 @@
}
},
"oneNonImageAtATimeToast": {
"message": "When including a non-image attachment, the limit is one attachment per message.",
"message": "Mittepildilisi manuseid sõnumile lisades kehtiv ühe manuse piirang.",
"description": "An error popup when the user has attempted to add an attachment"
},
"cannotMixImageAdnNonImageAttachments": {
"message": "You cannot mix non-image and image attachments in one message.",
"message": "Piltmanuseid ja teisi manuseid ei saa koos ühte sõnumisse panna.",
"description": "An error popup when the user has attempted to add an attachment"
},
"maximumAttachments": {
"message": "You cannot add any more attachments to this message.",
"message": "Sellele sõnumile pole võimalik rohkem manuseid lisada.",
"description": "An error popup when the user has attempted to add an attachment"
},
"fileSizeWarning": {
@ -611,14 +643,36 @@
"message": "Välju",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Sisesta nimi või number",
"search": {
"message": "Otsi",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "No results for \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Vestlused",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Kontaktid",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Sõnumid",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Tere tulemast Signalisse",
"description": ""
@ -673,6 +727,10 @@
"message": "postkast",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Laadin alla",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Laadi manus alla",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -694,7 +752,7 @@
"description": "Shown in toast if user clicks on quote references messages not loaded in view, but in database"
},
"voiceNoteMustBeOnlyAttachment": {
"message": "A voice note must be the only attachment included in a message.",
"message": "Häälmärkmed peavad olema sõnumi ainuke manus.",
"description": "Shown in toast if tries to record a voice note with any staged attachments"
},
"you": {
@ -735,6 +793,18 @@
"message": "Foto",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "Sobib",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "Saaja",
"message": "to",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1055,10 +1125,6 @@
"message": "See Signal Desktopi versioon on aegunud. Palun uuenda uusimale versioonile sõnumite saatmiseks jätkamiseks.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Androidi kasutajad saavad ainult selle sõnumi esimesed 2000 märki.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Uuenda",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "Tume",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Märkus endale",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "Peida menüüriba",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Alusta vestlust...",
"message": "Start new conversation…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Copy error and quit",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Unknown group",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Database Error",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Delete all data and restart",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&فایل",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "مکالمه های آرشیو شده",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "این مکالمه ها بایگانی شده اند و اگر پیام های جدید دریافت شوند فقط در صندوق به نمایش در می آیند.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Archive Conversation",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Move Conversation to Inbox",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "انتخاب پوشه",
"description": "Button to allow the user to find a folder on disk"
@ -611,14 +643,36 @@
"message": "خروج",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "نام یا شماره وارد کنید",
"search": {
"message": "جستجو",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "No results for \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "مکالمه ها",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "مخاطبین",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "پیام ها",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "به Signal خوش‌آمدید",
"description": ""
@ -673,6 +727,10 @@
"message": "صندوق پست",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "در حال دانلود",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "دانلود ضمیمه",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "تصویر",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "باشه",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "به",
"message": "to",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1055,10 +1125,6 @@
"message": "این نسخه‌ی Signal قدیمی است. برای ارسال پیام لطفا آن را به آخرین نسخه ارتقاء دهید.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "سیستم‌های اندرویدی فقط 2000 کاراکتر اول این پیام را دریافت خواهند کرد.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "ارتقاء",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "تاریک",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Note to Self",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "پنهان کردن نوار منو",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "شروع مکالمه...",
"message": "Start new conversation…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Kopioi virheilmoitus ja lopeta",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Tuntematon ryhmä",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Tietokantavirhe",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Tuhoa kaikki tiedot ja käynnistä uudelleen",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&Tiedosto",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Arkistoidut keskustelut",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "Nämä keskustelut ovat arkistoituja. Ne siirtyvät takaisin postilaatikkoon, jos niihin tulee uusia viestejä",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Arkistoi keskustelu",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Siirrä keskustelu takaisin postilaatikkoon",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Valitse kansio",
"description": "Button to allow the user to find a folder on disk"
@ -611,14 +643,36 @@
"message": "Lopeta",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Syötä nimi tai numero",
"search": {
"message": "Hae",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "Ei tuloksia haulle: \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Keskustelut",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Yhteystiedot",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Viestit",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Tervetuloa Signaliin",
"description": ""
@ -673,6 +727,10 @@
"message": "Postilokero",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Ladataan",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Lataa liite",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "Kuva",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "OK",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "Vastaanottajat",
"message": "vastaanottaja",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1055,10 +1125,6 @@
"message": "Käyttämäsi versio Signal Desktopista on vanhentunut. Viestien lähettäminen ja vastaanottaminen eivät enää toimi, ennen kuin olet päiväittänyt uusimpaan versioon.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Signalin Android-käyttäjät näkevät vain ensimmäiset 2000 merkkiä tästä viestistä.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Päivitä",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "Tumma",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Viestit itselleni",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "Piilota valikkopalkki",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Aloita keskustelu",
"message": "Aloita uusi keskustelu...",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Copier lerreur et quitter",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Groupe inconnu",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Erreur de base de données",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Supprimer toutes les données et relancer",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&Fichier",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Conversations archivées",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "Ces conversations sont archivées et napparaîtront dans la boîte de réception que si de nouveaux messages sont reçus.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Archiver la conversation",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Déplacer la conversation vers la boite de réception",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Sélectionner un dossier",
"description": "Button to allow the user to find a folder on disk"
@ -611,14 +643,36 @@
"message": "Quitter",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop pour ordinateur",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Saisir le nom ou le numéro",
"search": {
"message": "Chercher",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "Aucun résultat pour « $searchTerm$ »",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Conversations",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Contacts",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Messages",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Bienvenue sur Signal",
"description": ""
@ -673,6 +727,10 @@
"message": "Boîte postale",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Téléchargement",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Télécharger la pièce jointe",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "Photo",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "Valider",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "À",
"message": "à",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1055,10 +1125,6 @@
"message": "Cette version de Signal Desktop pour ordinateur est expirée. Veuillez la mettre à niveau vers la version la plus récente afin de continuer à échanger.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Les clients pour Android ne recevront que les 2 000 premiers caractères de ce message.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Mettre à niveau",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "Sombre",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Note à mon intention",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "Cacher la barre de menu",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Lancer la conversation…",
"message": "Lancer une nouvelle conversation…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "העתק שגיאה וצא",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "קבוצה לא ידועה",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "שגיאת מסד נתונים",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "מחק את כל הנתונים והפעל מחדש",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&קובץ",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "שיחות מאורכבות",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "שיחות אלו מאורכבות ויופיעו בתיבה הנכנסת רק אם מתקבלות הודעות חדשות.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "ארכב שיחה",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "העבר שיחה אל תיבה נכנסת",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "בחר תיקייה",
"description": "Button to allow the user to find a folder on disk"
@ -611,14 +643,36 @@
"message": "צא",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop עבודה",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "הכנס שם או מספר",
"search": {
"message": "חיפוש",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "אין תוצאות עבור \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "שיחות",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "אנשי קשר",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "הודעות",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "ברוכים הבאים לסיגנל",
"description": ""
@ -673,6 +727,10 @@
"message": "תא דואר",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "מוריד",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "הורד צרופה",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "תצלום",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "אישור",
"description": ""
@ -1055,10 +1125,6 @@
"message": "גרסה זו של Signal Desktop עבודה פגה. אנא שדרג אל הגרסה האחרונה כדי להמשיך בשליחת הודעות.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "לקוחות Android יקבלו רק את 2000 התווים הראשונים של הודעה זו.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "שדרג",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "כהה",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "הערה לעצמי",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "הסתר שורת תפריט",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "התחל שיחה...",
"message": "התחל שיחה חדשה...",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Copy error and quit",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Unknown group",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Database Error",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Delete all data and restart",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&File",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Archived Conversations",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "These conversations are archived and will only appear in the Inbox if new messages are received.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Archive Conversation",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Move Conversation to Inbox",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "फोल्डर को चुनो",
"description": "Button to allow the user to find a folder on disk"
@ -611,14 +643,36 @@
"message": "Quit",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Enter name or number",
"search": {
"message": "सर्च",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "No results for \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "संवाद",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "संपर्क",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "संदेश",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "सिग्‍नल में आपका स्वागत है ",
"description": ""
@ -673,6 +727,10 @@
"message": "PO Box",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Downloading",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Download Attachment",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "Photo",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "ठीक",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "किस को",
"message": "to",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1055,10 +1125,6 @@
"message": "Signal डेस्कटॉप का यह संस्करण समाप्त हो गया है। संदेश जारी रखने के लिए कृपया नवीनतम संस्करण में नवीनीकृत करें।",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "एंड्रॉयड क्लाइंट केवल इस संदेश के पहले 2000 वर्ण प्राप्त करेंगे",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "अपग्रेड",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "Dark",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Note to Self",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "मेनू बार छुपाएं",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Start conversation…",
"message": "Start new conversation…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Copy error and quit",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Unknown group",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Database Error",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Delete all data and restart",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&File",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Arhivirani razgovori",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "These conversations are archived and will only appear in the Inbox if new messages are received.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Archive Conversation",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Move Conversation to Inbox",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Odaberi direktorij",
"description": "Button to allow the user to find a folder on disk"
@ -611,14 +643,36 @@
"message": "Quit",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Enter name or number",
"search": {
"message": "Traži",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "No results for \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Conversations",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Kontakti",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Poruke",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Dobrodošli u Signal",
"description": ""
@ -673,6 +727,10 @@
"message": "PO Box",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Preuzimanje",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Download Attachment",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "Photo",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "OK",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "Za",
"message": "to",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1055,10 +1125,6 @@
"message": "Ova inačica Signal Desktopa je istekla. Molimo vas da za nastavak dopisivanja nadogradite na najnoviju verziju.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Android uređaji primit će samo prvih 2000 znakova ove poruke.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Nadogradi",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "Dark",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Note to Self",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "Hide menu bar",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Start conversation…",
"message": "Start new conversation…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Hiba másolása és kilépés",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Ismeretlen csoport",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Adatbázishiba",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Összes adat törlése és újraindítás",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&Fájl",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Archív beszélgetések",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "Ezek a beszélgetések archiválva vannak, ezért csak akkor jelennek meg újra a bejövő üzenet közt, ha újabb üzenet érkezik.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Beszélgetés archiválása",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Beszélgetés áthelyezése a beérkezett üzenetek közé",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Mappa kiválasztása",
"description": "Button to allow the user to find a folder on disk"
@ -611,14 +643,36 @@
"message": "Kilépés",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Név vagy telefonszám",
"search": {
"message": "Keresés",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "Nincs találat a \"$searchTerm$\" keresőkifejezése",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Beszélgetések",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Kontaktok",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Üzenetek",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Üdvözöl a Signal!",
"description": ""
@ -673,6 +727,10 @@
"message": "Postafiók",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Letöltés",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Csatolmány letöltése",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "Kép",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "OK",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "Címzett",
"message": "címzett",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1055,10 +1125,6 @@
"message": "A Signal Desktop ezen verziója elavult. Kérlek frissíts a legújabb verzióra, hogy folytatni tudd a beszélgetést!",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Az Androidos kliensek csak az üzenet első 2000 karakterét fogják megkapni.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Frissítés",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "Sötét",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Privát feljegyzés",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "Menü elrejtése",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Beszélgetés megkezdése...",
"message": "Új beszélgetés megkezdése…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Copy error and quit",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Unknown group",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Database Error",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Delete all data and restart",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&Berkas",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Percakapan Terarsipkan",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "These conversations are archived and will only appear in the Inbox if new messages are received.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Archive Conversation",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Move Conversation to Inbox",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Pilih map",
"description": "Button to allow the user to find a folder on disk"
@ -611,14 +643,36 @@
"message": "Berhenti",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Masukkan nama atau nomor ",
"search": {
"message": "Pencarian",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "No results for \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Percakapan",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Kontak",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Pesan",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Selamat datang di Signal",
"description": ""
@ -673,6 +727,10 @@
"message": "PO Box",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Mengunduh",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Unduh Lampiran",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "Foto",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "OK",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "Kepada",
"message": "to",
"description": "Label for the receiver of a message"
},
"sent": {
@ -866,7 +936,7 @@
"description": "Used for the icon layered on top of an image in message bubbles"
},
"addACaption": {
"message": "Add a caption...",
"message": "Tambah keterangan...",
"description": ""
},
"save": {
@ -1055,10 +1125,6 @@
"message": "Versi Signal Desktop ini telah kedaluwarsa. Mohom memutakhirkan ke versi terbaru untuk melanjutkan pengiriman pesan.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Klien Android hanya akan menerima 2000 karakter pertama dari pesan ini.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Pemutakhiran",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "Gelap",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Catatan Pribadi",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "Sembunyikan kolom menu",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Mulai percakapan...",
"message": "Start new conversation…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -3,6 +3,10 @@
"message": "Copia l'errore ed esci",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Gruppo sconosciuto",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Errore del database",
"description": "Shown in a popup if the database cannot start up properly"
@ -157,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Conversazioni archiviate",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "Queste conversazioni sono archiviate e compariranno nella lista di chat solo se verranno ricevuti nuovi messaggi.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Archivia conversazione",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Ripristina conversazione",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Scegli la cartella",
"description": "Button to allow the user to find a folder on disk"
@ -623,14 +643,36 @@
"message": "Esci",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Inserisci il nome o il numero",
"search": {
"message": "Cerca",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "Nessun risultato per \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Conversazioni",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Contatti",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Messaggi",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Benvenuto in Signal",
"description": ""
@ -685,6 +727,10 @@
"message": "Casella postale",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Caricamento in corso",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Scarica allegato",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -747,6 +793,18 @@
"message": "Foto",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "OK",
"description": ""
@ -784,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "A",
"message": "a",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1067,10 +1125,6 @@
"message": "Questa versione di Signal Desktop è scaduta. Per continuare a chattare aggiornala all'ultima versione.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "I client Android riceveranno solo i primi 2000 caratteri di questo messaggio.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Aggiorna",
"description": "Label text for button to upgrade the app to the latest version"
@ -1386,7 +1440,7 @@
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Inizia la conversazione...",
"message": "Inizia una nuova conversazione...",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -3,6 +3,10 @@
"message": "Copy error and quit",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Unknown group",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Database Error",
"description": "Shown in a popup if the database cannot start up properly"
@ -157,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "保存済みの会話",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "この会話は保存されます。新しいメッセージが届いた場合だけ受信箱に表示されます。",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Archive Conversation",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Move Conversation to Inbox",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "フォルダを選択",
"description": "Button to allow the user to find a folder on disk"
@ -623,14 +643,36 @@
"message": "終了",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "名前か番号を入力",
"search": {
"message": "検索",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "No results for \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "会話",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "連絡先",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "メッセージ",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Signalにようこそ",
"description": ""
@ -685,6 +727,10 @@
"message": "私書箱",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "ダウンロード中",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "添付ファイルをダウンロード",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -747,6 +793,18 @@
"message": "写真",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "OK",
"description": ""
@ -784,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "宛先",
"message": "to",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1067,10 +1125,6 @@
"message": "アプリのバージョンが古すぎます。最新版にアップデートしてください。",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Android端末ではこのメッセージの最初の2000字しか受信されません",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "アップデート",
"description": "Label text for button to upgrade the app to the latest version"
@ -1386,7 +1440,7 @@
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "会話を開始する...",
"message": "Start new conversation…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -3,6 +3,10 @@
"message": "ចម្លងបញ្ហា និងចាកចេញ",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "ក្រុមមិនស្គាល់",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "បញ្ហាទិន្នន័យ",
"description": "Shown in a popup if the database cannot start up properly"
@ -157,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "បណ្ណសារសន្ទនា",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "ការសន្ទនាទាំងនេះ នឹងត្រូវធ្វើបណ្ណសារ និងបង្ហាញក្នុងប្រអប់សំបុត្រតែប៉ុណ្ណោះ ប្រសិនបើទទួលបានសារថ្មី។",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "បណ្ណសារការសន្ទនា",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "ផ្លាស់ប្តូរការសន្ទនាទៅប្រអប់សារ",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "ជ្រើសរើសទីតាំងផ្ទុក",
"description": "Button to allow the user to find a folder on disk"
@ -623,14 +643,36 @@
"message": "ចាកចេញ",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "បញ្ចូល ឈ្មោះ ឬ លេខ",
"search": {
"message": "ស្វែងរក",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "គ្មានលទ្ធផលសម្រាប់ \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "ការសន្ទនា",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "បញ្ជីទំនាក់ទំនង",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "សារ",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "ស្វាគមន៍មកកាន់ Signal",
"description": ""
@ -685,6 +727,10 @@
"message": "ប្រអប់សំបុត្រ",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "កំពុងទាញយក",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "ទាញយកឯកសារភ្ជាប់",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -747,6 +793,18 @@
"message": "រូបភាព",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "យល់ព្រម",
"description": ""
@ -1067,10 +1125,6 @@
"message": "ជំនាន់ Signal Desktop នេះ បានហួសសុពលភាព។ សូមដំឡើងទីកាន់ជំនាន់ចុងក្រោយ ដើម្បីបន្តការផ្ញើសារ។",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "អ្នកប្រើប្រាស់ Android នឹងទទួលបានអក្សរ 2000 តួ ដំបូងនៃសារនេះតែប៉ុណ្ណោះ។",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "ដំឡើង",
"description": "Label text for button to upgrade the app to the latest version"
@ -1386,7 +1440,7 @@
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "ចាប់ផ្តើមការសន្ទនា...",
"message": "ចាប់ផ្តើមការសន្ទនាថ្មី...",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Copy error and quit",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Unknown group",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Database Error",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Delete all data and restart",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&File",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Archived Conversations",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "These conversations are archived and will only appear in the Inbox if new messages are received.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Archive Conversation",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Move Conversation to Inbox",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Choose folder",
"description": "Button to allow the user to find a folder on disk"
@ -611,14 +643,36 @@
"message": "Quit",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Enter name or number",
"search": {
"message": "ಹುಡುಕಿ",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "No results for \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Conversations",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "ಸಂಪರ್ಕಗಳು",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Messages",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "ಸಿಗ್ನಲ್‌ಗೆ ಸ್ವಾಗತ",
"description": ""
@ -673,6 +727,10 @@
"message": "PO Box",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Downloading",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Download Attachment",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "Photo",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "ಸರಿ",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "ಗೆ",
"message": "to",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1055,10 +1125,6 @@
"message": "Signal ಡೆಸ್ಕ್ಟಾಪ್ ಈ ಆವೃತ್ತಿಯ ಅವಧಿ ಮುಗಿದಿದೆ. ಸಂದೇಶ ಮುಂದುವರೆಸಲು ಹೊಸ ಆವೃತ್ತಿಗೆ ಅಪ್ಗ್ರೇಡ್ ಮಾಡಿ.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Android clients will only receive the first 2000 characters of this message.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "ಅಪ್ಗ್ರೇಡ್",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "Dark",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Note to Self",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "Hide menu bar",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Start conversation…",
"message": "Start new conversation…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Copy error and quit",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Unknown group",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Database Error",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Delete all data and restart",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&File",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Archived Conversations",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "These conversations are archived and will only appear in the Inbox if new messages are received.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Archive Conversation",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Move Conversation to Inbox",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Choose folder",
"description": "Button to allow the user to find a folder on disk"
@ -611,14 +643,36 @@
"message": "Quit",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Enter name or number",
"search": {
"message": "검색",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "No results for \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "대화",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "연락처",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Messages",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Welcome to Signal",
"description": ""
@ -673,6 +727,10 @@
"message": "PO Box",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "다운로드 중",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Download Attachment",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "Photo",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "OK",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "To",
"message": "to",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1055,10 +1125,6 @@
"message": "This version of Signal Desktop has expired. Please upgrade to the latest version to continue messaging.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Android clients will only receive the first 2000 characters of this message.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Upgrade",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "Dark",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Note to Self",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "Hide menu bar",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Start conversation…",
"message": "Start new conversation…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Kopijuoti klaidą ir išeiti",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Nežinoma grupė",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Duomenų bazės klaida",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Ištrinti visus duomenis ir paleisti iš naujo",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&Failas",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Archyvuoti pokalbiai",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "Šie pokalbiai yra archyvuoti ir atsiras skyrelyje Gauta tik tuomet, jei bus gautos naujos žinutės.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Archyvuoti pokalbį",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Perkelti pokalbį į skyrelį Gauta",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Pasirinkti aplanką",
"description": "Button to allow the user to find a folder on disk"
@ -611,14 +643,36 @@
"message": "Išeiti",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Įveskite vardą ar numerį",
"search": {
"message": "Ieškoti",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "\"$searchTerm$\" negrąžino jokių rezultatų",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Pokalbiai",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Kontaktai",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Žinutės",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Sveiki atvykę į Signal",
"description": ""
@ -673,6 +727,10 @@
"message": "Pašto dėžutė",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Atsisiunčiama",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Atsisiųsti priedą",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "Nuotrauka",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "Gerai",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "Kam",
"message": "skirta",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1055,10 +1125,6 @@
"message": "Pasibaigė šios Signal Desktop skirtos versijos galiojimas. Norint tęsti susirašinėjimą, prašome atsinaujinti iki naujausios versijos.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Android klientai gaus tik pirmuosius 2000 šios žinutės simbolių.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Naujinti",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "Tamsi",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Pastabos sau",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "Slėpti meniu juostą",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Pradėti pokalbį…",
"message": "Pradėti naują pokalbį…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Copy error and quit",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Unknown group",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Database Error",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Delete all data and restart",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&File",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Archived Conversations",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "These conversations are archived and will only appear in the Inbox if new messages are received.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Archive Conversation",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Move Conversation to Inbox",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Choose folder",
"description": "Button to allow the user to find a folder on disk"
@ -611,14 +643,36 @@
"message": "Quit",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Enter name or number",
"search": {
"message": "Барај",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "No results for \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Разговори",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Контакти",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Messages",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Добредојдовте во Signal",
"description": ""
@ -673,6 +727,10 @@
"message": "PO Box",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Превземање",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Download Attachment",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "Photo",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "Во ред",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "To",
"message": "to",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1055,10 +1125,6 @@
"message": "This version of Signal Desktop has expired. Please upgrade to the latest version to continue messaging.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Android clients will only receive the first 2000 characters of this message.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Upgrade",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "Dark",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Note to Self",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "Hide menu bar",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Start conversation…",
"message": "Start new conversation…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -3,6 +3,10 @@
"message": "Kopier feil og avslutt",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Ukjent gruppe",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Database feil",
"description": "Shown in a popup if the database cannot start up properly"
@ -157,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Arkiverte Samtaler",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "Disse samtalene er arkiverte og vil dukke opp igjen i innboksen om de får nye meldinger.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Arkiver samtalen",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Flytt samtalen til innboksen",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Velg mappe",
"description": "Button to allow the user to find a folder on disk"
@ -623,14 +643,36 @@
"message": "Avslutt",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Legg inn navn eller nummer",
"search": {
"message": "Søk",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "Ingen resultater for \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Samtaler",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Kontakter",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Meldinger",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Velkommen til Signal!",
"description": ""
@ -685,6 +727,10 @@
"message": "Postboks",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Laster ned",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Last ned Vedlegg",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -747,6 +793,18 @@
"message": "Bilde",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "OK",
"description": ""
@ -784,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "Til",
"message": "til",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1067,10 +1125,6 @@
"message": "Denne versjonen av Signal Desktop er foreldet. Oppgrader til siste versjon for å fortsette.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Android-klienter mottar bare de første 2000 tegnene i denne meldingen.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Oppgrader",
"description": "Label text for button to upgrade the app to the latest version"
@ -1386,7 +1440,7 @@
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Start samtale...",
"message": "Start en ny samtale...",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -3,6 +3,10 @@
"message": "Foutmelding kopiëren en afsluiten",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Onbekende groep",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Databasefout",
"description": "Shown in a popup if the database cannot start up properly"
@ -157,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Gearchiveerde gesprekken",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "Deze gesprekken worden gearchiveerd en zullen alleen in Postvak IN verschijnen als je nieuwe berichten ontvangt.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Gesprek archiveren",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Gesprek verplaatsen naar Postvak IN",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Map kiezen",
"description": "Button to allow the user to find a folder on disk"
@ -186,7 +206,7 @@
"description": "Header of screen shown as data is import"
},
"importErrorFirst": {
"message": "Zorg dat je de juiste map met je opgeslagen Signal-gegevens kiest. De naam begint normaal gezien met Signal Export. Je kan ook een nieuwe kopie van je gegevens uit de Chrome-app opslaan.",
"message": "Zorg dat je de juiste map met je opgeslagen Signal-gegevens kiest. De naam begint normaal gezien met Signal Export. Je kunt ook een nieuwe kopie van je gegevens uit de Chrome-app opslaan.",
"description": "Message shown if the import went wrong; first paragraph"
},
"importErrorSecond": {
@ -623,14 +643,36 @@
"message": "Afsluiten",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Voer naam of nummer in",
"search": {
"message": "Zoeken",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "Geen resultaten voor $searchTerm$",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Gesprekken",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Contacten",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Berichten",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Welkom bij Signal",
"description": ""
@ -685,6 +727,10 @@
"message": "postbus",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Wordt gedownload",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Bijlage downloaden",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -747,6 +793,18 @@
"message": "Foto",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "Begrepen",
"description": ""
@ -784,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "Naar",
"message": "aan",
"description": "Label for the receiver of a message"
},
"sent": {
@ -890,7 +948,7 @@
"description": "Used in the media gallery documents tab to visually represent a file"
},
"emojiAlt": {
"message": "Emoji-afbeelding van $title$",
"message": "Emoji-afbeelding $title$",
"description": "Used in the alt tag of all emoji images",
"placeholders": {
"title": {
@ -992,7 +1050,7 @@
"description": "Header of the full-screen delete data confirmation screen"
},
"deleteAllDataBody": {
"message": "Je staat op het punt alle opgeslagen accountgegevens van deze toepassing te wissen, inclusief alle contacten en alle berichten. Je kan altijd opnieuw koppelen met je mobiele apparaat, maar je gewiste berichten kunnen niet hersteld worden.",
"message": "Je staat op het punt alle opgeslagen accountgegevens van deze toepassing te wissen, inclusief alle contacten en alle berichten. Je kunt altijd opnieuw koppelen met je mobiele apparaat, maar je gewiste berichten kunnen niet hersteld worden.",
"description": "Text describing what exactly will happen if the user clicks the button to delete all data"
},
"deleteAllDataButton": {
@ -1067,10 +1125,6 @@
"message": "Deze versie van Signal Desktop is verouderd. Opwaardeer naar de laatste versie om verder te chatten.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Contacten die Signal op een Android-telefoon gebruiken zullen enkel de eerste 2000 tekens van dit bericht kunnen lezen.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Opwaarderen",
"description": "Label text for button to upgrade the app to the latest version"
@ -1386,7 +1440,7 @@
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Begin een gesprek…",
"message": "Begin een nieuw gesprek…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {
@ -1398,7 +1452,7 @@
"description": "When a person inputs a number that is invalid"
},
"unlinkedWarning": {
"message": "Herkoppel Signal Desktop met je mobiel apparaat om verder te kunnen chatten.",
"message": "Koppel Signal Desktop opnieuw aan je mobiele apparaat om verder te kunnen chatten.",
"description": ""
},
"unlinked": {
@ -1406,7 +1460,7 @@
"description": ""
},
"relink": {
"message": "Herkoppelen",
"message": "Opnieuw koppelen",
"description": ""
},
"autoUpdateNewVersionTitle": {
@ -1450,11 +1504,11 @@
}
},
"updatedTheGroup": {
"message": "De groep is bijgewerkt",
"message": "De groep is aangepast",
"description": "Shown in the conversation history when someone updates the group"
},
"titleIsNow": {
"message": "De titel is nu \"$name$\"",
"message": "De titel is nu “$name$”",
"description": "Shown in the conversation history when someone changes the title of the group",
"placeholders": {
"name": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Kopier feil og avslutt",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Unknown group",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Databasefeil",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Slett all data og start på nytt",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&Fil",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Archived Conversations",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "These conversations are archived and will only appear in the Inbox if new messages are received.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Archive Conversation",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Move Conversation to Inbox",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Vel mappe",
"description": "Button to allow the user to find a folder on disk"
@ -611,14 +643,36 @@
"message": "Avslutt",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Legg inn namn eller nummer",
"search": {
"message": "Søk",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "No results for \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Samtalar",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Kontakt",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Meldingar",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Velkommen til Signal!",
"description": ""
@ -673,6 +727,10 @@
"message": "postboks",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Lastar ned",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Last ned vedlegg",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "Bilde",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "OK",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "Til",
"message": "to",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1055,10 +1125,6 @@
"message": "Denne utgåva av Signal Desktop er forelda. Oppgrader til siste utgåve for å fortsetja.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Android-klientar mottek berre dei første 2000 teikna i denne meldinga.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Oppgrader",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "Mørkt",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Notat til meg sjølv",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "Skjul menylinje",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Start samtale …",
"message": "Start new conversation…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Copy error and quit",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Unknown group",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Database Error",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Delete all data and restart",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&Fil",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Archived Conversations",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "These conversations are archived and will only appear in the Inbox if new messages are received.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Archive Conversation",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Move Conversation to Inbox",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Velg mappe",
"description": "Button to allow the user to find a folder on disk"
@ -611,14 +643,36 @@
"message": "Avslutt",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Legg inn navn eller nummer",
"search": {
"message": "Søk",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "No results for \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Conversations",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Kontakt",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Messages",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Velkommen til Signal!",
"description": ""
@ -673,6 +727,10 @@
"message": "Postboks",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Laster ned",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Last ned Vedlegg",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "Bilde",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "OK",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "Til",
"message": "to",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1055,10 +1125,6 @@
"message": "Denne versjonen av Signal Desktop er foreldet. Oppgrader til siste versjon for å fortsette.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Android-klienter mottar bare de første 2000 tegnene i denne meldingen.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Oppgrader",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "Mørkt",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Note to Self",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "Skjul menylinje",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Start samtale...",
"message": "Start new conversation…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -3,6 +3,10 @@
"message": "Skopiuj błąd i zakończ",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Nieznana grupa",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Błąd bazy danych",
"description": "Shown in a popup if the database cannot start up properly"
@ -157,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Zarchiwizowane rozmowy",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "Te rozmowy są zarchiwizowane i pojawią się w Odebranych tylko po otrzymaniu nowych wiadomości.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Archiwum konwersacji",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Przenieś konwersacje do skrzynki odbiorczej",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Wybierz folder",
"description": "Button to allow the user to find a folder on disk"
@ -266,7 +286,7 @@
}
},
"youMarkedAsVerified": {
"message": "Oznaczyłeś(aś) Twój numer bezpieczeństwa $name$ jako zweryfikowany",
"message": "Oznaczyłeś(aś) Twój numer bezpieczeństwa z $name$ jako zweryfikowany",
"description": "Shown in the conversation history when the user marks a contact as verified.",
"placeholders": {
"name": {
@ -276,7 +296,7 @@
}
},
"youMarkedAsNotVerified": {
"message": "Oznaczyłeś(aś) Twój numer bezpieczeństwa $name$ jako niezweryfikowany",
"message": "Oznaczyłeś(aś) Twój numer bezpieczeństwa z $name$ jako niezweryfikowany",
"description": "Shown in the conversation history when the user marks a contact as not verified, whether on the Safety Number screen or by dismissing a banner or dialog.",
"placeholders": {
"name": {
@ -623,14 +643,36 @@
"message": "Wyjdź",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Wprowadź nazwę lub numer",
"search": {
"message": "Szukaj",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "Brak wyników dla \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Rozmowy",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Kontakty",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Wiadomości",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Witamy w Signal",
"description": ""
@ -685,6 +727,10 @@
"message": "Skrzynka pocztowa",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Pobieranie",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Pobierz załącznik",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -747,6 +793,18 @@
"message": "Zdjęcie",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "OK",
"description": ""
@ -784,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "Do",
"message": "do",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1067,10 +1125,6 @@
"message": "Ta wersja Signal Desktop jest przestarzała. Aby nadal wysyłać wiadomości, wykonaj aktualizację.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "W aplikacji na Androida widoczne będzie tylko pierwsze 2000 znaków z tej wiadomości.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Aktualizuj",
"description": "Label text for button to upgrade the app to the latest version"
@ -1386,7 +1440,7 @@
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Rozpocznij rozmowę...",
"message": "Rozpocznij nową rozmowę...",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Copiar erro e sair",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Grupo desconhecido",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Erro na base de dados",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Apagar todos os dados e reiniciar",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&Arquivo",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Conversas arquivadas",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "Estas conversas estão arquivadas. Elas aparecerão na caixa de entrada somente se novas mensagens forem recebidas.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Arquivar conversa",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Mover conversa para Caixa de Entrada",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Escolher pasta",
"description": "Button to allow the user to find a folder on disk"
@ -611,14 +643,36 @@
"message": "Sair",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Inserir nome ou número",
"search": {
"message": "Buscar",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "Sem resultados para \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Conversas",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Contatos",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Mensagens",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Boas-vindas ao Signal",
"description": ""
@ -673,6 +727,10 @@
"message": "Caixa postal",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "A transferir",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Baixar anexo",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "Foto",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "OK",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "Para",
"message": "para",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1055,10 +1125,6 @@
"message": "Esta versão do Signal Desktop expirou. Por favor, atualize-o para a versão mais recente para continuar enviando mensagens.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Clientes do Android receberão apenas os primeiros 2000 caracteres desta mensagem.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Atualizar",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "Escuro",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Recado para mim",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "Ocultar a barra de opções",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Iniciar conversa...",
"message": "Iniciar uma conversa…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -3,6 +3,10 @@
"message": "Copiar erro e sair",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Grupo desconhecido",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Erro na base de dados",
"description": "Shown in a popup if the database cannot start up properly"
@ -157,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Conversas arquivadas",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "Estas conversas estão arquivadas e apenas irão aparecer na caixa de entrada caso receba novas mensagens.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Arquivar conversa",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Mover conversas para a caixa de entrada",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Escolher pasta",
"description": "Button to allow the user to find a folder on disk"
@ -623,14 +643,36 @@
"message": "Sair",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Insira nome ou número",
"search": {
"message": "Procurar",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "Sem resultados para \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Conversas",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Contactos",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Mensagens",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Bem-vindo(a) ao Signal",
"description": ""
@ -685,6 +727,10 @@
"message": "Código postal",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "A descarregar",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Descarregar anexo",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -747,6 +793,18 @@
"message": "Foto",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "OK",
"description": ""
@ -784,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "Para",
"message": "para",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1067,10 +1125,6 @@
"message": "Esta versão do Signal Desktop expirou. Para poder continuar a enviar mensagens, actualize para a última versão .",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Os dispositivos Android receberão apenas os primeiros 2000 caracteres desta mensagem.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Atualizar",
"description": "Label text for button to upgrade the app to the latest version"
@ -1386,7 +1440,7 @@
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Iniciar conversa...",
"message": "Iniciar uma nova conversa…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -3,6 +3,10 @@
"message": "Copiază eroare și închide aplicația",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Grup necunoscut",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Eroare de bază de date",
"description": "Shown in a popup if the database cannot start up properly"
@ -157,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Conversații arhivate",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "Conversațiile sunt arhivate și vor apărea doar în Inbox dacă sunt primite mesaje noi.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Arhivați conversația",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Mutați conversația în Inbox",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Alege directorul",
"description": "Button to allow the user to find a folder on disk"
@ -492,7 +512,7 @@
"description": "Name for a voice message attachment"
},
"dangerousFileType": {
"message": "Attachment type not allowed for security reasons",
"message": "Tipul de atașament nu este permis din motive de securitate",
"description": "Shown in toast when user attempts to send .exe file, for example"
},
"loadingPreview": {
@ -623,14 +643,36 @@
"message": "Închide",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Introdu nume sau număr",
"search": {
"message": "Căutați",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "Nici un rezultat pentru \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Conversații",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Contacte",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Mesaje",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Bun venit la Signal",
"description": ""
@ -685,6 +727,10 @@
"message": "Căsuță poștală",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Se descarcă",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Descarcă atașamentul",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -747,6 +793,18 @@
"message": "Poză",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "OK",
"description": ""
@ -784,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "Către",
"message": "către",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1067,10 +1125,6 @@
"message": "Această versiune de Signal Desktop a expirat. Te rog actualizează aplicația la ultima versiune pentru a putea trimite mesaje în continuare.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Clienții Android vor primi doar primele 2000 de caractere din acest mesaj.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Actualizează",
"description": "Label text for button to upgrade the app to the latest version"
@ -1386,7 +1440,7 @@
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Pornește conversația...",
"message": "Pornește o conversație nouă...",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -3,6 +3,10 @@
"message": "Скопировать ошибку и выйти",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Неизвестная группа",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Ошибка базы данных",
"description": "Shown in a popup if the database cannot start up properly"
@ -157,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Архивированные разговоры",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "Эти разговоры архивированы и будут появляться во Входящих только когда получены новые сообщения.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Архивировать разговор",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Переместить разговор во Входящие",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Выберите папку",
"description": "Button to allow the user to find a folder on disk"
@ -623,14 +643,36 @@
"message": "Выйти",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Введите имя или номер",
"search": {
"message": "Поиск",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "Нет результатов для \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Разговоры",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Контакты",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Сообщения",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Добро пожаловать в Signal",
"description": ""
@ -685,6 +727,10 @@
"message": "почтовый ящик",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Скачивание",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Загрузить вложение",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -747,6 +793,18 @@
"message": "Фото",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "OK",
"description": ""
@ -784,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "Кому",
"message": "->",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1067,10 +1125,6 @@
"message": "Эта версия Signal Desktop устарела. Выполните обновление до последней версии, чтобы продолжить обмен сообщениями.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Пользователи Android получат только первые 2000 символов этого сообщения.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Обновить",
"description": "Label text for button to upgrade the app to the latest version"
@ -1386,7 +1440,7 @@
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Начать разговор…",
"message": "Начать новый разговор…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Kopírovať a ukončiť",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Neznáma skupina",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Chyba databázy",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Vymazať všetky dáta a reštartovať",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&Súbor",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Archivované konverzácie",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "These conversations are archived and will only appear in the Inbox if new messages are received.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Archivovať konverzáciu",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Presunúť konverzáciu do doručených",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Zvoľte priečinok",
"description": "Button to allow the user to find a folder on disk"
@ -484,7 +516,7 @@
"description": "Shown in toast when user attempts to send .exe file, for example"
},
"loadingPreview": {
"message": "Loading Preview...",
"message": "Načítavam náhľad...",
"description": "Shown while Signal Desktop is fetching metadata for a url in composition area"
},
"stagedPreviewThumbnail": {
@ -522,7 +554,7 @@
"description": "An error popup when the user has attempted to add an attachment"
},
"cannotMixImageAdnNonImageAttachments": {
"message": "You cannot mix non-image and image attachments in one message.",
"message": "V jednej správe nemôže byť súčasne príloha s obrázkom a príloha bez obrázku.",
"description": "An error popup when the user has attempted to add an attachment"
},
"maximumAttachments": {
@ -611,14 +643,36 @@
"message": "Ukončiť",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Zadajte meno alebo číslo",
"search": {
"message": "Hľadať",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "Žiadne výsledky pre \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Konverzácie",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Kontakty",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Správy",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Vitajte v aplikácii Signal",
"description": ""
@ -673,6 +727,10 @@
"message": "P.O.Box",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Sťahujem",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Stiahnuť prílohu",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "Fotka",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "OK",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "Pre",
"message": "pre",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1055,10 +1125,6 @@
"message": "Táto verzia aplikácie Signal Desktop je zastaralá. Pre pokračovanie ju prosím aktualizujte na najnovšiu verziu.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Klienti na systému Android obdržia len prvých 2000 znakov tejto správy.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Aktualizovať",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "Tmavý",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Poznámka pre seba",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "Skryť ponuku",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Začať rozhovor...",
"message": "Začať nový rozhovor…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Kopiraj napako in zapusti aplikacijo",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Neznana skupina",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Napaka v bazi podatkov",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Izbris vseh podatkov in ponovni zagon",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&Datoteka",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Arhivirani pogovori",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "Ti pogovori so bili premaknjeni v arhiv in se bodo znova pojavili v nabiralniku, če prejmete novo sporočilo.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Premakni pogovor v arhiv",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Več pogovorov v nabiralnik",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Izberite mapo",
"description": "Button to allow the user to find a folder on disk"
@ -611,14 +643,36 @@
"message": "Končaj",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Vnesite ime ali številko",
"search": {
"message": "Iskanje",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "Ni rezultata za \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Pogovori",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Stiki",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Sporočila",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Dobrodošli v aplikaciji Signal",
"description": ""
@ -673,6 +727,10 @@
"message": "p. p.",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Prenašam",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Prenesi priponko",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "Slika",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "OK",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "Naslovnik",
"message": "v",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1055,10 +1125,6 @@
"message": "Pričujoča različica programa Signal Desktop je potekla. Za ponovno delovanje morate program posodobiti na zadnjo različico.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Odjemalec za Android bo prejel le prvih 2000 znakov tega sporočila.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Posodobi",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "Temna",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Osebna zabeležka",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "Skrij menijsko vrstico",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Začetek pogovora ...",
"message": "Začni nov pogovor ...",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Kopjo gabimin dhe dil",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Grup i panjohur",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Gabim Baze të Dhënash",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Fshiji krejt të dhënat dhe rifillo",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&Kartelë",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Biseda të Arkivuara",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "Këto biseda janë të arkivuara dhe do të shfaqen te Të marrë vetëm nëse merren mesazhe të rinj.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Arkivojeni Bisedën",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Kaloje Bisedën te Të marrë",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Zgjidhni dosje",
"description": "Button to allow the user to find a folder on disk"
@ -178,7 +210,7 @@
"description": "Message shown if the import went wrong; first paragraph"
},
"importErrorSecond": {
"message": "Nëse këto hapa nuk bëjnë punë për ju, ju lutemi, parashtroni një regjistrim diagnostikimi (Shihni -> Regjistër Diagnostikimesh) që tju ndihmojmë të migroni!",
"message": "Nëse këto hapa sju bëjnë punë, ju lutemi, parashtroni një regjistrim diagnostikimi (Shihni -> Regjistër Diagnostikimesh) që tju ndihmojmë të migroni!",
"description": "Message shown if the import went wrong; second paragraph"
},
"importAgain": {
@ -611,14 +643,36 @@
"message": "Dil",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Jepni emër ose numër",
"search": {
"message": "Kërko",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "Ska përfundime për \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Biseda.",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Kontakte",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Mesazhe",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Mirë se vini te Signal-i",
"description": ""
@ -673,6 +727,10 @@
"message": "Kuti Postare",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Po shkarkohet",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Shkarko Bashkëngjitjen",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "Foto",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "OK",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "Për",
"message": "për",
"description": "Label for the receiver of a message"
},
"sent": {
@ -956,7 +1026,7 @@
"description": "Description of the media permission description"
},
"general": {
"message": "Përgjithshëm",
"message": "Të përgjithshme",
"description": "Header for general options on the settings screen"
},
"spellCheckDescription": {
@ -1055,10 +1125,6 @@
"message": "Ky version i Signal-it për Desktop ka skaduar. Ju lutemi, që të vazhdoni të shkëmbeni mesazhe, përmirësojeni me versionin më të ri.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Klientët me Android do të marrin vetëm 2000 shenjat e para të këtij mesazhi.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Përmirësojeni",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "E errët",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Shënim për Veten",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "Fshihe shtyllën e menusë",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Nisni bisedë…",
"message": "Filloni bisedë të re…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Copy error and quit",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Unknown group",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Database Error",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Delete all data and restart",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&File",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Archived Conversations",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "These conversations are archived and will only appear in the Inbox if new messages are received.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Archive Conversation",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Move Conversation to Inbox",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Одаберите фолдер",
"description": "Button to allow the user to find a folder on disk"
@ -611,14 +643,36 @@
"message": "Quit",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Enter name or number",
"search": {
"message": "Тражи",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "No results for \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Преписке",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Контакти",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Поруке",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Добродошли у Signal",
"description": ""
@ -673,6 +727,10 @@
"message": "PO Box",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Преузимам",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Download Attachment",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "Photo",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "У реду",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "За",
"message": "to",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1055,10 +1125,6 @@
"message": "Ваша верзија Signal-а за десктоп је застарела. Да би сте наставили дописивање, молимо вас да ажурирате програм.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Андроид клијент ће примити само првих 2000 карактера ове поруке",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Ажурирај",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "Dark",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Note to Self",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "Hide menu bar",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Start conversation…",
"message": "Start new conversation…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -3,6 +3,10 @@
"message": "Kopiera felmeddelande och avsluta",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Okänd grupp",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Databasfel",
"description": "Shown in a popup if the database cannot start up properly"
@ -157,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Arkiverade konversationer",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "Konversationerna här är arkiverade och kommer bara visas i inkorgen ifall nya meddelanden tas emot.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Arkivera konversation",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Flytta konversationen till Inkorg",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Välj mapp",
"description": "Button to allow the user to find a folder on disk"
@ -623,14 +643,36 @@
"message": "Avsluta",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Ange namn eller nummer",
"search": {
"message": "Sök",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "Inga resultat för \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Konversationer",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Kontakter",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Meddelanden",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Välkommen till Signal",
"description": ""
@ -685,6 +727,10 @@
"message": "PO-låda",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Laddar ner",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Hämta bifogad fil",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -747,6 +793,18 @@
"message": "Foto",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "OK",
"description": ""
@ -784,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "Till",
"message": "till",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1067,10 +1125,6 @@
"message": "Den här versionen av Signal Desktop har utgått. Vänligen uppgradera till den senaste versionen för att fortsätta chatta.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Androidklienter kommer bara ta emot de första 2000 tecknen av detta meddelande.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Uppgradera",
"description": "Label text for button to upgrade the app to the latest version"
@ -1386,7 +1440,7 @@
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Påbörja konversation...",
"message": "Starta en ny konversation…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Copy error and quit",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Unknown group",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Database Error",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Delete all data and restart",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "ไ&ฟล์",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Archived Conversations",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "These conversations are archived and will only appear in the Inbox if new messages are received.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Archive Conversation",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Move Conversation to Inbox",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "เลือกโฟลเดอร์",
"description": "Button to allow the user to find a folder on disk"
@ -611,14 +643,36 @@
"message": "ออก",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "ป้อนชื่อหรือหมายเลข",
"search": {
"message": "ค้นหา",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "No results for \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "การสนทนา",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "ผู้ติดต่อ",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "ข้อความ",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "ยินดีต้อนรับสู่ Signal",
"description": ""
@ -673,6 +727,10 @@
"message": "ตู้ไปรษณีย์",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Downloading",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Download Attachment",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "รูปภาพ",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "ตกลง",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "ถึง",
"message": "to",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1055,10 +1125,6 @@
"message": "Signal Desktop เวอร์ชันนี้หมดอายุแล้ว โปรดอัพเกรดไปเป็นเวอร์ชันล่าสุดเพื่อดำเนินการส่งข้อความต่อ",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "สำหรับไคลเอ็นต์ Android จะได้รับข้อความ 2000 ตัวอักษรแรกเท่านั้น",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "อัพเกรด",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "Dark",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Note to Self",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "ซ่อนแถบเมนู",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "เริ่มต้นการสนทนา",
"message": "Start new conversation…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -3,6 +3,10 @@
"message": "Hatayı kopyala ve çık",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Bilinmeyen grup",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Veritabanı hatası",
"description": "Shown in a popup if the database cannot start up properly"
@ -157,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Arşivlenmiş Sohbetler",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "Bu sohbetler arşivlendi ve sadece yeni iletiler alınırsa gelen kutusunda görünecekler.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Sohbeti Arşivle",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Sohbeti Gelen Kutusuna Taşı",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Klasör seçin",
"description": "Button to allow the user to find a folder on disk"
@ -623,14 +643,36 @@
"message": ıkış Yap",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "İsim ya da numara girin",
"search": {
"message": "Ara",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "\"$searchTerm$\" için arama sonucu yok",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Sohbetler",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Kişiler",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "İletiler",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Signal'e Hoşgeldin",
"description": ""
@ -685,6 +727,10 @@
"message": "Posta Kutusu",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "İndiriliyor",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Eklentiyi İndir",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -747,6 +793,18 @@
"message": "Fotoğraf",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "TAMAM",
"description": ""
@ -784,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "Alıcı",
"message": "alıcı",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1067,10 +1125,6 @@
"message": "Signal Desktop'ın bu sürümünün süresi doldu. İletişime devam etmek için lütfen en son sürüme geçin.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Android istemcileri bu iletinin yalnızca ilk 2000 karakterini alacaktır.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Yükselt",
"description": "Label text for button to upgrade the app to the latest version"
@ -1386,7 +1440,7 @@
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Sohbet başlat…",
"message": "Yeni sohbet başlat…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Copy error and quit",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Unknown group",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Database Error",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Delete all data and restart",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&Файл",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Архівовані розмови",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "Ці розмови — архівовані. Вони з’являтимуться у вхідних лише тоді, коли приходитимуть нові повідомлення.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Archive Conversation",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Move Conversation to Inbox",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Choose folder",
"description": "Button to allow the user to find a folder on disk"
@ -611,14 +643,36 @@
"message": "Вийти",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Enter name or number",
"search": {
"message": "Пошук",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "No results for \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Розмови",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Контакти",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Повідомлення",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Ласкаво просимо до Signal",
"description": ""
@ -673,6 +727,10 @@
"message": "PO Box",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Завантаження",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Download Attachment",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "Photo",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "Добре",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "Кому",
"message": "to",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1055,10 +1125,6 @@
"message": "Ця версія застаріла. Оновіться до останньої версії щоб продовжити спілкування.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "На Андроїді буде видно лише перші 2 000 знаків цього повідомлення.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Оновити",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "Dark",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Note to Self",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "Сховати стрічку меню",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Start conversation…",
"message": "Start new conversation…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "Copy error and quit",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "Unknown group",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "Database Error",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "Delete all data and restart",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "&File",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "Archived Conversations",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "These conversations are archived and will only appear in the Inbox if new messages are received.",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "Archive Conversation",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "Move Conversation to Inbox",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "Choose folder",
"description": "Button to allow the user to find a folder on disk"
@ -611,14 +643,36 @@
"message": "Quit",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "Enter name or number",
"search": {
"message": "Tìm kiếm",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "No results for \"$searchTerm$\"",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "Conversations",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "Liên hệ",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "Messages",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "Chào mừng đến với Signal",
"description": ""
@ -673,6 +727,10 @@
"message": "PO Box",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "Đang tải xuống",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "Download Attachment",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "Photo",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "Đồng ý",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "Tới",
"message": "to",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1055,10 +1125,6 @@
"message": "Phiên bản này của Signal Desktop đã hết hạn. Vui lòng nâng cấp lên phiên bản mới nhất để tiếp tục nhắn tin.",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Thiết bị Android sẽ chỉ nhận được 2000 ký tự đầu tiên của tin nhắn này.",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "Nâng cấp",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "Dark",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "Note to Self",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "Hide menu bar",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "Start conversation…",
"message": "Start new conversation…",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,4 +1,20 @@
{
"copyErrorAndQuit": {
"message": "复制出错信息并退出",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "未知群",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "数据库错误",
"description": "Shown in a popup if the database cannot start up properly"
},
"deleteAndRestart": {
"message": "删除所有数据并重启",
"description": "Shown in a popup if the database cannot start up properly; allows user to dalete database and restart"
},
"mainMenuFile": {
"message": "文件(&F)",
"description": "The label that is used for the File menu in the program main menu. The '&' indicates that the following letter will be used as the keyboard 'shortcut letter' for accessing the menu with the Alt-<letter> combination."
@ -145,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "已归档对话",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "这些对话已被归档,仅当有新消息到达时,它们才会重新出现在收件箱中。",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "存档会话",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "移动会话到收件箱",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "选择文件夹",
"description": "Button to allow the user to find a folder on disk"
@ -611,14 +643,36 @@
"message": "退出",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "桌面版Signal",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "请输入名字或号码",
"search": {
"message": "搜索",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "没有找到 “$searchTerm$” 相关结果",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "对话",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "联系人",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "信息",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "欢迎来到Signal",
"description": ""
@ -673,6 +727,10 @@
"message": "邮政信箱",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "下载中",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "下载附件",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -735,6 +793,18 @@
"message": "照片",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "无法更新",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "好",
"description": ""
@ -772,7 +842,7 @@
"description": "Label for the sender of a message"
},
"to": {
"message": "",
"message": "",
"description": "Label for the receiver of a message"
},
"sent": {
@ -1055,10 +1125,6 @@
"message": "此桌面版Signal已过期请升级到最新版本以继续发送消息。",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Android客户端仅能接收此消息的前2000个字符",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "升级",
"description": "Label text for button to upgrade the app to the latest version"
@ -1365,12 +1431,16 @@
"message": "暗色",
"description": "Label text for dark theme"
},
"noteToSelf": {
"message": "备忘录",
"description": "Name for the conversation with your own phone number"
},
"hideMenuBar": {
"message": "隐藏菜单栏",
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "开始话...",
"message": "开始新会话...",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -3,6 +3,10 @@
"message": "複製錯誤並離開。",
"description": "Shown in the top-level error popup, allowing user to copy the error text and close the app"
},
"unknownGroup": {
"message": "未知的群組",
"description": "Shown as the name of a group if we don't have any information about it"
},
"databaseError": {
"message": "資料庫錯誤",
"description": "Shown in a popup if the database cannot start up properly"
@ -157,6 +161,22 @@
}
}
},
"archivedConversations": {
"message": "封存對話",
"description": "Shown in place of the search box when showing archived conversation list"
},
"archiveHelperText": {
"message": "這些對話已經封存,並只有在收到新訊息時才會顯示在收件箱中。",
"description": "Shown at the top of the archived converations list in the left pane"
},
"archiveConversation": {
"message": "歸檔對話",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
},
"moveConversationToInbox": {
"message": "將對話移動到收件夾",
"description": "Undoes Archive Conversation action, and moves archived conversation back to the main conversation list"
},
"chooseDirectory": {
"message": "選擇資料夾",
"description": "Button to allow the user to find a folder on disk"
@ -623,14 +643,36 @@
"message": "離開",
"description": "Command in the tray icon menu, to quit the application"
},
"trayTooltip": {
"signalDesktop": {
"message": "Signal Desktop",
"description": "Tooltip for the tray icon"
},
"searchForPeopleOrGroups": {
"message": "輸入名稱或號碼",
"search": {
"message": "搜尋",
"description": "Placeholder text in the search input"
},
"noSearchResults": {
"message": "無 \"$searchTerm$\" 的搜尋結果",
"description": "Shown in the search left pane when no results were found",
"placeholders": {
"searchTerm": {
"content": "$1",
"example": "dog"
}
}
},
"conversationsHeader": {
"message": "對話",
"description": "Shown to separate the types of search results"
},
"contactsHeader": {
"message": "聯絡人",
"description": "Shown to separate the types of search results"
},
"messagesHeader": {
"message": "訊息",
"description": "Shown to separate the types of search results"
},
"welcomeToSignal": {
"message": "歡迎來到 Signal",
"description": ""
@ -685,6 +727,10 @@
"message": "郵箱號碼",
"description": "When rendering an address, used to provide context to a post office box"
},
"downloading": {
"message": "下載中...",
"description": "Shown in the message bubble while a long message attachment is being downloaded"
},
"downloadAttachment": {
"message": "下載附件",
"description": "Shown in a message's triple-dot menu if there isn't room for a dedicated download button"
@ -747,6 +793,18 @@
"message": "照片",
"description": "Shown in a quotation of a message containing a photo if no text was originally provided with that image"
},
"cannotUpdate": {
"message": "Cannot Update",
"description": "Shown as the title of our update error dialogs on windows"
},
"cannotUpdateDetail": {
"message": "Signal Desktop failed to update, but there is a new version available. Please go to https://signal.org/download and install the new version manually, then either contact support or file a bug about this problem.",
"description": "Shown if a general error happened while trying to install update package"
},
"readOnlyVolume": {
"message": "Signal Desktop is likely in a macOS quarantine, and will not be able to auto-update. Please try moving Signal.app to /Applications with Finder.",
"description": "Shown on MacOS if running on a read-only volume and we cannot update"
},
"ok": {
"message": "好",
"description": ""
@ -1067,10 +1125,6 @@
"message": "Signal Desktop版的版本已經過期。請更新到最新版來傳送訊息。",
"description": "Warning notification that this version of the app has expired"
},
"androidMessageLengthWarning": {
"message": "Android 使用者將只會收到訊息中的前 2000 個字",
"description": "Warning that long messages could not get received completely by Android clients."
},
"upgrade": {
"message": "升級",
"description": "Label text for button to upgrade the app to the latest version"
@ -1386,7 +1440,7 @@
"description": "Label text for menu bar visibility setting"
},
"startConversation": {
"message": "開始對話…",
"message": "開始新的對話...",
"description": "Label underneath number a user enters that is not an existing contact"
},
"newPhoneNumber": {

View File

@ -1,89 +0,0 @@
const { autoUpdater } = require('electron-updater');
const { dialog } = require('electron');
const config = require('./config');
const windowState = require('./window_state');
const hour = 60 * 60;
const autoUpdaterInterval = hour * 1000;
const RESTART_BUTTON = 0;
const LATER_BUTTON = 1;
function autoUpdateDisabled() {
return (
process.platform === 'linux' ||
process.mas ||
config.get('disableAutoUpdate')
);
}
async function checkForUpdates() {
try {
await autoUpdater.checkForUpdates();
} catch (error) {
console.log('checkForUpdates error:', error.stack);
}
}
let showingDialog = false;
function showUpdateDialog(mainWindow, messages) {
if (showingDialog || !mainWindow) {
return;
}
showingDialog = true;
const options = {
type: 'info',
buttons: [
messages.autoUpdateRestartButtonLabel.message,
messages.autoUpdateLaterButtonLabel.message,
],
title: messages.autoUpdateNewVersionTitle.message,
message: messages.autoUpdateNewVersionMessage.message,
detail: messages.autoUpdateNewVersionInstructions.message,
defaultId: LATER_BUTTON,
cancelId: RESTART_BUTTON,
};
dialog.showMessageBox(mainWindow, options, response => {
if (response === RESTART_BUTTON) {
// We delay these update calls because they don't seem to work in this
// callback - but only if the message box has a parent window.
// Fixes this bug: https://github.com/signalapp/Signal-Desktop/issues/1864
setTimeout(() => {
windowState.markShouldQuit();
autoUpdater.quitAndInstall();
}, 200);
}
showingDialog = false;
});
}
function onError(error) {
console.log('Got an error while updating:', error.stack);
}
function initialize(getMainWindow, messages) {
if (!messages) {
throw new Error('auto-update initialize needs localized messages');
}
if (autoUpdateDisabled()) {
return;
}
autoUpdater.addListener('update-downloaded', () => {
showUpdateDialog(getMainWindow(), messages);
});
autoUpdater.addListener('error', onError);
checkForUpdates();
setInterval(checkForUpdates, autoUpdaterInterval);
}
module.exports = {
initialize,
};

View File

@ -23,6 +23,7 @@ if (environment === 'production') {
process.env.NODE_APP_INSTANCE = '';
process.env.ALLOW_CONFIG_MUTATIONS = '';
process.env.SUPPRESS_NO_CONFIG_WARNING = '';
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '';
}
// We load config after we've made our modifications to NODE_ENV

View File

@ -84,6 +84,7 @@ exports.createTemplate = (options, messages) => {
label: messages.viewMenuResetZoom.message,
},
{
accelerator: platform === 'darwin' ? 'Command+=' : 'Control+Plus',
role: 'zoomin',
label: messages.viewMenuZoomIn.message,
},

View File

@ -25,7 +25,11 @@ function _createFileHandler({ userDataPath, installPath, isWindows }) {
return (request, callback) => {
// normalize() is primarily useful here for switching / to \ on windows
const target = path.normalize(_urlToPath(request.url, { isWindows }));
// here we attempt to follow symlinks to the ultimate final path, reflective of what
// we do in main.js on userDataPath and installPath
const realPath = fs.existsSync(target) ? fs.realpathSync(target) : target;
// finally we do case-insensitive checks on windows
const properCasing = isWindows ? realPath.toLowerCase() : realPath;
if (!path.isAbsolute(realPath)) {
console.log(
@ -35,8 +39,12 @@ function _createFileHandler({ userDataPath, installPath, isWindows }) {
}
if (
!realPath.startsWith(userDataPath) &&
!realPath.startsWith(installPath)
!properCasing.startsWith(
isWindows ? userDataPath.toLowerCase() : userDataPath
) &&
!properCasing.startsWith(
isWindows ? installPath.toLowerCase() : installPath
)
) {
console.log(
`Warning: denying request to path '${realPath}' (userDataPath: '${userDataPath}', installPath: '${installPath}')`

2
app/window_state.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
export function markShouldQuit(): void;
export function shouldQuit(): void;

View File

@ -622,6 +622,7 @@
<script type='text/javascript' src='js/conversation_controller.js'></script>
<script type='text/javascript' src='js/blocked_number_controller.js'></script>
<script type='text/javascript' src='js/link_previews_helper.js'></script>
<script type='text/javascript' src='js/message_controller.js'></script>
<script type='text/javascript' src='js/views/react_wrapper_view.js'></script>
<script type='text/javascript' src='js/views/whisper_view.js'></script>

View File

@ -6,6 +6,9 @@
"localServerPort": "8081",
"snodeServerPort": "8080",
"disableAutoUpdate": false,
"updatesUrl": "https://updates2.signal.org/desktop",
"updatesPublicKey": "fd7dd3de7149dc0a127909fee7de0f7620ddd0de061b37a2c303e37de802a401",
"updatesEnabled": false,
"openDevTools": false,
"buildExpiration": 0,
"commitHash": "",

View File

@ -1,5 +1,4 @@
{
"storageProfile": "development",
"disableAutoUpdate": true,
"openDevTools": true
}

View File

@ -1,5 +1,4 @@
{
"storageProfile": "staging",
"disableAutoUpdate": true,
"openDevTools": true
}

View File

@ -1,5 +1,4 @@
{
"storageProfile": "test",
"disableAutoUpdate": true,
"openDevTools": false
}

View File

@ -1,5 +1,4 @@
{
"storageProfile": "test",
"disableAutoUpdate": true,
"openDevTools": false
}

View File

@ -923,6 +923,8 @@
function onEmpty() {
initialLoadComplete = true;
window.readyForUpdates();
let interval = setInterval(() => {
const view = window.owsDesktopApp.appView;
if (view) {

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,158 @@
/* vim: ts=4:sw=4:expandtab */
var Internal = global.Internal || {};
(function() {
'use strict';
// Insert some bytes into the emscripten memory and return a pointer
function _allocate(bytes) {
var address = Module._malloc(bytes.length);
Module.HEAPU8.set(bytes, address);
return address;
}
function _readBytes(address, length, array) {
array.set(Module.HEAPU8.subarray(address, address + length));
}
var basepoint = new Uint8Array(32);
basepoint[0] = 9;
Internal.curve25519 = {
keyPair: function(privKey) {
var priv = new Uint8Array(privKey);
priv[0] &= 248;
priv[31] &= 127;
priv[31] |= 64;
// Where to store the result
var publicKey_ptr = Module._malloc(32);
// Get a pointer to the private key
var privateKey_ptr = _allocate(priv);
// The basepoint for generating public keys
var basepoint_ptr = _allocate(basepoint);
// The return value is just 0, the operation is done in place
var err = Module._curve25519_donna(
publicKey_ptr,
privateKey_ptr,
basepoint_ptr
);
var res = new Uint8Array(32);
_readBytes(publicKey_ptr, 32, res);
Module._free(publicKey_ptr);
Module._free(privateKey_ptr);
Module._free(basepoint_ptr);
return { pubKey: res.buffer, privKey: priv.buffer };
},
sharedSecret: function(pubKey, privKey) {
// Where to store the result
var sharedKey_ptr = Module._malloc(32);
// Get a pointer to our private key
var privateKey_ptr = _allocate(new Uint8Array(privKey));
// Get a pointer to their public key, the basepoint when you're
// generating a shared secret
var basepoint_ptr = _allocate(new Uint8Array(pubKey));
// Return value is 0 here too of course
var err = Module._curve25519_donna(
sharedKey_ptr,
privateKey_ptr,
basepoint_ptr
);
var res = new Uint8Array(32);
_readBytes(sharedKey_ptr, 32, res);
Module._free(sharedKey_ptr);
Module._free(privateKey_ptr);
Module._free(basepoint_ptr);
return res.buffer;
},
sign: function(privKey, message) {
// Where to store the result
var signature_ptr = Module._malloc(64);
// Get a pointer to our private key
var privateKey_ptr = _allocate(new Uint8Array(privKey));
// Get a pointer to the message
var message_ptr = _allocate(new Uint8Array(message));
var err = Module._curve25519_sign(
signature_ptr,
privateKey_ptr,
message_ptr,
message.byteLength
);
var res = new Uint8Array(64);
_readBytes(signature_ptr, 64, res);
Module._free(signature_ptr);
Module._free(privateKey_ptr);
Module._free(message_ptr);
return res.buffer;
},
verify: function(pubKey, message, sig) {
// Get a pointer to their public key
var publicKey_ptr = _allocate(new Uint8Array(pubKey));
// Get a pointer to the signature
var signature_ptr = _allocate(new Uint8Array(sig));
// Get a pointer to the message
var message_ptr = _allocate(new Uint8Array(message));
var res = Module._curve25519_verify(
signature_ptr,
publicKey_ptr,
message_ptr,
message.byteLength
);
Module._free(publicKey_ptr);
Module._free(signature_ptr);
Module._free(message_ptr);
return res !== 0;
},
};
Internal.curve25519_async = {
keyPair: function(privKey) {
return new Promise(function(resolve) {
resolve(Internal.curve25519.keyPair(privKey));
});
},
sharedSecret: function(pubKey, privKey) {
return new Promise(function(resolve) {
resolve(Internal.curve25519.sharedSecret(pubKey, privKey));
});
},
sign: function(privKey, message) {
return new Promise(function(resolve) {
resolve(Internal.curve25519.sign(privKey, message));
});
},
verify: function(pubKey, message, sig) {
return new Promise(function(resolve, reject) {
if (Internal.curve25519.verify(pubKey, message, sig)) {
reject(new Error('Invalid signature'));
} else {
resolve();
}
});
},
};
})();

View File

@ -1,7 +1,10 @@
/* global Backbone: false */
/* global Whisper: false */
/* global ConversationController: false */
/* global _: false */
/* global
Backbone,
Whisper,
ConversationController,
MessageController,
_
*/
/* eslint-disable more/no-then */
@ -45,10 +48,15 @@
const ids = groups.pluck('id');
ids.push(source);
return messages.find(
const target = messages.find(
item =>
!item.isIncoming() && _.contains(ids, item.get('conversationId'))
);
if (!target) {
return null;
}
return MessageController.register(target.id, target);
},
async onReceipt(receipt) {
try {

View File

@ -1,8 +1,11 @@
/* global _: false */
/* global Backbone: false */
/* global i18n: false */
/* global moment: false */
/* global Whisper: false */
/* global
_,
Backbone,
i18n,
MessageController,
moment,
Whisper
*/
// eslint-disable-next-line func-names
(function() {
@ -18,7 +21,9 @@
});
await Promise.all(
messages.map(async message => {
messages.map(async fromDB => {
const message = MessageController.register(fromDB.id, fromDB);
window.log.info('Message expired', {
sentAt: message.get('sent_at'),
});

65
js/message_controller.js Normal file
View File

@ -0,0 +1,65 @@
// eslint-disable-next-line func-names
(function() {
'use strict';
window.Whisper = window.Whisper || {};
const messageLookup = Object.create(null);
const SECOND = 1000;
const MINUTE = SECOND * 60;
const FIVE_MINUTES = MINUTE * 5;
const HOUR = MINUTE * 60;
function register(id, message) {
const existing = messageLookup[id];
if (existing) {
messageLookup[id] = {
message: existing.message,
timestamp: Date.now(),
};
return existing.message;
}
messageLookup[id] = {
message,
timestamp: Date.now(),
};
return message;
}
function unregister(id) {
delete messageLookup[id];
}
function cleanup() {
const messages = Object.values(messageLookup);
const now = Date.now();
for (let i = 0, max = messages.length; i < max; i += 1) {
const { message, timestamp } = messages[i];
const conversation = message.getConversation();
if (
now - timestamp > FIVE_MINUTES &&
(!conversation || !conversation.messageCollection.length)
) {
delete messageLookup[message.id];
}
}
}
function _get() {
return messageLookup;
}
setInterval(cleanup, HOUR);
window.MessageController = {
register,
unregister,
cleanup,
_get,
};
})();

View File

@ -3,6 +3,7 @@
i18n,
Backbone,
ConversationController,
MessageController,
storage,
textsecure,
Whisper,
@ -986,14 +987,6 @@
},
async onReadMessage(message, readAt) {
const existing = this.messageCollection.get(message.id);
if (existing) {
const fetched = await window.Signal.Data.getMessageById(existing.id, {
Message: Whisper.Message,
});
existing.merge(fetched);
}
// We mark as read everything older than this message - to clean up old stuff
// still marked unread in the database. If the user generally doesn't read in
// the desktop app, so the desktop app only gets read syncs, we can very
@ -1255,7 +1248,20 @@
});
}
const message = this.addSingleMessage(messageWithSchema);
if (this.isPrivate()) {
messageWithSchema.destination = destination;
}
const attributes = {
...messageWithSchema,
id: window.getGuid(),
};
const model = this.addSingleMessage(attributes);
const message = MessageController.register(model.id, model);
await window.Signal.Data.saveMessage(message.attributes, {
forceSave: true,
Message: Whisper.Message,
});
if (this.isPrivate()) {
message.set({ destination });
@ -1267,7 +1273,7 @@
message.set({ id });
this.set({
lastMessage: message.getNotificationText(),
lastMessage: model.getNotificationText(),
lastMessageStatus: 'sending',
active_at: now,
timestamp: now,
@ -1551,7 +1557,6 @@
? lastMessageModel.getMessagePropStatus()
: null;
const lastMessageUpdate = Conversation.createLastMessageUpdate({
currentLastMessageText: this.get('lastMessage') || null,
currentTimestamp: this.get('timestamp') || null,
lastMessage: lastMessageJSON,
lastMessageStatus: lastMessageStatusModel,
@ -1879,11 +1884,9 @@
let read = await Promise.all(
_.map(oldUnread, async providedM => {
let m = providedM;
const m = MessageController.register(providedM.id, providedM);
if (this.messageCollection.get(m.id)) {
m = this.messageCollection.get(m.id);
} else {
if (!this.messageCollection.get(m.id)) {
window.log.warn(
'Marked a message as read in the database, but ' +
'it was not in messageCollection.'

View File

@ -1,14 +1,17 @@
/* global _: false */
/* global Backbone: false */
/* global storage: false */
/* global filesize: false */
/* global ConversationController: false */
/* global clipboard: false */
/* global getAccountManager: false */
/* global i18n: false */
/* global Signal: false */
/* global textsecure: false */
/* global Whisper: false */
/* global
_,
Backbone,
storage,
filesize,
ConversationController,
MessageController,
getAccountManager,
i18n,
Signal,
textsecure,
Whisper,
clipboard
*/
/* eslint-disable more/no-then */
@ -355,6 +358,7 @@
this.cleanup();
},
async cleanup() {
MessageController.unregister(this.id);
this.unload();
await deleteExternalMessageFiles(this.attributes);
},
@ -968,46 +972,26 @@
return null;
}
const [retries, errors] = _.partition(
this.get('errors'),
this.isReplayableError.bind(this)
);
// Put the errors back which aren't replayable
this.set({ errors });
this.set({ errors: null });
const conversation = this.getConversation();
const intendedRecipients = this.get('recipients') || [];
const successfulRecipients = this.get('sent_to') || [];
const currentRecipients = conversation.getRecipients();
const profileKey = conversation.get('profileSharing')
? storage.get('profileKey')
: null;
const errorNumbers = retries
.map(retry => retry.number)
.filter(item => Boolean(item));
let numbers = _.intersection(
errorNumbers,
intendedRecipients,
currentRecipients
);
let recipients = _.intersection(intendedRecipients, currentRecipients);
recipients = _.without(recipients, successfulRecipients);
if (!numbers.length) {
window.log.warn(
'retrySend: No numbers in error set, using all recipients'
);
if (!recipients.length) {
window.log.warn('retrySend: Nobody to send to!');
if (conversation) {
numbers = _.intersection(currentRecipients, intendedRecipients);
// We clear all errors here to start with a fresh slate, since we are starting
// from scratch on this message with a fresh set of recipients
this.set({ errors: null });
} else {
throw new Error(
'No numbers in error set, did not find conversation for message'
);
}
return window.Signal.Data.saveMessage(this.attributes, {
Message: Whisper.Message,
});
}
const attachmentsWithData = await Promise.all(
@ -1023,8 +1007,8 @@
const previewWithData = await loadPreviewData(this.get('preview'));
// Special-case the self-send case - we send only a sync message
if (numbers.length === 1 && numbers[0] === this.OUR_NUMBER) {
const [number] = numbers;
if (recipients.length === 1 && recipients[0] === this.OUR_NUMBER) {
const [number] = recipients;
const dataMessage = await textsecure.messaging.getMessageProto(
number,
body,
@ -1043,7 +1027,7 @@
options.messageType = this.get('type');
if (conversation.isPrivate()) {
const [number] = numbers;
const [number] = recipients;
promise = textsecure.messaging.sendMessageToNumber(
number,
body,
@ -1061,7 +1045,7 @@
promise = textsecure.messaging.sendMessage(
{
recipients: numbers,
recipients,
body,
timestamp: this.get('sent_at'),
attachments,
@ -1633,17 +1617,18 @@
const collection = await window.Signal.Data.getMessagesBySentAt(id, {
MessageCollection: Whisper.MessageCollection,
});
const queryMessage = collection.find(item => {
const found = collection.find(item => {
const messageAuthor = item.getContact();
return messageAuthor && author === messageAuthor.id;
});
if (!queryMessage) {
if (!found) {
quote.referencedMessageNotFound = true;
return message;
}
const queryMessage = MessageController.register(found.id, found);
quote.text = queryMessage.get('body');
if (firstAttachment) {
firstAttachment.thumbnail = null;
@ -1729,6 +1714,9 @@
const conversation = ConversationController.get(conversationId);
return conversation.queueJob(async () => {
window.log.info(
`Starting handleDataMessage for message ${message.idForLogging()} in conversation ${conversation.idForLogging()}`
);
const withQuoteReference = await this.copyFromQuotedMessage(
initialMessage
);
@ -1994,6 +1982,7 @@
Message: Whisper.Message,
});
message.set({ id });
MessageController.register(message.id, message);
// Note that this can save the message again, if jobs were queued. We need to
// call it after we have an id for this message, because the jobs refer back
@ -2124,17 +2113,9 @@
});
// Receive will be enabled before we enable send
Whisper.Message.LONG_MESSAGE_SEND_DISABLED = true;
Whisper.Message.LONG_MESSAGE_CONTENT_TYPE = 'text/x-signal-plain';
Whisper.Message.getLongMessageAttachment = ({ body, attachments, now }) => {
if (Whisper.Message.LONG_MESSAGE_SEND_DISABLED) {
return {
body,
attachments,
};
}
if (body.length <= 2048) {
return {
body,
@ -2208,7 +2189,9 @@
}
);
const models = messages.filter(message => Boolean(message.id));
const models = messages
.filter(message => Boolean(message.id))
.map(message => MessageController.register(message.id, message));
const eliminated = messages.length - models.length;
if (eliminated > 0) {
window.log.warn(

View File

@ -1,4 +1,4 @@
/* global Whisper, Signal, setTimeout, clearTimeout */
/* global Whisper, Signal, setTimeout, clearTimeout, MessageController */
const { isFunction, isNumber, omit } = require('lodash');
const getGuid = require('uuid/v4');
@ -37,7 +37,6 @@ let timeout;
let getMessageReceiver;
let logger;
const _activeAttachmentDownloadJobs = {};
const _messageCache = {};
async function start(options = {}) {
({ getMessageReceiver, logger } = options);
@ -149,12 +148,15 @@ async function _runJob(job) {
);
}
message = await _getMessage(messageId);
if (!message) {
const found = await getMessageById(messageId, {
Message: Whisper.Message,
});
if (!found) {
logger.error('_runJob: Source message not found, deleting job');
await _finishJob(message, id);
await _finishJob(null, id);
return;
}
message = MessageController.register(found.id, found);
const pending = true;
await setAttachmentDownloadJobPending(id, pending);
@ -232,46 +234,6 @@ async function _runJob(job) {
}
}
async function _getMessage(id) {
let item = _messageCache[id];
if (item) {
const fiveMinutesAgo = Date.now() - 5 * MINUTE;
if (item.timestamp >= fiveMinutesAgo) {
return item.message;
}
delete _messageCache[id];
}
let message = await getMessageById(id, {
Message: Whisper.Message,
});
if (!message) {
return message;
}
// Once more, checking for race conditions
item = _messageCache[id];
if (item) {
const fiveMinutesAgo = Date.now() - 5 * MINUTE;
if (item.timestamp >= fiveMinutesAgo) {
return item.message;
}
}
const conversation = message.getConversation();
if (conversation && conversation.messageCollection.get(id)) {
message = conversation.get(id);
}
_messageCache[id] = {
timestamp: Date.now(),
message,
};
return message;
}
async function _finishJob(message, id) {
if (message) {
await saveMessage(message.attributes, {

View File

@ -1,4 +1,11 @@
/* global Whisper, Backbone, _, ConversationController, window */
/* global
Whisper,
Backbone,
_,
ConversationController,
MessageController,
window
*/
/* eslint-disable more/no-then */
@ -46,9 +53,14 @@
const ids = groups.pluck('id');
ids.push(reader);
return messages.find(
const target = messages.find(
item => item.isOutgoing() && _.contains(ids, item.get('conversationId'))
);
if (!target) {
return null;
}
return MessageController.register(target.id, target);
},
async onReceipt(receipt) {
try {

View File

@ -1,4 +1,8 @@
/* global Backbone, Whisper */
/* global
Backbone,
Whisper,
MessageController
*/
/* eslint-disable more/no-then */
@ -30,19 +34,19 @@
}
);
const message = messages.find(
const found = messages.find(
item =>
item.isIncoming() && item.get('source') === receipt.get('sender')
);
const notificationForMessage = message
? Whisper.Notifications.findWhere({ messageId: message.id })
const notificationForMessage = found
? Whisper.Notifications.findWhere({ messageId: found.id })
: null;
const removedNotification = Whisper.Notifications.remove(
notificationForMessage
);
const receiptSender = receipt.get('sender');
const receiptTimestamp = receipt.get('timestamp');
const wasMessageFound = Boolean(message);
const wasMessageFound = Boolean(found);
const wasNotificationFound = Boolean(notificationForMessage);
const wasNotificationRemoved = Boolean(removedNotification);
window.log.info('Receive read sync:', {
@ -53,10 +57,11 @@
wasNotificationRemoved,
});
if (!message) {
if (!found) {
return;
}
const message = MessageController.register(found.id, found);
const readAt = receipt.get('read_at');
// If message is unread, we mark it read. Otherwise, we update the expiration

View File

@ -64,6 +64,13 @@
},
});
const MAX_MESSAGE_BODY_LENGTH = 64 * 1024;
Whisper.MessageBodyTooLongToast = Whisper.ToastView.extend({
render_attributes() {
return { toastMessage: i18n('messageBodyTooLong') };
},
});
Whisper.ConversationLoadingScreen = Whisper.View.extend({
templateName: 'conversation-loading-screen',
className: 'conversation-loading-screen',
@ -91,6 +98,7 @@
this.listenTo(this.model, 'prune', this.onPrune);
this.listenTo(this.model, 'disable:input', this.onDisableInput);
this.listenTo(this.model, 'change:placeholder', this.onChangePlaceholder);
this.listenTo(this.model, 'unload', () => this.unload('model trigger'));
this.listenTo(this.model, 'typing-update', this.renderTypingBubble);
this.listenTo(
this.model.messageCollection,
@ -784,13 +792,15 @@
const collection = await window.Signal.Data.getMessagesBySentAt(id, {
MessageCollection: Whisper.MessageCollection,
});
const messageFromDatabase = collection.find(item => {
const messageAuthor = item.getContact();
const found = Boolean(
collection.find(item => {
const messageAuthor = item.getContact();
return messageAuthor && author === messageAuthor.id;
});
return messageAuthor && author === messageAuthor.id;
})
);
if (messageFromDatabase) {
if (found) {
const toast = new Whisper.FoundButNotLoadedToast();
toast.$el.appendTo(this.$el);
toast.render();
@ -1479,8 +1489,15 @@
Whisper.events.trigger('showConfirmationDialog', {
message: i18n('deleteConversationConfirmation'),
onOk: async () => {
await this.model.destroyMessages();
this.remove();
try {
await this.model.destroyMessages();
this.unload('delete messages');
} catch (error) {
window.log.error(
'destroyMessages: Failed to successfully delete conversation',
error && error.stack ? error.stack : error
);
}
},
});
},
@ -1698,6 +1715,9 @@
this.closeEmojiPanel();
this.model.clearTypingTimers();
const input = this.$messageField;
const message = window.Signal.Emoji.replaceColons(input.val()).trim();
let toast;
if (extension.expired()) {
toast = new Whisper.ExpiredToast();
@ -1711,6 +1731,9 @@
if (!this.model.isPrivate() && this.model.get('left')) {
toast = new Whisper.LeftGroupToast();
}
if (message.length > MAX_MESSAGE_BODY_LENGTH) {
toast = new Whisper.MessageBodyTooLongToast();
}
if (toast) {
toast.$el.appendTo(this.$el);
@ -1719,17 +1742,6 @@
return;
}
const input = this.$messageField;
const inputMessage = window.Signal.Emoji.replaceColons(
input.val()
).trim();
// Limit the message to 2000 characters
const message = inputMessage.substring(
0,
Math.min(2000, inputMessage.length)
);
try {
if (!message.length && !this.fileInput.hasFiles()) {
return;

View File

@ -1,4 +1,6 @@
/* global
$,
ConversationController,
extension,
ConversationController
getConversations,
@ -182,6 +184,27 @@
this.openConversationAction = openConversationExternal;
// In the future this listener will be added by the conversation view itself. But
// because we currently have multiple converations open at once, we install just
// one global handler.
$(document).on('keydown', event => {
const { ctrlKey, key } = event;
// We can add Command-E as the Mac shortcut when we add it to our Electron menus:
// https://stackoverflow.com/questions/27380018/when-cmd-key-is-kept-pressed-keyup-is-not-triggered-for-any-other-key
// For now, it will stay as CTRL-E only
if (key === 'e' && ctrlKey) {
const state = this.store.getState();
const selectedId = state.conversations.selectedConversation;
const conversation = ConversationController.get(selectedId);
if (conversation && !conversation.get('isArchived')) {
conversation.setArchived(true);
conversation.trigger('unload');
}
}
});
this.listenTo(convoCollection, 'remove', conversation => {
const { id } = conversation || {};
conversationRemoved(id);

View File

@ -150,12 +150,14 @@
value: window.initialData.spellCheck,
setFn: window.setSpellCheck,
});
new CheckboxView({
el: this.$('.menu-bar-setting'),
name: 'menu-bar-setting',
value: window.initialData.hideMenuBar,
setFn: window.setHideMenuBar,
});
if (Settings.isHideMenuBarSupported()) {
new CheckboxView({
el: this.$('.menu-bar-setting'),
name: 'menu-bar-setting',
value: window.initialData.hideMenuBar,
setFn: window.setHideMenuBar,
});
}
new CheckboxView({
el: this.$('.link-preview-setting'),
name: 'link-preview-setting',
@ -203,6 +205,7 @@
nameOnly: i18n('nameOnly'),
audioNotificationDescription: i18n('audioNotificationDescription'),
isAudioNotificationSupported: Settings.isAudioNotificationSupported(),
isHideMenuBarSupported: Settings.isHideMenuBarSupported(),
themeLight: i18n('themeLight'),
themeDark: i18n('themeDark'),
hideMenuBar: i18n('hideMenuBar'),

View File

@ -36185,7 +36185,8 @@ SessionCipher.prototype = {
var errors = [];
return this.decryptWithSessionList(buffer, record.getSessions(), errors).then(function(result) {
return this.getRecord(address).then(function(record) {
if (result.session.indexInfo.baseKey !== record.getOpenSession().indexInfo.baseKey) {
var openSession = record.getOpenSession();
if (!openSession || result.session.indexInfo.baseKey !== openSession.indexInfo.baseKey) {
record.archiveCurrentState();
record.promoteState(result.session);
}

View File

@ -1114,13 +1114,8 @@ MessageSender.prototype = {
window.textsecure = window.textsecure || {};
textsecure.MessageSender = function MessageSenderWrapper(
url,
username,
password,
cdnUrl
) {
const sender = new MessageSender(url, username, password, cdnUrl);
textsecure.MessageSender = function MessageSenderWrapper(username, password) {
const sender = new MessageSender(username, password);
this.sendExpirationTimerUpdateToNumber = sender.sendExpirationTimerUpdateToNumber.bind(
sender

36
main.js
View File

@ -63,8 +63,11 @@ const appInstance = config.util.getEnv('NODE_APP_INSTANCE') || 0;
// data directory has been set.
const attachments = require('./app/attachments');
const attachmentChannel = require('./app/attachment_channel');
// TODO: remove or restore when appropriate
// const autoUpdate = require('./app/auto_update');
// TODO: Enable when needed
// const updater = require('./ts/updater/index');
const updater = null;
const createTrayIcon = require('./app/tray_icon');
const ephemeralConfig = require('./app/ephemeral_config');
const logging = require('./app/logging');
@ -388,12 +391,29 @@ function createWindow() {
// when you should delete the corresponding element.
mainWindow = null;
});
ipc.on('show-window', () => {
showWindow();
});
}
ipc.on('show-window', () => {
showWindow();
});
let updatesStarted = false;
ipc.on('ready-for-updates', async () => {
if (updatesStarted || !updater) {
return;
}
updatesStarted = true;
try {
await updater.start(getMainWindow, locale.messages, logger);
} catch (error) {
logger.error(
'Error starting update checks:',
error && error.stack ? error.stack : error
);
}
});
function openReleaseNotes() {
shell.openExternal(
`https://github.com/loki-project/loki-messenger/releases/tag/v${app.getVersion()}`
@ -714,6 +734,7 @@ app.on('ready', async () => {
await logging.initialize();
logger = logging.getLogger();
logger.info('app ready');
logger.info(`starting version ${packageJson.version}`);
if (!locale) {
const appLocale = process.env.NODE_ENV === 'test' ? 'en' : app.getLocale();
@ -799,9 +820,6 @@ async function showMainWindow(sqlKey) {
ready = true;
// TODO: remove or restore when appropriate
// autoUpdate.initialize(getMainWindow, locale.messages);
createWindow();
if (usingTrayIcon) {

View File

@ -18,7 +18,8 @@
"icon-gen": "electron-icon-maker --input=images/icon_1024.png --output=./build",
"generate": "yarn icon-gen && yarn grunt",
"build": "build --config.extraMetadata.environment=$SIGNAL_ENV",
"build-release": "SIGNAL_ENV=production npm run build -- --config.directories.output=release",
"build-release": "SIGNAL_ENV=production && npm run build -- --config.directories.output=release",
"sign-release": "node ts/updater/generateSignature.js",
"build-module-protobuf": "pbjs --target static-module --wrap commonjs --out ts/protobuf/compiled.js protos/*.proto && pbts --out ts/protobuf/compiled.d.ts ts/protobuf/compiled.js",
"clean-module-protobuf": "rm -f ts/protobuf/compiled.d.ts ts/protobuf/compiled.js",
"build-protobuf": "yarn build-module-protobuf",
@ -41,15 +42,15 @@
"tslint": "tslint --format stylish --project .",
"format": "prettier --write \"*.{css,js,json,md,scss,ts,tsx}\" \"./**/*.{css,js,json,md,scss,ts,tsx}\"",
"transpile": "tsc",
"clean-transpile": "rimraf ts/**/*.js ts/*.js",
"clean-transpile": "rimraf ts/**/*.js && rimraf ts/*.js",
"open-coverage": "open coverage/lcov-report/index.html",
"styleguide": "styleguidist server",
"pow-metrics": "node metrics_app.js localhost 9000"
"pow-metrics": "node metrics_app.js localhost 9000",
"ready": "yarn clean-transpile && yarn grunt && yarn lint && yarn test-node && yarn test-electron && yarn lint-deps"
},
"dependencies": {
"@journeyapps/sqlcipher": "https://github.com/scottnonnenberg-signal/node-sqlcipher.git#2e28733b61640556b0272a3bfc78b0357daf71e6",
"@sindresorhus/is": "0.8.0",
"@types/react-virtualized": "9.18.12",
"backbone": "1.3.3",
"blob-util": "1.3.0",
"blueimp-canvas-to-blob": "3.14.0",
@ -58,9 +59,9 @@
"bunyan": "1.8.12",
"classnames": "2.2.5",
"config": "1.28.1",
"electron-context-menu": "^0.11.0",
"electron-editor-context-menu": "1.1.1",
"electron-is-dev": "0.3.0",
"electron-updater": "3.2.0",
"emoji-datasource": "4.0.0",
"emoji-datasource-apple": "4.0.0",
"emoji-js": "3.4.0",
@ -70,7 +71,7 @@
"form-data": "2.3.2",
"fs-extra": "5.0.0",
"glob": "7.1.2",
"google-libphonenumber": "3.0.7",
"google-libphonenumber": "3.2.2",
"got": "8.2.0",
"he": "1.2.0",
"identicon.js": "2.3.3",
@ -79,6 +80,7 @@
"js-sha512": "0.8.0",
"jsbn": "1.1.0",
"libsodium-wrappers": "^0.7.4",
"js-yaml": "3.13.0",
"linkify-it": "2.0.3",
"lodash": "4.17.11",
"mkdirp": "0.5.1",
@ -115,26 +117,36 @@
"devDependencies": {
"@types/chai": "4.1.2",
"@types/classnames": "2.2.3",
"@types/config": "0.0.34",
"@types/filesize": "3.6.0",
"@types/fs-extra": "5.0.5",
"@types/google-libphonenumber": "7.4.14",
"@types/got": "9.4.1",
"@types/jquery": "3.3.29",
"@types/js-yaml": "3.12.0",
"@types/linkify-it": "2.0.3",
"@types/lodash": "4.14.106",
"@types/mkdirp": "0.5.2",
"@types/mocha": "5.0.0",
"@types/pify": "3.0.2",
"@types/qs": "6.5.1",
"@types/react": "16.8.5",
"@types/react-dom": "16.8.2",
"@types/react-redux": "7.0.1",
"@types/react-virtualized": "9.18.12",
"@types/redux-logger": "3.0.7",
"@types/rimraf": "2.0.2",
"@types/semver": "5.5.0",
"@types/sinon": "4.3.1",
"@types/uuid": "3.4.4",
"arraybuffer-loader": "1.0.3",
"asar": "0.14.0",
"axios": "0.18.0",
"bower": "1.8.2",
"chai": "4.1.2",
"dashdash": "1.14.1",
"electron": "4.1.2",
"electron-builder": "20.33.1",
"electron-builder": "20.39.0",
"electron-icon-maker": "0.0.3",
"eslint": "4.14.0",
"eslint-config-airbnb-base": "12.1.0",

View File

@ -118,6 +118,7 @@ ipc.on('on-unblock-number', (event, number) => {
});
window.closeAbout = () => ipc.send('close-about');
window.readyForUpdates = () => ipc.send('ready-for-updates');
window.updateTrayIcon = unreadCount =>
ipc.send('update-tray-icon', unreadCount);
@ -375,6 +376,19 @@ window.Signal.Backup = require('./js/modules/backup');
window.Signal.Debug = require('./js/modules/debug');
window.Signal.Logs = require('./js/modules/logs');
// Add right-click listener for selected text and urls
const contextMenu = require('electron-context-menu');
contextMenu({
showInspectElement: false,
shouldShowMenu: (event, params) =>
Boolean(
!params.isEditable &&
params.mediaType === 'none' &&
(params.linkURL || params.selectionText)
),
});
// We pull this in last, because the native module involved appears to be sensitive to
// /tmp mounted as noexec on Linux.
require('./js/spell_check');

View File

@ -60,10 +60,12 @@
</div>
</div>
<br />
{{ #isHideMenuBarSupported }}
<div class='menu-bar-setting'>
<input type='checkbox' name='hide-menu-bar' id='hide-menu-bar'/>
<label for='hide-menu-bar'>{{ hideMenuBar }}</label>
</div>
{{ /isHideMenuBarSupported }}
<hr>
<div class='notification-settings'>
<h3>{{ notifications }}</h3>

View File

@ -22,8 +22,13 @@
font-weight: bold;
}
$roboto: Roboto, 'Helvetica Neue', Arial, Helvetica, sans-serif;
$roboto-light: Roboto-Light, 'Helvetica Neue', Arial, Helvetica, sans-serif;
$roboto: Roboto, 'Helvetica Neue', 'Source Sans Pro', 'Source Han Sans SC',
'Source Han Sans CN', 'Hiragino Sans GB', 'Hiragino Kaku Gothic',
'Microsoft Yahei UI', Helvetica, Arial, sans-serif;
$roboto-light: Roboto-Light, 'Helvetica Neue', 'Source Sans Pro Light',
'Source Han Sans SC Light', 'Source Han Sans CN Light',
'Hiragino Sans GB Light', 'Hiragino Kaku Gothic Light',
'Microsoft Yahei UI Light', Helvetica, Arial, sans-serif;
// Loki colors
$color-loki-light-gray: #e9e9e9;

View File

@ -115,6 +115,7 @@
"role": "resetzoom"
},
{
"accelerator": "Command+=",
"label": "Zoom In",
"role": "zoomin"
},

View File

@ -102,6 +102,7 @@
"role": "resetzoom"
},
{
"accelerator": "Command+=",
"label": "Zoom In",
"role": "zoomin"
},

View File

@ -74,6 +74,7 @@
"role": "resetzoom"
},
{
"accelerator": "Control+Plus",
"label": "Zoom In",
"role": "zoomin"
},

View File

@ -63,6 +63,7 @@
"role": "resetzoom"
},
{
"accelerator": "Control+Plus",
"label": "Zoom In",
"role": "zoomin"
},

View File

@ -501,6 +501,7 @@
<script type="text/javascript" src="../js/models/blockedNumbers.js" data-cover></script>
<script type="text/javascript" src="../js/conversation_controller.js" data-cover></script>
<script type='text/javascript' src='../js/blocked_number_controller.js'></script>
<script type="text/javascript" src="../js/message_controller.js" data-cover></script>
<script type="text/javascript" src="../js/keychange_listener.js" data-cover></script>
<script type='text/javascript' src='../js/expiring_messages.js' data-cover></script>
<script type='text/javascript' src='../js/notifications.js' data-cover></script>

View File

@ -13,6 +13,8 @@ describe('Conversation', () => {
const input = {};
const expected = {
lastMessage: '',
lastMessageStatus: null,
timestamp: null,
};
const actual = Conversation.createLastMessageUpdate(input);
@ -22,7 +24,6 @@ describe('Conversation', () => {
context('for regular message', () => {
it('should update last message text and timestamp', () => {
const input = {
currentLastMessageText: 'Existing message',
currentTimestamp: 555,
lastMessageStatus: 'read',
lastMessage: {
@ -46,7 +47,6 @@ describe('Conversation', () => {
context('for verified change message', () => {
it('should skip update', () => {
const input = {
currentLastMessageText: 'bingo',
currentTimestamp: 555,
lastMessage: {
type: 'verified-change',
@ -57,8 +57,8 @@ describe('Conversation', () => {
lastMessageNotificationText: 'Verified Changed',
};
const expected = {
lastMessage: 'bingo',
lastMessageStatus: undefined,
lastMessage: '',
lastMessageStatus: null,
timestamp: 555,
};
@ -70,7 +70,6 @@ describe('Conversation', () => {
context('for expire timer update from sync', () => {
it('should update message but not timestamp (to prevent bump to top)', () => {
const input = {
currentLastMessageText: 'I am expired',
currentTimestamp: 555,
lastMessage: {
type: 'incoming',
@ -87,7 +86,7 @@ describe('Conversation', () => {
};
const expected = {
lastMessage: 'Last message before expired',
lastMessageStatus: undefined,
lastMessageStatus: null,
timestamp: 555,
};

View File

@ -130,4 +130,65 @@ describe('Settings', () => {
});
});
});
describe('isHideMenuBarSupported', () => {
context('on macOS', () => {
beforeEach(() => {
sandbox.stub(process, 'platform').value('darwin');
});
afterEach(() => {
sandbox.restore();
});
it('should return false', () => {
assert.isFalse(Settings.isHideMenuBarSupported());
});
});
context('on Windows', () => {
context('version 7', () => {
beforeEach(() => {
sandbox.stub(process, 'platform').value('win32');
sandbox.stub(os, 'release').returns('7.0.0');
});
afterEach(() => {
sandbox.restore();
});
it('should return true', () => {
assert.isTrue(Settings.isHideMenuBarSupported());
});
});
context('version 8+', () => {
beforeEach(() => {
sandbox.stub(process, 'platform').value('win32');
sandbox.stub(os, 'release').returns('8.0.0');
});
afterEach(() => {
sandbox.restore();
});
it('should return true', () => {
assert.isTrue(Settings.isHideMenuBarSupported());
});
});
});
context('on Linux', () => {
beforeEach(() => {
sandbox.stub(process, 'platform').value('linux');
});
afterEach(() => {
sandbox.restore();
});
it('should return true', () => {
assert.isTrue(Settings.isHideMenuBarSupported());
});
});
});
});

View File

@ -0,0 +1,77 @@
import { assert } from 'chai';
import { getUpdateFileName, getVersion } from '../../updater/common';
describe('updater/signatures', () => {
const windows = `version: 1.23.2
files:
- url: signal-desktop-win-1.23.2.exe
sha512: hhK+cVAb+QOK/Ln0RBcq8Rb1iPcUC0KZeT4NwLB25PMGoPmakY27XE1bXq4QlkASJN1EkYTbKf3oUJtcllziyQ==
size: 92020776
path: signal-desktop-win-1.23.2.exe
sha512: hhK+cVAb+QOK/Ln0RBcq8Rb1iPcUC0KZeT4NwLB25PMGoPmakY27XE1bXq4QlkASJN1EkYTbKf3oUJtcllziyQ==
releaseDate: '2019-03-29T16:58:08.210Z'
`;
const mac = `version: 1.23.2
files:
- url: signal-desktop-mac-1.23.2.zip
sha512: f4pPo3WulTVi9zBWGsJPNIlvPOTCxPibPPDmRFDoXMmFm6lqJpXZQ9DSWMJumfc4BRp4y/NTQLGYI6b4WuJwhg==
size: 105179791
blockMapSize: 111109
path: signal-desktop-mac-1.23.2.zip
sha512: f4pPo3WulTVi9zBWGsJPNIlvPOTCxPibPPDmRFDoXMmFm6lqJpXZQ9DSWMJumfc4BRp4y/NTQLGYI6b4WuJwhg==
releaseDate: '2019-03-29T16:57:16.997Z'
`;
const windowsBeta = `version: 1.23.2-beta.1
files:
- url: signal-desktop-beta-win-1.23.2-beta.1.exe
sha512: ZHM1F3y/Y6ulP5NhbFuh7t2ZCpY4lD9BeBhPV+g2B/0p/66kp0MJDeVxTgjR49OakwpMAafA1d6y2QBail4hSQ==
size: 92028656
path: signal-desktop-beta-win-1.23.2-beta.1.exe
sha512: ZHM1F3y/Y6ulP5NhbFuh7t2ZCpY4lD9BeBhPV+g2B/0p/66kp0MJDeVxTgjR49OakwpMAafA1d6y2QBail4hSQ==
releaseDate: '2019-03-29T01:56:00.544Z'
`;
const macBeta = `version: 1.23.2-beta.1
files:
- url: signal-desktop-beta-mac-1.23.2-beta.1.zip
sha512: h/01N0DD5Jw2Q6M1n4uLGLTCrMFxcn8QOPtLR3HpABsf3w9b2jFtKb56/2cbuJXP8ol8TkTDWKnRV6mnqnLBDw==
size: 105182398
blockMapSize: 110894
path: signal-desktop-beta-mac-1.23.2-beta.1.zip
sha512: h/01N0DD5Jw2Q6M1n4uLGLTCrMFxcn8QOPtLR3HpABsf3w9b2jFtKb56/2cbuJXP8ol8TkTDWKnRV6mnqnLBDw==
releaseDate: '2019-03-29T01:53:23.881Z'
`;
describe('#getVersion', () => {
it('successfully gets version', () => {
const expected = '1.23.2';
assert.strictEqual(getVersion(windows), expected);
assert.strictEqual(getVersion(mac), expected);
const expectedBeta = '1.23.2-beta.1';
assert.strictEqual(getVersion(windowsBeta), expectedBeta);
assert.strictEqual(getVersion(macBeta), expectedBeta);
});
});
describe('#getUpdateFileName', () => {
it('successfully gets version', () => {
assert.strictEqual(
getUpdateFileName(windows),
'signal-desktop-win-1.23.2.exe'
);
assert.strictEqual(
getUpdateFileName(mac),
'signal-desktop-mac-1.23.2.zip'
);
assert.strictEqual(
getUpdateFileName(windowsBeta),
'signal-desktop-beta-win-1.23.2-beta.1.exe'
);
assert.strictEqual(
getUpdateFileName(macBeta),
'signal-desktop-beta-mac-1.23.2-beta.1.zip'
);
});
});
});

View File

@ -0,0 +1,14 @@
import { assert } from 'chai';
import { keyPair, sign, verify } from '../../updater/curve';
describe('updater/curve', () => {
it('roundtrips', () => {
const message = Buffer.from('message');
const { publicKey, privateKey } = keyPair();
const signature = sign(privateKey, message);
const verified = verify(publicKey, message, signature);
assert.strictEqual(verified, true);
});
});

View File

@ -0,0 +1,206 @@
import { existsSync } from 'fs';
import { join } from 'path';
import { assert } from 'chai';
import { copy } from 'fs-extra';
import {
_getFileHash,
getSignaturePath,
loadHexFromPath,
verifySignature,
writeHexToPath,
writeSignature,
} from '../../updater/signature';
import { createTempDir, deleteTempDir } from '../../updater/common';
import { keyPair } from '../../updater/curve';
describe('updater/signatures', () => {
it('_getFileHash returns correct hash', async () => {
const filePath = join(__dirname, '../../../fixtures/ghost-kitty.mp4');
const expected =
'7bc77f27d92d00b4a1d57c480ca86dacc43d57bc318339c92119d1fbf6b557a5';
const hash = await _getFileHash(filePath);
assert.strictEqual(expected, Buffer.from(hash).toString('hex'));
});
it('roundtrips binary file writes', async () => {
let tempDir;
try {
tempDir = await createTempDir();
const path = join(tempDir, 'something.bin');
const { publicKey } = keyPair();
await writeHexToPath(path, publicKey);
const fromDisk = await loadHexFromPath(path);
assert.strictEqual(
Buffer.from(fromDisk).compare(Buffer.from(publicKey)),
0
);
} finally {
if (tempDir) {
await deleteTempDir(tempDir);
}
}
});
it('roundtrips signature', async () => {
let tempDir;
try {
tempDir = await createTempDir();
const version = 'v1.23.2';
const sourcePath = join(__dirname, '../../../fixtures/ghost-kitty.mp4');
const updatePath = join(tempDir, 'ghost-kitty.mp4');
await copy(sourcePath, updatePath);
const privateKeyPath = join(tempDir, 'private.key');
const { publicKey, privateKey } = keyPair();
await writeHexToPath(privateKeyPath, privateKey);
await writeSignature(updatePath, version, privateKeyPath);
const signaturePath = getSignaturePath(updatePath);
assert.strictEqual(existsSync(signaturePath), true);
const verified = await verifySignature(updatePath, version, publicKey);
assert.strictEqual(verified, true);
} finally {
if (tempDir) {
await deleteTempDir(tempDir);
}
}
});
it('fails signature verification if version changes', async () => {
let tempDir;
try {
tempDir = await createTempDir();
const version = 'v1.23.2';
const brokenVersion = 'v1.23.3';
const sourcePath = join(__dirname, '../../../fixtures/ghost-kitty.mp4');
const updatePath = join(tempDir, 'ghost-kitty.mp4');
await copy(sourcePath, updatePath);
const privateKeyPath = join(tempDir, 'private.key');
const { publicKey, privateKey } = keyPair();
await writeHexToPath(privateKeyPath, privateKey);
await writeSignature(updatePath, version, privateKeyPath);
const verified = await verifySignature(
updatePath,
brokenVersion,
publicKey
);
assert.strictEqual(verified, false);
} finally {
if (tempDir) {
await deleteTempDir(tempDir);
}
}
});
it('fails signature verification if signature tampered with', async () => {
let tempDir;
try {
tempDir = await createTempDir();
const version = 'v1.23.2';
const sourcePath = join(__dirname, '../../../fixtures/ghost-kitty.mp4');
const updatePath = join(tempDir, 'ghost-kitty.mp4');
await copy(sourcePath, updatePath);
const privateKeyPath = join(tempDir, 'private.key');
const { publicKey, privateKey } = keyPair();
await writeHexToPath(privateKeyPath, privateKey);
await writeSignature(updatePath, version, privateKeyPath);
const signaturePath = getSignaturePath(updatePath);
const signature = Buffer.from(await loadHexFromPath(signaturePath));
signature[4] += 3;
await writeHexToPath(signaturePath, signature);
const verified = await verifySignature(updatePath, version, publicKey);
assert.strictEqual(verified, false);
} finally {
if (tempDir) {
await deleteTempDir(tempDir);
}
}
});
it('fails signature verification if binary file tampered with', async () => {
let tempDir;
try {
tempDir = await createTempDir();
const version = 'v1.23.2';
const sourcePath = join(__dirname, '../../../fixtures/ghost-kitty.mp4');
const updatePath = join(tempDir, 'ghost-kitty.mp4');
await copy(sourcePath, updatePath);
const privateKeyPath = join(tempDir, 'private.key');
const { publicKey, privateKey } = keyPair();
await writeHexToPath(privateKeyPath, privateKey);
await writeSignature(updatePath, version, privateKeyPath);
const brokenSourcePath = join(
__dirname,
'../../../fixtures/pixabay-Soap-Bubble-7141.mp4'
);
await copy(brokenSourcePath, updatePath);
const verified = await verifySignature(updatePath, version, publicKey);
assert.strictEqual(verified, false);
} finally {
if (tempDir) {
await deleteTempDir(tempDir);
}
}
});
it('fails signature verification if signed by different key', async () => {
let tempDir;
try {
tempDir = await createTempDir();
const version = 'v1.23.2';
const sourcePath = join(__dirname, '../../../fixtures/ghost-kitty.mp4');
const updatePath = join(tempDir, 'ghost-kitty.mp4');
await copy(sourcePath, updatePath);
const privateKeyPath = join(tempDir, 'private.key');
const { publicKey } = keyPair();
const { privateKey } = keyPair();
await writeHexToPath(privateKeyPath, privateKey);
await writeSignature(updatePath, version, privateKeyPath);
const verified = await verifySignature(updatePath, version, publicKey);
assert.strictEqual(verified, false);
} finally {
if (tempDir) {
await deleteTempDir(tempDir);
}
}
});
});

View File

@ -2,18 +2,16 @@ import { Message } from './Message';
interface ConversationLastMessageUpdate {
lastMessage: string;
lastMessageStatus?: string;
timestamp?: number;
lastMessageStatus: string | null;
timestamp: number | null;
}
export const createLastMessageUpdate = ({
currentLastMessageText,
currentTimestamp,
lastMessage,
lastMessageStatus,
lastMessageNotificationText,
}: {
currentLastMessageText?: string;
currentTimestamp?: number;
lastMessage?: Message;
lastMessageStatus?: string;
@ -22,6 +20,8 @@ export const createLastMessageUpdate = ({
if (!lastMessage) {
return {
lastMessage: '',
lastMessageStatus: null,
timestamp: null,
};
}
@ -30,10 +30,10 @@ export const createLastMessageUpdate = ({
const isExpireTimerUpdateFromSync = Boolean(
expirationTimerUpdate && expirationTimerUpdate.fromSync
);
const shouldUpdateTimestamp = Boolean(
!isVerifiedChangeMessage && !isExpireTimerUpdateFromSync
);
const newTimestamp = shouldUpdateTimestamp
? lastMessage.sent_at
: currentTimestamp;
@ -41,11 +41,11 @@ export const createLastMessageUpdate = ({
const shouldUpdateLastMessageText = !isVerifiedChangeMessage;
const newLastMessageText = shouldUpdateLastMessageText
? lastMessageNotificationText
: currentLastMessageText;
: '';
return {
lastMessage: newLastMessageText || '',
lastMessageStatus,
timestamp: newTimestamp,
lastMessageStatus: lastMessageStatus || null,
timestamp: newTimestamp || null,
};
};

View File

@ -9,3 +9,6 @@ export const isAudioNotificationSupported = () =>
// https://github.com/electron/electron/issues/11189
export const isNotificationGroupingSupported = () =>
!OS.isWindows() || OS.isWindows(MIN_WINDOWS_VERSION);
// the "hide menu bar" option is specific to Windows and Linux
export const isHideMenuBarSupported = () => !OS.isMacOS();

323
ts/updater/common.ts Normal file
View File

@ -0,0 +1,323 @@
import {
createWriteStream,
statSync,
writeFile as writeFileCallback,
} from 'fs';
import { join } from 'path';
import { tmpdir } from 'os';
// @ts-ignore
import { createParser } from 'dashdash';
// @ts-ignore
import ProxyAgent from 'proxy-agent';
import { FAILSAFE_SCHEMA, safeLoad } from 'js-yaml';
import { gt } from 'semver';
import { get as getFromConfig } from 'config';
import { get, GotOptions, stream } from 'got';
import { v4 as getGuid } from 'uuid';
import pify from 'pify';
import mkdirp from 'mkdirp';
import rimraf from 'rimraf';
import { app, BrowserWindow, dialog } from 'electron';
// @ts-ignore
import * as packageJson from '../../package.json';
import { getSignatureFileName } from './signature';
export type MessagesType = {
[key: string]: {
message: string;
description?: string;
};
};
type LogFunction = (...args: Array<any>) => void;
export type LoggerType = {
fatal: LogFunction;
error: LogFunction;
warn: LogFunction;
info: LogFunction;
debug: LogFunction;
trace: LogFunction;
};
const writeFile = pify(writeFileCallback);
const mkdirpPromise = pify(mkdirp);
const rimrafPromise = pify(rimraf);
const { platform } = process;
export async function checkForUpdates(
logger: LoggerType
): Promise<{
fileName: string;
version: string;
} | null> {
const yaml = await getUpdateYaml();
const version = getVersion(yaml);
if (!version) {
logger.warn('checkForUpdates: no version extracted from downloaded yaml');
return null;
}
if (isVersionNewer(version)) {
logger.info(`checkForUpdates: found newer version ${version}`);
return {
fileName: getUpdateFileName(yaml),
version,
};
}
logger.info(
`checkForUpdates: ${version} is not newer; no new update available`
);
return null;
}
export async function downloadUpdate(
fileName: string,
logger: LoggerType
): Promise<string> {
const baseUrl = getUpdatesBase();
const updateFileUrl = `${baseUrl}/${fileName}`;
const signatureFileName = getSignatureFileName(fileName);
const signatureUrl = `${baseUrl}/${signatureFileName}`;
let tempDir;
try {
tempDir = await createTempDir();
const targetUpdatePath = join(tempDir, fileName);
const targetSignaturePath = join(tempDir, getSignatureFileName(fileName));
logger.info(`downloadUpdate: Downloading ${signatureUrl}`);
const { body } = await get(signatureUrl, getGotOptions());
await writeFile(targetSignaturePath, body);
logger.info(`downloadUpdate: Downloading ${updateFileUrl}`);
const downloadStream = stream(updateFileUrl, getGotOptions());
const writeStream = createWriteStream(targetUpdatePath);
await new Promise((resolve, reject) => {
downloadStream.on('error', error => {
reject(error);
});
downloadStream.on('end', () => {
resolve();
});
writeStream.on('error', error => {
reject(error);
});
downloadStream.pipe(writeStream);
});
return targetUpdatePath;
} catch (error) {
if (tempDir) {
await deleteTempDir(tempDir);
}
throw error;
}
}
export async function showUpdateDialog(
mainWindow: BrowserWindow,
messages: MessagesType
): Promise<boolean> {
const RESTART_BUTTON = 0;
const LATER_BUTTON = 1;
const options = {
type: 'info',
buttons: [
messages.autoUpdateRestartButtonLabel.message,
messages.autoUpdateLaterButtonLabel.message,
],
title: messages.autoUpdateNewVersionTitle.message,
message: messages.autoUpdateNewVersionMessage.message,
detail: messages.autoUpdateNewVersionInstructions.message,
defaultId: LATER_BUTTON,
cancelId: RESTART_BUTTON,
};
return new Promise(resolve => {
dialog.showMessageBox(mainWindow, options, response => {
if (response === RESTART_BUTTON) {
// It's key to delay any install calls here because they don't seem to work inside this
// callback - but only if the message box has a parent window.
// Fixes this: https://github.com/signalapp/Signal-Desktop/issues/1864
resolve(true);
return;
}
resolve(false);
});
});
}
export async function showCannotUpdateDialog(
mainWindow: BrowserWindow,
messages: MessagesType
): Promise<boolean> {
const options = {
type: 'error',
buttons: [messages.ok.message],
title: messages.cannotUpdate.message,
message: messages.cannotUpdateDetail.message,
};
return new Promise(resolve => {
dialog.showMessageBox(mainWindow, options, () => {
resolve();
});
});
}
// Helper functions
export function getUpdateCheckUrl(): string {
return `${getUpdatesBase()}/${getUpdatesFileName()}`;
}
export function getUpdatesBase(): string {
return getFromConfig('updatesUrl');
}
export function getCertificateAuthority(): string {
return getFromConfig('certificateAuthority');
}
export function getProxyUrl(): string | undefined {
return process.env.HTTPS_PROXY || process.env.https_proxy;
}
export function getUpdatesFileName(): string {
const prefix = isBetaChannel() ? 'beta' : 'latest';
if (platform === 'darwin') {
return `${prefix}-mac.yml`;
} else {
return `${prefix}.yml`;
}
}
const hasBeta = /beta/i;
function isBetaChannel(): boolean {
return hasBeta.test(packageJson.version);
}
function isVersionNewer(newVersion: string): boolean {
const { version } = packageJson;
return gt(newVersion, version);
}
export function getVersion(yaml: string): string | undefined {
const info = parseYaml(yaml);
if (info && info.version) {
return info.version;
}
return;
}
export function getUpdateFileName(yaml: string) {
const info = parseYaml(yaml);
if (info && info.path) {
return info.path;
}
return;
}
function parseYaml(yaml: string): any {
return safeLoad(yaml, { schema: FAILSAFE_SCHEMA, json: true });
}
async function getUpdateYaml(): Promise<string> {
const targetUrl = getUpdateCheckUrl();
const { body } = await get(targetUrl, getGotOptions());
if (!body) {
throw new Error('Got unexpected response back from update check');
}
return body.toString('utf8');
}
function getGotOptions(): GotOptions<null> {
const ca = getCertificateAuthority();
const proxyUrl = getProxyUrl();
const agent = proxyUrl ? new ProxyAgent(proxyUrl) : undefined;
return {
agent,
ca,
headers: {
'Cache-Control': 'no-cache',
'User-Agent': 'Signal Desktop (+https://signal.org/download)',
},
useElectronNet: false,
};
}
function getBaseTempDir() {
// We only use tmpdir() when this code is run outside of an Electron app (as in: tests)
return app ? join(app.getPath('userData'), 'temp') : tmpdir();
}
export async function createTempDir() {
const baseTempDir = getBaseTempDir();
const uniqueName = getGuid();
const targetDir = join(baseTempDir, uniqueName);
await mkdirpPromise(targetDir);
return targetDir;
}
export async function deleteTempDir(targetDir: string) {
const pathInfo = statSync(targetDir);
if (!pathInfo.isDirectory()) {
throw new Error(
`deleteTempDir: Cannot delete path '${targetDir}' because it is not a directory`
);
}
const baseTempDir = getBaseTempDir();
if (!targetDir.startsWith(baseTempDir)) {
throw new Error(
`deleteTempDir: Cannot delete path '${targetDir}' since it is not within base temp dir`
);
}
await rimrafPromise(targetDir);
}
export function getPrintableError(error: Error) {
return error && error.stack ? error.stack : error;
}
export async function deleteBaseTempDir() {
const baseTempDir = getBaseTempDir();
await rimrafPromise(baseTempDir);
}
export function getCliOptions<T>(options: any): T {
const parser = createParser({ options });
const cliOptions = parser.parse(process.argv);
if (cliOptions.help) {
const help = parser.help().trimRight();
// tslint:disable-next-line:no-console
console.log(help);
process.exit(0);
}
return cliOptions;
}

59
ts/updater/curve.ts Normal file
View File

@ -0,0 +1,59 @@
import { randomBytes } from 'crypto';
const g = global as any;
// Because curve wrapper will populate this
g.Internal = {};
// Because curve wrapper uses 'Module' to get at curve-provided functionality
// tslint:disable-next-line
g.Module = require('../../js/curve/curve25519_compiled');
// tslint:disable-next-line
require('../../js/curve/curve25519_wrapper');
export type BinaryType = Uint8Array | Buffer;
interface CurveType {
keyPair: (
privateKey: BinaryType
) => {
pubKey: BinaryType;
privKey: BinaryType;
};
sign: (privateKey: BinaryType, message: BinaryType) => BinaryType;
verify: (
publicKey: BinaryType,
message: BinaryType,
signature: BinaryType
) => boolean;
}
const {
keyPair: internalKeyPair,
sign: internalSign,
verify: internalVerify,
} = g.Internal.curve25519 as CurveType;
export function keyPair() {
const privateKey = randomBytes(32);
const { pubKey, privKey } = internalKeyPair(privateKey);
return {
publicKey: pubKey,
privateKey: privKey,
};
}
export function sign(privateKey: BinaryType, message: BinaryType) {
return internalSign(privateKey, message);
}
export function verify(
publicKey: BinaryType,
message: BinaryType,
signature: BinaryType
) {
const failed = internalVerify(publicKey, message, signature);
return !failed;
}

View File

@ -0,0 +1,45 @@
import { getCliOptions, getPrintableError } from './common';
import { keyPair } from './curve';
import { writeHexToPath } from './signature';
/* tslint:disable:no-console */
const OPTIONS = [
{
names: ['help', 'h'],
type: 'bool',
help: 'Print this help and exit.',
},
{
names: ['key', 'k'],
type: 'string',
help: 'Path where public key will go',
default: 'public.key',
},
{
names: ['private', 'p'],
type: 'string',
help: 'Path where private key will go',
default: 'private.key',
},
];
type OptionsType = {
key: string;
private: string;
};
const cliOptions = getCliOptions<OptionsType>(OPTIONS);
go(cliOptions).catch(error => {
console.error('Something went wrong!', getPrintableError(error));
});
async function go(options: OptionsType) {
const { key: publicKeyPath, private: privateKeyPath } = options;
const { publicKey, privateKey } = keyPair();
await Promise.all([
writeHexToPath(publicKeyPath, publicKey),
writeHexToPath(privateKeyPath, privateKey),
]);
}

View File

@ -0,0 +1,85 @@
import { join, resolve } from 'path';
import { readdir as readdirCallback } from 'fs';
import pify from 'pify';
import { getCliOptions, getPrintableError } from './common';
import { writeSignature } from './signature';
// @ts-ignore
import * as packageJson from '../../package.json';
const readdir = pify(readdirCallback);
/* tslint:disable:no-console */
const OPTIONS = [
{
names: ['help', 'h'],
type: 'bool',
help: 'Print this help and exit.',
},
{
names: ['private', 'p'],
type: 'string',
help: 'Path to private key file (default: ./private.key)',
default: 'private.key',
},
{
names: ['update', 'u'],
type: 'string',
help: 'Path to the update package (default: the .exe or .zip in ./release)',
},
{
names: ['version', 'v'],
type: 'string',
help: `Version number of this package (default: ${packageJson.version})`,
default: packageJson.version,
},
];
type OptionsType = {
private: string;
update: string;
version: string;
};
const cliOptions = getCliOptions<OptionsType>(OPTIONS);
go(cliOptions).catch(error => {
console.error('Something went wrong!', getPrintableError(error));
});
async function go(options: OptionsType) {
const { private: privateKeyPath, version } = options;
let { update: updatePath } = options;
if (!updatePath) {
updatePath = await findUpdatePath();
}
console.log('Signing with...');
console.log(` version: ${version}`);
console.log(` update file: ${updatePath}`);
console.log(` private key file: ${privateKeyPath}`);
await writeSignature(updatePath, version, privateKeyPath);
}
const IS_EXE = /\.exe$/;
const IS_ZIP = /\.zip$/;
async function findUpdatePath(): Promise<string> {
const releaseDir = resolve('release');
const files: Array<string> = await readdir(releaseDir);
const max = files.length;
for (let i = 0; i < max; i += 1) {
const file = files[i];
const fullPath = join(releaseDir, file);
if (IS_EXE.test(file) || IS_ZIP.test(file)) {
return fullPath;
}
}
throw new Error("No suitable file found in 'release' folder!");
}

66
ts/updater/index.ts Normal file
View File

@ -0,0 +1,66 @@
import { get as getFromConfig } from 'config';
import { BrowserWindow } from 'electron';
import { start as startMacOS } from './macos';
import { start as startWindows } from './windows';
import {
deleteBaseTempDir,
getPrintableError,
LoggerType,
MessagesType,
} from './common';
let initialized = false;
export async function start(
getMainWindow: () => BrowserWindow,
messages?: MessagesType,
logger?: LoggerType
) {
const { platform } = process;
if (initialized) {
throw new Error('updater/start: Updates have already been initialized!');
}
initialized = true;
if (!messages) {
throw new Error('updater/start: Must provide messages!');
}
if (!logger) {
throw new Error('updater/start: Must provide logger!');
}
if (autoUpdateDisabled()) {
logger.info(
'updater/start: Updates disabled - not starting new version checks'
);
return;
}
try {
await deleteBaseTempDir();
} catch (error) {
logger.error(
'updater/start: Error deleting temp dir:',
getPrintableError(error)
);
}
if (platform === 'win32') {
await startWindows(getMainWindow, messages, logger);
} else if (platform === 'darwin') {
await startMacOS(getMainWindow, messages, logger);
} else {
throw new Error('updater/start: Unsupported platform');
}
}
function autoUpdateDisabled() {
return (
process.platform === 'linux' ||
process.mas ||
!getFromConfig('updatesEnabled')
);
}

324
ts/updater/macos.ts Normal file
View File

@ -0,0 +1,324 @@
import { createReadStream, statSync } from 'fs';
import { createServer, IncomingMessage, Server, ServerResponse } from 'http';
import { AddressInfo } from 'net';
import { dirname } from 'path';
import { v4 as getGuid } from 'uuid';
import { app, autoUpdater, BrowserWindow, dialog } from 'electron';
import { get as getFromConfig } from 'config';
import { gt } from 'semver';
import {
checkForUpdates,
deleteTempDir,
downloadUpdate,
getPrintableError,
LoggerType,
MessagesType,
showCannotUpdateDialog,
showUpdateDialog,
} from './common';
import { hexToBinary, verifySignature } from './signature';
import { markShouldQuit } from '../../app/window_state';
let isChecking = false;
const SECOND = 1000;
const MINUTE = SECOND * 60;
const INTERVAL = MINUTE * 30;
export async function start(
getMainWindow: () => BrowserWindow,
messages: MessagesType,
logger: LoggerType
) {
logger.info('macos/start: starting checks...');
loggerForQuitHandler = logger;
app.once('quit', quitHandler);
setInterval(async () => {
try {
await checkDownloadAndInstall(getMainWindow, messages, logger);
} catch (error) {
logger.error('macos/start: error:', getPrintableError(error));
}
}, INTERVAL);
await checkDownloadAndInstall(getMainWindow, messages, logger);
}
let fileName: string;
let version: string;
let updateFilePath: string;
let loggerForQuitHandler: LoggerType;
async function checkDownloadAndInstall(
getMainWindow: () => BrowserWindow,
messages: MessagesType,
logger: LoggerType
) {
if (isChecking) {
return;
}
logger.info('checkDownloadAndInstall: checking for update...');
try {
isChecking = true;
const result = await checkForUpdates(logger);
if (!result) {
return;
}
const { fileName: newFileName, version: newVersion } = result;
if (fileName !== newFileName || !version || gt(newVersion, version)) {
deleteCache(updateFilePath, logger);
fileName = newFileName;
version = newVersion;
updateFilePath = await downloadUpdate(fileName, logger);
}
const publicKey = hexToBinary(getFromConfig('updatesPublicKey'));
const verified = verifySignature(updateFilePath, version, publicKey);
if (!verified) {
// Note: We don't delete the cache here, because we don't want to continually
// re-download the broken release. We will download it only once per launch.
throw new Error(
`checkDownloadAndInstall: Downloaded update did not pass signature verification (version: '${version}'; fileName: '${fileName}')`
);
}
try {
await handToAutoUpdate(updateFilePath, logger);
} catch (error) {
const readOnly = 'Cannot update while running on a read-only volume';
const message: string = error.message || '';
if (message.includes(readOnly)) {
logger.info('checkDownloadAndInstall: showing read-only dialog...');
await showReadOnlyDialog(getMainWindow(), messages);
} else {
logger.info(
'checkDownloadAndInstall: showing general update failure dialog...'
);
await showCannotUpdateDialog(getMainWindow(), messages);
}
throw error;
}
// At this point, closing the app will cause the update to be installed automatically
// because Squirrel has cached the update file and will do the right thing.
logger.info('checkDownloadAndInstall: showing update dialog...');
const shouldUpdate = await showUpdateDialog(getMainWindow(), messages);
if (!shouldUpdate) {
return;
}
logger.info('checkDownloadAndInstall: calling quitAndInstall...');
markShouldQuit();
autoUpdater.quitAndInstall();
} catch (error) {
logger.error('checkDownloadAndInstall: error', getPrintableError(error));
} finally {
isChecking = false;
}
}
function quitHandler() {
deleteCache(updateFilePath, loggerForQuitHandler);
}
// Helpers
function deleteCache(filePath: string | null, logger: LoggerType) {
if (filePath) {
const tempDir = dirname(filePath);
deleteTempDir(tempDir).catch(error => {
logger.error(
'quitHandler: error deleting temporary directory:',
getPrintableError(error)
);
});
}
}
async function handToAutoUpdate(
filePath: string,
logger: LoggerType
): Promise<void> {
return new Promise((resolve, reject) => {
const updateFileUrl = generateFileUrl();
const server = createServer();
let serverUrl: string;
server.on('error', (error: Error) => {
logger.error(
'handToAutoUpdate: server had error',
getPrintableError(error)
);
shutdown(server, logger);
reject(error);
});
server.on(
'request',
(request: IncomingMessage, response: ServerResponse) => {
const { url } = request;
if (url === '/') {
const absoluteUrl = `${serverUrl}${updateFileUrl}`;
writeJSONResponse(absoluteUrl, response);
return;
}
if (!url || !url.startsWith(updateFileUrl)) {
write404(url, response, logger);
return;
}
pipeUpdateToSquirrel(filePath, server, response, logger, reject);
}
);
server.listen(0, '127.0.0.1', () => {
serverUrl = getServerUrl(server);
autoUpdater.on('error', (error: Error) => {
logger.error('autoUpdater: error', getPrintableError(error));
reject(error);
});
autoUpdater.on('update-downloaded', () => {
logger.info('autoUpdater: update-downloaded event fired');
shutdown(server, logger);
resolve();
});
autoUpdater.setFeedURL({
url: serverUrl,
headers: { 'Cache-Control': 'no-cache' },
});
autoUpdater.checkForUpdates();
});
});
}
function pipeUpdateToSquirrel(
filePath: string,
server: Server,
response: ServerResponse,
logger: LoggerType,
reject: (error: Error) => void
) {
const updateFileSize = getFileSize(filePath);
const readStream = createReadStream(filePath);
response.on('error', (error: Error) => {
logger.error(
'pipeUpdateToSquirrel: update file download request had an error',
getPrintableError(error)
);
shutdown(server, logger);
reject(error);
});
readStream.on('error', (error: Error) => {
logger.error(
'pipeUpdateToSquirrel: read stream error response:',
getPrintableError(error)
);
shutdown(server, logger, response);
reject(error);
});
response.writeHead(200, {
'Content-Type': 'application/zip',
'Content-Length': updateFileSize,
});
readStream.pipe(response);
}
function writeJSONResponse(url: string, response: ServerResponse) {
const data = Buffer.from(
JSON.stringify({
url,
})
);
response.writeHead(200, {
'Content-Type': 'application/json',
'Content-Length': data.byteLength,
});
response.end(data);
}
function write404(
url: string | undefined,
response: ServerResponse,
logger: LoggerType
) {
logger.error(`write404: Squirrel requested unexpected url '${url}'`);
response.writeHead(404);
response.end();
}
function getServerUrl(server: Server) {
const address = server.address() as AddressInfo;
// tslint:disable-next-line:no-http-string
return `http://127.0.0.1:${address.port}`;
}
function generateFileUrl(): string {
return `/${getGuid()}.zip`;
}
function getFileSize(targetPath: string): number {
const { size } = statSync(targetPath);
return size;
}
function shutdown(
server: Server,
logger: LoggerType,
response?: ServerResponse
) {
try {
if (server) {
server.close();
}
} catch (error) {
logger.error('shutdown: Error closing server', getPrintableError(error));
}
try {
if (response) {
response.end();
}
} catch (endError) {
logger.error(
"shutdown: couldn't end response",
getPrintableError(endError)
);
}
}
export async function showReadOnlyDialog(
mainWindow: BrowserWindow,
messages: MessagesType
): Promise<void> {
const options = {
type: 'warning',
buttons: [messages.ok.message],
title: messages.cannotUpdate.message,
message: messages.readOnlyVolume.message,
};
return new Promise(resolve => {
dialog.showMessageBox(mainWindow, options, () => {
resolve();
});
});
}

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