Merge branch 'main' into pr/5866

This commit is contained in:
Josh Perez 2022-05-04 21:28:12 -04:00
commit fb21285ce3
165 changed files with 4189 additions and 2541 deletions

View File

@ -16,7 +16,7 @@ contact_links:
url: https://community.signalusers.org/c/support/
about: Feel free to ask anything
- name: 📖 Contribution instructions
url: https://github.com/signalapp/Signal-Desktop/blob/development/CONTRIBUTING.md
url: https://github.com/signalapp/Signal-Desktop/blob/main/CONTRIBUTING.md
about: Want to contribute to Signal Desktop? Start here.
- name: ❓ Other issue?
url: https://community.signalusers.org/

View File

@ -16,7 +16,7 @@ Remember, you can preview this before saving it.
- [ ] 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.com/free-code-camp/git-rebase-and-the-golden-rule-explained-70715eccc372) on the latest [`development`](https://github.com/signalapp/Signal-Desktop/tree/development) branch
- [ ] My changes are [rebased](https://medium.com/free-code-camp/git-rebase-and-the-golden-rule-explained-70715eccc372) on the latest [`main`](https://github.com/signalapp/Signal-Desktop/tree/main) 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

View File

@ -6,6 +6,7 @@ on:
push:
branches:
- development
- main
- '[0-9]+.[0-9]+.x'
pull_request:
@ -27,7 +28,7 @@ jobs:
- name: Setup node.js
uses: actions/setup-node@v2
with:
node-version: '16.13.0'
node-version: '16.13.2'
- name: Install global dependencies
run: npm install -g yarn@1.22.10

View File

@ -6,6 +6,7 @@ on:
push:
branches:
- development
- main
- '[0-9]+.[0-9]+.x'
pull_request:
@ -20,7 +21,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '16.13.0'
node-version: '16.13.2'
- run: npm install -g yarn@1.22.10
- name: Cache Desktop node_modules
@ -42,7 +43,7 @@ jobs:
macos:
needs: lint
runs-on: macos-11.0
if: github.ref == 'refs/heads/development' || github.ref == 'refs/heads/master'
if: github.ref == 'refs/heads/development' || github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main'
timeout-minutes: 30
steps:
@ -50,7 +51,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '16.13.0'
node-version: '16.13.2'
- run: npm install -g yarn@1.22.10
- name: Cache Desktop node_modules
@ -88,7 +89,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '16.13.0'
node-version: '16.13.2'
- run: sudo apt-get install xvfb
- run: npm install -g yarn@1.22.10
@ -129,7 +130,7 @@ jobs:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: '16.13.0'
node-version: '16.13.2'
- run: npm install -g yarn@1.22.10
- name: Cache Desktop node_modules
@ -175,7 +176,7 @@ jobs:
- name: Setup node.js
uses: actions/setup-node@v2
with:
node-version: '16.13.0'
node-version: '16.13.2'
- name: Install global dependencies
run: npm install -g yarn@1.22.10

2
.nvmrc
View File

@ -1 +1 @@
16.13.0
16.13.2

View File

@ -20,7 +20,7 @@ ounce of prevention, as they say!](https://www.goodreads.com/quotes/247269-an-ou
## Developer Setup
First, you'll need [Node.js](https://nodejs.org/) which matches our current version.
You can check [`.nvmrc` in the `development` branch](https://github.com/signalapp/Signal-Desktop/blob/development/.nvmrc)
You can check [`.nvmrc` in the `main` branch](https://github.com/signalapp/Signal-Desktop/blob/main/.nvmrc)
to see what the current version is. If you have [nvm](https://github.com/creationix/nvm)
you can just run `nvm use` in the project directory and it will switch to the project's
desired Node.js version. [nvm for windows](https://github.com/coreybutler/nvm-windows) is
@ -199,7 +199,7 @@ So you wanna make a pull request? Please observe the following guidelines.
automatically based on that file and then periodically uploaded to Transifex for
translation.
- [Rebase](https://nathanleclaire.com/blog/2014/09/14/dont-be-scared-of-git-rebase/) your
changes on the latest `development` branch, resolving any conflicts.
changes on the latest `main` branch, resolving any conflicts.
This ensures that your changes will merge cleanly when you open your PR.
- Be sure to add and run tests!
- Make sure the diff between the development branch and your branch contains only the

View File

@ -28,7 +28,7 @@ https://www.transifex.com/projects/p/signal-desktop
## Contributing Code
Please see [CONTRIBUTING.md](https://github.com/signalapp/Signal-Desktop/blob/development/CONTRIBUTING.md)
Please see [CONTRIBUTING.md](https://github.com/signalapp/Signal-Desktop/blob/main/CONTRIBUTING.md)
for setup instructions and guidelines for new contributors. Don't forget to sign the [CLA](https://signal.org/cla/).
## Contributing Funds

View File

@ -192,11 +192,11 @@
"description": "Message shown on the loading screen before we've loaded any messages"
},
"optimizingApplication": {
"message": تم تحسين التطبيق...",
"message": جري تحسين التطبيق...",
"description": "Message shown on the loading screen while we are doing application optimizations"
},
"migratingToSQLCipher": {
"message": تم تحسين الرسائل... تمّ $status$.",
"message": جري تحسين الرسائل... تمّ $status$.",
"description": "Message shown on the loading screen while we are doing application optimizations",
"placeholders": {
"status": {
@ -7013,6 +7013,10 @@
"message": "إضافة قصة",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "القصص المخفية",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "لا توجد قصص حديثة للمشاهدة حاليا",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "‫يُرجى كتابة رد...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "لا جواب حاليا",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "المشاهدات",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "القصص",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "إظهار القصص",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "إخفاء قصة",
"description": "Label for menu item to hide the story"
@ -7095,22 +7107,6 @@
"message": "يحتوي هذا الإصدار على عدد من التعديلات الصغيرة وإصلاحات الأخطاء للحفاظ على تشغيل Signal بسلاسة.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "We're keeping short messages short, by putting stuff like timestamps on the same line as the text. Now you've got more space on the screen for that quick 'hey' to check in on a friend.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Missing sticker packs begone! Desktop should now be able to handle all sticker packs that your phone can!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "‫يمكنك الآن إضافة أفراد للمجموعات باستخدام رقم هاتفهم فقط.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Your favorite contacts are now just a few keystrokes away. Contact search now supports non-Latin alphabets like Cyrillic.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "‫إن إصلاح العلل يتضمن تصحيح مشكلة كانت تجعل أحيانا الضغط على القوائم عسيرا.",
"description": "Release notes for v5.40"

View File

@ -7013,6 +7013,10 @@
"message": "Bir hekayə əlavə et",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Gizli hekayələr",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "Hal-hazırda göstəriləcək yeni bir hekayə yoxdur",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "Bir cavab yazın...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Hələ ki, cavab yoxdur",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Baxış",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "Hekayə",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Hekayələri göstər",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Hekayəni gizlət",
"description": "Label for menu item to hide the story"
@ -7095,22 +7107,6 @@
"message": "Bu versiya, Signal-ın problemsiz işləməsini təmin etmək üçün kiçik düzəltmələr və xəta düzəltmələri ehtiva edir.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "Mətnlə eyni sətrə vaxtı əlavə edərək mesajları qısa saxlamağa çalışırıq. Artıq bir dostunuzu daha tez \"salamlamaq\" üçün ekranınızda daha çox yer var.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Əskik stiker paketlər geri qayıtdı! Artıq Masaüstü versiya, telefonunuzun bacara bildiyi bütün stiker paketlərini ələ ala bilməlidir!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "Artıq insanları, onların telefon nömrələrini istifadə edərək qruplara əlavə edə bilərsiniz.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Artıq sevimli əlaqələriniz sadəcə klaviaturadakı bir neçə toxunuş qədər yaxındır. Əlaqə axtarışı artıq Kiril kimi Latin olmayan əlifbaları da dəstəkləyir.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Bəzən menyuya klikləməni çətinləşdirən problemin həlli də daxil olmaqla bir çox xətalar aradan qaldırılıb.",
"description": "Release notes for v5.40"

View File

@ -7013,6 +7013,10 @@
"message": "Afegiu-hi una història",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Històries amagades",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "Ara no hi ha històries per veure.",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "Escriviu una resposta...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Encara no té respostes",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Visualitzacions",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "Història",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Mostra les històries",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Amaga la història",
"description": "Label for menu item to hide the story"
@ -7095,22 +7107,6 @@
"message": "Aquesta versió conté una sèrie de petites modificacions i correccions d'errors per tal que el Signal funcioni sense problemes.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "Mantenim els missatges curts, posant-hi coses com ara marques de temps a la mateixa línia que el text. Ara teniu més espai a la pantalla per a un \"Ei!\" ràpid amb una amistat.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Falten paquets d'adhesius! Ara l'escriptori hauria de poder gestionar els mateixos paquets d'adhesius que el telèfon!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "Ara podeu afegir persones als grups només amb el número de telèfon.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Els contactes preferits són ara només a unes poques tecles de distància. La cerca de contactes ara admet alfabets no llatins com ara el ciríl·lic.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Correccions d'errors, inclosa una solució a un problema que de vegades dificultava fer clic als menús.",
"description": "Release notes for v5.40"

View File

@ -7013,6 +7013,10 @@
"message": "Přidat příběh",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Skryté příběhy",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "Žádné poslední příběhy k zobrazení",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "Napište odpověď...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Zatím žádné odpovědi",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Zobrazení",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "Příběh",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Zobrazit příběhy",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Schovat příběh",
"description": "Label for menu item to hide the story"
@ -7095,22 +7107,6 @@
"message": "Tato verze obsahuje řadu drobných úprav a oprav chyb, aby Signal fungoval hladce.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "Krátké zprávy udržujeme krátké tím, že věci jako časová razítka umisťujeme na stejný řádek jako text. Nyní máte na obrazovce více místa pro rychlé \"ahoj\", abyste zkontrolovali přítele.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Chybějící balíčky samolepek jsou pryč! Počítač by nyní měl zvládnout všechny balíčky nálepek, které zvládne váš telefon!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "Nyní můžete přidávat lidi do skupin pomocí jejich telefonního čísla.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Vaše oblíbené kontakty jsou nyní vzdálené jen několik stisknutí kláves. Vyhledávání kontaktů nyní podporuje jiné než latinské abecedy, například cyrilici.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Opravy chyb včetně opravy problému, který někdy ztěžoval klikání na položky menu.",
"description": "Release notes for v5.40"

View File

@ -222,7 +222,7 @@
"description": "Shown at the top of the archived conversations list in the left pane"
},
"noArchivedConversations": {
"message": "No archived conversations.",
"message": "Dim sgyrsiau wedi'u harchifo.",
"description": "Shown at the top of the archived conversations list in the left pane if there is no any archived conversation"
},
"archiveConversation": {
@ -836,11 +836,11 @@
"description": "Shown to separate the types of search results"
},
"findByUsernameHeader": {
"message": "Find by username",
"message": "Canfod yn ôl Enw Defnyddiwr",
"description": "Shown when search could be a valid username, with one sub-item that will kick off the search"
},
"findByPhoneNumberHeader": {
"message": "Find by phone number",
"message": "Canfod yn ôl rhif ffôn",
"description": "Shown when search could be a valid phone number, with one sub-item that will kick off the search"
},
"at-username": {
@ -974,7 +974,7 @@
"description": "Confirmation dialog message for when the voice recording is interrupted due to app losing focus"
},
"voiceNoteLimit": {
"message": "Voice messages are limited to one hour. Recording will stop if you switch to another app.",
"message": "Mae negeseuon llais yn gyfyngedig i awr. Bydd recordio yn dod i ben os byddwch chi'n newid i ap arall.",
"description": "Shown in toast to warn user about limited time and that window must be in focus"
},
"voiceNoteMustBeOnlyAttachment": {
@ -1074,7 +1074,7 @@
}
},
"cannotUpdateRequireManualDetail": {
"message": "Signal couldn't update. Visit $url$ to install it manually. Then, $support$ about this problem",
"message": "Nid oedd Signal yn gallu diweddaru. Ewch i $url$ i'w osod â llaw. Yna, $support$ am y broblem hon",
"description": "Shown if a general error happened while trying to install update package and manual update is required",
"placeholders": {
"url": {
@ -2406,7 +2406,7 @@
"description": "Shown if request to Signal servers to find username fails"
},
"Toast--failed-to-fetch-phone-number": {
"message": "Failed to fetch phone number. Check your connection and try again.",
"message": "Wedi methu â nôl rhif ffôn. Gwiriwch eich cysylltiad a rhowch gynnig arall arni.",
"description": "Shown if request to Signal servers to find phone number fails"
},
"startConversation--username-not-found": {
@ -2420,7 +2420,7 @@
}
},
"startConversation--phone-number-not-found": {
"message": "User not found. \"$phoneNumber$\" is not a Signal user.",
"message": "Defnyddiwr heb ei ganfod. Nid yw \"$phoneNumber$\" yn ddefnyddiwr Signal.",
"description": "Shown in dialog if phone number is not found.",
"placeholders": {
"phoneNumber": {
@ -2430,7 +2430,7 @@
}
},
"startConversation--phone-number-not-valid": {
"message": "User not found. \"$phoneNumber$\" is not a valid phone number.",
"message": "Defnyddiwr heb ei ganfod. Nid yw \"$phoneNumber$\" yn rhif ffôn dilys.",
"description": "Shown in dialog if phone number is not valid.",
"placeholders": {
"phoneNumber": {
@ -6358,11 +6358,11 @@
"description": "Text for an option in Conversation Details Disappearing Messages setting when user previously selected custom time"
},
"DisappearingTimeDialog__label--value": {
"message": "Number",
"message": "Rhif",
"description": "aria-label for the number select box"
},
"DisappearingTimeDialog__label--units": {
"message": "Unit of time",
"message": "Uned o amser",
"description": "aria-label for the units of time select box"
},
"DisappearingTimeDialog__title": {
@ -6812,7 +6812,7 @@
"description": "Second line of the dialog displayed when Windows installer can't close application automatically and needs user intervention to complete the installation."
},
"NSIS__appRunning": {
"message": "$appName$ is running.\nClick OK to close it.\nIf it doesn't close, try closing it manually.",
"message": "Mae $appName$ yn rhedeg.\nCliciwch Iawn i'w gau.\nOs na fydd yn cau, ceisiwch ei gau â llaw.",
"description": "The contents of a dialog displayed when Windows installer detect that the application is running and asks user to close it. Note: please keep the line breaks so that the text occupies three separate lines",
"placeholders": {
"appName": {
@ -6822,11 +6822,11 @@
}
},
"NSIS__decompressionFailed": {
"message": "Failed to decompress files. Please try running the installer again.",
"message": "Wedi methu â datgywasgu ffeiliau. Ceisiwch redeg y gosodwr eto.",
"description": "Displayed when Windows installer cannot decompress application files"
},
"NSIS__uninstallFailed": {
"message": "Failed to uninstall old application files. Please try running the installer again.",
"message": "Wedi methu â dadosod hen ffeiliau rhaglen. Ceisiwch redeg y gosodwr eto.",
"description": "Displayed when Windows installer cannot uninstall the old application"
},
"CrashReportDialog__title": {
@ -7013,6 +7013,10 @@
"message": "Ychwanegu stori",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Straeon cuddiedig",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "Dim straeon diweddar i'w dangos ar hyn o bryd",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "Teipiwch ateb...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Dim atebion eto",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Golygon",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "Stori",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Dangos straeon",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Cuddio stori",
"description": "Label for menu item to hide the story"
@ -7095,28 +7107,12 @@
"message": "Mae'r fersiwn hon yn cynnwys nifer o drydariadau bach a chywiriadau gwallau i gadw Signal yn rhedeg yn llyfn.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "Rydyn ni'n cadw negeseuon byr yn fyr, trwy roi pethau fel stampiau amser ar yr un llinell â'r testun. Nawr mae gennych chi fwy o le ar y sgrin i'r 'helo' cyflym hwnnw gyfarch ffrind.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Diwedd ar becynnau sticer coll! Dylai Desktop nawr allu trin yr holl becynnau sticeri y gall eich ffôn!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "You can now add people to groups using just their phone number.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Your favorite contacts are now just a few keystrokes away. Contact search now supports non-Latin alphabets like Cyrillic.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Bug fixes including a fix to an issue that would sometimes make it difficult to click on menus. ",
"message": "Mae'r gwelliannau'n cynnwys datrysiad i broblem a fyddai weithiau'n ei gwneud hi'n anodd clicio ar ddewislenni.",
"description": "Release notes for v5.40"
},
"WhatsNew__v5.40--2": {
"message": "Thanks to our open source contributors $dsanders11$ and $yusufsahinhamza$ for contributing to these improvements.",
"message": "Diolch i'n cyfranwyr cod agored $dsanders11$ ac $yusufsahinhamza$ am gyfrannu at y gwelliannau hyn.",
"description": "Release notes for v5.40",
"placeholders": {
"dsanders11": {

View File

@ -2314,7 +2314,7 @@
"description": "Title for the modal for safety number verification"
},
"safetyNumberChanged": {
"message": "Sikkerhedsnummer har ændret sig",
"message": "Sikkerhedsnummer er ændret",
"description": "A notification shown in the conversation when a contact reinstalls"
},
"safetyNumberChanges": {
@ -7013,6 +7013,10 @@
"message": "Tilføj en historie",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Skjulte historier",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "Ingen nye historier at vise lige nu",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "Indtast et svar...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Ingen svar endnu",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Visninger",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "Historie",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Vis historier",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Skjul historie",
"description": "Label for menu item to hide the story"
@ -7095,28 +7107,12 @@
"message": "Denne version indeholder en række småjusteringer og fejlrettelser som sikrer, at Signal kører problemfrit.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "Vi sørger for at holde korte beskeder korte ved at sætte ting som tidsstempler på samme linje som teksten. Nu har du mere plads på skærmen til et hurtigt \"hej\" for at tjekke, hvordan det går med en ven.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Slut med manglende klistermærkepakker! Desktop burde nu kunne håndtere alle de samme klistermærkepakker, som din telefon kan!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "Du kan nu tilføje personer til grupper ved blot at bruge deres telefonnummer.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Dine foretrukne kontakter er nu kun et par tastetryk væk. Kontaktsøgning understøtter nu ikke-latinske alfabeter såsom kyrillisk.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Fejlrettelser, herunder en rettelse af et problem, som nogle gange gjorde det svært at klikke på menuer. ",
"description": "Release notes for v5.40"
},
"WhatsNew__v5.40--2": {
"message": "Tak til vores open source-bidragydere $dsanders11$ og $yusufsahinhamza$ for at bidrage med disse forbedringer.",
"message": "Tak til vores open source-bidragsydere $dsanders11$ og $yusufsahinhamza$ for at bidrage med disse forbedringer.",
"description": "Release notes for v5.40",
"placeholders": {
"dsanders11": {

View File

@ -7013,6 +7013,10 @@
"message": "Eine Story hinzufügen",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Ausgeblendete Stories",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "Im Moment sind keine aktuellen Stories zu sehen",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "Schreibe eine Antwort ...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Bisher keine Antworten",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Aufrufe",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "Story",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Stories anzeigen",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Story ausblenden",
"description": "Label for menu item to hide the story"
@ -7095,22 +7107,6 @@
"message": "Diese Version enthält eine Reihe kleinerer Optimierungen und Fehlerbehebungen, damit Signal weiterhin reibungslos funktioniert.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "Wir belassen kurze Nachrichten kurz, indem Infos wie der Zeitstempel in der gleichen Zeile wie der Text angezeigt werden. Jetzt hast du mehr Platz auf dem Bildschirm für das kurze »Hallo«, um sich bei einem Freund zu melden.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Hinfort mit den fehlenden Sticker-Sets! Desktop sollte nun in der Lage sein, mit allen von deinem Telefon unterstützten Sticker-Sets umzugehen!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "Du kannst nun über deren Rufnummer Personen zu Gruppen hinzufügen.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Deine Lieblingskontakte sind jetzt nur noch einige Tastenanschläge entfernt. Die Kontaktsuche unterstützt nun nicht-lateinische Alphabete wie Kyrillisch.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Fehlerkorrekturen einschließlich der Behebung eines Problems, das es manchmal schwierig machte, auf Menüs zu klicken.",
"description": "Release notes for v5.40"

View File

@ -7013,6 +7013,10 @@
"message": "Προσθήκη ιστορίας",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Κρυμμένες ιστορίες",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "Δεν υπάρχουν πρόσφατες ιστορίες αυτή τη στιγμή",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "Γράψε μια απάντηση...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Καμία απάντηση ακόμα",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Προβολές",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "Ιστορία",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Show stories",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Απόκρυψη ιστορίας",
"description": "Label for menu item to hide the story"
@ -7095,22 +7107,6 @@
"message": "Αυτή η έκδοση περιλαμβάνει διάφορες μικρές βελτιώσεις και αποσφαλματώσεις για να συνεχίσει το Signal να λειτουργεί ομαλά.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "Κρατάμε τα μικρά μηνύματα μικρά, βάζοντας πράγματα όπως χρονικές σημάνσεις στην ίδια γραμμή με το κείμενο. Πλέον έχετε περισσότερο χώρο στην οθόνη για να στείλετε ένα απλό «γεια» στον φίλο σας και να δείτε τι κάνει.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Αντίο στα ελλιπή πακέτα αυτοκολλήτων! Η έκδοση υπολογιστή θα μπορεί πλέον να διαχειρίζεται όλα τα πακέτα αυτοκολλήτων που λειτουργούν και στο κινητό!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "Μπορείτε πλέον να προσθέτετε άτομα σε ομάδες χρησιμοποιώντας τους τηλεφωνικούς τους αριθμούς.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Οι αγαπημένες σας επαφές είναι μόλις λίγα κουμπιά μακριά. Η αναζήτηση επαφών υποστηρίζει πλέον και τα μη λατινικά αλφάβητα, όπως το Κυριλλικό.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Διορθώσεις σφαλμάτων, συμπεριλαμβανομένης της διόρθωσης ενός προβλήματος που έκανε δύσκολο το κλικ στα μενού.",
"description": "Release notes for v5.40"

View File

@ -7026,6 +7026,10 @@
"message": "Type a reply...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "No replies yet",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Views",
"description": "Title for views tab"

View File

@ -7013,6 +7013,10 @@
"message": "Aldoni rakonton",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Kaŝitaj rakontoj",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "Neniu freŝa rakonto montrebla nun",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "Entajpi respondon...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Neniu respondo",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Vidoj",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "Rakonto",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Montri la rakontojn",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Kaŝi la rakonton",
"description": "Label for menu item to hide the story"
@ -7095,22 +7107,6 @@
"message": "Tiu versio enhavas kelkajn optimumaĵojn kaj riparetojn, por ke Signal plu funkciu bone.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "Por havi mallongan mesaĝomontron, ni metas la tempon en la sama linio ol la tekston. Nun, vi ĝuas pli da spaco por tiu rapida „saluton“ al amiko.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Ĉu mankantaj glumarkaroj? Desktop nun montras ĉiujn glumarkarojn, kiel ĉe via poŝtelefono!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "Vi povas nun aldoni homojn al grupoj pere de ilia telefonnumero.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Viaj plej ŝatataj kontaktoj estas nun pli facile alireblaj. Serĉo de kontaktoj en nelatinaj alfabetoj kiel la cirila nun eblas.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Riparoj korektas problemon kun menuoj malfacile alklakeblaj.",
"description": "Release notes for v5.40"

View File

@ -222,7 +222,7 @@
"description": "Shown at the top of the archived conversations list in the left pane"
},
"noArchivedConversations": {
"message": "No archived conversations.",
"message": "No hay chats archivados",
"description": "Shown at the top of the archived conversations list in the left pane if there is no any archived conversation"
},
"archiveConversation": {
@ -6358,11 +6358,11 @@
"description": "Text for an option in Conversation Details Disappearing Messages setting when user previously selected custom time"
},
"DisappearingTimeDialog__label--value": {
"message": "Number",
"message": "Número",
"description": "aria-label for the number select box"
},
"DisappearingTimeDialog__label--units": {
"message": "Unit of time",
"message": "Medida de tiempo",
"description": "aria-label for the units of time select box"
},
"DisappearingTimeDialog__title": {
@ -6812,7 +6812,7 @@
"description": "Second line of the dialog displayed when Windows installer can't close application automatically and needs user intervention to complete the installation."
},
"NSIS__appRunning": {
"message": "$appName$ is running.\nClick OK to close it.\nIf it doesn't close, try closing it manually.",
"message": "$appName$ está activa.\nHaz clic en Aceptar para cerrarla.\nSi no se cierra, inténtalo manualmente.",
"description": "The contents of a dialog displayed when Windows installer detect that the application is running and asks user to close it. Note: please keep the line breaks so that the text occupies three separate lines",
"placeholders": {
"appName": {
@ -6822,11 +6822,11 @@
}
},
"NSIS__decompressionFailed": {
"message": "Failed to decompress files. Please try running the installer again.",
"message": "Fallo al descomprimir archivos. Inténtalo de nuevo más tarde.",
"description": "Displayed when Windows installer cannot decompress application files"
},
"NSIS__uninstallFailed": {
"message": "Failed to uninstall old application files. Please try running the installer again.",
"message": "Fallo al desinstalar archivos antiguos de la aplicación. Inténtalo de nuevo más tarde.",
"description": "Displayed when Windows installer cannot uninstall the old application"
},
"CrashReportDialog__title": {
@ -7013,6 +7013,10 @@
"message": "Añade una historia",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Historias ocultas",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "No hay historias recientes que mostrar",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "Escribe una respuesta …",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Sin respuestas por ahora",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Vistas",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "Historia",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Mostrar historias",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Ocultar historia",
"description": "Label for menu item to hide the story"
@ -7095,28 +7107,12 @@
"message": "Esta versión contiene un par de pequeñas mejoras para que Signal funcione sin problemas.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "Mantenemos cortos los mensajes cortos, añadiendo las marcas de tiempo en la misma línea que el texto. Ahora tienes más espacio en la pantalla con ese «Hola» rápido para ver cómo está esa persona.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "¡Se acabaron los paquetes de stickers perdidos! ¡Ahora Desktop debería poder manejar todos los paquetes de stickers que tienes en tu teléfono!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "Ahora puedes añadir personas a grupos conociendo solo su número de teléfono.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Tus contactos favoritos son ahora más fácil de encontrar. La búsqueda de contactos ahora permite alfabetos no latinos como el cirílico",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Bug fixes including a fix to an issue that would sometimes make it difficult to click on menus. ",
"message": "Reparación de fallos incluyendo uno que hacía casi imposible hacer clic en menús.",
"description": "Release notes for v5.40"
},
"WhatsNew__v5.40--2": {
"message": "Thanks to our open source contributors $dsanders11$ and $yusufsahinhamza$ for contributing to these improvements.",
"message": "Gracias a nuestr@s colaborador@s $dsanders11$ y $yusufsahinhamza$ por contribuir con estas mejoras.",
"description": "Release notes for v5.40",
"placeholders": {
"dsanders11": {

View File

@ -6102,11 +6102,11 @@
"description": "aria-label for the 'next' button in the forward a message modal dialog"
},
"TimelineDateHeader--date-in-last-6-months": {
"message": "ddd D. MMMMta",
"message": "ddd D. MMMM[ta]",
"description": "Moment.js format for date headers in the message timeline, for dates <6 months old. See https://momentjs.com/docs/#/displaying/format/."
},
"TimelineDateHeader--date-older-than-6-months": {
"message": "ddd D. MMMMta YYYY",
"message": "ddd D. MMMM[ta] YYYY",
"description": "Moment.js format for date headers in the message timeline, for dates >=6 months old. See https://momentjs.com/docs/#/displaying/format/."
},
"MessageRequestWarning__learn-more": {
@ -7013,6 +7013,10 @@
"message": "Lisää tarina",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Piilotetut tarinat",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "Viimeiaikaisia tarinoita ei juuri nyt ole",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "Kirjoita vastaus...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Ei vastauksia vielä",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Näytöt",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "Tarina",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Näytä tarinat",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Piilota tarina",
"description": "Label for menu item to hide the story"
@ -7095,22 +7107,6 @@
"message": "Tämä versio sisältää useita pieniä parannuksia ja virhekorjauksia, jotka pitävät Signalin toiminnan sujuvana.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "Pidämme lyhyet viestit lyhyinä sijoitamalla asiat, kuten aikaleimat samalle riville tekstin kanssa. Nyt ruudulla on enemmän tilaa kaverin pikaiselle 'tervehdykselle'.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Puuttuvat tarrapaketit kadotkoon! Puhelimella toimivien tarrapakettien pitäisi nyt toimia myös työpöydällä!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "Voit nyt lisätä ihmisiä ryhmiin pelkän puhelinnumeron perusteella.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Lempiyhteystietosi ovat nyt vain muutaman näppäinpainalluksen päässä. Yhteystietohaku tukee nyt muitakin kuin latinalaisia merkistöjä, kuten esimerkiksi kyrillisiä merkistöjä.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Virheenkorjauksia, mukaan lukien sen virheen korjaaminen joka teki joskus valikoiden klikkaamisesta hankalaa.",
"description": "Release notes for v5.40"

View File

@ -1940,7 +1940,7 @@
"description": "Header in the settings dialog for the section dealing with data deletion"
},
"clearDataExplanation": {
"message": "Toutes les données dans lapplication seront supprimées, y compris tous les messages et les renseignements de compte enregistrés.",
"message": "Toutes les données dans lapplication seront supprimées, y compris tous les messages et les informations de compte enregistrées.",
"description": "Text describing what the clear data button will do."
},
"clearDataButton": {
@ -1952,7 +1952,7 @@
"description": "Header of the full-screen delete data confirmation screen"
},
"deleteAllDataBody": {
"message": "Vous êtes sur le point de supprimer tous les renseignements de compte enregistrés de cette application, y compris tous les contacts et messages. Vous pourrez toujours relier votre appareil mobile de nouveau, mais cela ne restaurera pas les messages supprimés.",
"message": "Vous êtes sur le point de supprimer toutes les informations de compte enregistrées de cette application, y compris tous les contacts et messages. Vous pourrez toujours relier votre appareil mobile de nouveau, mais cela ne restaurera pas les messages supprimés.",
"description": "Text describing what exactly will happen if the user clicks the button to delete all data"
},
"deleteAllDataButton": {
@ -4348,7 +4348,7 @@
"description": "Shown in timeline or conversation preview when v2 group changes"
},
"GroupV2--access-attributes--admins--other": {
"message": "$adminName$ a changé qui peut modifier les renseignements du groupe en « Les administrateurs ».",
"message": "$adminName$ a changé qui peut modifier les informations du groupe en « Les administrateurs ».",
"description": "Shown in timeline or conversation preview when v2 group changes",
"placeholders": {
"adminName": {
@ -4358,15 +4358,15 @@
}
},
"GroupV2--access-attributes--admins--you": {
"message": "Vous avez changé qui peut modifier les renseignements du groupe en « Les administrateurs ».",
"message": "Vous avez changé qui peut modifier les informations du groupe en « Les administrateurs ».",
"description": "Shown in timeline or conversation preview when v2 group changes"
},
"GroupV2--access-attributes--admins--unknown": {
"message": "Un administrateur a changé qui peut modifier les renseignements du groupe en « Les administrateurs ».",
"message": "Un administrateur a changé qui peut modifier les informations du groupe en « Les administrateurs ».",
"description": "Shown in timeline or conversation preview when v2 group changes"
},
"GroupV2--access-attributes--all--other": {
"message": "$adminName$ a changé qui peut modifier les renseignements du groupe en « Tous les membres ».",
"message": "$adminName$ a changé qui peut modifier les informations du groupe en « Tous les membres ».",
"description": "Shown in timeline or conversation preview when v2 group changes",
"placeholders": {
"adminName": {
@ -4376,11 +4376,11 @@
}
},
"GroupV2--access-attributes--all--you": {
"message": "Vous avez changé qui peut modifier les renseignements du groupe en « Tous les membres ».",
"message": "Vous avez changé qui peut modifier les informations du groupe en « Tous les membres ».",
"description": "Shown in timeline or conversation preview when v2 group changes"
},
"GroupV2--access-attributes--all--unknown": {
"message": "Un administrateur a changé qui peut modifier les renseignements du groupe en « Tous les membres ».",
"message": "Un administrateur a changé qui peut modifier les informations du groupe en « Tous les membres ».",
"description": "Shown in timeline or conversation preview when v2 group changes"
},
"GroupV2--access-members--admins--other": {
@ -5610,7 +5610,7 @@
"description": "This is the label for notifications in the conversation details screen"
},
"ConversationDetails--group-info-label": {
"message": "Qui peut modifier les renseignements du groupe",
"message": "Qui peut modifier les informations du groupe",
"description": "This is the label for the 'who can edit the group' panel"
},
"ConversationDetails--group-info-info": {
@ -6358,11 +6358,11 @@
"description": "Text for an option in Conversation Details Disappearing Messages setting when user previously selected custom time"
},
"DisappearingTimeDialog__label--value": {
"message": "Number",
"message": "Nombre",
"description": "aria-label for the number select box"
},
"DisappearingTimeDialog__label--units": {
"message": "Unit of time",
"message": "Unité de temps",
"description": "aria-label for the units of time select box"
},
"DisappearingTimeDialog__title": {
@ -6822,11 +6822,11 @@
}
},
"NSIS__decompressionFailed": {
"message": "Failed to decompress files. Please try running the installer again.",
"message": "Échec de décompression des fichiers. Veuillez réessayer dexécuter l'installeur.",
"description": "Displayed when Windows installer cannot decompress application files"
},
"NSIS__uninstallFailed": {
"message": "Failed to uninstall old application files. Please try running the installer again.",
"message": "Échec de désinstallation des anciens fichiers d'application . Veuillez réessayer dexécuter l'installeur.",
"description": "Displayed when Windows installer cannot uninstall the old application"
},
"CrashReportDialog__title": {
@ -7013,6 +7013,10 @@
"message": "Ajouter une histoire",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Histoires cachées",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "Aucune histoire récente à afficher pour linstant",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "Tapez une réponse…",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Aucune réponse pour le moment",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Vues",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "Histoire",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Montrer les histoires",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Cacher lhistoire",
"description": "Label for menu item to hide the story"
@ -7095,24 +7107,8 @@
"message": "Cette version contient un certain nombre de petits ajustements et de corrections de bogues pour assurer le bon fonctionnement de Signal.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "Les renseignements tels que les estampilles temporelles sont sur la même ligne que le texte afin que les messages courts soient courts. Vous avez désormais plus despace sur lécran pour ce « Salut » rapide à vos amis.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Adieu, paquets dautocollants manquants! Signal pour ordinateur devrait désormais pouvoir gérer tous les paquets que votre téléphone peut gérer.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "Vous pouvez désormais ajouter des personnes aux groupes grâce à leur numéro de téléphone.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Vos contacts favoris sont désormais facilement accessibles et la recherche de contacts prend en charge les alphabets non latins tels que le cyrillique.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Bug fixes including a fix to an issue that would sometimes make it difficult to click on menus. ",
"message": "Correction de bogues, notamment dun problème rendant parfois difficile de cliquer sur les menus.",
"description": "Release notes for v5.40"
},
"WhatsNew__v5.40--2": {

View File

@ -7013,6 +7013,10 @@
"message": "Cuir sgeul ris",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Hidden stories",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "Chan eil sgeul o chionn goirid ri shealltainn ann",
"description": "Description for when there are no stories to show"
@ -7063,6 +7067,10 @@
"message": "Sgeul",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Show stories",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Falaich an sgeul",
"description": "Label for menu item to hide the story"
@ -7095,22 +7103,6 @@
"message": "Chaidh rudan beaga a ghleusadh agus bugaichean a chàradh leis an tionndadh seo airson Signal a chumail a ruith gu rèidh.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "Cumaidh sinn teachdaireachdan goirid goirid le stuth mar stampaichean-tìde air an aon loidhne s a tha an teacsa. Tha barrachd rùm air an sgrìn agad a-nis airson an “Sin thu!” luath a chuireadh tu gu caraid.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Chan eil pacaidean steigearan a dhìth tuilleadh! Bu chòir dhut pacaid steigearan sam bith a chì am fòn agad fhaicinn air an tionndadh Desktop cuideachd a-nis!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "S urrainn dhut daoine a chur ri buidhnean leis an àireamh fòn a-mhàin a-nis.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Bidh an luchd-aithne as annsa leat ri làimh dhut le brùthadh iuchrach no dhà a-nis. Cuiridh an lorg san luchd-aithne taic ri aibidilean neo-Laideann mar Cirilis a-nis.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Bug fixes including a fix to an issue that would sometimes make it difficult to click on menus. ",
"description": "Release notes for v5.40"

View File

@ -7013,6 +7013,10 @@
"message": "הוסף סיפור",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "סיפורים מוסתרים",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "אין סיפורים אחרונים להראות כרגע",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "הקלד תשובה…",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "אין תשובות עדין",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "צפיות",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "סיפור",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "הראה סיפורים",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "הסתר סיפור",
"description": "Label for menu item to hide the story"
@ -7095,24 +7107,8 @@
"message": "גרסה זו מכילה מספר של שפצורים קטנים ותיקוני תקלים כדי לשמור על Signal שירוץ באופן חלק.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "We're keeping short messages short, by putting stuff like timestamps on the same line as the text. Now you've got more space on the screen for that quick 'hey' to check in on a friend.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Missing sticker packs begone! Desktop should now be able to handle all sticker packs that your phone can!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "אתה יכול עכשיו להוסיף אנשים ע״י שימוש רק במספר הטלפון שלהם.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Your favorite contacts are now just a few keystrokes away. Contact search now supports non-Latin alphabets like Cyrillic.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Bug fixes including a fix to an issue that would sometimes make it difficult to click on menus. ",
"message": "תיקוני תקלים כולל תיקון אל סוגייה שהקשתה לפעמים ללחוץ על תפריטים.",
"description": "Release notes for v5.40"
},
"WhatsNew__v5.40--2": {

View File

@ -222,7 +222,7 @@
"description": "Shown at the top of the archived conversations list in the left pane"
},
"noArchivedConversations": {
"message": "No archived conversations.",
"message": "Nincs archivált beszélgetés.",
"description": "Shown at the top of the archived conversations list in the left pane if there is no any archived conversation"
},
"archiveConversation": {
@ -6358,11 +6358,11 @@
"description": "Text for an option in Conversation Details Disappearing Messages setting when user previously selected custom time"
},
"DisappearingTimeDialog__label--value": {
"message": "Number",
"message": "Szám",
"description": "aria-label for the number select box"
},
"DisappearingTimeDialog__label--units": {
"message": "Unit of time",
"message": "Időegység",
"description": "aria-label for the units of time select box"
},
"DisappearingTimeDialog__title": {
@ -6812,7 +6812,7 @@
"description": "Second line of the dialog displayed when Windows installer can't close application automatically and needs user intervention to complete the installation."
},
"NSIS__appRunning": {
"message": "$appName$ is running.\nClick OK to close it.\nIf it doesn't close, try closing it manually.",
"message": "A $appName$ alkalmazás fut.\nKattints az OK gombra a bezárásához.\nHa így sem áll le, zárd be manuálisan.",
"description": "The contents of a dialog displayed when Windows installer detect that the application is running and asks user to close it. Note: please keep the line breaks so that the text occupies three separate lines",
"placeholders": {
"appName": {
@ -6822,11 +6822,11 @@
}
},
"NSIS__decompressionFailed": {
"message": "Failed to decompress files. Please try running the installer again.",
"message": "Kicsomagolási hiba. Kérlek futtasd a telepítőt újra!",
"description": "Displayed when Windows installer cannot decompress application files"
},
"NSIS__uninstallFailed": {
"message": "Failed to uninstall old application files. Please try running the installer again.",
"message": "A régi alkalmazás állományait nem sikerült törölni. Kérlek futtasd a telepítőt újra!",
"description": "Displayed when Windows installer cannot uninstall the old application"
},
"CrashReportDialog__title": {
@ -7013,6 +7013,10 @@
"message": "Történet hozzáadása",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Elrejtett történetek",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "Nincs aktuális friss történet",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "Küldj egy választ...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Még nem érkeztek reakciók",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Megtekintések",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "Történet",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Történetek megjelenítése",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Történet elrejtése",
"description": "Label for menu item to hide the story"
@ -7095,28 +7107,12 @@
"message": "Ebbe a verzióba néhány kisebb újítás és hibajavítás került annak érdekében, hogy a Signal továbbra is gond nélkül fusson.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "Mostantól a rövid üzenetek kevesebb helyet foglalnak, mivel az időbélyeget a szöveggel egy magasságba helyeztük. Így több hely marad a képernyőn frappáns egyszavas beköszönéseidnek.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Soha többé hiányzó matricacsomagok! Az asztali Signal verzió mostantól minden telefonon telepített csomaggal is megbirkózik.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "Mostantól hozzáadhatsz csoporttagokat pusztán telefonszámuk alapján is.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Kedvenc kontaktjaid csak pár gombnyomás távolságra vannak. A kontaktkereső már támogatja a nem-latin kiosztásokat is, mint például a cirill.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Bug fixes including a fix to an issue that would sometimes make it difficult to click on menus. ",
"message": "Hibajavítások. Orvosoltunk egy problémát, amikor a menüelemekre kattintás nem minden esetben működött.",
"description": "Release notes for v5.40"
},
"WhatsNew__v5.40--2": {
"message": "Thanks to our open source contributors $dsanders11$ and $yusufsahinhamza$ for contributing to these improvements.",
"message": "Köszönjük a nyílt forrású hozzájárulásokat $dsanders11$ és $yusufsahinhamza$ felhasználóknak, akik közreműködtek számos hiba javításában.",
"description": "Release notes for v5.40",
"placeholders": {
"dsanders11": {

View File

@ -221,6 +221,10 @@
"message": "Percakapan-percakapan ini diarsipkan dan hanya akan muncul di kotak masuk jika pesan baru diterima.",
"description": "Shown at the top of the archived conversations list in the left pane"
},
"noArchivedConversations": {
"message": "No archived conversations.",
"description": "Shown at the top of the archived conversations list in the left pane if there is no any archived conversation"
},
"archiveConversation": {
"message": "Arsip",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
@ -5892,11 +5896,11 @@
"description": "Information shown below the invite list"
},
"PendingRequests--block--button": {
"message": "Block request",
"message": "Blokir permintaan",
"description": "Shown in timeline if users cancel their request to join a group via a group link"
},
"PendingRequests--block--title": {
"message": "Block request?",
"message": "Blokir permintaan?",
"description": "Title of dialog to block a user from requesting to join via the link again"
},
"PendingRequests--block--contents": {
@ -6353,6 +6357,14 @@
"message": "Waktu kustom",
"description": "Text for an option in Conversation Details Disappearing Messages setting when user previously selected custom time"
},
"DisappearingTimeDialog__label--value": {
"message": "Number",
"description": "aria-label for the number select box"
},
"DisappearingTimeDialog__label--units": {
"message": "Unit of time",
"description": "aria-label for the units of time select box"
},
"DisappearingTimeDialog__title": {
"message": "Waktu Kustom",
"description": "Title for the custom disappearing message timeout dialog"
@ -6799,6 +6811,24 @@
"message": "Mohon tutup secara manual dan klik Coba Lagi untuk melanjutkan.",
"description": "Second line of the dialog displayed when Windows installer can't close application automatically and needs user intervention to complete the installation."
},
"NSIS__appRunning": {
"message": "$appName$ is running.\nClick OK to close it.\nIf it doesn't close, try closing it manually.",
"description": "The contents of a dialog displayed when Windows installer detect that the application is running and asks user to close it. Note: please keep the line breaks so that the text occupies three separate lines",
"placeholders": {
"appName": {
"content": "$1",
"example": "Signal"
}
}
},
"NSIS__decompressionFailed": {
"message": "Failed to decompress files. Please try running the installer again.",
"description": "Displayed when Windows installer cannot decompress application files"
},
"NSIS__uninstallFailed": {
"message": "Failed to uninstall old application files. Please try running the installer again.",
"description": "Displayed when Windows installer cannot uninstall the old application"
},
"CrashReportDialog__title": {
"message": "Aplikasi macet",
"description": "A title of the dialog displayed when starting an application after a recent crash"
@ -6912,7 +6942,7 @@
"description": "Performs the crop"
},
"MyStories__title": {
"message": "My Stories",
"message": "Cerita saya",
"description": "Title for the my stories list"
},
"MyStories__story": {
@ -6976,13 +7006,17 @@
"description": "Title for the stories list"
},
"Stories__mine": {
"message": "My Stories",
"message": "Cerita saya",
"description": "Label for your stories"
},
"Stories__add": {
"message": "Add a story",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Hidden stories",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "No recent stories to show right now",
"description": "Description for when there are no stories to show"
@ -7013,6 +7047,10 @@
"message": "Type a reply...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "No replies yet",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Views",
"description": "Title for views tab"
@ -7033,6 +7071,10 @@
"message": "Story",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Show stories",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Hide story",
"description": "Label for menu item to hide the story"
@ -7065,28 +7107,22 @@
"message": "Versi ini mengandung sejumlah perubahan kecil dan perbaikan bug agar Signal tetap berjalan lancar.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.36--1": {
"message": "Quickly scanning that group chat? There's more room for more messages on the screen at once. We now group sender's messages together if they're close together in time.",
"description": "Release notes for v5.36"
"WhatsNew__v5.40--1": {
"message": "Bug fixes including a fix to an issue that would sometimes make it difficult to click on menus. ",
"description": "Release notes for v5.40"
},
"WhatsNew__v5.36--2": {
"message": "When you perform a Delete for Everyone you'll now see a progress spinner letting you know whether it's been successfully sent or not. If it fails for some reason, you'll be able to retry too!",
"description": "Release notes for v5.36"
},
"WhatsNew__v5.37--1": {
"message": "We're keeping short messages short, by putting stuff like timestamps on the same line as the text. Now you've got more space on the screen for that quick 'hey' to check in on a friend.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Missing sticker packs begone! Desktop should now be able to handle all sticker packs that your phone can!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "You can now add people to groups using just their phone number.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Your favorite contacts are now just a few keystrokes away. Contact search now supports non-Latin alphabets like Cyrillic.",
"description": "Release notes for v5.39"
"WhatsNew__v5.40--2": {
"message": "Thanks to our open source contributors $dsanders11$ and $yusufsahinhamza$ for contributing to these improvements.",
"description": "Release notes for v5.40",
"placeholders": {
"dsanders11": {
"content": "$1",
"example": "dsanders11"
},
"yusufsahinhamza": {
"content": "$2",
"example": "yusufsahinhamza"
}
}
}
}

View File

@ -222,7 +222,7 @@
"description": "Shown at the top of the archived conversations list in the left pane"
},
"noArchivedConversations": {
"message": "No archived conversations.",
"message": "Engin samtöl í geymslu.",
"description": "Shown at the top of the archived conversations list in the left pane if there is no any archived conversation"
},
"archiveConversation": {
@ -6358,11 +6358,11 @@
"description": "Text for an option in Conversation Details Disappearing Messages setting when user previously selected custom time"
},
"DisappearingTimeDialog__label--value": {
"message": "Number",
"message": "Tala",
"description": "aria-label for the number select box"
},
"DisappearingTimeDialog__label--units": {
"message": "Unit of time",
"message": "Tímaeining",
"description": "aria-label for the units of time select box"
},
"DisappearingTimeDialog__title": {
@ -6812,7 +6812,7 @@
"description": "Second line of the dialog displayed when Windows installer can't close application automatically and needs user intervention to complete the installation."
},
"NSIS__appRunning": {
"message": "$appName$ is running.\nClick OK to close it.\nIf it doesn't close, try closing it manually.",
"message": "$appName$ er í gangi.\nSmelltu á 'Í lagi' til að loka því.\nEf það lokast ekki, geturðu reynt að loka því handvirkt..",
"description": "The contents of a dialog displayed when Windows installer detect that the application is running and asks user to close it. Note: please keep the line breaks so that the text occupies three separate lines",
"placeholders": {
"appName": {
@ -6822,11 +6822,11 @@
}
},
"NSIS__decompressionFailed": {
"message": "Failed to decompress files. Please try running the installer again.",
"message": "Mistókst að afþjappa skrám. Keyrðu uppsetningarforritið aftur.",
"description": "Displayed when Windows installer cannot decompress application files"
},
"NSIS__uninstallFailed": {
"message": "Failed to uninstall old application files. Please try running the installer again.",
"message": "Mistókst að hreinsa út gamlar forritsskrár. Keyrðu uppsetningarforritið aftur.",
"description": "Displayed when Windows installer cannot uninstall the old application"
},
"CrashReportDialog__title": {
@ -7013,6 +7013,10 @@
"message": "Bæta við sögu",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Faldar sögur",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "Í augnablikinu eru engar nýlegar sögur til að birta",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "Skrifaðu svar...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Ennþá engin svör",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Skoðað",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "Saga",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Birta sögur",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Fela sögu",
"description": "Label for menu item to hide the story"
@ -7095,28 +7107,12 @@
"message": "Þessi útgáfa inniheldur nokkrar villuleiðréttingar og fínstillingar til að Signal keyri sem áreiðanlegast.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "Við höldum stuttum skilaboðum verulega stuttum, með því að setja dót eins og tímamerki í sömu línu og sjálfann textann. Þá hefurðu meira pláss til að sinna öðru.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Nú ætti aldrei að vanta neina límmerkjapakka. Vinnutölvuútgáfan getur núna meðhöndlað alla þá sömu límmerkjapakka og síminn þinn getur.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "Þú getur núna bætt fólki í hópa með símanúmerinu þeirra.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Eftirlætistengiliðirnir þínir eru núna innan seilingar. Leit að tengiliðum styður núna stafróf sem ekki eru með latnesku letri, eins og t.d. kyrilísku.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Bug fixes including a fix to an issue that would sometimes make it difficult to click on menus. ",
"message": "Villulagfæringar, meðal annars á vandamáli við að smella á valmyndir.",
"description": "Release notes for v5.40"
},
"WhatsNew__v5.40--2": {
"message": "Thanks to our open source contributors $dsanders11$ and $yusufsahinhamza$ for contributing to these improvements.",
"message": "Þökk sé sjálfboðaliðunum $dsanders11$ og $yusufsahinhamza$ sem áttu stóran hlut í þessum endurbótum.",
"description": "Release notes for v5.40",
"placeholders": {
"dsanders11": {

View File

@ -7013,6 +7013,10 @@
"message": "Aggiungi una storia",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Storie nascoste",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "Nessuna storia recente da mostrare al momento",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "Scrivi una risposta...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Ancora nessuna risposta",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Visualizzazioni",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "Storia",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Mostra storie",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Nascondi storia",
"description": "Label for menu item to hide the story"
@ -7095,22 +7107,6 @@
"message": "Questa versione contiene una serie di piccole modifiche e correzioni di bug per far funzionare Signal senza problemi.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "Stiamo mantenendo i messaggi brevi, mettendo cose come i timestamp sulla stessa linea del testo. Ora hai più spazio sullo schermo per quel rapido 'ehi' per sentirti con un amico.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Addio ai pacchetti di adesivi mancanti! Desktop dovrebbe ora essere in grado di gestire tutti i pacchetti di adesivi che il tuo telefono è in grado di gestire!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "Ora puoi aggiungere persone ai gruppi usando solo il loro numero di telefono.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "I tuoi contatti preferiti sono ora a pochi tasti di distanza. La ricerca di contatti ora supporta alfabeti non latini come il cirillico.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Correzioni di bug, inclusa la correzione di un problema che a volte rendeva difficile cliccare sui menu. ",
"description": "Release notes for v5.40"

View File

@ -222,7 +222,7 @@
"description": "Shown at the top of the archived conversations list in the left pane"
},
"noArchivedConversations": {
"message": "No archived conversations.",
"message": "アーカイブ済みのチャットはありません。",
"description": "Shown at the top of the archived conversations list in the left pane if there is no any archived conversation"
},
"archiveConversation": {
@ -2406,7 +2406,7 @@
"description": "Shown if request to Signal servers to find username fails"
},
"Toast--failed-to-fetch-phone-number": {
"message": "Failed to fetch phone number. Check your connection and try again.",
"message": "電話番号の取得に失敗しました。接続を確認して再度お試しください。",
"description": "Shown if request to Signal servers to find phone number fails"
},
"startConversation--username-not-found": {
@ -2420,7 +2420,7 @@
}
},
"startConversation--phone-number-not-found": {
"message": "User not found. \"$phoneNumber$\" is not a Signal user.",
"message": "ユーザーが見つかりません。\"$phoneNumber$\"は、Signalユーザーではありません。",
"description": "Shown in dialog if phone number is not found.",
"placeholders": {
"phoneNumber": {
@ -2430,7 +2430,7 @@
}
},
"startConversation--phone-number-not-valid": {
"message": "User not found. \"$phoneNumber$\" is not a valid phone number.",
"message": "ユーザーが見つかりません。\"$phoneNumber$\"は、無効な電話番号です。",
"description": "Shown in dialog if phone number is not valid.",
"placeholders": {
"phoneNumber": {
@ -5196,7 +5196,7 @@
}
},
"GroupV2--admin-approval-bounce--one": {
"message": "$joinerName$ requested and cancelled their request to join via the group link",
"message": "$joinerName$ は、グループリンクからの参加申請をキャンセルしました。",
"description": "Shown in timeline or conversation preview when v2 group changes",
"placeholders": {
"joinerName": {
@ -5206,7 +5206,7 @@
}
},
"GroupV2--admin-approval-bounce": {
"message": "$joinerName$ requested and cancelled $numberOfRequests$ requests to join via the group link",
"message": "$joinerName$ は、グループリンクからの参加申請を$numberOfRequests$件キャンセルしました。",
"description": "Shown in timeline or conversation preview when v2 group changes",
"placeholders": {
"joinerName": {
@ -5796,7 +5796,7 @@
}
},
"PendingRequests--deny-for--with-link": {
"message": "Deny request from \"$name$\"? They will not be able to request to join via the group link again.",
"message": "\"$name$\" からの申請を拒否しますか?このユーザーは、このグループリンクから再申請できなくなります。",
"description": "This is the modal content when confirming denying a group request to join",
"placeholders": {
"name": {
@ -5904,7 +5904,7 @@
"description": "Title of dialog to block a user from requesting to join via the link again"
},
"PendingRequests--block--contents": {
"message": "$name$ will not be able to join or request to join this group via the group link. They can still be added to the group manually.",
"message": "$name$ はこのグループリンクからの参加申請ができなくなりますが、手動でグループに追加することはできます。",
"description": "Details of dialog to block a user from requesting to join via the link again",
"placeholders": {
"name": {
@ -6210,7 +6210,7 @@
}
},
"RemoveGroupMemberConfirmation__description__with-link": {
"message": "Remove \"$name$\" from the group? They will not be able to rejoin via the group link.",
"message": "\"$name$\"を、グループから削除しますか?このユーザは、グループリンクからもう一度このグループに入ることは、できなくなります。",
"description": "When confirming the removal of a group member, show this text in the dialog",
"placeholders": {
"name": {
@ -6812,7 +6812,7 @@
"description": "Second line of the dialog displayed when Windows installer can't close application automatically and needs user intervention to complete the installation."
},
"NSIS__appRunning": {
"message": "$appName$ is running.\nClick OK to close it.\nIf it doesn't close, try closing it manually.",
"message": "$appName$ が起動しています。\nOKをクリックして、閉じてください。\n閉じない場合は、手動で閉じてください。",
"description": "The contents of a dialog displayed when Windows installer detect that the application is running and asks user to close it. Note: please keep the line breaks so that the text occupies three separate lines",
"placeholders": {
"appName": {
@ -6822,11 +6822,11 @@
}
},
"NSIS__decompressionFailed": {
"message": "Failed to decompress files. Please try running the installer again.",
"message": "ファイルの解凍に失敗しました。もう一度インストーラーを実行してみてください。",
"description": "Displayed when Windows installer cannot decompress application files"
},
"NSIS__uninstallFailed": {
"message": "Failed to uninstall old application files. Please try running the installer again.",
"message": "古いアプリケーションファイルのアンインストールに失敗しました。もう一度インストーラーを実行してみてください。",
"description": "Displayed when Windows installer cannot uninstall the old application"
},
"CrashReportDialog__title": {
@ -7013,6 +7013,10 @@
"message": "ストーリーを追加",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "非表示のストーリー",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "表示できるストーリーはありません",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "返信を入力してください…",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "返信 なし",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "閲覧",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "ストーリー",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "ストーリーを表示",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "ストーリーを閉じる",
"description": "Label for menu item to hide the story"
@ -7095,28 +7107,12 @@
"message": "Signalをスムーズに動作させるための微調整とバグ修正を行いました。",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "タイムスタンプをテキストと同じ行に配置することで、画面のスペースを節約し、たくさんのメッセージを表示できるようになりました。",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "デスクトップ版Signalでステッカーパックが表示されないバグが、修正されました。スマートフォンと同じステッカーパックが使えます。",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "グループのメンバーを電話番号で追加できるようになりました。",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "連絡先の検索に、キリル文字などのラテン語以外の言語が対応しました。",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Bug fixes including a fix to an issue that would sometimes make it difficult to click on menus. ",
"message": "メニューがクリックしにくくなることがあるバグを修正しました。",
"description": "Release notes for v5.40"
},
"WhatsNew__v5.40--2": {
"message": "Thanks to our open source contributors $dsanders11$ and $yusufsahinhamza$ for contributing to these improvements.",
"message": "コントリビューターである、$dsanders11$ と、 $yusufsahinhamza$、ありがとうございます!",
"description": "Release notes for v5.40",
"placeholders": {
"dsanders11": {

View File

@ -7013,6 +7013,10 @@
"message": "Pridėti istoriją",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Paslėptos istorijos",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "Šiuo metu nėra paskiausių istorijų, kurias rodyti",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "Rašykite atsakymą...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Atsakymų kol kas nėra",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Peržiūros",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "Istorija",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Rodyti istorijas",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Slėpti istoriją",
"description": "Label for menu item to hide the story"
@ -7095,22 +7107,6 @@
"message": "Šioje versijoje yra daug smulkių patobulinimų ir klaidų ištaisymų, kurie padės Signal sklandžiai veikti.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "Trumpas žinutes išlaikome trumpomis, atvaizduodami laiko žymes toje pačioje eilutėje, kaip ir tekstą. Dabar, ekrane yra daugiau vietos, kad parašytumėte draugui greitą žinutę su žodžiu „Labas“.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Šalin trūkstamus lipdukų paketus! Dabar, darbalaukio programa turėtų gebėti apdoroti visus lipdukų paketus, kuriuos gali apdoroti jūsų telefonas!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "Dabar, galite pridėti žmones į grupes, naudodami tik jų telefono numerį.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Jūsų mėgstami adresatai yra tik kelių klavišų paspaudimų atstumu. Adresatų paieška nuo šiol palaiko ne lotyniškas abėcėles, pavyzdžiui, kirilicą.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Klaidų pataisymas, skirtas išspręsti problemą, dėl kurios, kartais, būdavo sunku spustelėti ant meniu.",
"description": "Release notes for v5.40"

View File

@ -221,6 +221,10 @@
"message": "Šīs sarunas ir arhivētas un iesūtnē būs redzamas tikai tad, ja tiks saņemtas jaunas ziņas.",
"description": "Shown at the top of the archived conversations list in the left pane"
},
"noArchivedConversations": {
"message": "No archived conversations.",
"description": "Shown at the top of the archived conversations list in the left pane if there is no any archived conversation"
},
"archiveConversation": {
"message": "Arhīvs",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
@ -6353,6 +6357,14 @@
"message": "Pielāgots laiks",
"description": "Text for an option in Conversation Details Disappearing Messages setting when user previously selected custom time"
},
"DisappearingTimeDialog__label--value": {
"message": "Number",
"description": "aria-label for the number select box"
},
"DisappearingTimeDialog__label--units": {
"message": "Unit of time",
"description": "aria-label for the units of time select box"
},
"DisappearingTimeDialog__title": {
"message": "Pielāgots laiks",
"description": "Title for the custom disappearing message timeout dialog"
@ -6799,6 +6811,24 @@
"message": "Please close it manually and click Retry to continue.",
"description": "Second line of the dialog displayed when Windows installer can't close application automatically and needs user intervention to complete the installation."
},
"NSIS__appRunning": {
"message": "$appName$ is running.\nClick OK to close it.\nIf it doesn't close, try closing it manually.",
"description": "The contents of a dialog displayed when Windows installer detect that the application is running and asks user to close it. Note: please keep the line breaks so that the text occupies three separate lines",
"placeholders": {
"appName": {
"content": "$1",
"example": "Signal"
}
}
},
"NSIS__decompressionFailed": {
"message": "Failed to decompress files. Please try running the installer again.",
"description": "Displayed when Windows installer cannot decompress application files"
},
"NSIS__uninstallFailed": {
"message": "Failed to uninstall old application files. Please try running the installer again.",
"description": "Displayed when Windows installer cannot uninstall the old application"
},
"CrashReportDialog__title": {
"message": "Application crashed",
"description": "A title of the dialog displayed when starting an application after a recent crash"
@ -6983,6 +7013,10 @@
"message": "Pievienot stāstu",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Paslēptie stāsti",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "No recent stories to show right now",
"description": "Description for when there are no stories to show"
@ -7013,6 +7047,10 @@
"message": "Type a reply...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Vēl nav atbilžu",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Skatījumi",
"description": "Title for views tab"
@ -7033,6 +7071,10 @@
"message": "Story",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Show stories",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Paslēpt stāstu",
"description": "Label for menu item to hide the story"
@ -7065,28 +7107,22 @@
"message": "This version contains a number of small tweaks and bug fixes to keep Signal running smoothly.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.36--1": {
"message": "Quickly scanning that group chat? There's more room for more messages on the screen at once. We now group sender's messages together if they're close together in time.",
"description": "Release notes for v5.36"
"WhatsNew__v5.40--1": {
"message": "Bug fixes including a fix to an issue that would sometimes make it difficult to click on menus. ",
"description": "Release notes for v5.40"
},
"WhatsNew__v5.36--2": {
"message": "When you perform a Delete for Everyone you'll now see a progress spinner letting you know whether it's been successfully sent or not. If it fails for some reason, you'll be able to retry too!",
"description": "Release notes for v5.36"
},
"WhatsNew__v5.37--1": {
"message": "We're keeping short messages short, by putting stuff like timestamps on the same line as the text. Now you've got more space on the screen for that quick 'hey' to check in on a friend.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Missing sticker packs begone! Desktop should now be able to handle all sticker packs that your phone can!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "You can now add people to groups using just their phone number.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Your favorite contacts are now just a few keystrokes away. Contact search now supports non-Latin alphabets like Cyrillic.",
"description": "Release notes for v5.39"
"WhatsNew__v5.40--2": {
"message": "Thanks to our open source contributors $dsanders11$ and $yusufsahinhamza$ for contributing to these improvements.",
"description": "Release notes for v5.40",
"placeholders": {
"dsanders11": {
"content": "$1",
"example": "dsanders11"
},
"yusufsahinhamza": {
"content": "$2",
"example": "yusufsahinhamza"
}
}
}
}

View File

@ -221,6 +221,10 @@
"message": "Овие разговори се архивирани и ќе се појават во сандачето само ако има нови пристигнати пораки.",
"description": "Shown at the top of the archived conversations list in the left pane"
},
"noArchivedConversations": {
"message": "No archived conversations.",
"description": "Shown at the top of the archived conversations list in the left pane if there is no any archived conversation"
},
"archiveConversation": {
"message": "Архива",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
@ -6353,6 +6357,14 @@
"message": "Прилагоди време",
"description": "Text for an option in Conversation Details Disappearing Messages setting when user previously selected custom time"
},
"DisappearingTimeDialog__label--value": {
"message": "Number",
"description": "aria-label for the number select box"
},
"DisappearingTimeDialog__label--units": {
"message": "Unit of time",
"description": "aria-label for the units of time select box"
},
"DisappearingTimeDialog__title": {
"message": "Прилагоди време",
"description": "Title for the custom disappearing message timeout dialog"
@ -6799,6 +6811,24 @@
"message": "Please close it manually and click Retry to continue.",
"description": "Second line of the dialog displayed when Windows installer can't close application automatically and needs user intervention to complete the installation."
},
"NSIS__appRunning": {
"message": "$appName$ is running.\nClick OK to close it.\nIf it doesn't close, try closing it manually.",
"description": "The contents of a dialog displayed when Windows installer detect that the application is running and asks user to close it. Note: please keep the line breaks so that the text occupies three separate lines",
"placeholders": {
"appName": {
"content": "$1",
"example": "Signal"
}
}
},
"NSIS__decompressionFailed": {
"message": "Failed to decompress files. Please try running the installer again.",
"description": "Displayed when Windows installer cannot decompress application files"
},
"NSIS__uninstallFailed": {
"message": "Failed to uninstall old application files. Please try running the installer again.",
"description": "Displayed when Windows installer cannot uninstall the old application"
},
"CrashReportDialog__title": {
"message": "Application crashed",
"description": "A title of the dialog displayed when starting an application after a recent crash"
@ -6983,6 +7013,10 @@
"message": "Додај приказна",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Скриени приказни",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "No recent stories to show right now",
"description": "Description for when there are no stories to show"
@ -7013,6 +7047,10 @@
"message": "Type a reply...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Сè уште нема одговори",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Прегледи",
"description": "Title for views tab"
@ -7033,6 +7071,10 @@
"message": "Story",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Show stories",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Сокриј приказна",
"description": "Label for menu item to hide the story"
@ -7065,28 +7107,22 @@
"message": "This version contains a number of small tweaks and bug fixes to keep Signal running smoothly.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.36--1": {
"message": "Quickly scanning that group chat? There's more room for more messages on the screen at once. We now group sender's messages together if they're close together in time.",
"description": "Release notes for v5.36"
"WhatsNew__v5.40--1": {
"message": "Bug fixes including a fix to an issue that would sometimes make it difficult to click on menus. ",
"description": "Release notes for v5.40"
},
"WhatsNew__v5.36--2": {
"message": "When you perform a Delete for Everyone you'll now see a progress spinner letting you know whether it's been successfully sent or not. If it fails for some reason, you'll be able to retry too!",
"description": "Release notes for v5.36"
},
"WhatsNew__v5.37--1": {
"message": "We're keeping short messages short, by putting stuff like timestamps on the same line as the text. Now you've got more space on the screen for that quick 'hey' to check in on a friend.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Missing sticker packs begone! Desktop should now be able to handle all sticker packs that your phone can!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "You can now add people to groups using just their phone number.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Your favorite contacts are now just a few keystrokes away. Contact search now supports non-Latin alphabets like Cyrillic.",
"description": "Release notes for v5.39"
"WhatsNew__v5.40--2": {
"message": "Thanks to our open source contributors $dsanders11$ and $yusufsahinhamza$ for contributing to these improvements.",
"description": "Release notes for v5.40",
"placeholders": {
"dsanders11": {
"content": "$1",
"example": "dsanders11"
},
"yusufsahinhamza": {
"content": "$2",
"example": "yusufsahinhamza"
}
}
}
}

View File

@ -324,7 +324,7 @@
"description": "Used as a label on a button allowing user to see more information"
},
"youLeftTheGroup": {
"message": "Je kunt geen berichten verzenden omdat je niet langer lid bent van de groep.",
"message": "Je bent niet langer lid van deze groep en je zult daarom geen nieuwe berichten zien.",
"description": "Displayed when a user can't send a message because they have left the group"
},
"invalidConversation": {
@ -464,7 +464,7 @@
"description": "Shown in conversation banner when more than one group member's safety number has changed, but they were previously verified."
},
"debugLogExplanation": {
"message": "Als je op uploaden klikt dan wordt dit log 30 dagen lang online beschikbaar gesteld op een unieke nergens onthulde URL. Die URL kun je vervolgens naar de ontwikkelaars sturen. Je kunt dit log ook offline op je eigen apparaat opslaan.",
"message": "Dit log bevat geen persoonlijke details zoals telefoonnummers. Als je op uploaden klikt dan wordt dit log 30 dagen lang online beschikbaar gesteld op een unieke nergens onthulde verwijzing. Die verwijzing kun je zelf naar de ontwikkelaars sturen. Je kunt dit log ook offline op je eigen apparaat opslaan.",
"description": "Description of what will happen with your debug log"
},
"debugLogError": {
@ -504,7 +504,7 @@
"description": "Label for a button that dismisses a dialog. The user clicks it to confirm that they understand the message in the dialog."
},
"submit": {
"message": "Verzenden",
"message": "Uploaden",
"description": ""
},
"acceptNewKey": {
@ -1276,7 +1276,7 @@
"description": "Shown in left pane preview when message delivery issue happens"
},
"DeliveryIssue--notification": {
"message": "Een bericht van $sender$ kon niet worden afgeleverd",
"message": "Een bericht van $sender$ kan niet worden afgeleverd",
"description": "Shown in timeline when message delivery issue happens",
"placeholders": {
"name": {
@ -1940,7 +1940,7 @@
"description": "Header in the settings dialog for the section dealing with data deletion"
},
"clearDataExplanation": {
"message": "Dit verwijdert alle gegevens in de toepassing: alle berichten, alle opgeslagen voorkeuren en alle profielinformatie.",
"message": "Dit wist alle gegevens in de toepassing: alle berichten, alle opgeslagen voorkeuren en alle profielinformatie.",
"description": "Text describing what the clear data button will do."
},
"clearDataButton": {
@ -1960,7 +1960,7 @@
"description": "Text of the button that deletes all data"
},
"deleteAllDataProgress": {
"message": "Verbinding wordt verbroken en alle gegevens worden verwijderd",
"message": "Verbinding wordt verbroken en alle gegevens worden gewist",
"description": "Message shown to user when app is disconnected and data deleted"
},
"deleteOldIndexedDBData": {
@ -2674,7 +2674,7 @@
}
},
"ConversationList__last-message-undefined": {
"message": "Het meest recente bericht is mogelijk verwijderd.",
"message": "Het meest recente bericht is mogelijk gewist.",
"description": "For aria-label within conversation list. Describes if last message is not defined."
},
"BaseConversationListItem__aria-label": {
@ -3556,7 +3556,7 @@
"description": "Shown as a button to let the user delete any message request"
},
"MessageRequests--delete-direct-confirm-title": {
"message": "Gesprek verwijderen?",
"message": "Gesprek wissen?",
"description": "Shown as the title in the confirmation modal for deleting a private message request"
},
"MessageRequests--delete-direct-confirm-body": {
@ -3564,7 +3564,7 @@
"description": "Shown as the body in the confirmation modal for deleting a private message request"
},
"MessageRequests--delete-group-confirm-title": {
"message": "$group$ verlaten en verwijderen?",
"message": "$group$ verlaten en wissen?",
"description": "Shown as the title in the confirmation modal for deleting a group message request",
"placeholders": {
"group": {
@ -3574,11 +3574,11 @@
}
},
"MessageRequests--delete-direct": {
"message": "Verwijderen",
"message": "Wissen",
"description": "Shown as a button to let the user delete a direct message request"
},
"MessageRequests--delete-group": {
"message": "Verwijderen en verlaten",
"message": "Wissen en verlaten",
"description": "Shown as a button to let the user delete a group message request"
},
"MessageRequests--delete-group-confirm-body": {
@ -6256,7 +6256,7 @@
"description": "Displayed when delete-for-everyone has failed to send to all recipients"
},
"ChatColorPicker__delete--title": {
"message": "Kleur verwijderen",
"message": "Kleur wissen",
"description": "Confirm title for deleting custom color"
},
"ChatColorPicker__delete--message": {
@ -6532,15 +6532,15 @@
"description": "Shown if something unknown has gone wrong with username save."
},
"ProfileEditor--username--delete-general-error": {
"message": "Je gebruikersnaam kan niet worden verwijderd. Ga na dat je apparaat met het internet is verbonden en probeer het opnieuw.",
"message": "Je gebruikersnaam kan niet worden gewist. Ga na dat je apparaat met het internet is verbonden en probeer het opnieuw.",
"description": "Shown if something unknown has gone wrong with username delete."
},
"ProfileEditor--username--delete-username": {
"message": "Gebruikersnaam verwijderen",
"message": "Gebruikersnaam wissen",
"description": "Shown as aria label for trash icon next to username"
},
"ProfileEditor--username--confirm-delete-body": {
"message": "Je staat op het punt je gebruikersnaam te verwijderen. Als je door gaat kunnen anderen deze naam claimen. Weet je het zeker?",
"message": "Je staat op het punt je gebruikersnaam te wissen. Als je door gaat kunnen anderen deze naam claimen. Weet je het zeker?",
"description": "Shown in dialog body if user has saved an empty string to delete their username"
},
"ProfileEditor--username--confirm-delete-button": {
@ -7013,6 +7013,10 @@
"message": "Een verhaal toevoegen",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Verborgen verhalen",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "Er zijn op dit moment geen recente verhalen om weer te geven",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "Typ een reactie …",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Nog geen reacties",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Aantal weergaven",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "Verhaal",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Verhalen niet langer verbergen",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Verhaal verbergen",
"description": "Label for menu item to hide the story"
@ -7095,22 +7107,6 @@
"message": "Deze versie bevat een aantal kleine foutoplossingen waardoor Signal voor nog meer mensen goed werkt.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "Korte berichten zijn vanaf nu nog korter, omdat de tijdsindicatie op dezelfde regel staat als de tekst van je bericht.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Er was een fout waardoor sommige stickerpakketten niet konden worden weergegeven in Signal-desktop. Vanaf nu kun je alle stickerpakketten zien net als op je telefoon.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "Je kunt vanaf nu ook personen toevoegen aan groepen door alleen hun telefoonnummer in te voeren.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Ook personen die niet het Latijnse alfabet gebruiken kunnen vanaf nu contactpersonen zoeken.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Foutoplossingen, waaronder een oplossing voor een fout waarbij het soms moeilijk was op op menuknoppen te klikken.",
"description": "Release notes for v5.40"

View File

@ -221,6 +221,10 @@
"message": "Desse samtalane er arkiverte og vil berre dukka opp i innboksen viss du får nye meldingar.",
"description": "Shown at the top of the archived conversations list in the left pane"
},
"noArchivedConversations": {
"message": "No archived conversations.",
"description": "Shown at the top of the archived conversations list in the left pane if there is no any archived conversation"
},
"archiveConversation": {
"message": "Arkiver",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
@ -6353,6 +6357,14 @@
"message": "Anna intervall",
"description": "Text for an option in Conversation Details Disappearing Messages setting when user previously selected custom time"
},
"DisappearingTimeDialog__label--value": {
"message": "Number",
"description": "aria-label for the number select box"
},
"DisappearingTimeDialog__label--units": {
"message": "Unit of time",
"description": "aria-label for the units of time select box"
},
"DisappearingTimeDialog__title": {
"message": "Anna intervall",
"description": "Title for the custom disappearing message timeout dialog"
@ -6799,6 +6811,24 @@
"message": "Please close it manually and click Retry to continue.",
"description": "Second line of the dialog displayed when Windows installer can't close application automatically and needs user intervention to complete the installation."
},
"NSIS__appRunning": {
"message": "$appName$ is running.\nClick OK to close it.\nIf it doesn't close, try closing it manually.",
"description": "The contents of a dialog displayed when Windows installer detect that the application is running and asks user to close it. Note: please keep the line breaks so that the text occupies three separate lines",
"placeholders": {
"appName": {
"content": "$1",
"example": "Signal"
}
}
},
"NSIS__decompressionFailed": {
"message": "Failed to decompress files. Please try running the installer again.",
"description": "Displayed when Windows installer cannot decompress application files"
},
"NSIS__uninstallFailed": {
"message": "Failed to uninstall old application files. Please try running the installer again.",
"description": "Displayed when Windows installer cannot uninstall the old application"
},
"CrashReportDialog__title": {
"message": "Application crashed",
"description": "A title of the dialog displayed when starting an application after a recent crash"
@ -6983,6 +7013,10 @@
"message": "Lag historie",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Gøymde historier",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "No recent stories to show right now",
"description": "Description for when there are no stories to show"
@ -7013,6 +7047,10 @@
"message": "Type a reply...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Ingen svar enno",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Visningar",
"description": "Title for views tab"
@ -7033,6 +7071,10 @@
"message": "Story",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Show stories",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Skjul historie",
"description": "Label for menu item to hide the story"
@ -7065,28 +7107,22 @@
"message": "This version contains a number of small tweaks and bug fixes to keep Signal running smoothly.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.36--1": {
"message": "Quickly scanning that group chat? There's more room for more messages on the screen at once. We now group sender's messages together if they're close together in time.",
"description": "Release notes for v5.36"
"WhatsNew__v5.40--1": {
"message": "Bug fixes including a fix to an issue that would sometimes make it difficult to click on menus. ",
"description": "Release notes for v5.40"
},
"WhatsNew__v5.36--2": {
"message": "When you perform a Delete for Everyone you'll now see a progress spinner letting you know whether it's been successfully sent or not. If it fails for some reason, you'll be able to retry too!",
"description": "Release notes for v5.36"
},
"WhatsNew__v5.37--1": {
"message": "We're keeping short messages short, by putting stuff like timestamps on the same line as the text. Now you've got more space on the screen for that quick 'hey' to check in on a friend.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Missing sticker packs begone! Desktop should now be able to handle all sticker packs that your phone can!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "You can now add people to groups using just their phone number.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Your favorite contacts are now just a few keystrokes away. Contact search now supports non-Latin alphabets like Cyrillic.",
"description": "Release notes for v5.39"
"WhatsNew__v5.40--2": {
"message": "Thanks to our open source contributors $dsanders11$ and $yusufsahinhamza$ for contributing to these improvements.",
"description": "Release notes for v5.40",
"placeholders": {
"dsanders11": {
"content": "$1",
"example": "dsanders11"
},
"yusufsahinhamza": {
"content": "$2",
"example": "yusufsahinhamza"
}
}
}
}

View File

@ -7013,6 +7013,10 @@
"message": "Dodaj historię",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Ukryte historie",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "W tej chwili nie ma nowych historii do pokazania",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "Napisz odpowiedź...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Brak odpowiedzi",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Odsłony",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "Historia",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Pokaż historie",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Ukryj historię",
"description": "Label for menu item to hide the story"
@ -7095,22 +7107,6 @@
"message": "Ta wersja zawiera wiele drobnych ulepszeń i poprawek błędów, zapewniających płynne działanie aplikacji Signal.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "Pilnujemy, żeby krótkie wiadomości pozostały krótkie, umieszczając stemple czasowe itp. w tej samej linii, co tekst. Masz teraz więcej przestrzeni na ekranie, żeby rzucić przyjaciołom krótkie \"cześć\".",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Przepadnijcie brakujące pakiety naklejek! Aplikacja Desktop powinna teraz obsługiwać wszystkie pakiety naklejek, które masz na telefonie!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "Teraz możesz dodawać ludzi do grup, używając tylko ich numeru telefonu.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Twoje ulubione kontakty znajdą się już po naciśnięciu kilku klawiszy. Wyszukiwanie kontaktów obsługuje teraz alfabety inne, niż łaciński, takie jak cyrylica.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Poprawki błędów, w tym problemu powodującego czasem trudności z kliknięciem menu.",
"description": "Release notes for v5.40"

View File

@ -222,7 +222,7 @@
"description": "Shown at the top of the archived conversations list in the left pane"
},
"noArchivedConversations": {
"message": "No archived conversations.",
"message": "Nenhuma conversa arquivada.",
"description": "Shown at the top of the archived conversations list in the left pane if there is no any archived conversation"
},
"archiveConversation": {
@ -6358,11 +6358,11 @@
"description": "Text for an option in Conversation Details Disappearing Messages setting when user previously selected custom time"
},
"DisappearingTimeDialog__label--value": {
"message": "Number",
"message": "Número",
"description": "aria-label for the number select box"
},
"DisappearingTimeDialog__label--units": {
"message": "Unit of time",
"message": "Unidade de tempo",
"description": "aria-label for the units of time select box"
},
"DisappearingTimeDialog__title": {
@ -6812,7 +6812,7 @@
"description": "Second line of the dialog displayed when Windows installer can't close application automatically and needs user intervention to complete the installation."
},
"NSIS__appRunning": {
"message": "$appName$ is running.\nClick OK to close it.\nIf it doesn't close, try closing it manually.",
"message": "$appName$ está funcionando.\nClique no OK para fechar.\nSe não fechar, tente fechá-lo manualmente.",
"description": "The contents of a dialog displayed when Windows installer detect that the application is running and asks user to close it. Note: please keep the line breaks so that the text occupies three separate lines",
"placeholders": {
"appName": {
@ -6822,11 +6822,11 @@
}
},
"NSIS__decompressionFailed": {
"message": "Failed to decompress files. Please try running the installer again.",
"message": "Falha ao descompactar os arquivos. Por favor, tente iniciar o instalador novamente.",
"description": "Displayed when Windows installer cannot decompress application files"
},
"NSIS__uninstallFailed": {
"message": "Failed to uninstall old application files. Please try running the installer again.",
"message": "Falha ao desinstalar os arquivos do aplicativo antigo. Por favor, tente iniciar o instalador novamente.",
"description": "Displayed when Windows installer cannot uninstall the old application"
},
"CrashReportDialog__title": {
@ -7013,6 +7013,10 @@
"message": "Adicionar um story",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Stories ocultados",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "Nenhum story em exibição no momento",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "Digitar uma resposta…",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Ainda não há respostas",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Visualizações",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "Story",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Mostrar Stories",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Ocultar story",
"description": "Label for menu item to hide the story"
@ -7095,28 +7107,12 @@
"message": "Essa versão contém pequenos retoques e consertos no Signal para ele continuar funcionando confortavelmente.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "Estamos mantendo as mensagens curtas curtas, colocando coisas como registros de tempo na mesma linha que o texto. Agora você tem mais espaço na tela para enviar um rápido \"alô\" para descobrir como estão seus amigos.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Os pacotes de figurinhas que tanto faltava estão aqui! Agora o Desktop deve suportar os mesmos pacotes de figurinhas que seu telefone!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "Agora você pode adicionar pessoas em grupos, por meio do número de telefone delas.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "A partir de agora, é mais fácil encontrar os seus contatos favoritos. A busca de contatos tem suporte para alfabetos não-latinos como o cirílico.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Bug fixes including a fix to an issue that would sometimes make it difficult to click on menus. ",
"message": "Correção de erros, incluindo correção da falha que às vezes tornava difícil clicar em menus. ",
"description": "Release notes for v5.40"
},
"WhatsNew__v5.40--2": {
"message": "Thanks to our open source contributors $dsanders11$ and $yusufsahinhamza$ for contributing to these improvements.",
"message": "Agradecimentos para nossos colaboradores de código aberto $dsanders11$ e $yusufsahinhamza$ por contribuir para essas melhorias.",
"description": "Release notes for v5.40",
"placeholders": {
"dsanders11": {

View File

@ -222,7 +222,7 @@
"description": "Shown at the top of the archived conversations list in the left pane"
},
"noArchivedConversations": {
"message": "No archived conversations.",
"message": "Sem conversas arquivadas",
"description": "Shown at the top of the archived conversations list in the left pane if there is no any archived conversation"
},
"archiveConversation": {
@ -6358,11 +6358,11 @@
"description": "Text for an option in Conversation Details Disappearing Messages setting when user previously selected custom time"
},
"DisappearingTimeDialog__label--value": {
"message": "Number",
"message": "Número",
"description": "aria-label for the number select box"
},
"DisappearingTimeDialog__label--units": {
"message": "Unit of time",
"message": "Unidade de tempo",
"description": "aria-label for the units of time select box"
},
"DisappearingTimeDialog__title": {
@ -6812,7 +6812,7 @@
"description": "Second line of the dialog displayed when Windows installer can't close application automatically and needs user intervention to complete the installation."
},
"NSIS__appRunning": {
"message": "$appName$ is running.\nClick OK to close it.\nIf it doesn't close, try closing it manually.",
"message": "$appName$ está a correr.\nClique em OK para o encerrar.\nSe não encerrar, tente encerrá-lo manualmente.",
"description": "The contents of a dialog displayed when Windows installer detect that the application is running and asks user to close it. Note: please keep the line breaks so that the text occupies three separate lines",
"placeholders": {
"appName": {
@ -6822,11 +6822,11 @@
}
},
"NSIS__decompressionFailed": {
"message": "Failed to decompress files. Please try running the installer again.",
"message": "Falha ao descomprimir ficheiros. Por favor, experimente correr o instalador de novo.",
"description": "Displayed when Windows installer cannot decompress application files"
},
"NSIS__uninstallFailed": {
"message": "Failed to uninstall old application files. Please try running the installer again.",
"message": "Falha ao desinstalar os ficheiros da aplicação antiga. Por favor, experimente correr novamente o instalador.",
"description": "Displayed when Windows installer cannot uninstall the old application"
},
"CrashReportDialog__title": {
@ -7013,6 +7013,10 @@
"message": "Adicionar uma história",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Histórias ocultas",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "De momento sem histórias recentes para exibir",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "Escreva uma resposta...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Ainda não existem respostas",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Visualizações",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "História",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Exibir histórias",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Ocultar história",
"description": "Label for menu item to hide the story"
@ -7095,24 +7107,8 @@
"message": "Esta versão contém um número de pequenas funcionalidades e correções de erros de forma a manter o Signal a correr suavemente.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "Estamos a manter as mensagens curtas, a colocar as coisas como carimbos da data/hora na mesma linha do texto. Agora você tem mais espaço na tela para aquele 'olá' rápido para verificar um amigo.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Os pacotes de autocolantes que faltavam apareceram! A área de trabalho agora deverá ser capaz de lidar com todos os pacotes de autocolantes que o seu telemóvel também pode!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "Agora você pode adicionar pessoas a grupos, através do número de telefone delas.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "A partir de agora, é mais fácil encontrar os seus contactos favoritos. A procura de contactos tem suporte para alfabetos não-latinos como o cirílico.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Bug fixes including a fix to an issue that would sometimes make it difficult to click on menus. ",
"message": "Correção de erros incluindo uma correção para um problema que algumas vezes tornava difícil clicar em menus.",
"description": "Release notes for v5.40"
},
"WhatsNew__v5.40--2": {

View File

@ -6174,7 +6174,7 @@
"description": "Title for the contact name spoofing review dialog in groups"
},
"ContactSpoofingReviewDialog__group__description": {
"message": "$count$ membri ai grupului au nume similar, revizuiește membri de mai jos sau alege să iei o decizie.",
"message": "$count$ membri ai grupului au nume similar, revizuiește membri de mai jos sau ia măsuri.",
"description": "Description for the group contact spoofing review dialog"
},
"ContactSpoofingReviewDialog__group__members-header": {
@ -7013,6 +7013,10 @@
"message": "Adaugă o poveste",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Povești ascunse",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "Nu există povești recente",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "Scrie un răspuns...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Niciun răspuns încă",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Vizualizări",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "Poveste",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Afișează povești",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Ascunde povestea",
"description": "Label for menu item to hide the story"
@ -7095,22 +7107,6 @@
"message": "Această versiune conține o serie de mici modificări și remedieri ale unor erori pentru ca Signal să funcționeze fără probleme.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "Menținem mesajele scurte, punând elemente precum marcajele de timp pe aceeași linie cu textul. Acum ai mai mult spațiu pe ecran pentru acel \"salut\" rapid către un prieten.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Nu vor mai exista pachete de autocolante lipsă! Signal Desktop ar trebui să fie acum capabil să gestioneze toate pachetele de autocolante pe care le poate gestiona telefonul tău!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "Acum poți adăuga persoane în grupuri folosind doar numărul lor de telefon.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Contactele tale preferate sunt acum la doar câteva apăsări de taste distanță. Căutarea de contacte acceptă acum alfabete non-latine, cum ar fi cel chirilic.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Remedieri de erori, printre care și o eroare ce făcea dificilă uneori folosirea meniurilor.",
"description": "Release notes for v5.40"

View File

@ -7013,6 +7013,10 @@
"message": "Добавьте историю",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Скрытые истории",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "Нет недавних историй",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "Введите ответ…",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Ещё нет ответов",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Просмотры",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "История",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Показывать истории",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Скрыть историю",
"description": "Label for menu item to hide the story"
@ -7095,22 +7107,6 @@
"message": "Эта версия содержит несколько небольших изменений и исправлений ошибок.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "Мы оставляем короткие сообщения короткими, помещая время и другие элементы на той же строке, что и текст. Теперь у вас на экране есть больше места для того, чтобы быстро узнать у друга, как дела.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Проблемы с недостатком наборов стикеров закончились! Теперь Signal Desktop поддерживает все наборы стикеров, которые поддерживает ваш телефон!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "Теперь вы можете добавлять людей в группы, просто используя их номера телефонов.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Ваши любимые контакты теперь всего в нескольких нажатиях по клавишам от вас. Поиск по контактам теперь поддерживает не латинские алфавиты, например кириллический.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Исправления ошибок, включающие исправление проблемы, из-за которой было иногда сложно нажимать на меню.",
"description": "Release notes for v5.40"

View File

@ -7013,6 +7013,10 @@
"message": "Pridajte príbeh",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Skryté príbehy",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "Momentálne nie sú k dispozícii žiadne najnovšie príbehy",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "Napíšte odpoveď...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Zatiaľ žiadne odpovede",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Pozretia",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "Príbeh",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Zobraziť príbehy",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Skryť príbeh",
"description": "Label for menu item to hide the story"
@ -7095,22 +7107,6 @@
"message": "Táto verzia obsahuje množstvo drobných vylepšení a opráv chýb, ktoré zaisťujú bezproblémový chod systému Signal.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "Krátke správy sú krátke tým, že veci, ako sú časové pečiatky, umiestňujeme na rovnaký riadok ako text. Teraz máte na obrazovke viac miesta na rýchle „ahoj“ na kontrolu priateľa.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Chýbajúce balíčky nálepiek sú preč! Desktop by teraz mal zvládnuť všetky balíčky nálepiek, ktoré dokáže váš telefón!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "Teraz môžete pridávať ľudí do skupín iba pomocou ich telefónneho čísla.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Vaše obľúbené kontakty sú teraz vzdialené len na niekoľko stlačení kláves. Vyhľadávanie kontaktov teraz podporuje aj inú ako latinskú abecedu, ako napríklad cyriliku.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Opravy chýb vrátane opravy problému, ktorý niekedy sťažoval klikanie na ponuky.",
"description": "Release notes for v5.40"

File diff suppressed because it is too large Load Diff

View File

@ -222,7 +222,7 @@
"description": "Shown at the top of the archived conversations list in the left pane"
},
"noArchivedConversations": {
"message": "No archived conversations.",
"message": "Ska biseda të arkivuara.",
"description": "Shown at the top of the archived conversations list in the left pane if there is no any archived conversation"
},
"archiveConversation": {
@ -6358,11 +6358,11 @@
"description": "Text for an option in Conversation Details Disappearing Messages setting when user previously selected custom time"
},
"DisappearingTimeDialog__label--value": {
"message": "Number",
"message": "Numër",
"description": "aria-label for the number select box"
},
"DisappearingTimeDialog__label--units": {
"message": "Unit of time",
"message": "Njësi kohe",
"description": "aria-label for the units of time select box"
},
"DisappearingTimeDialog__title": {
@ -6812,7 +6812,7 @@
"description": "Second line of the dialog displayed when Windows installer can't close application automatically and needs user intervention to complete the installation."
},
"NSIS__appRunning": {
"message": "$appName$ is running.\nClick OK to close it.\nIf it doesn't close, try closing it manually.",
"message": "$appName$ po xhiron.\nKlikoni mbi OK që të mbyllet.\nNëse smbyllet, provoni dorazi.",
"description": "The contents of a dialog displayed when Windows installer detect that the application is running and asks user to close it. Note: please keep the line breaks so that the text occupies three separate lines",
"placeholders": {
"appName": {
@ -6822,11 +6822,11 @@
}
},
"NSIS__decompressionFailed": {
"message": "Failed to decompress files. Please try running the installer again.",
"message": "Su arrit të çngjeshen kartela. Ju lutemi, provoni të xhironi sërish instaluesin.",
"description": "Displayed when Windows installer cannot decompress application files"
},
"NSIS__uninstallFailed": {
"message": "Failed to uninstall old application files. Please try running the installer again.",
"message": "Su arrit të çinstalohen kartela të vjetra aplikacioni. Ju lutemi, xhironi sërish instaluesin.",
"description": "Displayed when Windows installer cannot uninstall the old application"
},
"CrashReportDialog__title": {
@ -7013,6 +7013,10 @@
"message": "Shtoni një histori",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Histori të fshehura",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "Tani për tani ska histori të freskëta për tu shfaqur",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "Shtypni një përgjigje…",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Ende pa përgjigje",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Parje",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "Histori",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Shfaq histori",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Fshihe historinë",
"description": "Label for menu item to hide the story"
@ -7095,28 +7107,12 @@
"message": "Ky version përmban një numër përimtimesh të vockla dhe ndreqje të metash për ta mbajtur të rrjedhshme punën e Signal-it.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "Po i mbajmë mesazhet të shkurtër, duke vënë gjëra të tilla si vulat kohore në të njëjtin rresht me tekstin. Tani keni më tepër hapësirë në ekran për atë “hej” të shpejtë për një shokun tuaj.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Ska më paketa ngjitësish që mungojnë! Desktopi duhet të jetë në gjendje tanimë të trajtojë krejt paketat e ngjitësve që trajton telefoni juaj!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "Tani mund të shtoni persona te grupe duke përdorur thjesht numrin e tyre të telefonit.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Kontaktet tuaja të parapëlqyera tani janë vetëm disa taste larg. Kërkimi i kontakteve tani mbulon alfabete jolatine, bie fjala, cirilik.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Bug fixes including a fix to an issue that would sometimes make it difficult to click on menus. ",
"message": "Ndreqje të metash, përfshi një ndreqje për një problem që ndonjëherë e bënte të vështirë të klikohej te menutë ",
"description": "Release notes for v5.40"
},
"WhatsNew__v5.40--2": {
"message": "Thanks to our open source contributors $dsanders11$ and $yusufsahinhamza$ for contributing to these improvements.",
"message": "Falënderime për kontribuesit tanë në burimin e hapët$dsanders11$ dhe $yusufsahinhamza$, për sjelljen e këtyre përmirësimeve.",
"description": "Release notes for v5.40",
"placeholders": {
"dsanders11": {

View File

@ -221,6 +221,10 @@
"message": "Ове преписке су архивиране и у сандучету ће се појавити само по приспећу нових порука.",
"description": "Shown at the top of the archived conversations list in the left pane"
},
"noArchivedConversations": {
"message": "Нема архивиране преписке.",
"description": "Shown at the top of the archived conversations list in the left pane if there is no any archived conversation"
},
"archiveConversation": {
"message": "Архивирај",
"description": "Shown in menu for conversation, and moves conversation out of main conversation list"
@ -832,11 +836,11 @@
"description": "Shown to separate the types of search results"
},
"findByUsernameHeader": {
"message": "Find by username",
"message": "Пронађите корисничким именом",
"description": "Shown when search could be a valid username, with one sub-item that will kick off the search"
},
"findByPhoneNumberHeader": {
"message": "Find by phone number",
"message": "Пронађите по броју телефона",
"description": "Shown when search could be a valid phone number, with one sub-item that will kick off the search"
},
"at-username": {
@ -970,7 +974,7 @@
"description": "Confirmation dialog message for when the voice recording is interrupted due to app losing focus"
},
"voiceNoteLimit": {
"message": "Voice messages are limited to one hour. Recording will stop if you switch to another app.",
"message": "Говорне поруке су ограничене на 60 минута. Снимање ће се зауставити ако пређете на другу апликацију.",
"description": "Shown in toast to warn user about limited time and that window must be in focus"
},
"voiceNoteMustBeOnlyAttachment": {
@ -1070,7 +1074,7 @@
}
},
"cannotUpdateRequireManualDetail": {
"message": "Signal couldn't update. Visit $url$ to install it manually. Then, $support$ about this problem",
"message": "Signal није успео да се ажурира. Идите на $url$ да би ручно инсталирали. Онда, $support$ о проблему",
"description": "Shown if a general error happened while trying to install update package and manual update is required",
"placeholders": {
"url": {
@ -2402,7 +2406,7 @@
"description": "Shown if request to Signal servers to find username fails"
},
"Toast--failed-to-fetch-phone-number": {
"message": "Failed to fetch phone number. Check your connection and try again.",
"message": "Није могуће налазити број телефона. Проверите да ли сте повезани на интернет и покушајте поново.",
"description": "Shown if request to Signal servers to find phone number fails"
},
"startConversation--username-not-found": {
@ -2416,7 +2420,7 @@
}
},
"startConversation--phone-number-not-found": {
"message": "User not found. \"$phoneNumber$\" is not a Signal user.",
"message": "Корисник није нађен. \"$phoneNumber$\" није корисник Signal-а.",
"description": "Shown in dialog if phone number is not found.",
"placeholders": {
"phoneNumber": {
@ -2426,7 +2430,7 @@
}
},
"startConversation--phone-number-not-valid": {
"message": "User not found. \"$phoneNumber$\" is not a valid phone number.",
"message": "Корисник није нађен. \"$phoneNumber$\" није валидан број телефона.",
"description": "Shown in dialog if phone number is not valid.",
"placeholders": {
"phoneNumber": {
@ -6353,6 +6357,14 @@
"message": "Прилагодити време",
"description": "Text for an option in Conversation Details Disappearing Messages setting when user previously selected custom time"
},
"DisappearingTimeDialog__label--value": {
"message": "Број",
"description": "aria-label for the number select box"
},
"DisappearingTimeDialog__label--units": {
"message": "Јединица времена",
"description": "aria-label for the units of time select box"
},
"DisappearingTimeDialog__title": {
"message": "Прилагодити време",
"description": "Title for the custom disappearing message timeout dialog"
@ -6799,6 +6811,24 @@
"message": "Затворите га ручно и кликните на Покушај да наставите.",
"description": "Second line of the dialog displayed when Windows installer can't close application automatically and needs user intervention to complete the installation."
},
"NSIS__appRunning": {
"message": "$appName$ је у току.\nКликнути OK да би се затворило.\nАко се не затвори, покушајте да га ручно затворите.",
"description": "The contents of a dialog displayed when Windows installer detect that the application is running and asks user to close it. Note: please keep the line breaks so that the text occupies three separate lines",
"placeholders": {
"appName": {
"content": "$1",
"example": "Signal"
}
}
},
"NSIS__decompressionFailed": {
"message": "Декомпримовање датотека није успело. Покушајте поново да покренете инсталатер.",
"description": "Displayed when Windows installer cannot decompress application files"
},
"NSIS__uninstallFailed": {
"message": "Деинсталирање старих датотека апликације није успело. Покушајте поново да покренете инсталатер.",
"description": "Displayed when Windows installer cannot uninstall the old application"
},
"CrashReportDialog__title": {
"message": "Апликација се зауставила",
"description": "A title of the dialog displayed when starting an application after a recent crash"
@ -6983,6 +7013,10 @@
"message": "Додај причу",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Сакривене приче",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "Тренутно нема недавних прича за приказ",
"description": "Description for when there are no stories to show"
@ -7013,6 +7047,10 @@
"message": "Унесите одговор...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Без одговора",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Прегледа",
"description": "Title for views tab"
@ -7033,6 +7071,10 @@
"message": "Прича",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Прикажи приче",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Сакриј причу",
"description": "Label for menu item to hide the story"
@ -7065,28 +7107,22 @@
"message": "This version contains a number of small tweaks and bug fixes to keep Signal running smoothly.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.36--1": {
"message": "Quickly scanning that group chat? There's more room for more messages on the screen at once. We now group sender's messages together if they're close together in time.",
"description": "Release notes for v5.36"
"WhatsNew__v5.40--1": {
"message": "Bug fixes including a fix to an issue that would sometimes make it difficult to click on menus. ",
"description": "Release notes for v5.40"
},
"WhatsNew__v5.36--2": {
"message": "When you perform a Delete for Everyone you'll now see a progress spinner letting you know whether it's been successfully sent or not. If it fails for some reason, you'll be able to retry too!",
"description": "Release notes for v5.36"
},
"WhatsNew__v5.37--1": {
"message": "We're keeping short messages short, by putting stuff like timestamps on the same line as the text. Now you've got more space on the screen for that quick 'hey' to check in on a friend.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Missing sticker packs begone! Desktop should now be able to handle all sticker packs that your phone can!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "You can now add people to groups using just their phone number.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Your favorite contacts are now just a few keystrokes away. Contact search now supports non-Latin alphabets like Cyrillic.",
"description": "Release notes for v5.39"
"WhatsNew__v5.40--2": {
"message": "Хвала нашим сарадницима отвореног кода $dsanders11$ и $yusufsahinhamza$ за допринос овим побољшањима.",
"description": "Release notes for v5.40",
"placeholders": {
"dsanders11": {
"content": "$1",
"example": "dsanders11"
},
"yusufsahinhamza": {
"content": "$2",
"example": "yusufsahinhamza"
}
}
}
}

View File

@ -222,7 +222,7 @@
"description": "Shown at the top of the archived conversations list in the left pane"
},
"noArchivedConversations": {
"message": "No archived conversations.",
"message": "Inga arkiverade konversationer.",
"description": "Shown at the top of the archived conversations list in the left pane if there is no any archived conversation"
},
"archiveConversation": {
@ -464,7 +464,7 @@
"description": "Shown in conversation banner when more than one group member's safety number has changed, but they were previously verified."
},
"debugLogExplanation": {
"message": "When you click Submit, your log will be posted online for 30 days at a unique, unpublished URL. You may Save it locally first.",
"message": "När du klickar på Skicka kommer din logg att läggas upp på nätet i 30 dagar på en unik, opublicerad webbadress. Du kan spara den lokalt först.",
"description": "Description of what will happen with your debug log"
},
"debugLogError": {
@ -476,11 +476,11 @@
"description": "Title of the success page for submitting a debug log"
},
"debugLogSuccessNextSteps": {
"message": "Debug log uploaded. When you contact support, copy the URL below and attach it along with a description of the problem you saw and steps to reproduce it.",
"message": "Felsökningslogg uppladdad. När du kontaktar support kopierar du webbadressen nedan och bifogar den tillsammans med en beskrivning av problemet du såg och steg för att återskapa det.",
"description": "Explanation of next steps to take when submitting debug log"
},
"debugLogLogIsIncomplete": {
"message": "... to see the full log, click Save",
"message": "... för att se hela loggen, klicka på Spara",
"description": "Shown as the text for the copy button on the debug log screen"
},
"debugLogCopy": {
@ -584,11 +584,11 @@
"description": "The string \"yesterday\""
},
"thisWeek": {
"message": "Denna vecka",
"message": "Den här veckan",
"description": "Section header in the media gallery"
},
"thisMonth": {
"message": "Denna månad",
"message": "Den här månaden",
"description": "Section header in the media gallery"
},
"unsupportedAttachment": {
@ -744,7 +744,7 @@
"description": "Item under the Help menu, takes you to an article describing how to install the beta release of Signal Desktop"
},
"signalDesktopPreferences": {
"message": "Signal Desktop-inställningar",
"message": "Inställningar för Signal Desktop",
"description": "Title of the window that pops up with Signal Desktop preferences in it"
},
"signalDesktopStickerCreator": {
@ -836,11 +836,11 @@
"description": "Shown to separate the types of search results"
},
"findByUsernameHeader": {
"message": "Find by username",
"message": "Hitta via användarnamn",
"description": "Shown when search could be a valid username, with one sub-item that will kick off the search"
},
"findByPhoneNumberHeader": {
"message": "Find by phone number",
"message": "Hitta via telefonnummer",
"description": "Shown when search could be a valid phone number, with one sub-item that will kick off the search"
},
"at-username": {
@ -876,7 +876,7 @@
"description": ""
},
"typingAlt": {
"message": "Skrivanimation för denna konversation",
"message": "Skrivanimation för den här konversationen",
"description": "Used as the 'title' attribute for the typing animation"
},
"contactInAddressBook": {
@ -974,7 +974,7 @@
"description": "Confirmation dialog message for when the voice recording is interrupted due to app losing focus"
},
"voiceNoteLimit": {
"message": "Voice messages are limited to one hour. Recording will stop if you switch to another app.",
"message": "Röstmeddelanden är begränsade till en timme. Inspelningen avbryts om du byter till en annan app.",
"description": "Shown in toast to warn user about limited time and that window must be in focus"
},
"voiceNoteMustBeOnlyAttachment": {
@ -1074,7 +1074,7 @@
}
},
"cannotUpdateRequireManualDetail": {
"message": "Signal couldn't update. Visit $url$ to install it manually. Then, $support$ about this problem",
"message": "Signal kunde inte uppdateras. Besök $url$ för att installera det manuellt. Sedan, $support$ om det här problemet",
"description": "Shown if a general error happened while trying to install update package and manual update is required",
"placeholders": {
"url": {
@ -1150,7 +1150,7 @@
"description": "Label for when something is turned off"
},
"deleteWarning": {
"message": "Detta meddelande tas bort från denna enhet.",
"message": "Det här meddelandet tas bort från den här enheten.",
"description": "Text shown in the confirmation dialog for deleting a message locally"
},
"deleteForEveryoneWarning": {
@ -1208,7 +1208,7 @@
}
},
"theirIdentityUnknown": {
"message": "Du har inte utbytt några meddelanden med denna kontakt ännu. Ditt säkerhetsnummer med kontakten är tillgänglig efter det första meddelandet.",
"message": "Du har inte utbytt några meddelanden med den här kontakten ännu. Ditt säkerhetsnummer med kontakten är tillgänglig efter det första meddelandet.",
"description": ""
},
"back": {
@ -1264,7 +1264,7 @@
"description": "Shown in timeline when session is automatically reset, to provide access to a popup info dialog"
},
"ChatRefresh--summary": {
"message": "Signal använder end-to-end-kryptering och det kan behöva uppdatera din chattsession ibland. Detta påverkar inte din chatts säkerhet, men du kan ha missat ett meddelande från denna kontakt och du kan behöva be dem skicka det igen.",
"message": "Signal använder end-to-end-kryptering och det kan behöva uppdatera din chattsession ibland. Detta påverkar inte din chatts säkerhet, men du kan ha missat ett meddelande från den här kontakten och du kan behöva be dem skicka det igen.",
"description": "Shown on explainer dialog available from chat session refreshed timeline events"
},
"ChatRefresh--contactSupport": {
@ -1340,7 +1340,7 @@
"description": "Used in the alt tag for the image shown in a full-screen lightbox view"
},
"imageCaptionIconAlt": {
"message": "Ikon visandes att denna bild har en bildtext",
"message": "Ikon visandes att den här bilden har en bildtext",
"description": "Used for the icon layered on top of an image in message bubbles"
},
"save": {
@ -2170,11 +2170,11 @@
"description": "Shown if the user tries to send more than 64kb of text"
},
"unblockToSend": {
"message": "Sluta blockera denna kontakt för att skicka meddelanden.",
"message": "Sluta blockera den här kontakten för att skicka meddelanden.",
"description": "Brief message shown when trying to message a blocked number"
},
"unblockGroupToSend": {
"message": "Sluta blockera denna grupp för att skicka meddelanden.",
"message": "Sluta blockera den här gruppen för att skicka meddelanden.",
"description": "Brief message shown when trying to message a blocked group"
},
"youChangedTheTimer": {
@ -2362,7 +2362,7 @@
"description": "Label text for system theme"
},
"noteToSelf": {
"message": "Notering till mig själv",
"message": "Egen anteckning",
"description": "Name for the conversation with your own phone number"
},
"noteToSelfHero": {
@ -2406,7 +2406,7 @@
"description": "Shown if request to Signal servers to find username fails"
},
"Toast--failed-to-fetch-phone-number": {
"message": "Failed to fetch phone number. Check your connection and try again.",
"message": "Det gick inte att hämta telefonnummer. Kontrollera din anslutning och försök igen.",
"description": "Shown if request to Signal servers to find phone number fails"
},
"startConversation--username-not-found": {
@ -2420,7 +2420,7 @@
}
},
"startConversation--phone-number-not-found": {
"message": "User not found. \"$phoneNumber$\" is not a Signal user.",
"message": "Användaren hittades inte. \"$phoneNumber$\" är inte en Signal-användare.",
"description": "Shown in dialog if phone number is not found.",
"placeholders": {
"phoneNumber": {
@ -2430,7 +2430,7 @@
}
},
"startConversation--phone-number-not-valid": {
"message": "User not found. \"$phoneNumber$\" is not a valid phone number.",
"message": "Användaren hittades inte. \"$phoneNumber$\" är inte ett giltigt telefonnummer.",
"description": "Shown in dialog if phone number is not valid.",
"placeholders": {
"phoneNumber": {
@ -2508,7 +2508,7 @@
"description": "The header for the members list in the 'set group metadata' left pane screen"
},
"setGroupMetadata__error-message": {
"message": "Denna grupp kunde inte skapas. Kontrollera din anslutning och försök igen.",
"message": "Den här gruppen kunde inte skapas. Kontrollera din anslutning och försök igen.",
"description": "Shown in the modal when we can't create a group"
},
"updateGroupAttributes__title": {
@ -3482,11 +3482,11 @@
}
},
"MessageRequests--message-group": {
"message": "Gå med i denna grupp och dela ditt namn och foto med dess medlemmar? De vet inte att du har sett sina meddelanden förrän du accepterar det.",
"message": "Gå med i den här gruppen och dela ditt namn och foto med dess medlemmar? De vet inte att du har sett sina meddelanden förrän du accepterar det.",
"description": "Shown as the message for a message request in a group"
},
"MessageRequests--message-group-blocked": {
"message": "Ta bort blockeringen av denna grupp och dela ditt namn och foto med dess medlemmar? Du får inte några meddelanden förrän du har avblockerat gruppen.",
"message": "Ta bort blockeringen av den här gruppen och dela ditt namn och foto med dess medlemmar? Du får inte några meddelanden förrän du har avblockerat gruppen.",
"description": "Shown as the message for a message request in a blocked group"
},
"MessageRequests--block": {
@ -3512,7 +3512,7 @@
"description": "Shown as the body in the confirmation modal for unblocking a private message request"
},
"MessageRequests--unblock-group-confirm-body": {
"message": "Gruppmedlemmar kommer att kunna lägga till dig i denna grupp igen.",
"message": "Gruppmedlemmar kommer att kunna lägga till dig i den här gruppen igen.",
"description": "Shown as the body in the confirmation modal for unblocking a group message request"
},
"MessageRequests--block-and-report-spam": {
@ -3560,7 +3560,7 @@
"description": "Shown as the title in the confirmation modal for deleting a private message request"
},
"MessageRequests--delete-direct-confirm-body": {
"message": "Denna konversation tas bort från alla dina enheter.",
"message": "Den här konversationen tas bort från alla dina enheter.",
"description": "Shown as the body in the confirmation modal for deleting a private message request"
},
"MessageRequests--delete-group-confirm-title": {
@ -3582,7 +3582,7 @@
"description": "Shown as a button to let the user delete a group message request"
},
"MessageRequests--delete-group-confirm-body": {
"message": "Du kommer lämnar denna grupp och den tas bort från alla dina enheter.",
"message": "Du kommer lämnar den här gruppen och den tas bort från alla dina enheter.",
"description": "Shown as the body in the confirmation modal for deleting a group message request"
},
"MessageRequests--accept": {
@ -3604,7 +3604,7 @@
}
},
"MessageRequests--profile-sharing--direct": {
"message": "Fortsätt denna konversation med $firstName$ och dela ditt namn och foto med personen? $learnMore$",
"message": "Fortsätt den här konversationen med $firstName$ och dela ditt namn och foto med personen? $learnMore$",
"description": "Shown when user hasn't shared their profile in a 1:1 conversation yet",
"placeholders": {
"firstName": {
@ -3960,7 +3960,7 @@
}
},
"calling__in-another-call-tooltip": {
"message": "Du har redan ett samtal",
"message": "Du är redan i ett samtal",
"description": "Tooltip in disabled notification button when you're on another call"
},
"calling__call-notification__button__call-full-tooltip": {
@ -4126,15 +4126,15 @@
"description": "Shown if we are unable to parse a group link"
},
"GroupV2--join--prompt": {
"message": "Vill du gå med i denna grupp och dela ditt namn och foto med dess medlemmar?",
"message": "Vill du gå med i den här gruppen och dela ditt namn och foto med dess medlemmar?",
"description": "Shown when you click on a group link to confirm"
},
"GroupV2--join--already-in-group": {
"message": "Du är redan i denna grupp.",
"message": "Du är redan i den här gruppen.",
"description": "Shown if you click a group link for a group where you're already a member"
},
"GroupV2--join--already-awaiting-approval": {
"message": "Du har redan begärt godkännande för att gå med i denna grupp.",
"message": "Du har redan begärt godkännande för att gå med i den här gruppen.",
"description": "Shown if you click a group link for a group where you've already requested approval'"
},
"GroupV2--join--unknown-link-version--title": {
@ -4150,7 +4150,7 @@
"description": "Shown if you click a group link and we can't get information about it"
},
"GroupV2--join--link-revoked": {
"message": "Denna grupplänk är inte längre giltig.",
"message": "Den här grupplänken är inte längre giltig.",
"description": "Shown if you click a group link and we can't get information about it"
},
"GroupV2--join--link-forbidden--title": {
@ -4178,7 +4178,7 @@
"description": "The button to cancel request to join the group"
},
"GroupV2--join--cancel-request-to-join--confirmation": {
"message": "Avbryt din förfrågan om att gå med i denna grupp?",
"message": "Avbryt din förfrågan om att gå med i den här gruppen?",
"description": "A confirmation message that shows after you click the button"
},
"GroupV2--join--cancel-request-to-join--yes": {
@ -5196,7 +5196,7 @@
}
},
"GroupV2--admin-approval-bounce--one": {
"message": "$joinerName$ requested and cancelled their request to join via the group link",
"message": "$joinerName$ begärde och avbröt sin förfrågan om att gå med via grupplänken",
"description": "Shown in timeline or conversation preview when v2 group changes",
"placeholders": {
"joinerName": {
@ -5206,7 +5206,7 @@
}
},
"GroupV2--admin-approval-bounce": {
"message": "$joinerName$ requested and cancelled $numberOfRequests$ requests to join via the group link",
"message": "$joinerName$ begärt och avbröt $numberOfRequests$ förfrågningar om att gå med via grupplänken",
"description": "Shown in timeline or conversation preview when v2 group changes",
"placeholders": {
"joinerName": {
@ -5364,7 +5364,7 @@
"description": "Shown in timeline or conversation preview when v2 group changes"
},
"GroupV1--Migration--disabled": {
"message": "Uppgradera den här gruppen för att aktivera nya funktioner som @omnämnanden och administratörer. Medlemmar som inte har delat sitt namn eller foto i denna grupp kommer att bjudas in att gå med. $learnMore$",
"message": "Uppgradera den här gruppen för att aktivera nya funktioner som @omnämnanden och administratörer. Medlemmar som inte har delat sitt namn eller foto i den här gruppen kommer att bjudas in att gå med. $learnMore$",
"description": "Shown instead of composition area when user is forced to migrate a legacy group (GV1).",
"placeholders": {
"learnMore": {
@ -5374,7 +5374,7 @@
}
},
"GroupV1--Migration--was-upgraded": {
"message": "Denna grupp uppgraderades till en Ny grupp.",
"message": "Den här gruppen uppgraderades till en Ny grupp.",
"description": "Shown in timeline when a legacy group (GV1) is upgraded to a new group (GV2)"
},
"GroupV1--Migration--learn-more": {
@ -5406,7 +5406,7 @@
"description": "Shown on Migration popup before GV1 migration"
},
"GroupV1--Migration--info--invited--you": {
"message": "Du måste acceptera en inbjudan för att gå med i denna grupp igen och kommer inte att få gruppmeddelanden förrän du accepterar.",
"message": "Du måste acceptera en inbjudan för att gå med i den här gruppen igen och kommer inte att få gruppmeddelanden förrän du accepterar.",
"description": "Shown on Learn More popup after GV1 migration"
},
"GroupV1--Migration--info--invited--many": {
@ -5414,7 +5414,7 @@
"description": "Shown on Learn More popup after or Migration popup before GV1 migration"
},
"GroupV1--Migration--info--invited--one": {
"message": "Denna medlem måste acceptera en inbjudan att gå med i denna grupp igen och kommer inte att få gruppmeddelanden förrän medlemmen accepterar:",
"message": "Den här medlemmen måste acceptera en inbjudan att gå med i den här gruppen igen och kommer inte att få gruppmeddelanden förrän medlemmen accepterar:",
"description": "Shown on Learn More popup after or Migration popup before GV1 migration"
},
"GroupV1--Migration--info--removed--before--many": {
@ -5422,7 +5422,7 @@
"description": "Shown on Learn More popup after or Migration popup before GV1 migration"
},
"GroupV1--Migration--info--removed--before--one": {
"message": "Denna medlem kan inte gå med i Nya grupper och kommer att tas bort från gruppen:",
"message": "Den här medlemmen kan inte gå med i Nya grupper och kommer att tas bort från gruppen:",
"description": "Shown on Learn More popup after or Migration popup before GV1 migration"
},
"GroupV1--Migration--info--removed--after--many": {
@ -5430,7 +5430,7 @@
"description": "Shown on Learn More popup after or Migration popup before GV1 migration"
},
"GroupV1--Migration--info--removed--after--one": {
"message": "Denna medlem kunde inte gå med i Nya grupper och togs bort från gruppen:",
"message": "Den här medlemmen kunde inte gå med i Nya grupper och togs bort från gruppen:",
"description": "Shown on Learn More popup after or Migration popup before GV1 migration"
},
"GroupV1--Migration--invited--you": {
@ -5598,7 +5598,7 @@
"description": "This is the label for the disappearing messages setting panel"
},
"ConversationDetails--disappearing-messages-info--group": {
"message": "När det är aktiverat, kommer meddelanden som skickats och tagits emot i den här gruppen att försvinna när de har setts.",
"message": "När det är aktiverat försvinner meddelanden som skickas och tas emot i den här gruppen efter att de har setts.",
"description": "This is the info about the disappearing messages setting, in groups"
},
"ConversationDetails--disappearing-messages-info--direct": {
@ -5646,7 +5646,7 @@
"description": "This is a button to block a group"
},
"ConversationDetailsActions--leave-group-must-choose-new-admin": {
"message": "Innan du lämnar måste du välja minst en ny administratör för denna grupp.",
"message": "Innan du lämnar måste du välja minst en ny administratör för den här gruppen.",
"description": "Shown if, before leaving a group, you need to choose an admin"
},
"ConversationDetailsActions--leave-group-modal-title": {
@ -5654,7 +5654,7 @@
"description": "This is the modal title for confirming leaving a group"
},
"ConversationDetailsActions--leave-group-modal-content": {
"message": "Du kommer inte längre att kunna skicka eller ta emot meddelanden i denna grupp.",
"message": "Du kommer inte längre att kunna skicka eller ta emot meddelanden i den här gruppen.",
"description": "This is the modal content for confirming leaving a group"
},
"ConversationDetailsActions--leave-group-modal-confirm": {
@ -5776,7 +5776,7 @@
}
},
"PendingRequests--approve-for": {
"message": "Godkänn begäran från \"$name$\"?",
"message": "Godkänn förfrågan från \"$name$\"?",
"description": "This is the modal content when confirming approving a group request to join",
"placeholders": {
"name": {
@ -5796,7 +5796,7 @@
}
},
"PendingRequests--deny-for--with-link": {
"message": "Deny request from \"$name$\"? They will not be able to request to join via the group link again.",
"message": "Avfärda förfrågan från \"$name$\"? De kommer inte att kunna begära att gå med via grupplänken igen.",
"description": "This is the modal content when confirming denying a group request to join",
"placeholders": {
"name": {
@ -5874,7 +5874,7 @@
"description": "This is the modal button to confirm revoking invites"
},
"PendingRequests--approve": {
"message": "Godkänn begäran",
"message": "Godkänn förfrågan",
"description": "This is the modal button to approve group request to join"
},
"PendingRequests--deny": {
@ -5904,7 +5904,7 @@
"description": "Title of dialog to block a user from requesting to join via the link again"
},
"PendingRequests--block--contents": {
"message": "$name$ will not be able to join or request to join this group via the group link. They can still be added to the group manually.",
"message": "$name$ kommer inte att kunna gå med i eller begära att gå med i den här gruppen via grupplänken. De kan fortfarande läggas till i gruppen manuellt.",
"description": "Details of dialog to block a user from requesting to join via the link again",
"placeholders": {
"name": {
@ -5914,7 +5914,7 @@
}
},
"PendingRequests--block--confirm": {
"message": "Block Request",
"message": "Blockera förfrågan",
"description": "Confirmation button of dialog to block a user from requesting to join via the link again"
},
"AvatarInput--no-photo-label--group": {
@ -6210,7 +6210,7 @@
}
},
"RemoveGroupMemberConfirmation__description__with-link": {
"message": "Remove \"$name$\" from the group? They will not be able to rejoin via the group link.",
"message": "Ta bort \"$name$\" från gruppen? De kommer inte att kunna gå med igen via grupplänken.",
"description": "When confirming the removal of a group member, show this text in the dialog",
"placeholders": {
"name": {
@ -6358,11 +6358,11 @@
"description": "Text for an option in Conversation Details Disappearing Messages setting when user previously selected custom time"
},
"DisappearingTimeDialog__label--value": {
"message": "Number",
"message": "Nummer",
"description": "aria-label for the number select box"
},
"DisappearingTimeDialog__label--units": {
"message": "Unit of time",
"message": "Tidsenhet",
"description": "aria-label for the units of time select box"
},
"DisappearingTimeDialog__title": {
@ -6492,7 +6492,7 @@
"description": "Placeholder for the username field"
},
"ProfileEditor--username--helper": {
"message": "Användarnamn på Signal är valfritt. Om du väljer att skapa ett användarnamn kommer andra Signal-användare att kunna hitta dig genom detta användarnamn och kontakta dig utan att veta ditt telefonnummer.",
"message": "Användarnamn på Signal är valfritt. Om du väljer att skapa ett användarnamn kommer andra Signal-användare att kunna hitta dig via detta användarnamn och kontakta dig utan att veta ditt telefonnummer.",
"description": "Shown on the edit username screen"
},
"ProfileEditor--username--check-characters": {
@ -6766,7 +6766,7 @@
"description": "Label for the see my phone number setting"
},
"Preferences--find-me": {
"message": "Hitta mig efter mitt telefonnummer",
"message": "Hitta mig via mitt telefonnummer",
"description": "Label for the find me by my phone number setting"
},
"Preferences--read-receipts": {
@ -6812,7 +6812,7 @@
"description": "Second line of the dialog displayed when Windows installer can't close application automatically and needs user intervention to complete the installation."
},
"NSIS__appRunning": {
"message": "$appName$ is running.\nClick OK to close it.\nIf it doesn't close, try closing it manually.",
"message": "$appName$ är igång.\nKlicka på OK för att stänga det.\nOm det inte stängs, försök att stänga det manuellt.",
"description": "The contents of a dialog displayed when Windows installer detect that the application is running and asks user to close it. Note: please keep the line breaks so that the text occupies three separate lines",
"placeholders": {
"appName": {
@ -6822,11 +6822,11 @@
}
},
"NSIS__decompressionFailed": {
"message": "Failed to decompress files. Please try running the installer again.",
"message": "Det gick inte att dekomprimera filer. Försök att köra installationsprogrammet igen.",
"description": "Displayed when Windows installer cannot decompress application files"
},
"NSIS__uninstallFailed": {
"message": "Failed to uninstall old application files. Please try running the installer again.",
"message": "Det gick inte att avinstallera gamla programfiler. Försök att köra installationsprogrammet igen.",
"description": "Displayed when Windows installer cannot uninstall the old application"
},
"CrashReportDialog__title": {
@ -6886,7 +6886,7 @@
"description": "Describes what attribute the color picker will change on the text"
},
"MediaEditor__text--highlight": {
"message": "Highlight",
"message": "Markera",
"description": "Describes what attribute the color picker will change on the text"
},
"MediaEditor__text--outline": {
@ -6902,7 +6902,7 @@
"description": "Type of brush to free draw"
},
"MediaEditor__draw--highlighter": {
"message": "Highlighter",
"message": "Markerare",
"description": "Type of brush to free draw"
},
"MediaEditor__draw--thin": {
@ -7013,6 +7013,10 @@
"message": "Lägg till en berättelse",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Dolda berättelser",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "Inga nyliga berättelser att visa just nu",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "Skriv ett svar...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Inga svar ännu",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Visningar",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "Berättelse",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Visa berättelser",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Dölj berättelse",
"description": "Label for menu item to hide the story"
@ -7095,28 +7107,12 @@
"message": "Den här versionen innehåller ett antal små justeringar och felrättningar för att Signal ska fungera smidigt.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "We're keeping short messages short, by putting stuff like timestamps on the same line as the text. Now you've got more space on the screen for that quick 'hey' to check in on a friend.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Missing sticker packs begone! Desktop should now be able to handle all sticker packs that your phone can!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "You can now add people to groups using just their phone number.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Your favorite contacts are now just a few keystrokes away. Contact search now supports non-Latin alphabets like Cyrillic.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Bug fixes including a fix to an issue that would sometimes make it difficult to click on menus. ",
"message": "Felrättningar inklusive en korrigering av ett problem som ibland skulle göra det svårt att klicka på menyer.",
"description": "Release notes for v5.40"
},
"WhatsNew__v5.40--2": {
"message": "Thanks to our open source contributors $dsanders11$ and $yusufsahinhamza$ for contributing to these improvements.",
"message": "Tack till våra bidragsgivare $dsanders11$ och $yusufsahinhamza$ för att de har bidragit till dessa förbättringar med öppen källkod.",
"description": "Release notes for v5.40",
"placeholders": {
"dsanders11": {

View File

@ -5896,11 +5896,11 @@
"description": "Information shown below the invite list"
},
"PendingRequests--block--button": {
"message": "Block request",
"message": "İsteği engelle",
"description": "Shown in timeline if users cancel their request to join a group via a group link"
},
"PendingRequests--block--title": {
"message": "Block request?",
"message": "İstek engellensin mi?",
"description": "Title of dialog to block a user from requesting to join via the link again"
},
"PendingRequests--block--contents": {
@ -7013,6 +7013,10 @@
"message": "Bir hikaye ekle",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Gizlenmiş hikayeler",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "No recent stories to show right now",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "Type a reply...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Henüz yanıt yok",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Görülmeler",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "Story",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Show stories",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Hikayeyi gizle",
"description": "Label for menu item to hide the story"
@ -7095,22 +7107,6 @@
"message": "Bu sürüm Signal'in sorunsuz çalışması için gereken bir takım küçük düzeltme ve hata gidermelerini içerir.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "We're keeping short messages short, by putting stuff like timestamps on the same line as the text. Now you've got more space on the screen for that quick 'hey' to check in on a friend.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Missing sticker packs begone! Desktop should now be able to handle all sticker packs that your phone can!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "You can now add people to groups using just their phone number.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Your favorite contacts are now just a few keystrokes away. Contact search now supports non-Latin alphabets like Cyrillic.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Bug fixes including a fix to an issue that would sometimes make it difficult to click on menus. ",
"description": "Release notes for v5.40"

View File

@ -7013,6 +7013,10 @@
"message": "Додати історію",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "Приховані історії",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "Нових історій немає",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "Відповісти...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "Ще немає відповідей",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "Перегляди",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "Історія",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "Показати історії",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "Сховати історію",
"description": "Label for menu item to hide the story"
@ -7095,22 +7107,6 @@
"message": "Ця версія містить ряд невеликих налаштувань і виправлень помилок для забезпечення безперебійної роботи Signal.",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "Ми зберігаємо короткі повідомлення короткими, розміщуючи такі речі, як позначки часу, в одному рядку з текстом. Тепер у вас є більше місця на екрані для швидкого «привіт», щоб дізнатись, як себе має ваш друг.",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "Зниклі стікер-паки знайшлись! Відтепер комп'ютерна версія застосунку підтримує усі стікер-паки, що й телефон!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "Відтепер можна додавати користувачів до груп за їхнім номером телефону.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "Ваші улюблені контакти усього у декількох натисканнях на клавіатуру від вас. Пошук контактів відтепер підтримує не лише латинські літери, як-от кирилицю.",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "Виправлення помилок, зокрема помилки, яка інколи призводила до важкостей з клацанням на меню.",
"description": "Release notes for v5.40"

View File

@ -7013,6 +7013,10 @@
"message": "新增一個報導",
"description": "Description hint to add a story"
},
"Stories__hidden-stories": {
"message": "已隱藏的限時動態",
"description": "Button label to go to hidden stories pane"
},
"Stories__list-empty": {
"message": "目前沒有可顯示的近期報導",
"description": "Description for when there are no stories to show"
@ -7043,6 +7047,10 @@
"message": "輸入回覆...",
"description": "Placeholder text for the story reply modal"
},
"StoryViewsNRepliesModal__no-replies": {
"message": "未有回覆",
"description": "Placeholder text for when there are no replies"
},
"StoryViewsNRepliesModal__tab--views": {
"message": "檢視",
"description": "Title for views tab"
@ -7063,6 +7071,10 @@
"message": "報導",
"description": "aria-label for the story list button"
},
"StoryListItem__unhide": {
"message": "顯示限時動態",
"description": "Label for menu item to un-hide the story"
},
"StoryListItem__hide": {
"message": "隱藏報導",
"description": "Label for menu item to hide the story"
@ -7095,22 +7107,6 @@
"message": "此版本包含許多小調整和錯誤修復,以維持 Signal 穩定運作。",
"description": "Release notes for releases that only include bug fixes"
},
"WhatsNew__v5.37--1": {
"message": "我們透過將時間戳之類的內容與文本放在同一行來保持簡短的訊息。 現在,你在螢幕上有更多空間可以快速說“嘿”與確認朋友。",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.37--2": {
"message": "想念遺失的貼圖包! 電腦版本現在能夠處理你的手機可以處理的所有貼圖包!",
"description": "Release notes for v5.37"
},
"WhatsNew__v5.39--1": {
"message": "你現在可以使用電話號碼將成員新增到群組。",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.39--2": {
"message": "你最喜歡的聯絡人現在只需幾個按鍵即可。 搜索聯絡人現在支援非拉丁字母,例如塞里爾字母。",
"description": "Release notes for v5.39"
},
"WhatsNew__v5.40--1": {
"message": "錯誤修復,包括修復有時難以點擊選單的問題。",
"description": "Release notes for v5.40"

View File

@ -489,7 +489,6 @@ async function createWindow() {
__dirname,
usePreloadBundle ? '../preload.bundle.js' : '../preload.js'
),
nativeWindowOpen: true,
spellcheck: await getSpellCheckSetting(),
backgroundThrottling: isThrottlingEnabled,
enablePreferredSizeMode: true,
@ -1288,6 +1287,21 @@ function showPermissionsPopupWindow(forCalling: boolean, forCamera: boolean) {
});
}
const runSQLCorruptionHandler = async () => {
// This is a glorified event handler. Normally, this promise never resolves,
// but if there is a corruption error triggered by any query that we run
// against the database - the promise will resolve and we will call
// `onDatabaseError`.
const error = await sql.whenCorrupted();
getLogger().error(
'Detected sql corruption in main process. ' +
`Restarting the application immediately. Error: ${error.message}`
);
await onDatabaseError(error.stack || error.message);
};
async function initializeSQL(
userDataPath: string
): Promise<{ ok: true; error: undefined } | { ok: false; error: Error }> {
@ -1332,6 +1346,9 @@ async function initializeSQL(
sqlInitTimeEnd = Date.now();
}
// Only if we've initialized things successfully do we set up the corruption handler
runSQLCorruptionHandler();
return { ok: true, error: undefined };
}
@ -1347,44 +1364,32 @@ const onDatabaseError = async (error: string) => {
const buttonIndex = dialog.showMessageBoxSync({
buttons: [
getLocale().i18n('copyErrorAndQuit'),
getLocale().i18n('deleteAndRestart'),
getLocale().i18n('copyErrorAndQuit'),
],
defaultId: 0,
defaultId: 1,
cancelId: 1,
detail: redactAll(error),
message: getLocale().i18n('databaseError'),
noLink: true,
type: 'error',
});
if (buttonIndex === 0) {
if (buttonIndex === 1) {
clipboard.writeText(`Database startup error:\n\n${redactAll(error)}`);
} else {
await sql.removeDB();
userConfig.remove();
getLogger().error(
'onDatabaseError: Requesting immediate restart after quit'
);
app.relaunch();
}
getLogger().error('onDatabaseError: Quitting application');
app.exit(1);
};
const runSQLCorruptionHandler = async () => {
// This is a glorified event handler. Normally, this promise never resolves,
// but if there is a corruption error triggered by any query that we run
// against the database - the promise will resolve and we will call
// `onDatabaseError`.
const error = await sql.whenCorrupted();
getLogger().error(
'Detected sql corruption in main process. ' +
`Restarting the application immediately. Error: ${error.message}`
);
await onDatabaseError(error.stack || error.message);
};
runSQLCorruptionHandler();
let sqlInitPromise:
| Promise<{ ok: true; error: undefined } | { ok: false; error: Error }>
| undefined;

View File

@ -9,6 +9,15 @@ import type {
import { isAbsolute, normalize } from 'path';
import { existsSync, realpathSync } from 'fs';
import {
getAvatarsPath,
getBadgesPath,
getDraftPath,
getPath,
getStickersPath,
getTempPath,
getUpdateCachePath,
} from '../ts/util/attachments';
type CallbackType = (response: string | ProtocolResponse) => void;
@ -51,6 +60,17 @@ function _createFileHandler({
installPath: string;
isWindows: boolean;
}) {
const allowedRoots = [
userDataPath,
installPath,
getAvatarsPath(userDataPath),
getBadgesPath(userDataPath),
getDraftPath(userDataPath),
getPath(userDataPath),
getStickersPath(userDataPath),
getTempPath(userDataPath),
getUpdateCachePath(userDataPath),
];
return (request: ProtocolRequest, callback: CallbackType): void => {
let targetPath;
@ -95,24 +115,17 @@ function _createFileHandler({
return;
}
if (
!properCasing.startsWith(
isWindows ? userDataPath.toLowerCase() : userDataPath
) &&
!properCasing.startsWith(
isWindows ? installPath.toLowerCase() : installPath
)
) {
console.log(
`Warning: denying request to path '${realPath}' (userDataPath: '${userDataPath}', installPath: '${installPath}')`
);
callback({ error: -10 });
return;
for (const root of allowedRoots) {
if (properCasing.startsWith(isWindows ? root.toLowerCase() : root)) {
callback({ path: realPath });
return;
}
}
callback({
path: realPath,
});
console.log(
`Warning: denying request to path '${realPath}' (allowedRoots: '${allowedRoots}')`
);
callback({ error: -10 });
};
}

View File

@ -0,0 +1 @@
<svg fill="none" height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="m23.2028 3.06066c.5857.58579.5857 1.53553 0 2.12132l-11.0104 11.01042 11.0104 11.0104c.5858.5858.5858 1.5356 0 2.1213-.5858.5858-1.5355.5858-2.1213 0l-12.02084-12.0208c-.3055-.3055-.45168-.71-.43852-1.1102-.01354-.4007.13262-.8058.43847-1.1116l12.02079-12.02084c.5858-.58579 1.5356-.58579 2.1214 0z" fill="#000" fill-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 463 B

View File

@ -0,0 +1 @@
<svg fill="none" height="32" viewBox="0 0 32 32" width="32" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="m9.06066 3.06066c-.58578.58579-.58578 1.53553 0 2.12132l11.01044 11.01042-11.01048 11.0104c-.58579.5858-.58579 1.5356 0 2.1213.58578.5858 1.53558.5858 2.12128 0l12.0209-12.0208c.3055-.3055.4516-.71.4385-1.1102.0135-.4007-.1326-.8058-.4385-1.1116l-12.0208-12.02084c-.5858-.58579-1.53555-.58579-2.12134 0z" fill="#000" fill-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 468 B

View File

@ -4,7 +4,7 @@
"description": "Private messaging from your desktop",
"desktopName": "signal.desktop",
"repository": "https://github.com/signalapp/Signal-Desktop.git",
"version": "5.41.0-beta.1",
"version": "5.43.0-beta.1",
"license": "AGPL-3.0-only",
"author": {
"name": "Signal Messenger, LLC",
@ -80,7 +80,7 @@
"@evanhahn/lottie-web-light": "5.8.1",
"@popperjs/core": "2.9.2",
"@react-spring/web": "9.4.1",
"@signalapp/libsignal-client": "0.15.0",
"@signalapp/libsignal-client": "0.16.0",
"@sindresorhus/is": "0.8.0",
"@types/fabric": "4.5.3",
"abort-controller": "3.0.0",
@ -164,7 +164,7 @@
"redux-ts-utils": "3.2.2",
"reselect": "4.1.2",
"rimraf": "2.6.2",
"ringrtc": "https://github.com/signalapp/signal-ringrtc-node.git#0464fe30a74b0617c976b66528c9a033fa80ad38",
"ringrtc": "https://github.com/signalapp/signal-ringrtc-node.git#ccb71f118a8f8962addc53333730c77b287d7e43",
"rotating-file-stream": "2.1.5",
"sanitize.css": "11.0.0",
"semver": "5.4.1",
@ -189,7 +189,7 @@
"@chanzuckerberg/axe-storybook-testing": "3.0.2",
"@electron/fuses": "1.5.0",
"@mixer/parallel-prettier": "2.0.1",
"@signalapp/mock-server": "1.5.0-rc.3",
"@signalapp/mock-server": "1.5.1",
"@storybook/addon-actions": "5.1.11",
"@storybook/addon-knobs": "5.1.11",
"@storybook/addons": "5.1.11",
@ -221,7 +221,7 @@
"@types/mkdirp": "0.5.2",
"@types/mocha": "9.0.0",
"@types/mustache": "4.1.2",
"@types/node": "16.11.26",
"@types/node": "16.11.29",
"@types/node-fetch": "2.5.7",
"@types/node-forge": "0.9.5",
"@types/normalize-path": "3.0.0",
@ -264,10 +264,10 @@
"cross-env": "5.2.0",
"css-loader": "3.2.0",
"debug": "4.3.3",
"electron": "17.3.1",
"electron-builder": "23.0.1",
"electron": "18.1.0",
"electron-builder": "23.0.8",
"electron-mocha": "11.0.2",
"electron-notarize": "0.1.1",
"electron-notarize": "1.2.1",
"esbuild": "0.14.28",
"eslint": "7.7.0",
"eslint-config-airbnb-typescript-prettier": "4.2.0",
@ -309,7 +309,7 @@
"sharp/color/color-string": "1.7.4"
},
"engines": {
"node": "16.13.0"
"node": "16.13.2"
},
"build": {
"appId": "org.whispersystems.signal-desktop",

View File

@ -1,107 +0,0 @@
diff --git a/node_modules/app-builder-lib/out/asar/asar.d.ts b/node_modules/app-builder-lib/out/asar/asar.d.ts
index be27052..97db603 100644
--- a/node_modules/app-builder-lib/out/asar/asar.d.ts
+++ b/node_modules/app-builder-lib/out/asar/asar.d.ts
@@ -1,3 +1,3 @@
-export declare function readAsarHeader(archive: string): Promise<ReadAsarHeader>;
-export declare function readAsar(archive: string): Promise<AsarFilesystem>;
+export declare function readAsarHeader(archive: string): Promise<unknown>;
+export declare function readAsar(archive: string): Promise<unknown>;
export declare function readAsarJson(archive: string, file: string): Promise<any>;
diff --git a/node_modules/app-builder-lib/out/asar/integrity.d.ts b/node_modules/app-builder-lib/out/asar/integrity.d.ts
index 01da9f4..094c175 100644
--- a/node_modules/app-builder-lib/out/asar/integrity.d.ts
+++ b/node_modules/app-builder-lib/out/asar/integrity.d.ts
@@ -1,5 +1,4 @@
/// <reference types="node" />
-import { NodeIntegrity } from "./asar";
export interface AsarIntegrityOptions {
readonly resourcesPath: string;
readonly resourcesRelativePath: string;
@@ -12,5 +11,5 @@ export interface AsarIntegrity {
[key: string]: HeaderHash;
}
export declare function computeData({ resourcesPath, resourcesRelativePath }: AsarIntegrityOptions): Promise<AsarIntegrity>;
-export declare function hashFile(file: string, blockSize?: number): Promise<NodeIntegrity>;
-export declare function hashFileContents(contents: Buffer | string, blockSize?: number): NodeIntegrity;
+export declare function hashFile(file: string, blockSize?: number): Promise<unknown>;
+export declare function hashFileContents(contents: Buffer | string, blockSize?: number): unknown;
diff --git a/node_modules/app-builder-lib/out/targets/LinuxTargetHelper.js b/node_modules/app-builder-lib/out/targets/LinuxTargetHelper.js
index ffcc8bd..bafab0e 100644
--- a/node_modules/app-builder-lib/out/targets/LinuxTargetHelper.js
+++ b/node_modules/app-builder-lib/out/targets/LinuxTargetHelper.js
@@ -88,7 +88,7 @@ class LinuxTargetHelper {
// https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#exec-variables
const execCodes = ["%f", "%u", "%F", "%U"];
if (executableArgs == null || executableArgs.findIndex(arg => execCodes.includes(arg)) === -1) {
- exec += " %U";
+ exec += " --no-sandbox %U";
}
}
const desktopMeta = {
diff --git a/node_modules/app-builder-lib/templates/linux/after-install.tpl b/node_modules/app-builder-lib/templates/linux/after-install.tpl
index 1536059..555f8f5 100644
--- a/node_modules/app-builder-lib/templates/linux/after-install.tpl
+++ b/node_modules/app-builder-lib/templates/linux/after-install.tpl
@@ -3,8 +3,5 @@
# Link to the binary
ln -sf '/opt/${sanitizedProductName}/${executable}' '/usr/bin/${executable}'
-# SUID chrome-sandbox for Electron 5+
-chmod 4755 '/opt/${sanitizedProductName}/chrome-sandbox' || true
-
update-mime-database /usr/share/mime || true
update-desktop-database /usr/share/applications || true
diff --git a/node_modules/app-builder-lib/templates/nsis/include/allowOnlyOneInstallerInstance.nsh b/node_modules/app-builder-lib/templates/nsis/include/allowOnlyOneInstallerInstance.nsh
index cc77993..ac36618 100644
--- a/node_modules/app-builder-lib/templates/nsis/include/allowOnlyOneInstallerInstance.nsh
+++ b/node_modules/app-builder-lib/templates/nsis/include/allowOnlyOneInstallerInstance.nsh
@@ -40,7 +40,7 @@
${nsProcess::FindProcess} "${_FILE}" ${_ERR}
!else
# find process owned by current user
- nsExec::Exec `cmd /c tasklist /FI "USERNAME eq %USERNAME%" /FI "IMAGENAME eq ${_FILE}" | find "${_FILE}"`
+ nsExec::Exec `cmd /c tasklist /FI "USERNAME eq %USERNAME%" /FI "IMAGENAME eq ${_FILE}" | %SYSTEMROOT%\System32\find.exe "${_FILE}"`
Pop ${_ERR}
!endif
!macroend
diff --git a/node_modules/app-builder-lib/templates/nsis/include/extractAppPackage.nsh b/node_modules/app-builder-lib/templates/nsis/include/extractAppPackage.nsh
index d96a655..f5470bf 100644
--- a/node_modules/app-builder-lib/templates/nsis/include/extractAppPackage.nsh
+++ b/node_modules/app-builder-lib/templates/nsis/include/extractAppPackage.nsh
@@ -113,13 +113,21 @@
# Try copying a few times before asking for a user action.
Goto RetryExtract7za
${else}
- MessageBox MB_RETRYCANCEL|MB_ICONEXCLAMATION "$(appCannotBeClosed)" /SD IDCANCEL IDRETRY RetryExtract7za
+ MessageBox MB_RETRYCANCEL|MB_ICONEXCLAMATION "$(appCannotBeClosed)" /SD IDRETRY IDCANCEL AbortExtract7za
${endIf}
# As an absolutely last resort after a few automatic attempts and user
# intervention - we will just overwrite everything with `Nsis7z::Extract`
# even though it is not atomic and will ignore errors.
+
+ # Clear the temporary folder first to make sure we don't use twice as
+ # much disk space.
+ RMDir /r "$PLUGINSDIR\7z-out"
+
Nsis7z::Extract "${FILE}"
+ Goto DoneExtract7za
+
+ AbortExtract7za:
Quit
RetryExtract7za:
diff --git a/node_modules/app-builder-lib/templates/nsis/messages.yml b/node_modules/app-builder-lib/templates/nsis/messages.yml
index 6527c99..695444c 100644
--- a/node_modules/app-builder-lib/templates/nsis/messages.yml
+++ b/node_modules/app-builder-lib/templates/nsis/messages.yml
@@ -45,7 +45,7 @@ x64WinRequired:
es: Windows de 64 bits es requerido
da: 64-bit Windows er påkrævet
appRunning:
- en: "${PRODUCT_NAME} is running.\nClick OK to close it."
+ en: "${PRODUCT_NAME} is running.\nClick OK to close it.\nIf it doesn't close, try closing it manually."
de: "${PRODUCT_NAME} ist geöffnet. \nKlicken Sie zum Schliessen auf «OK»."
it: "${PRODUCT_NAME} è in esecuzione. \nPremi OK per chiudere."
fr: "${PRODUCT_NAME} est en cours dutilisation. \nCliquez sur «OK» pour fermer ce programme."

View File

@ -0,0 +1,39 @@
diff --git a/node_modules/app-builder-lib/out/targets/LinuxTargetHelper.js b/node_modules/app-builder-lib/out/targets/LinuxTargetHelper.js
index ffcc8bd..bafab0e 100644
--- a/node_modules/app-builder-lib/out/targets/LinuxTargetHelper.js
+++ b/node_modules/app-builder-lib/out/targets/LinuxTargetHelper.js
@@ -88,7 +88,7 @@ class LinuxTargetHelper {
// https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#exec-variables
const execCodes = ["%f", "%u", "%F", "%U"];
if (executableArgs == null || executableArgs.findIndex(arg => execCodes.includes(arg)) === -1) {
- exec += " %U";
+ exec += " --no-sandbox %U";
}
}
const desktopMeta = {
diff --git a/node_modules/app-builder-lib/templates/linux/after-install.tpl b/node_modules/app-builder-lib/templates/linux/after-install.tpl
index 1536059..555f8f5 100644
--- a/node_modules/app-builder-lib/templates/linux/after-install.tpl
+++ b/node_modules/app-builder-lib/templates/linux/after-install.tpl
@@ -3,8 +3,5 @@
# Link to the binary
ln -sf '/opt/${sanitizedProductName}/${executable}' '/usr/bin/${executable}'
-# SUID chrome-sandbox for Electron 5+
-chmod 4755 '/opt/${sanitizedProductName}/chrome-sandbox' || true
-
update-mime-database /usr/share/mime || true
update-desktop-database /usr/share/applications || true
diff --git a/node_modules/app-builder-lib/templates/nsis/messages.yml b/node_modules/app-builder-lib/templates/nsis/messages.yml
index 6527c99..695444c 100644
--- a/node_modules/app-builder-lib/templates/nsis/messages.yml
+++ b/node_modules/app-builder-lib/templates/nsis/messages.yml
@@ -45,7 +45,7 @@ x64WinRequired:
es: Windows de 64 bits es requerido
da: 64-bit Windows er påkrævet
appRunning:
- en: "${PRODUCT_NAME} is running.\nClick OK to close it."
+ en: "${PRODUCT_NAME} is running.\nClick OK to close it.\nIf it doesn't close, try closing it manually."
de: "${PRODUCT_NAME} ist geöffnet. \nKlicken Sie zum Schliessen auf «OK»."
it: "${PRODUCT_NAME} è in esecuzione. \nPremi OK per chiudere."
fr: "${PRODUCT_NAME} est en cours dutilisation. \nCliquez sur «OK» pour fermer ce programme."

View File

@ -779,7 +779,7 @@
width: calc(100% + 24px);
outline: none;
margin-top: -10px;
margin-top: -8px;
margin-bottom: 5px;
overflow: hidden;
@ -2132,103 +2132,6 @@ button.ConversationDetails__action-button {
color: $color-gray-45;
}
// Module: Conversation Hero
.module-conversation-hero {
padding: 32px 0 28px 0;
text-align: center;
&__avatar {
margin-bottom: 12px;
}
&__profile-name {
@include font-title-2;
margin-bottom: 2px;
@include light-theme {
color: $color-gray-90;
}
@include dark-theme {
color: $color-gray-05;
}
}
&__with {
@include font-body-2;
margin: 0 auto;
margin-bottom: 16px;
max-width: 500px;
@include light-theme {
color: $color-gray-60;
}
@include dark-theme {
color: $color-gray-25;
}
}
&__membership {
@include font-body-2;
padding: 0 16px;
@include light-theme {
color: $color-gray-60;
}
@include dark-theme {
color: $color-gray-25;
}
&__name {
@include font-body-2-bold;
}
}
&__message-request-warning {
@include font-body-2;
&__message {
display: flex;
margin-bottom: 12px;
align-items: center;
justify-content: center;
user-select: none;
@include light-theme {
color: $color-gray-60;
}
@include dark-theme {
color: $color-gray-25;
}
&::before {
content: '';
display: block;
height: 14px;
margin-right: 8px;
width: 14px;
@include light-theme {
@include color-svg(
'../images/icons/v2/info-outline-24.svg',
$color-gray-60
);
}
@include dark-theme {
@include color-svg(
'../images/icons/v2/info-solid-24.svg',
$color-gray-25
);
}
}
}
}
}
// Module: Message Request Actions
.module-message-request-actions {
@ -2589,30 +2492,10 @@ button.ConversationDetails__action-button {
left: 6px;
}
.module-image--soft-corners {
border-radius: 4px;
}
.module-image--cropped {
overflow: hidden;
}
.module-image--curved-top-left {
border-top-left-radius: 18px;
}
.module-image--curved-top-right {
border-top-right-radius: 18px;
}
.module-image--curved-bottom-left {
border-bottom-left-radius: 18px;
}
.module-image--curved-bottom-right {
border-bottom-right-radius: 18px;
}
.module-image--small-curved-top-left {
border-top-left-radius: 10px;
}
.module-image__border-overlay {
@include button-reset;
@ -7291,6 +7174,8 @@ button.module-image__border-overlay:focus {
select {
@include font-body-1;
background: $color-gray-75;
color: $color-gray-02;
-webkit-appearance: none;
border-radius: 4px;
border: 1px solid $color-gray-45;

View File

@ -40,6 +40,7 @@ $color-black-alpha-05: rgba($color-black, 0.05);
$color-black-alpha-06: rgba($color-black, 0.06);
$color-black-alpha-08: rgba($color-black, 0.08);
$color-black-alpha-12: rgba($color-black, 0.12);
$color-black-alpha-16: rgba($color-black, 0.16);
$color-black-alpha-20: rgba($color-black, 0.2);
$color-black-alpha-30: rgba($color-black, 0.3);
$color-black-alpha-40: rgba($color-black, 0.4);
@ -49,6 +50,8 @@ $color-black-alpha-70: rgba($color-black, 0.7);
$color-black-alpha-80: rgba($color-black, 0.8);
$color-black-alpha-90: rgba($color-black, 0.9);
$color-transparent: rgba(0, 0, 0, 0);
$color-ultramarine-dark: #1851b4;
$color-ultramarine-icon: #3a76f0;
$color-ultramarine-light: #6191f3;

View File

@ -0,0 +1,125 @@
// Copyright 2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
.module-conversation-hero {
padding: 32px 0 28px 0;
text-align: center;
&__avatar {
margin-bottom: 12px;
}
&__profile-name {
@include font-title-2;
margin-bottom: 2px;
@include light-theme {
color: $color-gray-90;
}
@include dark-theme {
color: $color-gray-05;
}
}
&__with {
@include font-body-2;
margin: 0 auto;
margin-bottom: 16px;
max-width: 500px;
@include light-theme {
color: $color-gray-60;
}
@include dark-theme {
color: $color-gray-25;
}
}
&__membership {
@include font-body-2;
padding: 0 16px;
@include light-theme {
color: $color-gray-60;
}
@include dark-theme {
color: $color-gray-25;
}
&__name {
@include font-body-2-bold;
}
}
&__message-request-warning {
@include font-body-2;
&__message {
display: flex;
margin-bottom: 12px;
align-items: center;
justify-content: center;
user-select: none;
@include light-theme {
color: $color-gray-60;
}
@include dark-theme {
color: $color-gray-25;
}
&::before {
content: '';
display: block;
height: 14px;
margin-right: 8px;
width: 14px;
@include light-theme {
@include color-svg(
'../images/icons/v2/info-outline-24.svg',
$color-gray-60
);
}
@include dark-theme {
@include color-svg(
'../images/icons/v2/info-solid-24.svg',
$color-gray-25
);
}
}
}
}
&__linkNotification {
@include font-body-2;
text-align: center;
user-select: none;
&::before {
content: '';
display: inline-block;
height: 16px;
margin-right: 8px;
vertical-align: middle;
width: 16px;
@include light-theme {
@include color-svg(
'../images/icons/v2/info-outline-24.svg',
$color-gray-60
);
}
@include dark-theme {
@include color-svg(
'../images/icons/v2/info-solid-24.svg',
$color-gray-25
);
}
}
}
}

View File

@ -97,6 +97,7 @@
@include scrollbar;
flex: 1;
overflow-y: overlay;
padding: 0 10px;
&--empty {
@include font-body-1;

View File

@ -3,7 +3,6 @@
.StoryImage {
align-items: center;
border-radius: 8px;
display: flex;
height: 100%;
justify-content: center;
@ -23,7 +22,7 @@
width: 100%;
}
&__spinner-container {
&__overlay-container {
align-items: center;
display: flex;
height: 100%;

View File

@ -6,8 +6,8 @@
align-items: center;
border-radius: 10px;
display: flex;
padding: 0 20px;
height: 96px;
padding: 0 10px;
width: 100%;
@include keyboard-mode {

View File

@ -3,8 +3,7 @@
.StoryViewer {
&__overlay {
background: $color-gray-95;
filter: blur(160px);
background-size: contain;
height: 100vh;
left: 0;
position: absolute;
@ -15,6 +14,8 @@
&__content {
align-items: center;
backdrop-filter: blur(90px);
background: $color-black-alpha-20;
display: flex;
flex-direction: column;
height: 100vh;
@ -29,16 +30,19 @@
&__close-button {
@include button-reset;
@include modal-close-button;
right: 28px;
top: var(--title-bar-drag-area-height);
z-index: $z-index-above-base;
}
&__more {
@include button-reset;
height: 24px;
position: absolute;
right: 48px;
right: 80px;
top: var(--title-bar-drag-area-height);
width: 24px;
z-index: $z-index-above-base;
@include color-svg('../images/icons/v2/more-horiz-24.svg', $color-white);
@ -51,14 +55,10 @@
&__container {
flex-grow: 1;
margin-top: 36px;
overflow: hidden;
position: relative;
z-index: $z-index-base;
}
&__story {
border-radius: 12px;
max-height: 100%;
outline: none;
width: auto;
@ -67,11 +67,12 @@
&__meta {
bottom: 0;
left: 50%;
padding: 16px;
padding: 0 16px;
position: absolute;
transform: translateX(-50%);
width: 284px;
z-index: $z-index-above-base;
min-width: 284px;
width: 56.25vh;
z-index: $z-index-above-above-base;
&--group-avatar {
margin-left: -8px;
@ -91,11 +92,13 @@
}
&__caption {
@include font-body-1-bold;
@include font-body-1;
color: $color-gray-05;
padding: 4px 0;
margin-bottom: 24px;
&__overlay {
@include button-reset;
background: $color-black-alpha-60;
height: 100%;
left: 0;
@ -107,11 +110,9 @@
}
&__actions {
align-items: center;
display: flex;
justify-content: center;
margin-bottom: 32px;
min-height: 52px;
min-height: 60px;
}
&__reply {
@ -144,4 +145,77 @@
height: 100%;
}
}
&__animated-emojis {
height: 100vh;
position: absolute;
width: 100%;
z-index: $z-index-above-base;
}
&__arrow {
@include button-reset;
align-items: center;
display: flex;
height: 100vh;
position: absolute;
width: 25%;
z-index: $z-index-above-above-base;
&::before {
content: '';
height: 24px;
opacity: 0;
width: 24px;
transition: opacity 200ms ease-in-out;
}
&--left {
justify-content: flex-start;
left: 0;
&::before {
margin-left: 24px;
@include color-svg(
'../images/icons/v2/arrow-left-32.svg',
$color-white
);
}
}
&--right {
justify-content: flex-end;
right: 0;
&::before {
margin-right: 24px;
@include color-svg(
'../images/icons/v2/arrow-right-32.svg',
$color-white
);
}
}
&--visible::before {
opacity: 1;
}
}
&__protection {
position: absolute;
width: 100%;
z-index: $z-index-base;
&--top {
background: linear-gradient($color-black-alpha-16, $color-transparent);
top: 0;
height: 80px;
}
&--bottom {
background: linear-gradient($color-transparent, $color-black-alpha-40);
bottom: 0;
height: 180px;
}
}
}

View File

@ -3,9 +3,27 @@
.StoryViewsNRepliesModal {
min-width: 320px;
overflow: hidden;
&--group {
min-height: 360px;
display: flex;
flex-direction: column;
min-height: 400px;
}
&__replies {
flex: 1;
max-height: 75vh;
overflow-y: overlay;
&--none {
align-items: center;
color: $color-gray-45;
display: flex;
flex: 1;
justify-content: center;
user-select: none;
}
}
&__overlay-container {

View File

@ -219,13 +219,6 @@
);
}
&--icon-unsynced::before {
@include system-message-icon(
'../images/icons/v2/info-outline-24.svg',
'../images/icons/v2/info-solid-24.svg'
);
}
&--icon-verified::before {
@include system-message-icon(
'../images/icons/v2/check-24.svg',

View File

@ -6,7 +6,6 @@
&__story {
align-items: center;
border-radius: 12px;
display: flex;
flex-direction: column;
height: 1280px;

View File

@ -57,6 +57,7 @@
@import './components/ContextMenu.scss';
@import './components/ConversationDetails.scss';
@import './components/ConversationHeader.scss';
@import './components/ConversationHero.scss';
@import './components/ConversationView.scss';
@import './components/CustomColorEditor.scss';
@import './components/CustomizingPreferredReactionsModal.scss';

25
ts/MessageSeenStatus.ts Normal file
View File

@ -0,0 +1,25 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
/**
* `SeenStatus` represents either the idea that a message doesn't need to track its seen
* status, or the standard unseen/seen status pair.
*
* Unseen is a lot like unread - except that unseen messages only affect the placement
* of the last seen indicator and the count it shows. Unread messages will affect the
* left pane badging for conversations, as well as the overall badge count on the app.
*/
export enum SeenStatus {
NotApplicable = 0,
Unseen = 1,
Seen = 2,
}
const STATUS_NUMBERS: Record<SeenStatus, number> = {
[SeenStatus.NotApplicable]: 0,
[SeenStatus.Unseen]: 1,
[SeenStatus.Seen]: 2,
};
export const maxSeenStatus = (a: SeenStatus, b: SeenStatus): SeenStatus =>
STATUS_NUMBERS[a] > STATUS_NUMBERS[b] ? a : b;

View File

@ -1859,9 +1859,9 @@ export class SignalProtocolStore extends EventsMixin {
});
}
getAllUnprocessed(): Promise<Array<UnprocessedType>> {
getAllUnprocessedAndIncrementAttempts(): Promise<Array<UnprocessedType>> {
return this.withZone(GLOBAL_ZONE, 'getAllUnprocessed', async () => {
return window.Signal.Data.getAllUnprocessed();
return window.Signal.Data.getAllUnprocessedAndIncrementAttempts();
});
}

View File

@ -143,6 +143,7 @@ import { ReactionSource } from './reactions/ReactionSource';
import { singleProtoJobQueue } from './jobs/singleProtoJobQueue';
import { getInitialState } from './state/getInitialState';
import { conversationJobQueue } from './jobs/conversationJobQueue';
import { SeenStatus } from './MessageSeenStatus';
const MAX_ATTACHMENT_DOWNLOAD_AGE = 3600 * 72 * 1000;
@ -2177,9 +2178,6 @@ export async function startApp(): Promise<void> {
);
}
log.info('firstRun: disabling post link experience');
window.Signal.Util.postLinkExperience.stop();
// Switch to inbox view even if contact sync is still running
if (
window.reduxStore.getState().app.appView === AppViewType.Installer
@ -2646,13 +2644,6 @@ export async function startApp(): Promise<void> {
}
);
}
if (window.Signal.Util.postLinkExperience.isActive()) {
log.info(
'onContactReceived: Adding the message history disclaimer on link'
);
await conversation.addMessageHistoryDisclaimer();
}
} catch (error) {
log.error('onContactReceived error:', Errors.toLogFormat(error));
}
@ -2721,12 +2712,6 @@ export async function startApp(): Promise<void> {
window.Signal.Data.updateConversation(conversation.attributes);
if (window.Signal.Util.postLinkExperience.isActive()) {
log.info(
'onGroupReceived: Adding the message history disclaimer on link'
);
await conversation.addMessageHistoryDisclaimer();
}
const { expireTimer } = details;
const isValidExpireTimer = typeof expireTimer === 'number';
if (!isValidExpireTimer) {
@ -2920,6 +2905,7 @@ export async function startApp(): Promise<void> {
}
if (handleGroupCallUpdateMessage(data.message, messageDescriptor)) {
confirm();
return Promise.resolve();
}
@ -3052,22 +3038,24 @@ export async function startApp(): Promise<void> {
}
return new window.Whisper.Message({
source: window.textsecure.storage.user.getNumber(),
sourceUuid: window.textsecure.storage.user.getUuid()?.toString(),
sourceDevice: data.device,
sent_at: timestamp,
serverTimestamp: data.serverTimestamp,
received_at: data.receivedAtCounter,
received_at_ms: data.receivedAtDate,
conversationId: descriptor.id,
timestamp,
type: 'outgoing',
sendStateByConversationId,
unidentifiedDeliveries,
expirationStartTimestamp: Math.min(
data.expirationStartTimestamp || timestamp,
now
),
readStatus: ReadStatus.Read,
received_at_ms: data.receivedAtDate,
received_at: data.receivedAtCounter,
seenStatus: SeenStatus.NotApplicable,
sendStateByConversationId,
sent_at: timestamp,
serverTimestamp: data.serverTimestamp,
source: window.textsecure.storage.user.getNumber(),
sourceDevice: data.device,
sourceUuid: window.textsecure.storage.user.getUuid()?.toString(),
timestamp,
type: 'outgoing',
unidentifiedDeliveries,
} as Partial<MessageAttributesType> as WhatIsThis);
}
@ -3316,6 +3304,7 @@ export async function startApp(): Promise<void> {
unidentifiedDeliveryReceived: data.unidentifiedDeliveryReceived,
type: data.message.isStory ? 'story' : 'incoming',
readStatus: ReadStatus.Unread,
seenStatus: SeenStatus.Unseen,
timestamp: data.timestamp,
} as Partial<MessageAttributesType> as WhatIsThis);
}

View File

@ -14,7 +14,7 @@
import { assert } from './util/assert';
import { isOlderThan } from './util/timestamp';
import { parseRetryAfter } from './util/parseRetryAfter';
import { parseRetryAfterWithDefault } from './util/parseRetryAfter';
import { clearTimeoutIfNecessary } from './util/clearTimeoutIfNecessary';
import { getEnvironment, Environment } from './environment';
import type { StorageInterface } from './types/Storage.d';
@ -70,7 +70,7 @@ export const STORAGE_KEY = 'challenge:conversations';
export type RegisteredChallengeType = Readonly<{
conversationId: string;
createdAt: number;
retryAt: number;
retryAt?: number;
token?: string;
}>;
@ -80,7 +80,12 @@ const CAPTCHA_STAGING_URL =
'https://signalcaptchas.org/staging/challenge/generate.html';
function shouldStartQueue(registered: RegisteredChallengeType): boolean {
if (!registered.retryAt || registered.retryAt <= Date.now()) {
// No retryAt provided; waiting for user to complete captcha
if (!registered.retryAt) {
return false;
}
if (registered.retryAt <= Date.now()) {
return true;
}
@ -214,21 +219,26 @@ export class ChallengeHandler {
return;
}
const waitTime = Math.max(0, challenge.retryAt - Date.now());
const oldTimer = this.startTimers.get(conversationId);
if (oldTimer) {
clearTimeoutIfNecessary(oldTimer);
if (challenge.retryAt) {
const waitTime = Math.max(0, challenge.retryAt - Date.now());
const oldTimer = this.startTimers.get(conversationId);
if (oldTimer) {
clearTimeoutIfNecessary(oldTimer);
}
this.startTimers.set(
conversationId,
setTimeout(() => {
this.startTimers.delete(conversationId);
this.startQueue(conversationId);
}, waitTime)
);
log.info(
`challenge: tracking ${conversationId} with waitTime=${waitTime}`
);
} else {
log.info(`challenge: tracking ${conversationId} with no waitTime`);
}
this.startTimers.set(
conversationId,
setTimeout(() => {
this.startTimers.delete(conversationId);
this.startQueue(conversationId);
}, waitTime)
);
log.info(`challenge: tracking ${conversationId} with waitTime=${waitTime}`);
if (data && !data.options?.includes('recaptcha')) {
log.error(
@ -379,7 +389,9 @@ export class ChallengeHandler {
throw error;
}
const retryAfter = parseRetryAfter(error.responseHeaders['retry-after']);
const retryAfter = parseRetryAfterWithDefault(
error.responseHeaders['retry-after']
);
log.info(`challenge: retry after ${retryAfter}ms`);
this.options.onChallengeFailed(retryAfter);

View File

@ -34,7 +34,7 @@ export const About = ({
<div>
<a
className="acknowledgments"
href="https://github.com/signalapp/Signal-Desktop/blob/development/ACKNOWLEDGMENTS.md"
href="https://github.com/signalapp/Signal-Desktop/blob/main/ACKNOWLEDGMENTS.md"
>
{i18n('softwareAcknowledgments')}
</a>

View File

@ -0,0 +1,20 @@
// Copyright 2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import type { PropsType } from './AnimatedEmojiGalore';
import { AnimatedEmojiGalore } from './AnimatedEmojiGalore';
const story = storiesOf('Components/AnimatedEmojiGalore', module);
function getDefaultProps(): PropsType {
return {
emoji: '❤️',
onAnimationEnd: action('onAnimationEnd'),
};
}
story.add('Hearts', () => <AnimatedEmojiGalore {...getDefaultProps()} />);

View File

@ -0,0 +1,72 @@
// Copyright 2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React from 'react';
import { animated, to as interpolate, useSprings } from '@react-spring/web';
import { random } from 'lodash';
import { Emojify } from './conversation/Emojify';
export type PropsType = {
emoji: string;
onAnimationEnd: () => unknown;
rotate?: number;
scale?: number;
x?: number;
};
const NUM_EMOJIS = 16;
const MAX_HEIGHT = 1280;
const to = (i: number, f: () => unknown) => ({
delay: i * random(80, 120),
rotate: random(-24, 24),
scale: random(0.5, 1.0, true),
y: -144,
onRest: i === NUM_EMOJIS - 1 ? f : undefined,
});
const from = (_i: number) => ({
rotate: 0,
scale: 1,
y: MAX_HEIGHT,
});
function transform(y: number, scale: number, rotate: number): string {
return `translateY(${y}px) scale(${scale}) rotate(${rotate}deg)`;
}
export const AnimatedEmojiGalore = ({
emoji,
onAnimationEnd,
}: PropsType): JSX.Element => {
const [springs] = useSprings(NUM_EMOJIS, i => ({
...to(i, onAnimationEnd),
from: from(i),
config: {
mass: 20,
tension: 120,
friction: 80,
clamp: true,
},
}));
return (
<>
{springs.map((styles, index) => (
<animated.div
// eslint-disable-next-line react/no-array-index-key
key={index}
style={{
left: `${random(0, 100)}%`,
position: 'absolute',
transform: interpolate(
[styles.y, styles.scale, styles.rotate],
transform
),
}}
>
<Emojify sizeClass="extra-large" text={emoji} />
</animated.div>
))}
</>
);
};

View File

@ -14,7 +14,7 @@ import classNames from 'classnames';
import * as grapheme from '../util/grapheme';
import type { LocalizerType } from '../types/Util';
import { getClassNamesFor } from '../util/getClassNamesFor';
import { refMerger } from '../util/refMerger';
import { useRefMerger } from '../hooks/useRefMerger';
import { byteLength } from '../Bytes';
export type PropsType = {
@ -84,6 +84,7 @@ export const Input = forwardRef<
const valueOnKeydownRef = useRef<string>(value);
const selectionStartOnKeydownRef = useRef<number>(value.length);
const [isLarge, setIsLarge] = useState(false);
const refMerger = useRefMerger();
const maybeSetLarge = useCallback(() => {
if (!expandable) {

View File

@ -43,9 +43,23 @@ export const Stories = ({
});
const onNextUserStories = useCallback(() => {
// First find the next unread story if there are any
const nextUnreadIndex = stories.findIndex(conversationStory =>
conversationStory.stories.some(story => story.isUnread)
);
if (nextUnreadIndex >= 0) {
const nextStory = stories[nextUnreadIndex];
setConversationIdToView(nextStory.conversationId);
return;
}
// If not then play the next available story
const storyIndex = stories.findIndex(
x => x.conversationId === conversationIdToView
);
// If we've reached the end, close the viewer
if (storyIndex >= stories.length - 1 || storyIndex === -1) {
setConversationIdToView(undefined);
return;
@ -59,7 +73,8 @@ export const Stories = ({
x => x.conversationId === conversationIdToView
);
if (storyIndex <= 0) {
setConversationIdToView(undefined);
// Restart playback on the story if it's the oldest
setConversationIdToView(conversationIdToView);
return;
}
const prevStory = stories[storyIndex - 1];
@ -80,12 +95,12 @@ export const Stories = ({
<StoriesPane
hiddenStories={hiddenStories}
i18n={i18n}
onBack={toggleStoriesView}
onStoryClicked={setConversationIdToView}
openConversationInternal={openConversationInternal}
queueStoryDownload={queueStoryDownload}
stories={stories}
toggleHideStories={toggleHideStories}
toggleStoriesView={toggleStoriesView}
/>
</div>
</FocusTrap>

View File

@ -52,23 +52,23 @@ function getNewestStory(story: ConversationStoryType): StoryViewType {
export type PropsType = {
hiddenStories: Array<ConversationStoryType>;
i18n: LocalizerType;
onBack: () => unknown;
onStoryClicked: (conversationId: string) => unknown;
openConversationInternal: (_: { conversationId: string }) => unknown;
queueStoryDownload: (storyId: string) => unknown;
stories: Array<ConversationStoryType>;
toggleHideStories: (conversationId: string) => unknown;
toggleStoriesView: () => unknown;
};
export const StoriesPane = ({
hiddenStories,
i18n,
onBack,
onStoryClicked,
openConversationInternal,
queueStoryDownload,
stories,
toggleHideStories,
toggleStoriesView,
}: PropsType): JSX.Element => {
const [searchTerm, setSearchTerm] = useState('');
const [isShowingHiddenStories, setIsShowingHiddenStories] = useState(false);
@ -89,7 +89,7 @@ export const StoriesPane = ({
<button
aria-label={i18n('back')}
className="Stories__pane__header--back"
onClick={onBack}
onClick={toggleStoriesView}
tabIndex={0}
type="button"
/>
@ -119,11 +119,10 @@ export const StoriesPane = ({
onClick={() => {
onStoryClicked(story.conversationId);
}}
onHideStory={() => {
toggleHideStories(getNewestStory(story).sender.id);
}}
onHideStory={toggleHideStories}
onGoToConversation={conversationId => {
openConversationInternal({ conversationId });
toggleStoriesView();
}}
queueStoryDownload={queueStoryDownload}
story={getNewestStory(story)}
@ -149,11 +148,10 @@ export const StoriesPane = ({
onClick={() => {
onStoryClicked(story.conversationId);
}}
onHideStory={() => {
toggleHideStories(getNewestStory(story).sender.id);
}}
onHideStory={toggleHideStories}
onGoToConversation={conversationId => {
openConversationInternal({ conversationId });
toggleStoriesView();
}}
queueStoryDownload={queueStoryDownload}
story={getNewestStory(story)}

View File

@ -1,7 +1,8 @@
// Copyright 2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React, { useEffect } from 'react';
import type { ReactNode } from 'react';
import React, { useEffect, useRef } from 'react';
import classNames from 'classnames';
import { Blurhash } from 'react-blurhash';
@ -22,7 +23,9 @@ import { isVideoTypeSupported } from '../util/GoogleChrome';
export type PropsType = {
readonly attachment?: AttachmentType;
readonly children?: ReactNode;
readonly i18n: LocalizerType;
readonly isPaused?: boolean;
readonly isThumbnail?: boolean;
readonly label: string;
readonly moduleClassName?: string;
@ -32,7 +35,9 @@ export type PropsType = {
export const StoryImage = ({
attachment,
children,
i18n,
isPaused,
isThumbnail,
label,
moduleClassName,
@ -40,7 +45,11 @@ export const StoryImage = ({
storyId,
}: PropsType): JSX.Element | null => {
const shouldDownloadAttachment =
!isDownloaded(attachment) && !isDownloading(attachment);
!isDownloaded(attachment) &&
!isDownloading(attachment) &&
!hasNotResolved(attachment);
const videoRef = useRef<HTMLVideoElement | null>(null);
useEffect(() => {
if (shouldDownloadAttachment) {
@ -48,6 +57,18 @@ export const StoryImage = ({
}
}, [queueStoryDownload, shouldDownloadAttachment, storyId]);
useEffect(() => {
if (!videoRef.current) {
return;
}
if (isPaused) {
videoRef.current.pause();
} else {
videoRef.current.play();
}
}, [isPaused]);
if (!attachment) {
return null;
}
@ -61,7 +82,11 @@ export const StoryImage = ({
let storyElement: JSX.Element;
if (attachment.textAttachment) {
storyElement = (
<TextAttachment i18n={i18n} textAttachment={attachment.textAttachment} />
<TextAttachment
i18n={i18n}
isThumbnail={isThumbnail}
textAttachment={attachment.textAttachment}
/>
);
} else if (isNotReadyToShow) {
storyElement = (
@ -79,7 +104,9 @@ export const StoryImage = ({
autoPlay
className={getClassName('__image')}
controls={false}
key={attachment.url}
loop={shouldLoop}
ref={videoRef}
>
<source src={attachment.url} />
</video>
@ -98,10 +125,10 @@ export const StoryImage = ({
);
}
let spinner: JSX.Element | undefined;
let overlay: JSX.Element | undefined;
if (isPending) {
spinner = (
<div className="StoryImage__spinner-container">
overlay = (
<div className="StoryImage__overlay-container">
<div className="StoryImage__spinner-bubble" title={i18n('loading')}>
<Spinner moduleClassName="StoryImage__spinner" svgSize="small" />
</div>
@ -117,7 +144,8 @@ export const StoryImage = ({
)}
>
{storyElement}
{spinner}
{overlay}
{children}
</div>
);
};

View File

@ -23,6 +23,8 @@ function getDefaultProps(): PropsType {
return {
i18n,
onClick: action('onClick'),
onGoToConversation: action('onGoToConversation'),
onHideStory: action('onHideStory'),
queueStoryDownload: action('queueStoryDownload'),
story: {
messageId: '123',

View File

@ -40,7 +40,6 @@ export type StoryViewType = {
isHidden?: boolean;
isUnread?: boolean;
messageId: string;
selectedReaction?: string;
sender: Pick<
ConversationType,
| 'acceptedMessageRequest'
@ -63,8 +62,8 @@ export type PropsType = Pick<
> & {
i18n: LocalizerType;
onClick: () => unknown;
onGoToConversation?: (conversationId: string) => unknown;
onHideStory?: (conversationId: string) => unknown;
onGoToConversation: (conversationId: string) => unknown;
onHideStory: (conversationId: string) => unknown;
queueStoryDownload: (storyId: string) => unknown;
story: StoryViewType;
};
@ -218,7 +217,7 @@ export const StoryListItem = ({
: i18n('StoryListItem__hide'),
onClick: () => {
if (isHidden) {
onHideStory?.(sender.id);
onHideStory(sender.id);
} else {
setHasConfirmHideStory(true);
}
@ -228,7 +227,7 @@ export const StoryListItem = ({
icon: 'StoryListItem__icon--chat',
label: i18n('StoryListItem__go-to-chat'),
onClick: () => {
onGoToConversation?.(sender.id);
onGoToConversation(sender.id);
},
},
]}
@ -243,7 +242,7 @@ export const StoryListItem = ({
<ConfirmationDialog
actions={[
{
action: () => onHideStory?.(sender.id),
action: () => onHideStory(sender.id),
style: 'affirmative',
text: i18n('StoryListItem__hide-modal--confirm'),
},

View File

@ -27,6 +27,8 @@ function getDefaultProps(): PropsType {
loadStoryReplies: action('loadStoryReplies'),
markStoryRead: action('markStoryRead'),
onClose: action('onClose'),
onGoToConversation: action('onGoToConversation'),
onHideStory: action('onHideStory'),
onNextUserStories: action('onNextUserStories'),
onPrevUserStories: action('onPrevUserStories'),
onReactToStory: action('onReactToStory'),
@ -40,8 +42,10 @@ function getDefaultProps(): PropsType {
stories: [
{
attachment: fakeAttachment({
path: 'snow.jpg',
url: '/fixtures/snow.jpg',
}),
canReply: true,
messageId: '123',
sender,
timestamp: Date.now(),
@ -58,8 +62,10 @@ story.add('Wide story', () => (
stories={[
{
attachment: fakeAttachment({
path: 'file.jpg',
url: '/fixtures/nathan-anderson-316188-unsplash.jpg',
}),
canReply: true,
messageId: '123',
sender: getDefaultConversation(),
timestamp: Date.now(),
@ -87,6 +93,7 @@ story.add('Multi story', () => {
stories={[
{
attachment: fakeAttachment({
path: 'snow.jpg',
url: '/fixtures/snow.jpg',
}),
messageId: '123',
@ -95,8 +102,10 @@ story.add('Multi story', () => {
},
{
attachment: fakeAttachment({
path: 'file.jpg',
url: '/fixtures/nathan-anderson-316188-unsplash.jpg',
}),
canReply: true,
messageId: '456',
sender,
timestamp: Date.now() - 3600,
@ -106,19 +115,41 @@ story.add('Multi story', () => {
);
});
story.add('So many stories', () => {
const sender = getDefaultConversation();
return (
<StoryViewer
{...getDefaultProps()}
stories={Array(20).fill({
story.add('Caption', () => (
<StoryViewer
{...getDefaultProps()}
stories={[
{
attachment: fakeAttachment({
caption: 'This place looks lovely',
path: 'file.jpg',
url: '/fixtures/nathan-anderson-316188-unsplash.jpg',
}),
canReply: true,
messageId: '123',
sender: getDefaultConversation(),
timestamp: Date.now(),
},
]}
/>
));
story.add('Long Caption', () => (
<StoryViewer
{...getDefaultProps()}
stories={[
{
attachment: fakeAttachment({
caption:
'Snowycle, snowycle, snowycle\nI want to ride my snowycle, snowycle, snowycle\nI want to ride my snowycle\nI want to ride my snow\nI want to ride my snowycle\nI want to ride it where I like\nSnowycle, snowycle, snowycle\nI want to ride my snowycle, snowycle, snowycle\nI want to ride my snowycle\nI want to ride my snow\nI want to ride my snowycle\nI want to ride it where I like\nSnowycle, snowycle, snowycle\nI want to ride my snowycle, snowycle, snowycle\nI want to ride my snowycle\nI want to ride my snow\nI want to ride my snowycle\nI want to ride it where I like',
path: 'file.jpg',
url: '/fixtures/snow.jpg',
}),
canReply: true,
messageId: '123',
sender,
sender: getDefaultConversation(),
timestamp: Date.now(),
})}
/>
);
});
},
]}
/>
));

View File

@ -2,7 +2,14 @@
// SPDX-License-Identifier: AGPL-3.0-only
import FocusTrap from 'focus-trap-react';
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import React, {
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from 'react';
import classNames from 'classnames';
import { useSpring, animated, to } from '@react-spring/web';
import type { BodyRangeType, LocalizerType } from '../types/Util';
import type { ConversationType } from '../state/ducks/conversations';
@ -11,12 +18,16 @@ import type { PreferredBadgeSelectorType } from '../state/selectors/badges';
import type { RenderEmojiPickerProps } from './conversation/ReactionPicker';
import type { ReplyStateType } from '../types/Stories';
import type { StoryViewType } from './StoryListItem';
import { AnimatedEmojiGalore } from './AnimatedEmojiGalore';
import { Avatar, AvatarSize } from './Avatar';
import { ConfirmationDialog } from './ConfirmationDialog';
import { ContextMenuPopper } from './ContextMenu';
import { Intl } from './Intl';
import { MessageTimestamp } from './conversation/MessageTimestamp';
import { StoryImage } from './StoryImage';
import { StoryViewsNRepliesModal } from './StoryViewsNRepliesModal';
import { getAvatarColor } from '../types/Colors';
import { getStoryBackground } from '../util/getStoryBackground';
import { getStoryDuration } from '../util/getStoryDuration';
import { graphemeAwareSlice } from '../util/graphemeAwareSlice';
import { isDownloaded, isDownloading } from '../types/Attachment';
@ -40,6 +51,8 @@ export type PropsType = {
loadStoryReplies: (conversationId: string, messageId: string) => unknown;
markStoryRead: (mId: string) => unknown;
onClose: () => unknown;
onGoToConversation: (conversationId: string) => unknown;
onHideStory: (conversationId: string) => unknown;
onNextUserStories: () => unknown;
onPrevUserStories: () => unknown;
onSetSkinTone: (tone: number) => unknown;
@ -59,11 +72,19 @@ export type PropsType = {
replyState?: ReplyStateType;
skinTone?: number;
stories: Array<StoryViewType>;
views?: Array<string>;
};
const CAPTION_BUFFER = 20;
const CAPTION_INITIAL_LENGTH = 200;
const CAPTION_MAX_LENGTH = 700;
const MOUSE_IDLE_TIME = 3000;
enum Arrow {
None,
Left,
Right,
}
export const StoryViewer = ({
conversationId,
@ -73,6 +94,8 @@ export const StoryViewer = ({
loadStoryReplies,
markStoryRead,
onClose,
onGoToConversation,
onHideStory,
onNextUserStories,
onPrevUserStories,
onReactToStory,
@ -87,18 +110,26 @@ export const StoryViewer = ({
replyState,
skinTone,
stories,
views,
}: PropsType): JSX.Element => {
const [currentStoryIndex, setCurrentStoryIndex] = useState(0);
const [storyDuration, setStoryDuration] = useState<number | undefined>();
const [isShowingContextMenu, setIsShowingContextMenu] = useState(false);
const [hasConfirmHideStory, setHasConfirmHideStory] = useState(false);
const [referenceElement, setReferenceElement] =
useState<HTMLButtonElement | null>(null);
const [reactionEmoji, setReactionEmoji] = useState<string | undefined>();
const visibleStory = stories[currentStoryIndex];
const { attachment, canReply, messageId, timestamp } = visibleStory;
const { attachment, canReply, isHidden, messageId, timestamp } = visibleStory;
const {
acceptedMessageRequest,
avatarPath,
color,
isMe,
id,
firstName,
name,
profileName,
sharedGroupNames,
@ -137,6 +168,23 @@ export const StoryViewer = ({
setHasExpandedCaption(false);
}, [messageId]);
// These exist to change currentStoryIndex to the oldest unread story a user
// has, or set to 0 whenever conversationId changes.
// We use a ref so that we only depend on conversationId changing, since
// the stories Array will change once we mark as story as viewed.
const storiesRef = useRef(stories);
useEffect(() => {
const unreadStoryIndex = storiesRef.current.findIndex(
story => story.isUnread
);
setCurrentStoryIndex(unreadStoryIndex < 0 ? 0 : unreadStoryIndex);
}, [conversationId]);
useEffect(() => {
storiesRef.current = stories;
}, [stories]);
// Either we show the next story in the current user's stories or we ask
// for the next user's stories.
const showNextStory = useCallback(() => {
@ -195,6 +243,11 @@ export const StoryViewer = ({
// We need to be careful about this effect refreshing, it should only run
// every time a story changes or its duration changes.
useEffect(() => {
if (!storyDuration) {
spring.stop();
return;
}
spring.start({
config: {
duration: storyDuration,
@ -208,13 +261,20 @@ export const StoryViewer = ({
};
}, [currentStoryIndex, spring, storyDuration]);
const shouldPauseViewing =
hasConfirmHideStory ||
hasExpandedCaption ||
hasReplyModal ||
isShowingContextMenu ||
Boolean(reactionEmoji);
useEffect(() => {
if (hasReplyModal) {
if (shouldPauseViewing) {
spring.pause();
} else {
spring.resume();
}
}, [hasReplyModal, spring]);
}, [shouldPauseViewing, spring]);
useEffect(() => {
markStoryRead(messageId);
@ -230,7 +290,7 @@ export const StoryViewer = ({
.map(story => story.messageId);
}, [stories]);
useEffect(() => {
storiesToDownload.forEach(id => queueStoryDownload(id));
storiesToDownload.forEach(storyId => queueStoryDownload(storyId));
}, [queueStoryDownload, storiesToDownload]);
const navigateStories = useCallback(
@ -264,20 +324,248 @@ export const StoryViewer = ({
loadStoryReplies(conversationId, messageId);
}, [conversationId, isGroupStory, loadStoryReplies, messageId]);
const [arrowToShow, setArrowToShow] = useState<Arrow>(Arrow.None);
useEffect(() => {
if (arrowToShow === Arrow.None) {
return;
}
let lastMouseMove: number | undefined;
function updateLastMouseMove() {
lastMouseMove = Date.now();
}
function checkMouseIdle() {
requestAnimationFrame(() => {
if (lastMouseMove && Date.now() - lastMouseMove > MOUSE_IDLE_TIME) {
setArrowToShow(Arrow.None);
} else {
checkMouseIdle();
}
});
}
checkMouseIdle();
document.addEventListener('mousemove', updateLastMouseMove);
return () => {
lastMouseMove = undefined;
document.removeEventListener('mousemove', updateLastMouseMove);
};
}, [arrowToShow]);
const replies =
replyState && replyState.messageId === messageId ? replyState.replies : [];
const viewCount = 0;
const viewCount = (views || []).length;
const replyCount = replies.length;
return (
<FocusTrap focusTrapOptions={{ allowOutsideClick: true }}>
<div className="StoryViewer">
<div className="StoryViewer__overlay" />
<div
className="StoryViewer__overlay"
style={{ background: getStoryBackground(attachment) }}
/>
<div className="StoryViewer__content">
<button
aria-label={i18n('back')}
className={classNames(
'StoryViewer__arrow StoryViewer__arrow--left',
{
'StoryViewer__arrow--visible': arrowToShow === Arrow.Left,
}
)}
onClick={showPrevStory}
onMouseMove={() => setArrowToShow(Arrow.Left)}
type="button"
/>
<div className="StoryViewer__protection StoryViewer__protection--top" />
<div className="StoryViewer__container">
<StoryImage
attachment={attachment}
i18n={i18n}
isPaused={shouldPauseViewing}
label={i18n('lightboxImageAlt')}
moduleClassName="StoryViewer__story"
queueStoryDownload={queueStoryDownload}
storyId={messageId}
>
{reactionEmoji && (
<div className="StoryViewer__animated-emojis">
<AnimatedEmojiGalore
emoji={reactionEmoji}
onAnimationEnd={() => {
setReactionEmoji(undefined);
}}
/>
</div>
)}
</StoryImage>
{hasExpandedCaption && (
<button
aria-label={i18n('close-popup')}
className="StoryViewer__caption__overlay"
onClick={() => setHasExpandedCaption(false)}
type="button"
/>
)}
</div>
<div className="StoryViewer__meta">
{caption && (
<div className="StoryViewer__caption">
{caption.text}
{caption.hasReadMore && !hasExpandedCaption && (
<button
className="MessageBody__read-more"
onClick={() => {
setHasExpandedCaption(true);
}}
onKeyDown={(ev: React.KeyboardEvent) => {
if (ev.key === 'Space' || ev.key === 'Enter') {
setHasExpandedCaption(true);
}
}}
type="button"
>
...
{i18n('MessageBody--read-more')}
</button>
)}
</div>
)}
<Avatar
acceptedMessageRequest={acceptedMessageRequest}
avatarPath={avatarPath}
badge={undefined}
color={getAvatarColor(color)}
conversationType="direct"
i18n={i18n}
isMe={Boolean(isMe)}
name={name}
profileName={profileName}
sharedGroupNames={sharedGroupNames}
size={AvatarSize.TWENTY_EIGHT}
title={title}
/>
{group && (
<Avatar
acceptedMessageRequest={group.acceptedMessageRequest}
avatarPath={group.avatarPath}
badge={undefined}
className="StoryViewer__meta--group-avatar"
color={getAvatarColor(group.color)}
conversationType="group"
i18n={i18n}
isMe={false}
name={group.name}
profileName={group.profileName}
sharedGroupNames={group.sharedGroupNames}
size={AvatarSize.TWENTY_EIGHT}
title={group.title}
/>
)}
<div className="StoryViewer__meta--title">
{group
? i18n('Stories__from-to-group', {
name: title,
group: group.title,
})
: title}
</div>
<MessageTimestamp
i18n={i18n}
module="StoryViewer__meta--timestamp"
timestamp={timestamp}
/>
<div className="StoryViewer__progress">
{stories.map((story, index) => (
<div
className="StoryViewer__progress--container"
key={story.messageId}
>
{currentStoryIndex === index ? (
<animated.div
className="StoryViewer__progress--bar"
style={{
width: to([styles.width], width => `${width}%`),
}}
/>
) : (
<div
className="StoryViewer__progress--bar"
style={{
width: currentStoryIndex < index ? '0%' : '100%',
}}
/>
)}
</div>
))}
</div>
<div className="StoryViewer__actions">
{canReply && (
<button
className="StoryViewer__reply"
onClick={() => setHasReplyModal(true)}
tabIndex={0}
type="button"
>
<>
{viewCount > 0 &&
(viewCount === 1 ? (
<Intl
i18n={i18n}
id="MyStories__views--singular"
components={[<strong>{viewCount}</strong>]}
/>
) : (
<Intl
i18n={i18n}
id="MyStories__views--plural"
components={[<strong>{viewCount}</strong>]}
/>
))}
{viewCount > 0 && replyCount > 0 && ' '}
{replyCount > 0 &&
(replyCount === 1 ? (
<Intl
i18n={i18n}
id="MyStories__replies--singular"
components={[<strong>{replyCount}</strong>]}
/>
) : (
<Intl
i18n={i18n}
id="MyStories__replies--plural"
components={[<strong>{replyCount}</strong>]}
/>
))}
{!viewCount && !replyCount && i18n('StoryViewer__reply')}
</>
</button>
)}
</div>
</div>
<button
aria-label={i18n('forward')}
className={classNames(
'StoryViewer__arrow StoryViewer__arrow--right',
{
'StoryViewer__arrow--visible': arrowToShow === Arrow.Right,
}
)}
onClick={showNextStory}
onMouseMove={() => setArrowToShow(Arrow.Right)}
type="button"
/>
<div className="StoryViewer__protection StoryViewer__protection--bottom" />
<button
aria-label={i18n('MyStories__more')}
className="StoryViewer__more"
onClick={() => setIsShowingContextMenu(true)}
ref={setReferenceElement}
tabIndex={0}
type="button"
/>
@ -288,170 +576,55 @@ export const StoryViewer = ({
tabIndex={0}
type="button"
/>
<div className="StoryViewer__container">
<StoryImage
attachment={attachment}
i18n={i18n}
label={i18n('lightboxImageAlt')}
moduleClassName="StoryViewer__story"
queueStoryDownload={queueStoryDownload}
storyId={messageId}
/>
{hasExpandedCaption && (
<div className="StoryViewer__caption__overlay" />
)}
<div className="StoryViewer__meta">
{caption && (
<div className="StoryViewer__caption">
{caption.text}
{caption.hasReadMore && !hasExpandedCaption && (
<button
className="MessageBody__read-more"
onClick={() => {
setHasExpandedCaption(true);
}}
onKeyDown={(ev: React.KeyboardEvent) => {
if (ev.key === 'Space' || ev.key === 'Enter') {
setHasExpandedCaption(true);
}
}}
type="button"
>
...
{i18n('MessageBody--read-more')}
</button>
)}
</div>
)}
<Avatar
acceptedMessageRequest={acceptedMessageRequest}
avatarPath={avatarPath}
badge={undefined}
color={getAvatarColor(color)}
conversationType="direct"
i18n={i18n}
isMe={Boolean(isMe)}
name={name}
profileName={profileName}
sharedGroupNames={sharedGroupNames}
size={AvatarSize.TWENTY_EIGHT}
title={title}
/>
{group && (
<Avatar
acceptedMessageRequest={group.acceptedMessageRequest}
avatarPath={group.avatarPath}
badge={undefined}
className="StoryViewer__meta--group-avatar"
color={getAvatarColor(group.color)}
conversationType="group"
i18n={i18n}
isMe={false}
name={group.name}
profileName={group.profileName}
sharedGroupNames={group.sharedGroupNames}
size={AvatarSize.TWENTY_EIGHT}
title={group.title}
/>
)}
<div className="StoryViewer__meta--title">
{group
? i18n('Stories__from-to-group', {
name: title,
group: group.title,
})
: title}
</div>
<MessageTimestamp
i18n={i18n}
module="StoryViewer__meta--timestamp"
timestamp={timestamp}
/>
<div className="StoryViewer__progress">
{stories.map((story, index) => (
<div
className="StoryViewer__progress--container"
key={story.messageId}
>
{currentStoryIndex === index ? (
<animated.div
className="StoryViewer__progress--bar"
style={{
width: to([styles.width], width => `${width}%`),
}}
/>
) : (
<div
className="StoryViewer__progress--bar"
style={{
width: currentStoryIndex < index ? '0%' : '100%',
}}
/>
)}
</div>
))}
</div>
</div>
</div>
<div className="StoryViewer__actions">
{isMe ? (
<>
{viewCount &&
(viewCount === 1 ? (
<Intl
i18n={i18n}
id="MyStories__views--singular"
components={[<strong>{viewCount}</strong>]}
/>
) : (
<Intl
i18n={i18n}
id="MyStories__views--plural"
components={[<strong>{viewCount}</strong>]}
/>
))}
{viewCount && replyCount && ' '}
{replyCount &&
(replyCount === 1 ? (
<Intl
i18n={i18n}
id="MyStories__replies--singular"
components={[<strong>{replyCount}</strong>]}
/>
) : (
<Intl
i18n={i18n}
id="MyStories__replies--plural"
components={[<strong>{replyCount}</strong>]}
/>
))}
</>
) : (
canReply && (
<button
className="StoryViewer__reply"
onClick={() => setHasReplyModal(true)}
tabIndex={0}
type="button"
>
{i18n('StoryViewer__reply')}
</button>
)
)}
</div>
</div>
<ContextMenuPopper
isMenuShowing={isShowingContextMenu}
menuOptions={[
{
icon: 'StoryListItem__icon--hide',
label: isHidden
? i18n('StoryListItem__unhide')
: i18n('StoryListItem__hide'),
onClick: () => {
if (isHidden) {
onHideStory(id);
} else {
setHasConfirmHideStory(true);
}
},
},
{
icon: 'StoryListItem__icon--chat',
label: i18n('StoryListItem__go-to-chat'),
onClick: () => {
onGoToConversation(id);
},
},
]}
onClose={() => setIsShowingContextMenu(false)}
popperOptions={{
placement: 'bottom',
strategy: 'absolute',
}}
referenceElement={referenceElement}
/>
{hasReplyModal && canReply && (
<StoryViewsNRepliesModal
authorTitle={title}
getPreferredBadge={getPreferredBadge}
i18n={i18n}
isGroupStory={isGroupStory}
isMyStory={isMe}
onClose={() => setHasReplyModal(false)}
onReact={emoji => {
onReactToStory(emoji, visibleStory);
setHasReplyModal(false);
setReactionEmoji(emoji);
}}
onReply={(message, mentions, replyTimestamp) => {
setHasReplyModal(false);
if (!isGroupStory) {
setHasReplyModal(false);
}
onReplyToStory(message, mentions, replyTimestamp, visibleStory);
}}
onSetSkinTone={onSetSkinTone}
@ -466,6 +639,23 @@ export const StoryViewer = ({
views={[]}
/>
)}
{hasConfirmHideStory && (
<ConfirmationDialog
actions={[
{
action: () => onHideStory(id),
style: 'affirmative',
text: i18n('StoryListItem__hide-modal--confirm'),
},
]}
i18n={i18n}
onClose={() => {
setHasConfirmHideStory(false);
}}
>
{i18n('StoryListItem__hide-modal--body', [String(firstName)])}
</ConfirmationDialog>
)}
</div>
</FocusTrap>
);

View File

@ -112,12 +112,17 @@ story.add('Views only', () => (
/>
));
story.add('In a group (no replies)', () => (
<StoryViewsNRepliesModal {...getDefaultProps()} isGroupStory />
));
story.add('In a group', () => {
const { views, replies } = getViewsAndReplies();
return (
<StoryViewsNRepliesModal
{...getDefaultProps()}
isGroupStory
replies={replies}
views={views}
/>

View File

@ -1,7 +1,7 @@
// Copyright 2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React, { useCallback, useState } from 'react';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import classNames from 'classnames';
import { usePopper } from 'react-popper';
import type { AttachmentType } from '../types/Attachment';
@ -52,6 +52,7 @@ export type PropsType = {
authorTitle: string;
getPreferredBadge: PreferredBadgeSelectorType;
i18n: LocalizerType;
isGroupStory?: boolean;
isMyStory?: boolean;
onClose: () => unknown;
onReact: (emoji: string) => unknown;
@ -76,6 +77,7 @@ export const StoryViewsNRepliesModal = ({
authorTitle,
getPreferredBadge,
i18n,
isGroupStory,
isMyStory,
onClose,
onReact,
@ -91,7 +93,8 @@ export const StoryViewsNRepliesModal = ({
storyPreviewAttachment,
views,
}: PropsType): JSX.Element => {
const inputApiRef = React.useRef<InputApi | undefined>();
const inputApiRef = useRef<InputApi | undefined>();
const [bottom, setBottom] = useState<HTMLDivElement | null>(null);
const [messageBodyText, setMessageBodyText] = useState('');
const [showReactionPicker, setShowReactionPicker] = useState(false);
@ -122,13 +125,19 @@ export const StoryViewsNRepliesModal = ({
strategy: 'fixed',
});
useEffect(() => {
if (replies.length) {
bottom?.scrollIntoView({ behavior: 'smooth' });
}
}, [bottom, replies.length]);
let composerElement: JSX.Element | undefined;
if (!isMyStory) {
composerElement = (
<div className="StoryViewsNRepliesModal__compose-container">
<div className="StoryViewsNRepliesModal__composer">
{!replies.length && (
{!isGroupStory && (
<Quote
authorTitle={authorTitle}
conversationColor="ultramarine"
@ -154,7 +163,10 @@ export const StoryViewsNRepliesModal = ({
setMessageBodyText(messageText);
}}
onPickEmoji={insertEmoji}
onSubmit={onReply}
onSubmit={(...args) => {
inputApiRef.current?.reset();
onReply(...args);
}}
onTextTooLong={onTextTooLong}
placeholder={i18n('StoryViewsNRepliesModal__placeholder')}
theme={ThemeType.dark}
@ -204,12 +216,48 @@ export const StoryViewsNRepliesModal = ({
);
}
const repliesElement = replies.length ? (
<div className="StoryViewsNRepliesModal__replies">
{replies.map(reply =>
reply.reactionEmoji ? (
<div className="StoryViewsNRepliesModal__reaction" key={reply.id}>
<div className="StoryViewsNRepliesModal__reaction--container">
let repliesElement: JSX.Element | undefined;
if (replies.length) {
repliesElement = (
<div className="StoryViewsNRepliesModal__replies">
{replies.map(reply =>
reply.reactionEmoji ? (
<div className="StoryViewsNRepliesModal__reaction" key={reply.id}>
<div className="StoryViewsNRepliesModal__reaction--container">
<Avatar
acceptedMessageRequest={reply.acceptedMessageRequest}
avatarPath={reply.avatarPath}
badge={undefined}
color={getAvatarColor(reply.color)}
conversationType="direct"
i18n={i18n}
isMe={Boolean(reply.isMe)}
name={reply.name}
profileName={reply.profileName}
sharedGroupNames={reply.sharedGroupNames || []}
size={AvatarSize.TWENTY_EIGHT}
title={reply.title}
/>
<div className="StoryViewsNRepliesModal__reaction--body">
<div className="StoryViewsNRepliesModal__reply--title">
<ContactName
contactNameColor={reply.contactNameColor}
title={reply.title}
/>
</div>
{i18n('StoryViewsNRepliesModal__reacted')}
<MessageTimestamp
i18n={i18n}
module="StoryViewsNRepliesModal__reply--timestamp"
timestamp={reply.timestamp}
/>
</div>
</div>
<Emojify text={reply.reactionEmoji} />
</div>
) : (
<div className="StoryViewsNRepliesModal__reply" key={reply.id}>
<Avatar
acceptedMessageRequest={reply.acceptedMessageRequest}
avatarPath={reply.avatarPath}
@ -224,14 +272,32 @@ export const StoryViewsNRepliesModal = ({
size={AvatarSize.TWENTY_EIGHT}
title={reply.title}
/>
<div className="StoryViewsNRepliesModal__reaction--body">
<div
className={classNames(
'StoryViewsNRepliesModal__message-bubble',
{
'StoryViewsNRepliesModal__message-bubble--doe': Boolean(
reply.deletedForEveryone
),
}
)}
>
<div className="StoryViewsNRepliesModal__reply--title">
<ContactName
contactNameColor={reply.contactNameColor}
title={reply.title}
/>
</div>
{i18n('StoryViewsNRepliesModal__reacted')}
<MessageBody
i18n={i18n}
text={
reply.deletedForEveryone
? i18n('message--deletedForEveryone')
: String(reply.body)
}
/>
<MessageTimestamp
i18n={i18n}
module="StoryViewsNRepliesModal__reply--timestamp"
@ -239,58 +305,18 @@ export const StoryViewsNRepliesModal = ({
/>
</div>
</div>
<Emojify text={reply.reactionEmoji} />
</div>
) : (
<div className="StoryViewsNRepliesModal__reply" key={reply.id}>
<Avatar
acceptedMessageRequest={reply.acceptedMessageRequest}
avatarPath={reply.avatarPath}
badge={undefined}
color={getAvatarColor(reply.color)}
conversationType="direct"
i18n={i18n}
isMe={Boolean(reply.isMe)}
name={reply.name}
profileName={reply.profileName}
sharedGroupNames={reply.sharedGroupNames || []}
size={AvatarSize.TWENTY_EIGHT}
title={reply.title}
/>
<div
className={classNames('StoryViewsNRepliesModal__message-bubble', {
'StoryViewsNRepliesModal__message-bubble--doe': Boolean(
reply.deletedForEveryone
),
})}
>
<div className="StoryViewsNRepliesModal__reply--title">
<ContactName
contactNameColor={reply.contactNameColor}
title={reply.title}
/>
</div>
<MessageBody
i18n={i18n}
text={
reply.deletedForEveryone
? i18n('message--deletedForEveryone')
: String(reply.body)
}
/>
<MessageTimestamp
i18n={i18n}
module="StoryViewsNRepliesModal__reply--timestamp"
timestamp={reply.timestamp}
/>
</div>
</div>
)
)}
</div>
) : undefined;
)
)}
<div ref={setBottom} />
</div>
);
} else if (isGroupStory) {
repliesElement = (
<div className="StoryViewsNRepliesModal__replies--none">
{i18n('StoryViewsNRepliesModal__no-replies')}
</div>
);
}
const viewsElement = views.length ? (
<div className="StoryViewsNRepliesModal__views">
@ -358,28 +384,26 @@ export const StoryViewsNRepliesModal = ({
</Tabs>
) : undefined;
const hasOnlyViewsElement =
viewsElement && !repliesElement && !composerElement;
return (
<Modal
i18n={i18n}
moduleClassName={classNames('StoryViewsNRepliesModal', {
'StoryViewsNRepliesModal--group': Boolean(
views.length && replies.length
),
})}
moduleClassName="StoryViewsNRepliesModal"
onClose={onClose}
useFocusTrap={!hasOnlyViewsElement}
useFocusTrap={Boolean(composerElement)}
theme={Theme.Dark}
>
{tabsElement || (
<>
{viewsElement}
{repliesElement}
{composerElement}
</>
)}
<div
className={classNames({
'StoryViewsNRepliesModal--group': Boolean(isGroupStory),
})}
>
{tabsElement || (
<>
{viewsElement || repliesElement}
{composerElement}
</>
)}
</div>
</Modal>
);
};

View File

@ -164,7 +164,20 @@ story.add('Link preview', () => (
preview: {
url: 'https://www.signal.org/workworkwork',
title: 'Signal >> Careers',
// TODO add image
},
}}
/>
));
story.add('Link preview (thumbnail)', () => (
<TextAttachment
{...getDefaultProps()}
isThumbnail
textAttachment={{
color: 4294951251,
preview: {
url: 'https://www.signal.org/workworkwork',
title: 'Signal >> Careers',
},
}}
/>

View File

@ -13,6 +13,10 @@ import { TextAttachmentStyleType } from '../types/Attachment';
import { count } from '../util/grapheme';
import { getDomain } from '../types/LinkPreview';
import { getFontNameByTextScript } from '../util/getFontNameByTextScript';
import {
getHexFromNumber,
getBackgroundColor,
} from '../util/getStoryBackground';
const renderNewLines: RenderTextCallbackType = ({
text: textWithNewLines,
@ -36,6 +40,7 @@ enum TextSize {
export type PropsType = {
i18n: LocalizerType;
isThumbnail?: boolean;
textAttachment: TextAttachmentType;
};
@ -53,20 +58,6 @@ function getTextSize(text: string): TextSize {
return TextSize.Small;
}
function getHexFromNumber(color: number): string {
return `#${color.toString(16).slice(2)}`;
}
function getBackground({ color, gradient }: TextAttachmentType): string {
if (gradient) {
return `linear-gradient(${gradient.angle}deg, ${getHexFromNumber(
gradient.startColor || COLOR_WHITE_INT
)}, ${getHexFromNumber(gradient.endColor || COLOR_WHITE_INT)})`;
}
return getHexFromNumber(color || COLOR_WHITE_INT);
}
function getFont(
text: string,
textSize: TextSize,
@ -95,6 +86,7 @@ function getFont(
export const TextAttachment = ({
i18n,
isThumbnail,
textAttachment,
}: PropsType): JSX.Element | null => {
const linkPreview = useRef<HTMLDivElement | null>(null);
@ -123,7 +115,7 @@ export const TextAttachment = ({
<div
className="TextAttachment__story"
style={{
background: getBackground(textAttachment),
background: getBackgroundColor(textAttachment),
transform: `scale(${(contentRect.bounds?.height || 1) / 1280})`,
}}
>
@ -159,25 +151,27 @@ export const TextAttachment = ({
)}
{textAttachment.preview && (
<>
{linkPreviewOffsetTop && textAttachment.preview.url && (
<a
className="TextAttachment__preview__tooltip"
href={textAttachment.preview.url}
rel="noreferrer"
style={{
top: linkPreviewOffsetTop - 150,
}}
target="_blank"
>
<div>
<div>{i18n('TextAttachment__preview__link')}</div>
<div className="TextAttachment__preview__tooltip__url">
{textAttachment.preview.url}
{linkPreviewOffsetTop &&
!isThumbnail &&
textAttachment.preview.url && (
<a
className="TextAttachment__preview__tooltip"
href={textAttachment.preview.url}
rel="noreferrer"
style={{
top: linkPreviewOffsetTop - 150,
}}
target="_blank"
>
<div>
<div>{i18n('TextAttachment__preview__link')}</div>
<div className="TextAttachment__preview__tooltip__url">
{textAttachment.preview.url}
</div>
</div>
</div>
<div className="TextAttachment__preview__tooltip__arrow" />
</a>
)}
<div className="TextAttachment__preview__tooltip__arrow" />
</a>
)}
<div
className={classNames('TextAttachment__preview', {
'TextAttachment__preview--large': Boolean(

View File

@ -3,7 +3,7 @@
import React from 'react';
import { Image } from './Image';
import { CurveType, Image } from './Image';
import { StagedGenericAttachment } from './StagedGenericAttachment';
import { StagedPlaceholderAttachment } from './StagedPlaceholderAttachment';
import type { LocalizerType } from '../../types/Util';
@ -109,7 +109,10 @@ export const AttachmentList = <T extends AttachmentType | AttachmentDraftType>({
i18n={i18n}
attachment={attachment}
isDownloaded={isDownloaded}
softCorners
curveBottomLeft={CurveType.Tiny}
curveBottomRight={CurveType.Tiny}
curveTopLeft={CurveType.Tiny}
curveTopRight={CurveType.Tiny}
playIconOverlay={isVideo}
height={IMAGE_HEIGHT}
width={IMAGE_WIDTH}

View File

@ -204,6 +204,9 @@ export const ConversationHero = ({
phoneNumber,
sharedGroupNames,
})}
<div className="module-conversation-hero__linkNotification">
{i18n('messageHistoryUnsynced')}
</div>
</div>
{isShowingMessageRequestWarning && (
<ConfirmationDialog

View File

@ -9,7 +9,7 @@ import { storiesOf } from '@storybook/react';
import { pngUrl } from '../../storybook/Fixtures';
import type { Props } from './Image';
import { Image } from './Image';
import { CurveType, Image } from './Image';
import { IMAGE_PNG } from '../../types/MIME';
import type { ThemeType } from '../../types/Util';
import { setupI18n } from '../../util/setupI18n';
@ -34,16 +34,22 @@ const createProps = (overrideProps: Partial<Props> = {}): Props => ({
blurHash: text('blurHash', overrideProps.blurHash || ''),
bottomOverlay: boolean('bottomOverlay', overrideProps.bottomOverlay || false),
closeButton: boolean('closeButton', overrideProps.closeButton || false),
curveBottomLeft: boolean(
curveBottomLeft: number(
'curveBottomLeft',
overrideProps.curveBottomLeft || false
overrideProps.curveBottomLeft || CurveType.None
),
curveBottomRight: boolean(
curveBottomRight: number(
'curveBottomRight',
overrideProps.curveBottomRight || false
overrideProps.curveBottomRight || CurveType.None
),
curveTopLeft: number(
'curveTopLeft',
overrideProps.curveTopLeft || CurveType.None
),
curveTopRight: number(
'curveTopRight',
overrideProps.curveTopRight || CurveType.None
),
curveTopLeft: boolean('curveTopLeft', overrideProps.curveTopLeft || false),
curveTopRight: boolean('curveTopRight', overrideProps.curveTopRight || false),
darkOverlay: boolean('darkOverlay', overrideProps.darkOverlay || false),
height: number('height', overrideProps.height || 100),
i18n,
@ -57,11 +63,6 @@ const createProps = (overrideProps: Partial<Props> = {}): Props => ({
'playIconOverlay',
overrideProps.playIconOverlay || false
),
smallCurveTopLeft: boolean(
'smallCurveTopLeft',
overrideProps.smallCurveTopLeft || false
),
softCorners: boolean('softCorners', overrideProps.softCorners || false),
tabIndex: number('tabIndex', overrideProps.tabIndex || 0),
theme: text('theme', overrideProps.theme || 'light') as ThemeType,
url: text('url', 'url' in overrideProps ? overrideProps.url || null : pngUrl),
@ -145,10 +146,10 @@ story.add('Pending w/blurhash', () => {
story.add('Curved Corners', () => {
const props = createProps({
curveBottomLeft: true,
curveBottomRight: true,
curveTopLeft: true,
curveTopRight: true,
curveBottomLeft: CurveType.Normal,
curveBottomRight: CurveType.Normal,
curveTopLeft: CurveType.Normal,
curveTopRight: CurveType.Normal,
});
return <Image {...props} />;
@ -156,7 +157,7 @@ story.add('Curved Corners', () => {
story.add('Small Curve Top Left', () => {
const props = createProps({
smallCurveTopLeft: true,
curveTopLeft: CurveType.Small,
});
return <Image {...props} />;
@ -164,7 +165,10 @@ story.add('Small Curve Top Left', () => {
story.add('Soft Corners', () => {
const props = createProps({
softCorners: true,
curveBottomLeft: CurveType.Tiny,
curveBottomRight: CurveType.Tiny,
curveTopLeft: CurveType.Tiny,
curveTopRight: CurveType.Tiny,
});
return <Image {...props} />;

View File

@ -13,6 +13,13 @@ import {
defaultBlurHash,
} from '../../types/Attachment';
export enum CurveType {
None = 0,
Tiny = 4,
Small = 10,
Normal = 18,
}
export type Props = {
alt: string;
attachment: AttachmentType;
@ -32,16 +39,13 @@ export type Props = {
noBackground?: boolean;
bottomOverlay?: boolean;
closeButton?: boolean;
curveBottomLeft?: boolean;
curveBottomRight?: boolean;
curveTopLeft?: boolean;
curveTopRight?: boolean;
smallCurveTopLeft?: boolean;
curveBottomLeft?: CurveType;
curveBottomRight?: CurveType;
curveTopLeft?: CurveType;
curveTopRight?: CurveType;
darkOverlay?: boolean;
playIconOverlay?: boolean;
softCorners?: boolean;
blurHash?: string;
i18n: LocalizerType;
@ -158,8 +162,6 @@ export class Image extends React.Component<Props> {
onError,
overlayText,
playIconOverlay,
smallCurveTopLeft,
softCorners,
tabIndex,
theme,
url,
@ -176,25 +178,25 @@ export class Image extends React.Component<Props> {
const resolvedBlurHash = blurHash || defaultBlurHash(theme);
const overlayClassName = classNames('module-image__border-overlay', {
'module-image__border-overlay--with-border': !noBorder,
'module-image__border-overlay--with-click-handler': canClick,
'module-image--curved-top-left': curveTopLeft,
'module-image--curved-top-right': curveTopRight,
'module-image--curved-bottom-left': curveBottomLeft,
'module-image--curved-bottom-right': curveBottomRight,
'module-image--small-curved-top-left': smallCurveTopLeft,
'module-image--soft-corners': softCorners,
'module-image__border-overlay--dark': darkOverlay,
'module-image--not-downloaded': imgNotDownloaded,
});
const curveStyles = {
borderTopLeftRadius: curveTopLeft || CurveType.None,
borderTopRightRadius: curveTopRight || CurveType.None,
borderBottomLeftRadius: curveBottomLeft || CurveType.None,
borderBottomRightRadius: curveBottomRight || CurveType.None,
};
const overlay = canClick ? (
// Not sure what this button does.
// eslint-disable-next-line jsx-a11y/control-has-associated-label
<button
type="button"
className={overlayClassName}
className={classNames('module-image__border-overlay', {
'module-image__border-overlay--with-border': !noBorder,
'module-image__border-overlay--with-click-handler': canClick,
'module-image__border-overlay--dark': darkOverlay,
'module-image--not-downloaded': imgNotDownloaded,
})}
style={curveStyles}
onClick={this.handleClick}
onKeyDown={this.handleKeyDown}
tabIndex={tabIndex}
@ -210,15 +212,13 @@ export class Image extends React.Component<Props> {
'module-image',
className,
!noBackground ? 'module-image--with-background' : null,
curveBottomLeft ? 'module-image--curved-bottom-left' : null,
curveBottomRight ? 'module-image--curved-bottom-right' : null,
curveTopLeft ? 'module-image--curved-top-left' : null,
curveTopRight ? 'module-image--curved-top-right' : null,
smallCurveTopLeft ? 'module-image--small-curved-top-left' : null,
softCorners ? 'module-image--soft-corners' : null,
cropWidth || cropHeight ? 'module-image--cropped' : null
)}
style={{ width: width - cropWidth, height: height - cropHeight }}
style={{
width: width - cropWidth,
height: height - cropHeight,
...curveStyles,
}}
>
{pending ? (
this.renderPending()
@ -248,11 +248,11 @@ export class Image extends React.Component<Props> {
) : null}
{bottomOverlay ? (
<div
className={classNames(
'module-image__bottom-overlay',
curveBottomLeft ? 'module-image--curved-bottom-left' : null,
curveBottomRight ? 'module-image--curved-bottom-right' : null
)}
className="module-image__bottom-overlay"
style={{
borderBottomLeftRadius: curveBottomLeft || CurveType.None,
borderBottomRightRadius: curveBottomRight || CurveType.None,
}}
/>
) : null}
{!pending && !imgNotDownloaded && playIconOverlay ? (

View File

@ -37,6 +37,7 @@ const createProps = (overrideProps: Partial<Props> = {}): Props => ({
}),
],
bottomOverlay: boolean('bottomOverlay', overrideProps.bottomOverlay || false),
direction: overrideProps.direction || 'incoming',
i18n,
isSticker: boolean('isSticker', overrideProps.isSticker || false),
onClick: action('onClick'),

View File

@ -14,18 +14,23 @@ import {
isVideoAttachment,
} from '../../types/Attachment';
import { Image } from './Image';
import { Image, CurveType } from './Image';
import type { LocalizerType, ThemeType } from '../../types/Util';
export type DirectionType = 'incoming' | 'outgoing';
export type Props = {
attachments: Array<AttachmentType>;
withContentAbove?: boolean;
withContentBelow?: boolean;
bottomOverlay?: boolean;
direction: DirectionType;
isSticker?: boolean;
shouldCollapseAbove?: boolean;
shouldCollapseBelow?: boolean;
stickerSize?: number;
tabIndex?: number;
withContentAbove?: boolean;
withContentBelow?: boolean;
i18n: LocalizerType;
theme?: ThemeType;
@ -36,27 +41,85 @@ export type Props = {
const GAP = 1;
function getCurves({
direction,
shouldCollapseAbove,
shouldCollapseBelow,
withContentAbove,
withContentBelow,
}: {
direction: DirectionType;
shouldCollapseAbove?: boolean;
shouldCollapseBelow?: boolean;
withContentAbove?: boolean;
withContentBelow?: boolean;
}): {
curveTopLeft: CurveType;
curveTopRight: CurveType;
curveBottomLeft: CurveType;
curveBottomRight: CurveType;
} {
let curveTopLeft = CurveType.None;
let curveTopRight = CurveType.None;
let curveBottomLeft = CurveType.None;
let curveBottomRight = CurveType.None;
if (shouldCollapseAbove && direction === 'incoming') {
curveTopLeft = CurveType.Tiny;
curveTopRight = CurveType.Normal;
} else if (shouldCollapseAbove && direction === 'outgoing') {
curveTopLeft = CurveType.Normal;
curveTopRight = CurveType.Tiny;
} else if (!withContentAbove) {
curveTopLeft = CurveType.Normal;
curveTopRight = CurveType.Normal;
}
if (shouldCollapseBelow && direction === 'incoming') {
curveBottomLeft = CurveType.Tiny;
curveBottomRight = CurveType.None;
} else if (shouldCollapseBelow && direction === 'outgoing') {
curveBottomLeft = CurveType.None;
curveBottomRight = CurveType.Tiny;
} else if (!withContentBelow) {
curveBottomLeft = CurveType.Normal;
curveBottomRight = CurveType.Normal;
}
return {
curveTopLeft,
curveTopRight,
curveBottomLeft,
curveBottomRight,
};
}
export const ImageGrid = ({
attachments,
bottomOverlay,
direction,
i18n,
isSticker,
stickerSize,
onError,
onClick,
shouldCollapseAbove,
shouldCollapseBelow,
tabIndex,
theme,
withContentAbove,
withContentBelow,
}: Props): JSX.Element | null => {
const curveTopLeft = !withContentAbove;
const curveTopRight = curveTopLeft;
const { curveTopLeft, curveTopRight, curveBottomLeft, curveBottomRight } =
getCurves({
direction,
shouldCollapseAbove,
shouldCollapseBelow,
withContentAbove,
withContentBelow,
});
const curveBottom = !withContentBelow;
const curveBottomLeft = curveBottom;
const curveBottomRight = curveBottom;
const withBottomOverlay = Boolean(bottomOverlay && curveBottom);
const withBottomOverlay = Boolean(bottomOverlay && !withContentBelow);
if (!attachments || !attachments.length) {
return null;

View File

@ -1,16 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react';
import { storiesOf } from '@storybook/react';
import { setupI18n } from '../../util/setupI18n';
import enMessages from '../../../_locales/en/messages.json';
import { LinkNotification } from './LinkNotification';
const story = storiesOf('Components/Conversation/LinkNotification', module);
const i18n = setupI18n('en', enMessages);
story.add('Default', () => <LinkNotification i18n={i18n} />);

View File

@ -1,13 +0,0 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react';
import { SystemMessage } from './SystemMessage';
import type { LocalizerType } from '../../types/Util';
export const LinkNotification = ({
i18n,
}: Readonly<{ i18n: LocalizerType }>): JSX.Element => (
<SystemMessage icon="unsynced" contents={i18n('messageHistoryUnsynced')} />
);

View File

@ -222,15 +222,30 @@ const renderMany = (propsArray: ReadonlyArray<Props>) =>
/>
));
const renderBothDirections = (props: Props) =>
renderMany([
props,
{
const renderThree = (props: Props) => renderMany([props, props, props]);
const renderBothDirections = (props: Props) => (
<>
{renderThree(props)}
{renderThree({
...props,
author: { ...props.author, id: getDefaultConversation().id },
direction: 'outgoing',
},
]);
})}
</>
);
const renderSingleBothDirections = (props: Props) => (
<>
<Message {...props} />
<Message
{...{
...props,
author: { ...props.author, id: getDefaultConversation().id },
direction: 'outgoing',
}}
/>
</>
);
story.add('Plain Message', () => {
const props = createProps({
@ -353,7 +368,7 @@ story.add('Delivered', () => {
text: 'Hello there from a pal! I am sending a long message so that it will wrap a bit, since I like that look.',
});
return <Message {...props} />;
return renderThree(props);
});
story.add('Read', () => {
@ -363,7 +378,7 @@ story.add('Read', () => {
text: 'Hello there from a pal! I am sending a long message so that it will wrap a bit, since I like that look.',
});
return <Message {...props} />;
return renderThree(props);
});
story.add('Sending', () => {
@ -373,7 +388,7 @@ story.add('Sending', () => {
text: 'Hello there from a pal! I am sending a long message so that it will wrap a bit, since I like that look.',
});
return <Message {...props} />;
return renderThree(props);
});
story.add('Expiring', () => {
@ -502,7 +517,7 @@ story.add('Reactions (wider message)', () => {
],
});
return renderBothDirections(props);
return renderSingleBothDirections(props);
});
const joyReactions = Array.from({ length: 52 }, () => getJoyReaction());
@ -577,7 +592,7 @@ story.add('Reactions (short message)', () => {
],
});
return renderBothDirections(props);
return renderSingleBothDirections(props);
});
story.add('Avatar in Group', () => {
@ -588,7 +603,7 @@ story.add('Avatar in Group', () => {
text: 'Hello it is me, the saxophone.',
});
return <Message {...props} />;
return renderThree(props);
});
story.add('Badge in Group', () => {
@ -599,7 +614,7 @@ story.add('Badge in Group', () => {
text: 'Hello it is me, the saxophone.',
});
return <Message {...props} />;
return renderThree(props);
});
story.add('Sticker', () => {
@ -673,8 +688,8 @@ story.add('Deleted with error', () => {
return (
<>
<Message {...propsPartialError} />
<Message {...propsError} />
{renderThree(propsPartialError)}
{renderThree(propsError)}
</>
);
});
@ -684,9 +699,10 @@ story.add('Can delete for everyone', () => {
status: 'read',
text: 'I hope you get this.',
canDeleteForEveryone: true,
direction: 'outgoing',
});
return <Message {...props} direction="outgoing" />;
return renderThree(props);
});
story.add('Error', () => {
@ -916,7 +932,7 @@ story.add('Link Preview with too new a date', () => {
});
story.add('Image', () => {
const props = createProps({
const darkImageProps = createProps({
attachments: [
fakeAttachment({
url: '/fixtures/tina-rolf-269345-unsplash.jpg',
@ -928,8 +944,25 @@ story.add('Image', () => {
],
status: 'sent',
});
const lightImageProps = createProps({
attachments: [
fakeAttachment({
url: pngUrl,
fileName: 'the-sax.png',
contentType: IMAGE_PNG,
height: 240,
width: 320,
}),
],
status: 'sent',
});
return renderBothDirections(props);
return (
<>
{renderBothDirections(darkImageProps)}
{renderBothDirections(lightImageProps)}
</>
);
});
for (let i = 2; i <= 5; i += 1) {
@ -937,39 +970,39 @@ for (let i = 2; i <= 5; i += 1) {
const props = createProps({
attachments: [
fakeAttachment({
url: '/fixtures/tina-rolf-269345-unsplash.jpg',
fileName: 'tina-rolf-269345-unsplash.jpg',
contentType: IMAGE_JPEG,
width: 128,
height: 128,
url: pngUrl,
fileName: 'the-sax.png',
contentType: IMAGE_PNG,
height: 240,
width: 320,
}),
fakeAttachment({
url: '/fixtures/tina-rolf-269345-unsplash.jpg',
fileName: 'tina-rolf-269345-unsplash.jpg',
contentType: IMAGE_JPEG,
width: 128,
height: 128,
url: pngUrl,
fileName: 'the-sax.png',
contentType: IMAGE_PNG,
height: 240,
width: 320,
}),
fakeAttachment({
url: '/fixtures/tina-rolf-269345-unsplash.jpg',
fileName: 'tina-rolf-269345-unsplash.jpg',
contentType: IMAGE_JPEG,
width: 128,
height: 128,
url: pngUrl,
fileName: 'the-sax.png',
contentType: IMAGE_PNG,
height: 240,
width: 320,
}),
fakeAttachment({
url: '/fixtures/tina-rolf-269345-unsplash.jpg',
fileName: 'tina-rolf-269345-unsplash.jpg',
contentType: IMAGE_JPEG,
width: 128,
height: 128,
url: pngUrl,
fileName: 'the-sax.png',
contentType: IMAGE_PNG,
height: 240,
width: 320,
}),
fakeAttachment({
url: '/fixtures/tina-rolf-269345-unsplash.jpg',
fileName: 'tina-rolf-269345-unsplash.jpg',
contentType: IMAGE_JPEG,
width: 128,
height: 128,
url: pngUrl,
fileName: 'the-sax.png',
contentType: IMAGE_PNG,
height: 240,
width: 320,
}),
].slice(0, i),
status: 'sent',
@ -1316,7 +1349,7 @@ story.add('TapToView Error', () => {
status: 'sent',
});
return <Message {...props} />;
return renderThree(props);
});
story.add('Dangerous File Type', () => {
@ -1419,23 +1452,23 @@ story.add('Not approved, with link preview', () => {
story.add('Custom Color', () => (
<>
<Message
{...createProps({ text: 'Solid.' })}
direction="outgoing"
customColor={{
{renderThree({
...createProps({ text: 'Solid.' }),
direction: 'outgoing',
customColor: {
start: { hue: 82, saturation: 35 },
}}
/>
},
})}
<br style={{ clear: 'both' }} />
<Message
{...createProps({ text: 'Gradient.' })}
direction="outgoing"
customColor={{
{renderThree({
...createProps({ text: 'Gradient.' }),
direction: 'outgoing',
customColor: {
deg: 192,
start: { hue: 304, saturation: 85 },
end: { hue: 231, saturation: 76 },
}}
/>
},
})}
</>
));
@ -1506,20 +1539,18 @@ story.add('Collapsing text-only group messages', () => {
story.add('Story reply', () => {
const conversation = getDefaultConversation();
return (
<Message
{...createProps({ text: 'Wow!' })}
storyReplyContext={{
authorTitle: conversation.title,
conversationColor: ConversationColors[0],
isFromMe: false,
rawAttachment: fakeAttachment({
url: '/fixtures/snow.jpg',
thumbnail: fakeThumbnail('/fixtures/snow.jpg'),
}),
}}
/>
);
return renderThree({
...createProps({ text: 'Wow!' }),
storyReplyContext: {
authorTitle: conversation.title,
conversationColor: ConversationColors[0],
isFromMe: false,
rawAttachment: fakeAttachment({
url: '/fixtures/snow.jpg',
thumbnail: fakeThumbnail('/fixtures/snow.jpg'),
}),
},
});
});
const fullContact = {
@ -1559,7 +1590,7 @@ story.add('EmbeddedContact: Full Contact', () => {
return renderBothDirections(props);
});
story.add('EmbeddedContact: 2x Incoming, with Send Message', () => {
story.add('EmbeddedContact: with Send Message', () => {
const props = createProps({
contact: {
...fullContact,
@ -1568,19 +1599,7 @@ story.add('EmbeddedContact: 2x Incoming, with Send Message', () => {
},
direction: 'incoming',
});
return renderMany([props, props]);
});
story.add('EmbeddedContact: 2x Outgoing, with Send Message', () => {
const props = createProps({
contact: {
...fullContact,
firstNumber: fullContact.number[0].value,
uuid: UUID.generate().toString(),
},
direction: 'outgoing',
});
return renderMany([props, props]);
return renderBothDirections(props);
});
story.add('EmbeddedContact: Only Email', () => {

View File

@ -28,7 +28,7 @@ import { MessageMetadata } from './MessageMetadata';
import { MessageTextMetadataSpacer } from './MessageTextMetadataSpacer';
import { ImageGrid } from './ImageGrid';
import { GIF } from './GIF';
import { Image } from './Image';
import { CurveType, Image } from './Image';
import { ContactName } from './ContactName';
import type { QuotedAttachmentType } from './Quote';
import { Quote } from './Quote';
@ -908,18 +908,17 @@ export class Message extends React.PureComponent<Props, State> {
<div className={containerClassName}>
<ImageGrid
attachments={attachments}
withContentAbove={
isSticker || withContentAbove || shouldCollapseAbove
}
withContentBelow={
isSticker || withContentBelow || shouldCollapseBelow
}
direction={direction}
withContentAbove={isSticker || withContentAbove}
withContentBelow={isSticker || withContentBelow}
isSticker={isSticker}
stickerSize={STICKER_SIZE}
bottomOverlay={bottomOverlay}
i18n={i18n}
theme={theme}
onError={this.handleImageError}
theme={theme}
shouldCollapseAbove={shouldCollapseAbove}
shouldCollapseBelow={shouldCollapseBelow}
tabIndex={tabIndex}
onClick={attachment => {
if (!isDownloaded(attachment)) {
@ -1060,6 +1059,7 @@ export class Message extends React.PureComponent<Props, State> {
openLink,
previews,
quote,
shouldCollapseAbove,
theme,
kickOffAttachmentDownload,
} = this.props;
@ -1113,6 +1113,8 @@ export class Message extends React.PureComponent<Props, State> {
<ImageGrid
attachments={[first.image]}
withContentAbove={withContentAbove}
direction={direction}
shouldCollapseAbove={shouldCollapseAbove}
withContentBelow
onError={this.handleImageError}
i18n={i18n}
@ -1124,10 +1126,14 @@ export class Message extends React.PureComponent<Props, State> {
{first.image && previewHasImage && !isFullSizeImage ? (
<div className="module-message__link-preview__icon_container">
<Image
smallCurveTopLeft={!withContentAbove}
noBorder
noBackground
softCorners
curveBottomLeft={
withContentAbove ? CurveType.Tiny : CurveType.Small
}
curveBottomRight={CurveType.Tiny}
curveTopRight={CurveType.Tiny}
curveTopLeft={CurveType.Tiny}
alt={i18n('previewThumbnail', [first.domain])}
height={72}
width={72}
@ -2668,6 +2674,10 @@ export class Message extends React.PureComponent<Props, State> {
className={containerClassnames}
style={containerStyles}
onContextMenu={this.showContextMenu}
role="row"
onKeyDown={this.handleKeyDown}
onClick={this.handleClick}
tabIndex={-1}
>
{this.renderAuthor()}
{this.renderContents()}
@ -2717,7 +2727,6 @@ export class Message extends React.PureComponent<Props, State> {
// cannot be within another button
role="button"
onKeyDown={this.handleKeyDown}
onClick={this.handleClick}
onFocus={this.handleFocus}
ref={this.focusRef}
>

View File

@ -1,7 +1,13 @@
// Copyright 2021-2022 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React, { useRef, useEffect, useState } from 'react';
import React, {
useRef,
useEffect,
useState,
useReducer,
useCallback,
} from 'react';
import classNames from 'classnames';
import { noop } from 'lodash';
@ -9,6 +15,7 @@ import { assert } from '../../util/assert';
import type { LocalizerType } from '../../types/Util';
import type { AttachmentType } from '../../types/Attachment';
import { isDownloaded } from '../../types/Attachment';
import { missingCaseError } from '../../util/missingCaseError';
import type { DirectionType, MessageStatusType } from './Message';
import type { ComputePeaksResult } from '../GlobalAudioContext';
@ -133,6 +140,37 @@ const Button: React.FC<ButtonProps> = props => {
);
};
type StateType = Readonly<{
isPlaying: boolean;
currentTime: number;
lastAriaTime: number;
}>;
type ActionType = Readonly<
| {
type: 'SET_IS_PLAYING';
value: boolean;
}
| {
type: 'SET_CURRENT_TIME';
value: number;
}
>;
function reducer(state: StateType, action: ActionType): StateType {
if (action.type === 'SET_IS_PLAYING') {
return {
...state,
isPlaying: action.value,
lastAriaTime: state.currentTime,
};
}
if (action.type === 'SET_CURRENT_TIME') {
return { ...state, currentTime: action.value };
}
throw missingCaseError(action);
}
/**
* Display message audio attachment along with its waveform, duration, and
* toggle Play/Pause button.
@ -184,11 +222,27 @@ export const MessageAudio: React.FC<Props> = (props: Props) => {
activeAudioID === id && activeAudioContext === renderingContext;
const waveformRef = useRef<HTMLDivElement | null>(null);
const [isPlaying, setIsPlaying] = useState(
isActive && !(audio.paused || audio.ended)
const [{ isPlaying, currentTime, lastAriaTime }, dispatch] = useReducer(
reducer,
{
isPlaying: isActive && !(audio.paused || audio.ended),
currentTime: isActive ? audio.currentTime : 0,
lastAriaTime: isActive ? audio.currentTime : 0,
}
);
const [currentTime, setCurrentTime] = useState(
isActive ? audio.currentTime : 0
const setIsPlaying = useCallback(
(value: boolean) => {
dispatch({ type: 'SET_IS_PLAYING', value });
},
[dispatch]
);
const setCurrentTime = useCallback(
(value: number) => {
dispatch({ type: 'SET_CURRENT_TIME', value });
},
[dispatch]
);
// NOTE: Avoid division by zero
@ -326,7 +380,15 @@ export const MessageAudio: React.FC<Props> = (props: Props) => {
audio.removeEventListener('loadedmetadata', onLoadedMetadata);
audio.removeEventListener('durationchange', onDurationChange);
};
}, [id, audio, isActive, currentTime, duration]);
}, [
id,
audio,
isActive,
currentTime,
duration,
setCurrentTime,
setIsPlaying,
]);
// This effect detects `isPlaying` changes and starts/pauses playback when
// needed (+keeps waveform position and audio position in sync).
@ -457,10 +519,10 @@ export const MessageAudio: React.FC<Props> = (props: Props) => {
role="slider"
aria-label={i18n('MessageAudio--slider')}
aria-orientation="horizontal"
aria-valuenow={currentTime}
aria-valuenow={lastAriaTime}
aria-valuemin={0}
aria-valuemax={duration}
aria-valuetext={timeToText(currentTime)}
aria-valuetext={timeToText(lastAriaTime)}
>
{peaks.map((peak, i) => {
let height = Math.max(BAR_MIN_HEIGHT, BAR_MAX_HEIGHT * peak);
@ -531,6 +593,7 @@ export const MessageAudio: React.FC<Props> = (props: Props) => {
const metadata = (
<div className={`${CSS_BASE}__metadata`}>
<div
aria-hidden="true"
className={classNames(
`${CSS_BASE}__countdown`,
`${CSS_BASE}__countdown--${played ? 'played' : 'unplayed'}`

View File

@ -5,7 +5,7 @@ import React from 'react';
import classNames from 'classnames';
import { unescape } from 'lodash';
import { Image } from './Image';
import { CurveType, Image } from './Image';
import { LinkPreviewDate } from './LinkPreviewDate';
import type { AttachmentType } from '../../types/Attachment';
@ -51,7 +51,10 @@ export const StagedLinkPreview: React.FC<Props> = ({
<div className="module-staged-link-preview__icon-container">
<Image
alt={i18n('stagedPreviewThumbnail', [domain])}
softCorners
curveBottomLeft={CurveType.Tiny}
curveBottomRight={CurveType.Tiny}
curveTopRight={CurveType.Tiny}
curveTopLeft={CurveType.Tiny}
height={72}
width={72}
url={image.url}

View File

@ -337,11 +337,6 @@ const items: Record<string, TimelineItemType> = {
},
timestamp: Date.now(),
},
'id-15': {
type: 'linkNotification',
data: null,
timestamp: Date.now(),
},
};
const actions = () => ({
@ -540,9 +535,9 @@ const useProps = (overrideProps: Partial<PropsType> = {}): PropsType => ({
items: overrideProps.items || Object.keys(items),
scrollToIndex: overrideProps.scrollToIndex,
scrollToIndexCounter: 0,
totalUnread: number('totalUnread', overrideProps.totalUnread || 0),
oldestUnreadIndex:
number('oldestUnreadIndex', overrideProps.oldestUnreadIndex || 0) ||
totalUnseen: number('totalUnseen', overrideProps.totalUnseen || 0),
oldestUnseenIndex:
number('oldestUnseenIndex', overrideProps.oldestUnseenIndex || 0) ||
undefined,
invitedContactsForNewlyCreatedGroup:
overrideProps.invitedContactsForNewlyCreatedGroup || [],
@ -608,8 +603,8 @@ story.add('Empty (just hero)', () => {
story.add('Last Seen', () => {
const props = useProps({
oldestUnreadIndex: 13,
totalUnread: 2,
oldestUnseenIndex: 13,
totalUnseen: 2,
});
return <Timeline {...props} />;

View File

@ -88,10 +88,10 @@ export type PropsDataType = {
messageLoadingState?: TimelineMessageLoadingState;
isNearBottom?: boolean;
items: ReadonlyArray<string>;
oldestUnreadIndex?: number;
oldestUnseenIndex?: number;
scrollToIndex?: number;
scrollToIndexCounter: number;
totalUnread: number;
totalUnseen: number;
};
type PropsHousekeepingType = {
@ -342,7 +342,7 @@ export class Timeline extends React.Component<
items,
loadNewestMessages,
messageLoadingState,
oldestUnreadIndex,
oldestUnseenIndex,
selectMessage,
} = this.props;
const { newestBottomVisibleMessageId } = this.state;
@ -358,15 +358,15 @@ export class Timeline extends React.Component<
if (
newestBottomVisibleMessageId &&
isNumber(oldestUnreadIndex) &&
isNumber(oldestUnseenIndex) &&
items.findIndex(item => item === newestBottomVisibleMessageId) <
oldestUnreadIndex
oldestUnseenIndex
) {
if (setFocus) {
const messageId = items[oldestUnreadIndex];
const messageId = items[oldestUnseenIndex];
selectMessage(messageId, id);
} else {
this.scrollToItemIndex(oldestUnreadIndex);
this.scrollToItemIndex(oldestUnseenIndex);
}
} else if (haveNewest) {
this.scrollToBottom(setFocus);
@ -790,7 +790,7 @@ export class Timeline extends React.Component<
isSomeoneTyping,
items,
messageLoadingState,
oldestUnreadIndex,
oldestUnseenIndex,
onBlock,
onBlockAndReportSpam,
onDelete,
@ -804,7 +804,7 @@ export class Timeline extends React.Component<
reviewMessageRequestNameCollision,
showContactModal,
theme,
totalUnread,
totalUnseen,
unblurAvatar,
unreadCount,
updateSharedGroups,
@ -898,17 +898,17 @@ export class Timeline extends React.Component<
}
let unreadIndicatorPlacement: undefined | UnreadIndicatorPlacement;
if (oldestUnreadIndex === itemIndex) {
if (oldestUnseenIndex === itemIndex) {
unreadIndicatorPlacement = UnreadIndicatorPlacement.JustAbove;
messageNodes.push(
<LastSeenIndicator
key="last seen indicator"
count={totalUnread}
count={totalUnseen}
i18n={i18n}
ref={this.lastSeenIndicatorRef}
/>
);
} else if (oldestUnreadIndex === nextItemIndex) {
} else if (oldestUnseenIndex === nextItemIndex) {
unreadIndicatorPlacement = UnreadIndicatorPlacement.JustBelow;
}

View File

@ -417,10 +417,6 @@ storiesOf('Components/Conversation/TimelineItem', module)
startedTime: Date.now(),
},
},
{
type: 'linkNotification',
data: null,
},
{
type: 'profileChange',
data: {

View File

@ -23,7 +23,6 @@ import type {
PropsDataType as DeliveryIssueProps,
} from './DeliveryIssueNotification';
import { DeliveryIssueNotification } from './DeliveryIssueNotification';
import { LinkNotification } from './LinkNotification';
import type { PropsData as ChangeNumberNotificationProps } from './ChangeNumberNotification';
import { ChangeNumberNotification } from './ChangeNumberNotification';
import type { CallingNotificationType } from '../../util/callingNotification';
@ -69,10 +68,6 @@ type DeliveryIssueType = {
type: 'deliveryIssue';
data: DeliveryIssueProps;
};
type LinkNotificationType = {
type: 'linkNotification';
data: null;
};
type MessageType = {
type: 'message';
data: Omit<MessageProps, 'renderingContext'>;
@ -129,7 +124,6 @@ export type TimelineItemType = (
| GroupNotificationType
| GroupV1MigrationType
| GroupV2ChangeType
| LinkNotificationType
| MessageType
| ProfileChangeNotificationType
| ResetSessionNotificationType
@ -261,8 +255,6 @@ export class TimelineItem extends React.PureComponent<PropsType> {
i18n={i18n}
/>
);
} else if (item.type === 'linkNotification') {
notification = <LinkNotification i18n={i18n} />;
} else if (item.type === 'timerNotification') {
notification = (
<TimerNotification {...this.props} {...item.data} i18n={i18n} />

View File

@ -89,19 +89,20 @@ export class MediaGallery extends React.Component<Props, State> {
}
public override render(): JSX.Element {
const { i18n } = this.props;
const { selectedTab } = this.state;
return (
<div className="module-media-gallery" tabIndex={-1} ref={this.focusRef}>
<div className="module-media-gallery__tab-container">
<Tab
label="Media"
label={i18n('media')}
type="media"
isSelected={selectedTab === 'media'}
onSelect={this.handleTabSelect}
/>
<Tab
label="Documents"
label={i18n('documents')}
type="documents"
isSelected={selectedTab === 'documents'}
onSelect={this.handleTabSelect}

View File

@ -3,7 +3,7 @@
import { isRecord } from '../../util/isRecord';
import { HTTPError } from '../../textsecure/Errors';
import { parseRetryAfter } from '../../util/parseRetryAfter';
import { parseRetryAfterWithDefault } from '../../util/parseRetryAfter';
export function findRetryAfterTimeFromError(err: unknown): number {
let rawValue: unknown;
@ -16,5 +16,5 @@ export function findRetryAfterTimeFromError(err: unknown): number {
}
}
return parseRetryAfter(rawValue);
return parseRetryAfterWithDefault(rawValue);
}

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